Controlling Naze32 with Arduino Uno over SBUS

Hello Guys,

i searched days for a SBUS "Generator" and nothing works:

https://www.rcgroups.com/forums/showthread.php?2420473-Arduino-S-BUS-Packet-Generator-Code/page2 http://forum.arduino.cc/index.php?topic=99708.0

I tested every code i could find (fixed it before i know c++ and arduino very well) with an SBUS Inverter but nothing works, the terminal spits out characters but the Naze gets no input or only for a split of a second (sets receiver values to random)

Hope anybody can help with his own code or some tips or advices... :)

Working code:

For newest updates and maybe a full library later:
https://bitbucket.org/r3booz/arduinofutabasbus

SBUS.hpp

#ifndef SBUS_H
#define SBUS_H

#define SBUS_SERIAL_PORT Serial //Change to Serial1/2/3 for Mega etc
#define SBUS_CHANNEL_START 512  //Channel init value

class SBUS
{
public:
  SBUS();
  void Start();
  
  void BuildData();
  void WriteData();
  
  void SetChannel(unsigned char ch, unsigned int data)
  {
    if (ch<18) m_channelData[ch] = data;
  }
  unsigned int GetChannel(unsigned char ch)
  {
    if (ch<18) return m_channelData[ch]; else return 0;
  }
  
  void SetFailsafe(byte failsafe) {m_failsafeActive = failsafe;}
  byte GetFailsafe() {return m_failsafeActive;}
  void SetLostFrame(byte lostframe) {m_lostFrame = lostframe;}
  byte GetLostFrame() {return m_lostFrame;}
  
private:
  unsigned int m_channelData[18];
  byte m_failsafeActive = 0;
  byte m_lostFrame = 0;
  byte m_packetData[25];
  
  byte m_currentChannel = 0;
  byte m_currentChannelBit = 0;
  byte m_currentPacketBit = 0;
  byte m_packetPosition = 0;
};

SBUS::SBUS()
{
  for (unsigned char c=0;c<17;c++)
    m_channelData[c] = SBUS_CHANNEL_START;
  m_failsafeActive = 0;
  m_lostFrame = 0;
}

void SBUS::Start()
{
  SBUS_SERIAL_PORT.flush();
  SBUS_SERIAL_PORT.begin(100000);
}

void SBUS::BuildData()
{
  for(m_packetPosition = 0; m_packetPosition < 25; m_packetPosition++) m_packetData[m_packetPosition] = 0x00;  //Zero out packet data
  
  m_currentPacketBit = 0;
  m_packetPosition = 0;
  m_packetData[m_packetPosition] = 0x0F;  //Start Byte
  m_packetPosition++;
  
  for(m_currentChannel = 0; m_currentChannel < 16; m_currentChannel++)
  {
    for(m_currentChannelBit = 0; m_currentChannelBit < 11; m_currentChannelBit++)
    {
      if(m_currentPacketBit > 7)
      {
        m_currentPacketBit = 0;  //If we just set bit 7 in a previous step, reset the packet bit to 0 and
        m_packetPosition++;       //Move to the next packet byte
      }
      m_packetData[m_packetPosition] |= (((m_channelData[m_currentChannel]>>m_currentChannelBit) & 0x01)<<m_currentPacketBit);  //Downshift the channel data bit, then upshift it to set the packet data byte
      m_currentPacketBit++;
    }
  }
  if(m_channelData[16] > 1023) m_packetData[23] |= (1<<0);  //Any number above 1023 will set the digital servo bit
  if(m_channelData[17] > 1023) m_packetData[23] |= (1<<1);
  if(m_lostFrame != 0) m_packetData[23] |= (1<<2);          //Any number above 0 will set the lost frame and failsafe bits
  if(m_failsafeActive != 0) m_packetData[23] |= (1<<3);
  m_packetData[24] = 0x00;  //End byte  
}

void SBUS::WriteData()
{
  SBUS_SERIAL_PORT.write(m_packetData, 25);
}

#endif

With following wiring needed:

See attachment

inverter.png

Does it fly?

-jim lee

Yes it works like a charme :)

Setup: NRF24L01+PA+LNA + Arduino Nano + Naze32 Rev 6

Good on ya!

Why do you have a Serial.flush(); before Serial.begin();?

-jim lee

To make sure eventual data is transmitted before the possible baud change and serial reset.

In case somebody tries to do something like this:

void setup()
{
  Serial.begin(9600);
  Serial.println("Startup");
}

void loop
{
  SBUS sbus;
  while(true)
  {
    //SBUS build/write etc...
  }
}