Hello everybody,
I am having some trouble forwarding the RC channels through I2c to an arduino. The data flow looks like this:
RCreceiver- Pixhawx6x - I2c- arduino -servos
When the drone is flying, the pixhawk should control the propellers as usual. When landed, the forwarding of the RC-channels should allow an arduino board to control 4 Servos. The servos include some control logic whose driver is already available for Arduino.
I wrote an I2C driver that subscribes to the uOrb rc_channels topic, and forwards it to arduino (the slave in the i2c bus). It took me some time, but I think I got it right. I am a newbie to Nuttx, but C++ is my friend. Using the terminal I launch my driver:
arduino start -X
arduino status
Using my I2c debugger, I see the status of my board, everything is ok. The problem is that the uOrb poll function does not return anything.
Later I found that the task rc_input fails to start. Right after booting my FMU I type dmesg to find two weird lines:
INFO [rc_input] valid device required
ERROR [rc_input] Task start failed (-1)
I am not sure, but I think rc_input takes the raw rc channels from the receiver and translates it to some valid ranges (trimming?) and publishes in the uOrb topic. If rc_input fails to start my code cannot receive anything through uOrb, right?
So, what am I missing?
Any help would be appreciated.
For completeness, here is my RunImpl function and how I declared some variables:
int _rc_channels_sub_fd;
px4_pollfd_struct_t _fds[1];
_rc_channels_sub_fd = orb_subscribe(ORB_ID(rc_channels));
_fds[0].fd = _rc_channels_sub_fd;
_fds[0].events = POLLIN;
void
Arduino::RunImpl()
{
struct rc_channels_s rc_t;
int poll_ret = px4_poll(_fds, 1, 1000);
if ( poll_ret > 0 ) {
orb_copy(ORB_ID(rc_channels), _rc_channels_sub_fd, &rc_t);
_roll = rc_t.channels[0];
_pitch = rc_t.channels[1];
_yaw = rc_t.channels[2];
PX4_INFO("Rc channels:\t%lu\t%lu\t%lu", _roll, _pitch, _yaw);
}
else{
PX4_ERR("Nothing received!");
}
/* To scale from 0..255 -> 0..15 shift right by 4 bits */
const uint8_t msg[6] = {
SUB_ADDR_ROLL, static_cast<uint8_t> (_roll >> 4 ) ,
SUB_ADDR_PITCH, static_cast<uint8_t> (_pitch >> 4 ),
SUB_ADDR_YAW, static_cast<uint8_t> (_yaw >> 4 )
};
int ret = transfer(msg, sizeof(msg), nullptr, 0);
if (ret != OK)
PX4_ERR("Error sending");
/* re-queue ourselves to run again later */
ScheduleDelayed(TRANSMISSION_RATE);
}