NANO RP2040 Connect IBus RC Receiver

Does anyone have a hint as to how to get IBus working with a FlySky FS-i6X (FS-iA10B receiver) and an Arduino NANO RP2040 Connect using an IBus library?

With IBusBM, I get:

#include <IBusBM.h>
void setup() {}
void loop() {}

IBusBM Error:
'NRF_TIMER4' was not declared in this scope
if (NRF_TIMER4->EVENTS_COMPARE[0] == 1) {
^~~~~~~~~~

This code works to process IBus data from an RC receiver. There's no error checking though:

#include <string.h>
                  #define IBUS_BUFFSIZE 32    
                  #define IBUS_MAXCHANNELS 10 // I am using only 10 channels because my TX (FlySky i6) supports max 10 channels
                  #include <Servo.h>
                  static uint8_t ibusIndex = 0;
                  static uint8_t ibus[IBUS_BUFFSIZE] = {0};
                  static uint16_t rcValue[IBUS_MAXCHANNELS];
                  
                  static boolean rxFrameDone;
                  
                  int ch_width_1;
                  int ch_width_2;
                  int ch_width_3;
                  int ch_width_4;
                  int ch_width_5;
                  int ch_width_6;
                  int ch_width_7;
                  int ch_width_8;
                  int ch_width_9;
                  int ch_width_10;
                  
                  Servo ch1;
                  Servo ch2;
                  Servo ch3;
                  Servo ch4;
                  Servo ch5;
                  Servo ch6;
                  Servo ch7;
                  Servo ch8;
                  Servo ch9;
                  Servo ch10;
                  
                  void setup()
                  {
                    Serial.begin(115200);
                    ch1.attach(2);
                    ch2.attach(3);
                    ch3.attach(4);
                    ch4.attach(5);
                    ch5.attach(6);
                    ch6.attach(7);
                    ch7.attach(8);
                    ch8.attach(9);
                    ch9.attach(10);
                    ch10.attach(11);
                  }
                  
                  void loop()
                  {
                    readRx();
                   
                   }
                  
                  void readRx()
                  {
                    rxFrameDone = false;
                   
                    if (Serial.available())
                    {
                      uint8_t val = Serial.read();
                      // Look for 0x2040 as start of packet
                      if (ibusIndex == 0 && val != 0x20)
                      {
                        ibusIndex = 0;
                        return;
                      }
                      if (ibusIndex == 1 && val != 0x40)
                      {
                        ibusIndex = 0;
                        return;
                      }
                  
                      if (ibusIndex == IBUS_BUFFSIZE)
                      {
                        ibusIndex = 0;
                        int high=3;
                        int low=2;
                        for(int i=0;i<IBUS_MAXCHANNELS; i++)
                        {
                          rcValue[i] = (ibus[high] << 8) + ibus[low];
                          high += 2;
                          low += 2;
                        }
                        ch_width_1 = map(rcValue[0], 1000, 2000, 1000, 2000);
                        ch1.writeMicroseconds(ch_width_1);
                  
                        //Serial.print(ch_width_1);
                        //Serial.print("     ");
                  
                        ch_width_2 = map(rcValue[1], 1000, 2000, 1000, 2000);
                        ch2.writeMicroseconds(ch_width_2);
                  
                        //Serial.print(ch_width_2);
                        //Serial.print("     ");
                  
                        ch_width_3 = map(rcValue[2], 1000, 2000, 1000, 2000);
                        ch3.writeMicroseconds(ch_width_3);
                  
                        //Serial.print(ch_width_3);
                        //Serial.print("     ");
                  
                        ch_width_4 = map(rcValue[3], 1000, 2000, 1000, 2000);
                        ch4.writeMicroseconds(ch_width_4);
                  
                        //Serial.print(ch_width_4);
                        //Serial.print("     ");
                                    
                        ch_width_5 = map(rcValue[4], 1000, 2000, 1000, 2000);
                        ch5.writeMicroseconds(ch_width_5);
                  
                        //Serial.print(ch_width_5);
                        //Serial.print("      ");
                  
                        ch_width_6 = map(rcValue[5], 1000, 2000, 1000, 2000);
                        ch6.writeMicroseconds(ch_width_6);
                  
                        //Serial.print(ch_width_6);
                        //Serial.print("      ");
                  
                        ch_width_7 = map(rcValue[6], 1000, 2000, 1000, 2000);
                        ch7.writeMicroseconds(ch_width_7);
                  
                        //Serial.print(ch_width_7);
                        //Serial.print("      ");
                       
                       
                        ch_width_8 = map(rcValue[7], 1000, 2000, 1000, 2000);
                        ch8.writeMicroseconds(ch_width_8);
                        //Serial.print(ch_width_8);
                        //Serial.print("     ");
                       
                        ch_width_9 = map(rcValue[8], 1000, 2000, 1000, 2000);
                        ch9.writeMicroseconds(ch_width_9);
                  
                        //Serial.print(ch_width_9);
                        //Serial.print("     ");
                  
                        ch_width_10 = map(rcValue[9], 1000, 2000, 1000, 2000);
                        ch10.writeMicroseconds(ch_width_10);
                  
                        //Serial.print(ch_width_10);
                        //Serial.println("     ");
                                                  
                        rxFrameDone = true;
                        return;
                      }
                      else
                      {
                        ibus[ibusIndex] = val;
                        ibusIndex++;
                      }
                    }
                  }

This library has some error checking, but I haven't tried it yet. Seems like it should work:

There's enough information there to get you started.

RC receivers usually put out 5 volts, so make sure to use a level converter to bring the signal down to 3.3 volts for the NANO RP2040 CONNECT.

Happy New Year!

1 Like

Hi @jhaytera ,

I have some trouble to get this with my RPI Pico working.
I watched the whole video. I also "uncommented" the Serial.Print stuff.

So far, so good. But I don't know how to use this code on the RPI Pico.(Better: I get no output at the serial monitor)
I think I need to add a definiton for the RX Pin but I don't know how. I'll be very thankfull if you (or someone) could help me.

Thanks! Jakob

Edit: I disconnectet the pins before every upload.

From my knowledge, I don't know. I did a search and found this:

Seems like some good information there. Hope it helps.

And, welcome aboard! :slight_smile:

Thanks,
I'll have a look at your link.

Big big Thanks for this :point_down: . Btw this GitHub - VICLER/iBus: Arduino library for decoding iBus receiver signals small library worked also for me. But cause of an limit for new users, I wasn't able to write this as answer :frowning:

I'm incorporating 10 channel RC control for my robot and made a few changes to say the least. This should work for you. It's what I'm using. Just change your UART Serial communication initialization to a serial port that works with your board, and you should be good to go. The code below works with the Portenta H7. Cheers!

#include <Arduino.h>

//--put in seperate file--------------------------------------------------------
#define IBUS_BUFFSIZE 32   
#define IBUS_MAXCHANNELS 10 // Supports 10 channel (FlySky i6)


static uint8_t ibusIndex = 0;
static uint8_t ibus[IBUS_BUFFSIZE] = {0};
static uint16_t rcValue[IBUS_MAXCHANNELS];

static boolean rxFrameDone;

//--Serial Comm Setup
UART myUART3(PJ_8,  PJ_9,  NC, NC);

void Setup_10CH_Receiver()
{
  myUART3.begin(115200);   
  myUART3.setTimeout(10);
}

void read_10CH()
{

  rxFrameDone = false;

  while (myUART3.available()) {
    uint8_t val = myUART3.read();
    // Look for 0x2040 as start of packet
    if (ibusIndex == 0 && val != 0x20)
    {
      ibusIndex = 0;
    }
    if (ibusIndex == 1 && val != 0x40)
    {
      ibusIndex = 0;
    }

    if (ibusIndex >= IBUS_BUFFSIZE)
    {
      int high=3;
      int low=2;
      for(uint8_t i=0;i<IBUS_MAXCHANNELS; i++)
      {
        uint16_t tmpValue = (ibus[high] << 8) + ibus[low];
        if (tmpValue >= 1000 && tmpValue <= 2000)
        {
          rcValue[i] = tmpValue;
        }
        high += 2;
        low += 2;
      }
          
      rxFrameDone = true;
      ibusIndex = 0;
    }
    else
    {
      ibus[ibusIndex] = val;
      ibusIndex++;
    }
  }
}

unsigned long delay_Check_10CH_Receiver = 0;

#define CHECK_10CH_RECEIVER_DELAY_MS 10
unsigned long check_10CH_Receiver = 0;

void Check_10CH_Receiver(unsigned long current_MS)
{
  if (current_MS - check_10CH_Receiver > CHECK_10CH_RECEIVER_DELAY_MS) {
    check_10CH_Receiver = current_MS;
    delay_Check_10CH_Receiver = millis();
    read_10CH();
    delay_Check_10CH_Receiver = millis() - delay_Check_10CH_Receiver;
  }
}
//--put in seperate file--------------------------------------------------------


unsigned long current_MS = 0;

#define TRANSMIT_DATA_DELAY_MS 10
unsigned long transmit_Data_MS = 0;


void setup() {
  // pinMode(LEDR, OUTPUT);
  // pinMode(LEDG, OUTPUT);
  // pinMode(LEDB, OUTPUT);
  // digitalWrite(LEDR, HIGH);
  // digitalWrite(LEDG, HIGH);
  // digitalWrite(LEDB, HIGH);
  
  Serial.begin(1000000); //115200);
  while (!Serial) delay(10);

  Serial.println("Initializing 10Channel RX"); Serial.flush();
  Setup_10CH_Receiver();

}


void loop() {
  current_MS = millis();

  Check_10CH_Receiver(current_MS);

  if (current_MS - transmit_Data_MS >= TRANSMIT_DATA_DELAY_MS) { 
      transmit_Data_MS = current_MS;
      
      Serial.print("10CH_RX " + String(delay_Check_10CH_Receiver) + "ms ");
      for (byte rx_10CH_Channel = 0; rx_10CH_Channel < IBUS_MAXCHANNELS; rx_10CH_Channel++)
      {
        Serial.print("," + String(rcValue[rx_10CH_Channel]));
      }
      Serial.println("");
  }
}




1 Like

Big big Thanks for this. Btw this GitHub - VICLER/iBus: Arduino library for decoding iBus receiver signals small library worked also for me. But cause of an limit for new users, I wasn't able to write this earlier haha.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.