Arduino Forum

Community => Exhibition / Gallery => Topic started by: mikesbaker on Apr 03, 2012, 06:55 pm

Title: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Apr 03, 2012, 06:55 pm
Hi guys,

http://www.futaba-rc.com/sbus/index.html (http://www.futaba-rc.com/sbus/index.html)

I needed to use both regular servos and SBUS servos for a project I have going on right now. SBUS is an interesting thing. It uses a 100000 baud inverted UART with a 25 byte transmission. Each channel is transmitted using 11 bits of data. There is also a start an end byte. They also use 2 stop bits and even parity. Now is where the fun comes in. The signal is transmitted big endian, but each of the individual bytes are little endian. I had figured all this stuff out when I stumbled upon this gem:

http://mbed.org/users/Digixx/notebook/futaba-s-bus-controlled-by-mbed/ (http://mbed.org/users/Digixx/notebook/futaba-s-bus-controlled-by-mbed/)

Not only did what they have to say confirm my reverse engineering suspicions, but they had already made a great algorithm to bit bang the transmission into the correct format. A thanks is also due to user fat16lib for his excellent serial library which allows things like changing the parity and stop bits. I modified the code the guys over at MBED had done and used a hex inverter and the results are perfect. I wrote basically none of this code and those that did allow free redistribution so go nuts. IMO the ability to use SBUS is pretty big for arduino. If I feel motivated I'll turn this into a proper library. But for now it is what it is. If you can read code, the way this thing works is pretty self explanatory:

http://www.youtube.com/watch?v=_qeLBebtsdw (http://www.youtube.com/watch?v=_qeLBebtsdw)

Code: [Select]
#include <SerialPort.h>

#define SBUS_SIGNAL_OK          0x00
#define SBUS_SIGNAL_LOST        0x01
#define SBUS_SIGNAL_FAILSAFE    0x03

SerialPort<0,25,25> port0;

uint8_t sbus_data[25] = {
  0x0f,0x01,0x04,0x20,0x00,0xff,0x07,0x40,0x00,0x02,0x10,0x80,0x2c,0x64,0x21,0x0b,0x59,0x08,0x40,0x00,0x02,0x10,0x80,0x00,0x00};
int16_t channels[18]  = {
  1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,0,0};
int16_t servos[18]    = {
  1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,0,0};
uint8_t  failsafe_status = SBUS_SIGNAL_FAILSAFE;
int sbus_passthrough = 1;
uint8_t byte_in_sbus;
uint8_t bit_in_sbus;
uint8_t ch;
uint8_t bit_in_channel;
uint8_t bit_in_servo;
uint8_t inBuffer[25];
int bufferIndex=0;
uint8_t inData;
int toChannels = 0;
uint32_t baud = 100000;
void setup(){
  //Serial.begin(100000);
  port0.begin(baud,  SP_2_STOP_BIT | SP_EVEN_PARITY | SP_8_BIT_CHAR);

}

void loop(){
  feedLine();
  if(toChannels==1){
    update_channels();
    update_servos();
    toChannels=0;
  } 
  //update_servos();
}





int16_t channel(uint8_t ch) {
  // Read channel data
  if ((ch>0)&&(ch<=16)){
    return channels[ch-1];
  }
  else{
    return 1023;
  }
}
uint8_t digichannel(uint8_t ch) {
  // Read digital channel data
  if ((ch>0) && (ch<=2)) {
    return channels[15+ch];
  }
  else{
    return 0;
  }
}
void servo(uint8_t ch, int16_t position) {
  // Set servo position
  if ((ch>0)&&(ch<=16)) {
    if (position>2048) {
      position=2048;
    }
    servos[ch-1] = position;
  }
}
void digiservo(uint8_t ch, uint8_t position) {
  // Set digital servo position
  if ((ch>0) && (ch<=2)) {
    if (position>1) {
      position=1;
    }
    servos[15+ch] = position;
  }
}
uint8_t failsafe(void) {
  return failsafe_status;
}

void passthroughSet(int mode) {
  // Set passtrough mode, if true, received channel data is send to servos
  sbus_passthrough = mode;
}

int passthroughRet(void) {
  // Return current passthrough mode
  return sbus_passthrough;
}
void update_servos(void) {
  // Send data to servos
  // Passtrough mode = false >> send own servo data
  // Passtrough mode = true >> send received channel data
  uint8_t i;
  if (sbus_passthrough==0) {
    // clear received channel data
    for (i=1; i<24; i++) {
      sbus_data[i] = 0;
    }

    // reset counters
    ch = 0;
    bit_in_servo = 0;
    byte_in_sbus = 1;
    bit_in_sbus = 0;

    // store servo data
    for (i=0; i<176; i++) {
      if (servos[ch] & (1<<bit_in_servo)) {
        sbus_data[byte_in_sbus] |= (1<<bit_in_sbus);
      }
      bit_in_sbus++;
      bit_in_servo++;

      if (bit_in_sbus == 8) {
        bit_in_sbus =0;
        byte_in_sbus++;
      }
      if (bit_in_servo == 11) {
        bit_in_servo =0;
        ch++;
      }
    }

    // DigiChannel 1
    if (channels[16] == 1) {
      sbus_data[23] |= (1<<0);
    }
    // DigiChannel 2
    if (channels[17] == 1) {
      sbus_data[23] |= (1<<1);
    }

    // Failsafe
    if (failsafe_status == SBUS_SIGNAL_LOST) {
      sbus_data[23] |= (1<<2);
    }

    if (failsafe_status == SBUS_SIGNAL_FAILSAFE) {
      sbus_data[23] |= (1<<2);
      sbus_data[23] |= (1<<3);
    }
  }
  // send data out
  //serialPort.write(sbus_data,25);
for (i=0;i<25;i++) {
    port0.write(sbus_data[i]);
  }
}
void update_channels(void) {
  uint8_t i;
  uint8_t sbus_pointer = 0;
  // clear channels[]
  for (i=0; i<16; i++) {
    channels[i] = 0;
  }

  // reset counters
  byte_in_sbus = 1;
  bit_in_sbus = 0;
  ch = 0;
  bit_in_channel = 0;

  // process actual sbus data
  for (i=0; i<176; i++) {
    if (sbus_data[byte_in_sbus] & (1<<bit_in_sbus)) {
      channels[ch] |= (1<<bit_in_channel);
    }
    bit_in_sbus++;
    bit_in_channel++;

    if (bit_in_sbus == 8) {
      bit_in_sbus =0;
      byte_in_sbus++;
    }
    if (bit_in_channel == 11) {
      bit_in_channel =0;
      ch++;
    }
  }
  // DigiChannel 1
  if (sbus_data[23] & (1<<0)) {
    channels[16] = 1;
  }
  else{
    channels[16] = 0;
  }
  // DigiChannel 2
  if (sbus_data[23] & (1<<1)) {
    channels[17] = 1;
  }
  else{
    channels[17] = 0;
  }
  // Failsafe
  failsafe_status = SBUS_SIGNAL_OK;
  if (sbus_data[23] & (1<<2)) {
    failsafe_status = SBUS_SIGNAL_LOST;
  }
  if (sbus_data[23] & (1<<3)) {
    failsafe_status = SBUS_SIGNAL_FAILSAFE;
  }

}
void feedLine(){
  while(port0.available()){
    inData = port0.read();
    if (inData == 0x0f){
      bufferIndex = 0;
      inBuffer[bufferIndex] = inData;
      inBuffer[24] = 0xff;
    }
    else{
      bufferIndex ++;
      inBuffer[bufferIndex] = inData;
    }
    if(inBuffer[0]==0x0f & inBuffer[24] == 0x00){

      memcpy(sbus_data,inBuffer,25);
      toChannels = 1;
      return;
    }
  }
}

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Andy2No on Jun 10, 2012, 07:45 am
It took me a while to find the fat16lib SerialPort library you've used (probably because I'm new at this), so here's the link:

http://arduino.cc/forum/index.php/topic,85207.0.html
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: april.steel on Jun 10, 2012, 11:11 pm
Have you seen the price of these things?
I won't be using them anytime soon

http://www3.towerhobbies.com/cgi-bin/WTI0095P?FVSEARCH=sbus&search=Go
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: graynomad on Jun 11, 2012, 04:30 am
Quote
Have you seen the price of these things?

Yes but they have EASY PAY :)

_____
Rob
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Jul 16, 2012, 07:46 pm
I found a major bug in the code. The problem come from one of the channels transmitting a byte of 0x0F. I changed the code so that is not longer a problem. It also runs slightly faster:

Code: [Select]

#include <SerialPort.h>

#define SBUS_SIGNAL_OK          0x00
#define SBUS_SIGNAL_LOST        0x01
#define SBUS_SIGNAL_FAILSAFE    0x03



SerialPort<0,64,64> port0;


uint8_t sbus_data[25] = {
  0x0f,0x01,0x04,0x20,0x00,0xff,0x07,0x40,0x00,0x02,0x10,0x80,0x2c,0x64,0x21,0x0b,0x59,0x08,0x40,0x00,0x02,0x10,0x80,0x00,0x00};
int16_t channels[18]  = {
  1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,0,0};
int16_t servos[18]    = {
  1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,0,0};
uint8_t  failsafe_status = SBUS_SIGNAL_FAILSAFE;
int sbus_passthrough = 1;
uint8_t byte_in_sbus;
uint8_t bit_in_sbus;
uint8_t ch;
uint8_t bit_in_channel;
uint8_t bit_in_servo;
uint8_t inBuffer[25];
int bufferIndex=0;
uint8_t inData;
int toChannels = 0;
uint32_t baud = 99000;
int feedState = 0;


void setup(){
  port0.begin(baud,  SP_2_STOP_BIT | SP_EVEN_PARITY | SP_8_BIT_CHAR);

}

void loop(){

  feedLine();
 
  if(toChannels==1){
    update_channels();
    update_servos();
    toChannels=0;
  } 

}





int16_t channel(uint8_t ch) {
  // Read channel data
  if ((ch>0)&&(ch<=16)){
    return channels[ch-1];
  }
  else{
    return 1023;
  }
}
uint8_t digichannel(uint8_t ch) {
  // Read digital channel data
  if ((ch>0) && (ch<=2)) {
    return channels[15+ch];
  }
  else{
    return 0;
  }
}
void servo(uint8_t ch, int16_t position) {
  // Set servo position
  if ((ch>0)&&(ch<=16)) {
    if (position>2048) {
      position=2048;
    }
    servos[ch-1] = position;
  }
}
void digiservo(uint8_t ch, uint8_t position) {
  // Set digital servo position
  if ((ch>0) && (ch<=2)) {
    if (position>1) {
      position=1;
    }
    servos[15+ch] = position;
  }
}
uint8_t failsafe(void) {
  return failsafe_status;
}

void passthroughSet(int mode) {
  // Set passtrough mode, if true, received channel data is send to servos
  sbus_passthrough = mode;
}

int passthroughRet(void) {
  // Return current passthrough mode
  return sbus_passthrough;
}
void update_servos(void) {
  // Send data to servos
  // Passtrough mode = false >> send own servo data
  // Passtrough mode = true >> send received channel data
  uint8_t i;
  if (sbus_passthrough==0) {
    // clear received channel data
    for (i=1; i<24; i++) {
      sbus_data[i] = 0;
    }

    // reset counters
    ch = 0;
    bit_in_servo = 0;
    byte_in_sbus = 1;
    bit_in_sbus = 0;

    // store servo data
    for (i=0; i<176; i++) {
      if (servos[ch] & (1<<bit_in_servo)) {
        sbus_data[byte_in_sbus] |= (1<<bit_in_sbus);
      }
      bit_in_sbus++;
      bit_in_servo++;

      if (bit_in_sbus == 8) {
        bit_in_sbus =0;
        byte_in_sbus++;
      }
      if (bit_in_servo == 11) {
        bit_in_servo =0;
        ch++;
      }
    }

    // DigiChannel 1
    if (channels[16] == 1) {
      sbus_data[23] |= (1<<0);
    }
    // DigiChannel 2
    if (channels[17] == 1) {
      sbus_data[23] |= (1<<1);
    }

    // Failsafe
    if (failsafe_status == SBUS_SIGNAL_LOST) {
      sbus_data[23] |= (1<<2);
    }

    if (failsafe_status == SBUS_SIGNAL_FAILSAFE) {
      sbus_data[23] |= (1<<2);
      sbus_data[23] |= (1<<3);
    }
  }
  // send data out
  //serialPort.write(sbus_data,25);
  for (i=0;i<25;i++) {
    port0.write(sbus_data[i]);
  }
}
void update_channels(void) {
  uint8_t i;
  uint8_t sbus_pointer = 0;
  // clear channels[]
  for (i=0; i<16; i++) {
    channels[i] = 0;
  }

  // reset counters
  byte_in_sbus = 1;
  bit_in_sbus = 0;
  ch = 0;
  bit_in_channel = 0;

  // process actual sbus data
  for (i=0; i<176; i++) {
    if (sbus_data[byte_in_sbus] & (1<<bit_in_sbus)) {
      channels[ch] |= (1<<bit_in_channel);
    }
    bit_in_sbus++;
    bit_in_channel++;

    if (bit_in_sbus == 8) {
      bit_in_sbus =0;
      byte_in_sbus++;
    }
    if (bit_in_channel == 11) {
      bit_in_channel =0;
      ch++;
    }
  }
  // DigiChannel 1
  if (sbus_data[23] & (1<<0)) {
    channels[16] = 1;
  }
  else{
    channels[16] = 0;
  }
  // DigiChannel 2
  if (sbus_data[23] & (1<<1)) {
    channels[17] = 1;
  }
  else{
    channels[17] = 0;
  }
  // Failsafe
  failsafe_status = SBUS_SIGNAL_OK;
  if (sbus_data[23] & (1<<2)) {
    failsafe_status = SBUS_SIGNAL_LOST;
  }
  if (sbus_data[23] & (1<<3)) {
    failsafe_status = SBUS_SIGNAL_FAILSAFE;
  }

}
void feedLine(){
  if (port0.available() > 24){
    while(port0.available() > 0){
      inData = port0.read();
      switch (feedState){
      case 0:
        if (inData != 0x0f){
          while(port0.available() > 0){//read the contents of in buffer this should resync the transmission
            inData = port0.read();
          }
          return;
        }
        else{
          bufferIndex = 0;
          inBuffer[bufferIndex] = inData;
          inBuffer[24] = 0xff;
          feedState = 1;
        }
        break;
      case 1:
        bufferIndex ++;
        inBuffer[bufferIndex] = inData;
        if (bufferIndex < 24 && port0.available() == 0){
          feedState = 0;
        }
        if (bufferIndex == 24){
          feedState = 0;
          if (inBuffer[0]==0x0f && inBuffer[24] == 0x00){
            memcpy(sbus_data,inBuffer,25);
            toChannels = 1;
          }
        }
        break;
      }
    }
  }
}
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Sep 12, 2012, 04:54 pm
I have turned this into a library finally.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: alekoy on Oct 14, 2012, 12:25 pm
Hi.
It would be very nice if you could include a small description of the hardware-side of this :)
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Oct 20, 2012, 01:08 am

Hi.
It would be very nice if you could include a small description of the hardware-side of this :)


The output of the SBUS receiver goes into one of the inputs on an inverter (74HC14). The output from that input goes into the serial port. The output of the serial port you are using goes into the inverter and the output will drive SBUS servos. You must have a common ground to all the devices. It is best to run the servos from a different power supply than the arduino.

http://www.datasheetarchive.com/74HC14-datasheet.html
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Dec 08, 2012, 09:15 pm
https://github.com/mikeshub/FUTABA_SBUS
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Dec 12, 2012, 05:13 pm
The library has been updated to no longer rely on the SerialPort.h library
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: techspy on Dec 12, 2012, 07:48 pm
Nice project. FYI, you can get cheap sbus receivers from Hobby King now. I have been looking for a similar solution. I want to convert the sbus protocol into a ppm signal. Does your project have that ability? If so, any idea of how much lag there would be?

Thanks
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: m_marc0 on Jan 09, 2013, 08:56 am
Sir
I am very interested by this project.
I use the Arduino 1.0 version.
I'm not an Arduino specialist and so, I doesn't compile This like the reply 4.
I have an error like "expected constructor,destructor,or type conversion before '<' token and the line "SerialPort<0,64,64> port0;" is in Yellow.
I have had file "SerialPort.h"  from "SerialPortBeta20120106.zip"
In fact, I have a lot of error :
sketch_jan07b.cpp:1:24: error: SerialPort.h: No such file or directory
sketch_jan07b:4: error: expected constructor, destructor, or type conversion before '<' token
sketch_jan07b.cpp: In function 'void setup()':
sketch_jan07b:22: error: 'port0' was not declared in this scope
sketch_jan07b:22: error: 'SP_2_STOP_BIT' was not declared in this scope
sketch_jan07b:22: error: 'SP_EVEN_PARITY' was not declared in this scope
sketch_jan07b:22: error: 'SP_8_BIT_CHAR' was not declared in this scope
sketch_jan07b.cpp: In function 'void update_servos()':
sketch_jan07b:86: error: 'sbus_data' was not declared in this scope
sketch_jan07b:96: error: 'sbus_data' was not declared in this scope
sketch_jan07b:111: error: 'sbus_data' was not declared in this scope
sketch_jan07b:115: error: 'sbus_data' was not declared in this scope
sketch_jan07b:119: error: 'sbus_data' was not declared in this scope
sketch_jan07b:121: error: 'sbus_data' was not declared in this scope
sketch_jan07b:128: error: 'port0' was not declared in this scope
sketch_jan07b:128: error: 'sbus_data' was not declared in this scope
sketch_jan07b.cpp: In function 'void update_channels()':
sketch_jan07b:145: error: 'sbus_data' was not declared in this scope
sketch_jan07b:160: error: 'sbus_data' was not declared in this scope
sketch_jan07b:167: error: 'sbus_data' was not declared in this scope
sketch_jan07b:175: error: 'sbus_data' was not declared in this scope
sketch_jan07b:178: error: 'sbus_data' was not declared in this scope
sketch_jan07b.cpp: In function 'void feedLine()':
sketch_jan07b:183: error: 'port0' was not declared in this scope
sketch_jan07b:210: error: 'sbus_data' was not declared in this scope
Could you hepl me ?
Best regards
Marc
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Tissy on Mar 18, 2013, 08:32 pm
Fantastic work on this Mike  8)

I have a Futaba 14 channel transmitter (T8FG) with the R6208SB S-BUS receiver.

I would like to use the S-BUS channel to control 4 PPM outputs via the Arduino.  Just probably simple switched outputs not servos at all.

One appplication is two create a different output depending on the PMM input range from the transmitter.

Is it possible to use your code for this 4 channel application, or is it designed for just one channel.

Many thanks and great work again.

Steve
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Apr 17, 2013, 03:29 pm
Sorry for the slow response guys, I thought I was subscribed to this thread. In the future if someone needs some help with this library PM me if I don't respond fairly quickly.

m_marc0 - I have updated the library to no longer require SerialPort.h. It now uses the standard arduino conventions. The library is currently configured to run off of Serial1 on a mega. To change the edit the FUTABA_SBUS.h line 12

Code: [Select]

#define SBUS_SIGNAL_OK          0x00
#define SBUS_SIGNAL_LOST        0x01
#define SBUS_SIGNAL_FAILSAFE    0x03
#define BAUDRATE 100000
#define port Serial1  <---- this is the line to change


Tissy -I'm not quite clear on what you are trying to accomplish. You can create a PPM signal based off the different channels, but to what end? If you could describe your project in a little more detial hopefully I can give you a better answer. Also, are you sure you aren't confusing PPM with PWM?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Tissy on Apr 17, 2013, 06:12 pm
Thanks Mike.

Sorry, you're right, I wasn't very clear.

Basically I have a Futaba R6208SB S-BUS receiver which I am using on a multi-rotor.

I have one of the outputs from this receiver going to an Arduino MiniPro which is programmed to detect the PWM signal and use an IR LED to control a Sony NEX5 camera.  This works very will and I can switch the camera modes between video and stills and take manual or automatic interval pictures.

As this is connected to one of the main outputs of the Rx and I have a Futaba 14 channel Tx (T8FG), I would like to move auxiliary functions such as this to the S-Bus.

So the code on the MiniPro will read the S-BUS and perform a function (either servo based or logic based) on say 4 channels.

I know this device (FUTM4191 SBD-1 S.Bus Decoder) is available to decode the S-Bus signal to PWM, however I would still need the MiniPro to perform certain functions, so I was looking at cutting out the middle man if possible.

http://www.futaba-rc.com/sbus/

I would need to define the channel on the MiniPro which corresponds to the channel on the Tx, for example channels 9 - 12.

Does that make sense or have I made it worse :-D

Steve
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Apr 18, 2013, 12:21 am
Got it. What you need to do is have a way to turn SBUS into PWM.

Let's talk at little bit more about SBUS and DSM2/DSMx serial. They are simply transmitting unsigned integers in raw binary over a UART. This means once you have these values you can do whatever you want with them. DSMx and SBUS have a 2048 resolution (2^11) whereas DSM2 has a 1024 (2^10) resolution. OK so the question now is how do we do something with this information.

First you map those values to a range you want to use:

Code: [Select]


void MapVar (float *x, float *y, float in_min, float in_max, float out_min, float out_max){
  *y = (*x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void MapVar (int16_t *x, float *y, float in_min, float in_max, float out_min, float out_max){
  *y = (*x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void MapVar (uint16_t *x, float *y, float in_min, float in_max, float out_min, float out_max){
  *y = (*x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}



In the above code I am using pointers. In addition to using pointers you could simple pass the variables or make the variables global. For the servo control you want to generate a PWM signal. Here is a great article about the difference between the two:

http://www.endurance-rc.com/ppmtut.php

Both PPM and PWM use square waves of varying width to convey information. Let's look at servos and ESC (electronic speed controllers). They are controlled by PWM signal with a frequency between 50 - 500Hz and a pulse width of around 1000 - 2000us. For this signal we are concerned with the pulse width and not the PWM's duty cycle. The center is 1500us, but many servos center at 1520. If you run a servo at too high a frequency it will break the servo. This is also for ESCs.

There are a number of ways that you can generate these signals with the arduino. The easiest is to use servo.h. It will allow you to make a lot of these signals on any pin you want. It also doesn't run all that fast. The maximum refresh rate is ~125Hz. A good flight controller runs the control loops very fast and updates the ESCs at ~400Hz. You want to use AVR C. I know that can be a big turn off for a lot of people here since it is considered difficult. And it is, but it is not too bad. If you do it right you only have to figure it out once. Here is another code sample to illustrate how to generate higher frequency ESC PWM signals. This code was written for the mega, but if you look at the datasheet for the 128 it will become clear to you as to how to do it. If it not don't be afraid to ask for assistance with a concept you are struggling with.

Code: [Select]


//motor defines
#define FREQ 400
#define PRESCALE 8
#define PERIOD ((F_CPU/PRESCALE/FREQ) - 1)

#define Motor1WriteMicros(x) OCR3B = x * 2//motor 1 is attached to pin2
#define Motor2WriteMicros(x) OCR3C = x * 2//motor 2 is attached to pin3
#define Motor3WriteMicros(x) OCR3A = x * 2//motor 3 is attached to pin5
#define Motor4WriteMicros(x) OCR4A = x * 2//motor 4 is attached to pin6

void setup(){
  MotorInit();
  //do other stuff
}

void loop(){
  Motor1WriteMicros(1250);
  Motor2WriteMicros(someVar);
  //do other stuff
}

void MotorInit(){
  DDRE |= B00111000;//set the ports as outputs
  DDRH |= B00001000;

 
  // Init PWM Timer 3                                       
  // WGMn1 WGMn2 WGMn3  = Mode 14 Fast PWM, TOP = ICRn ,Update of OCRnx at BOTOM
  TCCR3A = (1<<WGM31)|(1<<COM3A1)|(1<<COM3B1)|(1<<COM3C1);  // Clear OCnA/OCnB/OCnC on compare match, set OCnA/OCnB/OCnC at BOTTOM (non-inverting mode)
  TCCR3B = (1<<WGM33)|(1<<WGM32)|(1<<CS31);                 // Prescaler set to 8, that gives us a resolution of 0.5us
  ICR3 = PERIOD;                                // Clock_speed / ( Prescaler * desired_PWM_Frequency) #defined above. 

  TCCR4A = (1<<WGM41)|(1<<COM4A1);
  TCCR4B = (1<<WGM43)|(1<<WGM42)|(1<<CS41);
  ICR4 = PERIOD;
 
  Motor1WriteMicros(1000);//set the output compare value
  Motor2WriteMicros(1000);
  Motor3WriteMicros(1000);
  Motor4WriteMicros(1000);
 
}



This code will not run on the miniPro. This is meant to be an example as to how to set this all up. Furthermore, the 128 only has 1 16bit timer. The above code gives a 0.5us resolution. To use this method with the 128 it will give you two channels with 16bit resolution and two channels with 8 bit of resolution.

Hope that helps. Let me know if there is anything further I can clear up for you.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Tissy on Apr 18, 2013, 03:08 pm
Michael,

Thank you so much for your detailed response, its really appreciated.

I always seem to jump straight into the deep end.

Is there a reason the code will not run on a ATMega328 Pro Mini?

I have posted my code below to hopefully give you an idea of what I am trying to achieve.  Instead of using the normal output from my RC receiver, I would like to adapt the code to use the S-BUS instead and thereby freeing up at least one of the normal Rx channels.

You will see from the code below that if the PWM input is detected between certain frequencies, then it outputs accordingly, in this case utilising an IR Led.

In addition, I would like to use another S-Bus channel for the Arduino to switch on landing lights for example if again a switch on the Tx is 'on'.  Chances are I won't need it to control servos, just some auxiliary devices.

So my need is not to generate a PWM signal from the Arduino, but to interpret the S-BUS signal and have set routines depending on the channel input.

Hope that makes sense and thank you again for your assistance.

Steve
Code: [Select]

#include <multiCameraIrControl.h>

int x=50, y=300, z=100;
int ledPin = 13;
int IRPin = 2;
int RxInput = A0;
int pic_pause = 5000;
Sony Nex5(IRPin);

void setup()
{
Serial.begin(9600);      //
  pinMode (IRPin, OUTPUT);  // Output pin for IR LED
  pinMode (RxInput, INPUT);    // Input pin for PWM from Rx
}

void loop () {
z = pulseIn(RxInput, HIGH, 20000);
if (z<1400) {
  digitalWrite(IRPin, 0);
  Serial.println(z);
  delay(y); 
  }
//if (z>1401 && z<1599) {

  if (z>1155 && z<1170) {
    digitalWrite(IRPin, 1);
    Nex5.shutterNow();
  //  Nex5.shutterDelayed();
  //  delay(500);
    digitalWrite(IRPin, 0);
    Serial.println(z);
  //  delay(y);
    }
 
  if (z>1780 && z<1820) {
    digitalWrite(IRPin, 1);
    Nex5.shutterNow();
  //  delay(500);
    digitalWrite(IRPin, 0);
    Serial.println(z);
    delay(pic_pause);
    }

  if (z>1430 && z<1500) {
    digitalWrite(IRPin, 1);
    Nex5.toggleVideo();
    delay(500);
    digitalWrite(IRPin, 0);
    Serial.println(z);
  //  delay(y);
    }
 
  if (z>1600)   { 
    digitalWrite(IRPin, 1); delay (x); digitalWrite(IRPin, 0); delay (x);
    digitalWrite(IRPin, 1); delay (x); digitalWrite(IRPin, 0); delay (x);
    delay(y);
    Serial.println(z);
    }
  }
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Apr 20, 2013, 04:23 pm
You should be able to do that no problem. Just assign the variable Z to one of the channels off the SBUS. Use that map function to map max and min of the SBUS channel to whatever you want or modify the code to work with different ranges.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Tissy on Apr 21, 2013, 01:11 am
Thanks Mike.

So should the code you have posted above still use the FUTABA_SBUS.h library?

I haven't used the map function before, so should the variables in_min & in_max be the expected PWM frequencies such as 1023 for example from the Rx?

I think I can work my code, I'm just trying to understand how the S_Bus channels are defined etc.

Could you expand a little more please :-)

Thanks again Mike,

Steve
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: ssozonoff on May 14, 2013, 10:30 pm
Hi Mike,

Great stuff you have done, have you had a chance to look at the SBUS2 protocol? It seems to be frames appended after the channel data is sent. I just received an FX32 so should be able to do some tests shortly. Would be interested in building a "base" sensor PCB around Arduino which people could extend to build their own sensors.

One thing I did read is that increasing the telemetry data rate has a direct impact on servo smoothness, which I guess makes perfect sense. Price to pay for sharing bandwidth I guess however not clear if there is any difference depending on amount of telemetry slots being used.

Best,
Serge
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: rharms427 on Aug 22, 2013, 04:19 am
I am attempting to test compile the example code and am having an issue.
Arduino IDE 1.5.2  Board is Mega
This is the line that fails
Serial<<sBus.channels[0]<<","<<sBus.channels[1]<<","<<sBus.channels[2]<<"\r\n";

With this error:
invalid operands of types "int" and 'const char[2]' to binary 'operator<<'
sbus_example.ino: In function 'void loop()':
sbus_example:19: error: invalid operands of types 'int' and 'const char [2]' to binary 'operator<<'

I am sorry to bother you, but I am at a loss.  While I have done some Arduino projects, I must confess that I am having a difficult time following  even the example  However, If I can get it to compile, then I will continue to plug away a figure out how this works.
Thank you for your time and efforts.
Rick Harms
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: rharms427 on Aug 23, 2013, 03:59 am
In regards to my previous reply, please ignore my question on the compile error.  I realized that for my project I do not need that ability.   For now, I replaced it with a series of print statements to verify that I can indeed read the sbus.  IT WORKED. I am ecstatic.  This will become the basis for an on board mixer that I am working on.  Thank you.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: codeforge on Jan 14, 2014, 06:31 pm
Hi,

is there a way to make sbus signal with your library?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: irony74 on Jan 14, 2014, 07:28 pm
Any plans to extend the library to SBUS2?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Soler on Apr 14, 2014, 07:19 pm
I am using the following code and I am not getting any output
Code: [Select]
#include <FUTABA_SBUS.h>
#include <Streaming.h>


FUTABA_SBUS sBus;
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
               // a maximum of eight servo objects can be created

int pos = 0;    // variable to store the servo position



void setup(){
 sBus.begin();
 Serial.begin(115200);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop(){
 sBus.FeedLine();

 if (sBus.toChannels == 1){
   sBus.UpdateServos();
   sBus.UpdateChannels();
   sBus.toChannels = 0;
  Serial<<sBus.channels[0]<<","<<sBus.channels[1]<<","<<sBus.channels[2]<<"\r\n";

 }
 pos = sBus.channels[2];
 myservo.write(map(pos, 1000, 2000, 1, 180));

}

From what i see the if condition    sBus.toChannels == 1  is never reached.

I have tried 2 different Hex investors and on a Nano and Mega, the receiver I am using is the FR Sky TFR8SB and I have the Signal line from the S.Bus port connected to the input to the Hex inverter,  output of that pin to RX on Arduino.  The receiver is bound to the transmitter.

If I use Serial<<sBus.failsafe_status<<" Fail safe status \r\n";  I always receive a 0 from the status.

if someone can post some working code I would appreciate it,  Thanks
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Soler on Apr 14, 2014, 09:09 pm
Please see the attached schematic that I have used for this.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on Apr 20, 2014, 02:13 am
That all looks fine. Do you have access to an oscilloscope or logic analyzer? Are you getting anything on the serial port? Try echoing each byte received in hex. Is your receiver 3.3v logic levels?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Soler on Apr 20, 2014, 11:59 am
Hi All,

I got this working now,  looks like i had a poor connection on my breadboard that was causing the issues.   

Thanks for the help.

One issues i am having is detecting the s.bus signal loss or failsafe,  it seams to detect for one pulse and stops,  should i have this within the " if (toChannels == 1){"   or out side this?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Soler on May 04, 2014, 12:51 am
Does this have to be on the RX and TX pins or could this use other pins?   I see that people are using other pins to read and write PPM signals,  but does S.Bus need to be on the RX and TX?


Thanks
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on May 23, 2014, 04:48 pm
Yes it has to be the serial port.

I have an updated version of this code now. It is written for the mega. It will handle DSMx serial (no DSM2, but the change to DSM2 is trivial), sbus, or PWM RC signals. I may or may not get around to including a PPM decoder.

The only library required is streaming, but only because I find a bunch of printlns to be a pain to read. In addition to the obvious hardware you need a push button or toggle switch to go through the calibration process.

The way this works is you first center the sticks on your transmitter. It will output the raw values during this time.  Toggle the switch. It will output the center values. Toggle again and you are in the min max calibration section. Move all the switches and sticks through their entire range. Toggle the switch a few times and it will give you info regarding the calibration.

From there it just outputs the values scaled to +/- 1000 (great for servo PWM signal). The aileron, rudder, and elevator will be centered at 1500. The rest of the channels will have their minimum value be guaranteed to be 1000. Pretty important to make sure minimum stick on throttle is actually the minimum command! If you have the range on the transmitter set the same IE 100% both directions it will also center the values at 1500. The purpose of centering A,E,R to 1500 is for my quad copter project so I don't have to use any trims. Hope this helps someone and I'll try to be better about keeping on top of this thread.

Pastbin link because it is too long to post on the forum:

http://pastebin.com/LNHFg7Fq
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: nique on Jun 03, 2014, 11:32 pm
@mikesbaker : Wow, what a job. Seams to be what I'm looking for.

I have an X8R RX from FrSky. Supports also S-Bus. Do you have any experiance with this RX? What I now is that an inverter is not needed, because FrSky works already inverted.

Well, I used your Code from GitHub. At least, the X8R is still alive.

What I have done: I have a Teensy 3.1-Board (http://www.pjrc.com/teensy/teensy31.html) and connected there the X8R to the RX1 pin

The Code is very dummy:
Code: [Select]

#include <FUTABA_SBUS.h>
FUTABA_SBUS sBus;

void setup(){
  sBus.begin();
  Serial.begin(115200);
}

void loop(){
  sBus.FeedLine();

  if (sBus.toChannels == 1){
    sBus.UpdateChannels();
    sBus.toChannels = 0;
   Serial.print("0: ");
   Serial.println(sBus.channels[0]);
   Serial.print("1: ");
   Serial.println(sBus.channels[1]);
   delay(500);
  }
}


The Code is loaded, but the Terminal does not show anything. So, FeedLine does not recognice any changes and the if will never happen. If I do the Serial.print in the main-loop, I have an output of 1023 all time.

There may be two errors:
- I have connected the wrong pin as teensy board seams to be different
- FrSky-S.Bus is to different to futaba

Do you have any ideas?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Jun 25, 2014, 11:24 am
@nique

I have used the library with a FrSky X8R.

It works very well, see the test sketch below for an example I use on a Mini Pro.
The only problem with that is that I can't get any debug output, so I used a 1284 board to test as it has two hardware serial ports.

Quote
FrSky works already inverted.


Yes, and therefor you need an inverter I have tried a 74hc14 or just a transistor with two resistors
Ans I use 3.3V on the Pro Mini to avoid logic level converter
Code: [Select]

// for using mini with one serial
// change SBUS.h line 12 for normal Arduino
// #define port Serial1 --for  Arduino with more than one Serial port
// #define port Serial --for normal Arduino with one Serial port

#include <FUTABA_SBUS.h>
#include <Servo.h>

FUTABA_SBUS sBus;
Servo myservo;

void setup(){
 sBus.begin();
 myservo.attach(14);
}

void loop(){
 sBus.FeedLine();
 if (sBus.toChannels == 1){
   sBus.UpdateServos();
   sBus.UpdateChannels();
   sBus.toChannels = 0;
   myservo.writeMicroseconds(sBus.channels[6]+800);
 }
}

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: nique on Jun 25, 2014, 01:08 pm
Thanks Erni

It is working now! For teensy, you need other Port-Assignements. Because it is teensy-specific, the teensy-solution is here: http://forum.pjrc.com/threads/25265-Arduino-RC-library?p=48935&viewfull=1#post48935
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: AvengerIl on Jul 30, 2014, 02:26 pm
Hi guys,

for the life of me  I cannot receive the s.bus data correctly using the arduino pro mini/nano..

using real term i get the data fine, consistent etc...

0F E0 03 5F 2B C0 C7 0A 56 80 0F 7C 00 00 00 00 00 00 00 00 00 00 00 0C 00
0F E0 03 5F 2B C0 C7 0A 56 80 0F 7C 00 00 00 00 00 00 00 00 00 00 00 0C 00
0F E0 03 5F 2B C0 C7 0A 56 80 0F 7C 00 00 00 00 00 00 00 00 00 00 00 0C 00

but using the serial library mentioned here, and others, the best i can get is

0C 00 0F E0 03 5F 0F 7C 00 00 00 00 00 0F E0 C7 0A 56 00 00
00 00 0F E0 03 5F 2B 7C 00 00 00 00 00 00 0F E0 0A 56 80 00 00
00 00 0F E0 5F 2B C0 C7 00 00 00 00
0C 00 0F E0 03 80 0F 7C 00 00
00 00 0F E0 C0 C7 0A 00 00 00 0C 00 0F E0 03 5F 0F 7C 00

its as if bytes being dropped,
//also tried 99 and 100k.
port0.begin(98000,SP_2_STOP_BIT | SP_EVEN_PARITY | SP_8_BIT_CHAR);


while(port0.available()<100) delay(10);
 
  for(int i = 0; i < 100; i++)
  {
      sData = port0.read();
  }
 
  for(int i = 0; i < 100; i++)
  {
      _serial.write(sData);
  }

any ideas please?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: AvengerIl on Jul 30, 2014, 02:29 pm

@nique

I have used the library with a FrSky X8R.

It works very well, see the test sketch below for an example I use on a Mini Pro.
The only problem with that is that I can't get any debug output, so I used a 1284 board to test as it has two hardware serial ports.

Quote
FrSky works already inverted.


Yes, and therefor you need an inverter I have tried a 74hc14 or just a transistor with two resistors
Ans I use 3.3V on the Pro Mini to avoid logic level converter
Code: [Select]

// for using mini with one serial
// change SBUS.h line 12 for normal Arduino
// #define port Serial1 --for  Arduino with more than one Serial port
// #define port Serial --for normal Arduino with one Serial port

#include <FUTABA_SBUS.h>
#include <Servo.h>

FUTABA_SBUS sBus;
Servo myservo;

void setup(){
  sBus.begin();
  myservo.attach(14);
}

void loop(){
  sBus.FeedLine();
  if (sBus.toChannels == 1){
    sBus.UpdateServos();
    sBus.UpdateChannels();
    sBus.toChannels = 0;
    myservo.writeMicroseconds(sBus.channels[6]+800);
  }
}




you can use
#include <SoftwareSerial.h>
SoftwareSerial _serial(9,8,false);
_serial.begin(9600);

and connect pin 8 on arduino to the rx on ftdi usb...

but i cant receive sbus data.. its inverted and everything... arghh..
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: crchisholm on Nov 01, 2014, 05:45 pm
I've been trying to make this work and freely admit I am lost.  installed the library, found the SerialPort library and installed it, now I get....

sketch_nov01a:15: error: 'class FUTABA_SBUS' has no member named 'begin'

I see the public declaration in Futaba_sbus.h, but don't see any function by that name.  Should there be a cpp file that goes along with this.  Not a C++ programmer so I am sure the problem is the vacant spots in my brain.

Any clarification would be greatly appreciated.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Nov 02, 2014, 12:04 pm
If you use the SBUS library here, you don't need any SerialPort library

Code: [Select]
https://github.com/mikeshub/FUTABA_SBUS/tree/master/FUTABA_SBUS

Quote
Should there be a cpp file that goes along with this.
Yes there is a .h file and a .cpp file like other librarys.

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Nov 02, 2014, 12:10 pm
If your goal is to control servos via SBUS, you could uses this sketch (16.oct by mstrens)

OpenRcForum (http://openrcforums.com/forum/viewtopic.php?f=84&t=4539)

It dosn't use any librarys and are able to control 16 servos with an Arduino


Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: crchisholm on Nov 02, 2014, 02:59 pm
I will try the suggested library.  Thanks

At present, my goal is to control several options via switches on the Taranus Tx.  I can tipically derive about 4 states from each channel so being able to control many options using sbus would be great.  I was using a 4 channel rx which was limited, but I also have an sbus X4R and would like to try doing everything through sbus.

More brain exercise than needs requirement.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: crchisholm on Nov 02, 2014, 05:17 pm
I seem to be going backwards.  I downloaded and installed the library as above, and now I get the following.  It is said above that I would not need the SerialPort library, but FUTABA_SBUS.h does call that library.

Quote
In file included from sbus_example.ino:1:
C:\Users\misadmin\Documents\Arduino\libraries\FUTABA_SBUS/FUTABA_SBUS.h:41: error: ISO C++ forbids declaration of 'SerialPort' with no type
C:\Users\misadmin\Documents\Arduino\libraries\FUTABA_SBUS/FUTABA_SBUS.h:41: error: expected ';' before '<' token
sbus_example.ino: In function 'void setup()':
sbus_example:9: error: 'class FUTABA_SBUS' has no member named 'begin'
sbus_example.ino: In function 'void loop()':
sbus_example:19: error: invalid operands of types 'int' and 'const char [2]' to binary 'operator<<'
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Nov 02, 2014, 05:45 pm
A quote from the author in post #9 in this thread:
Quote
The library has been updated to no longer rely on the SerialPort.h library
If you are using an Arduino UNO you have to change line 12 in FUTABA_SBUS.h
from:
Code: [Select]
#define port Serial1
to
Code: [Select]
#define port Serial
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: crchisholm on Nov 04, 2014, 01:40 am
this really does make me think I am ending up with different versions of the files than you all are.  If you look at the copy of futaba_sbus.h that I downloaded from github, it certainly does not match the statement above about not needing SerialPort any more or the changes to "line 12 in FUTABA_SBUS.h"  

Code: [Select]
//#include <SerialPort.h> must be in the main program
//port number is changed below
#ifndef FUTABA_SBUS_h
#define FUTABA_SBUS_h

#include <Arduino.h>
#include <SerialPort.h>


#define SBUS_SIGNAL_OK          0x00
#define SBUS_SIGNAL_LOST        0x01
#define SBUS_SIGNAL_FAILSAFE    0x03
#define BAUDRATE 99000
#define RXBUFFER 64
#define TXBUFFER 64
#define PORTNUMBER 1



class FUTABA_SBUS
{
 public:
 uint8_t sbusData[25];
 int16_t channels[18];
 int16_t servos[18];
 uint8_t  failsafe_status;
 int sbus_passthrough;
 int toChannels;
 void Begin(void);
 int16_t Channel(uint8_t ch);
 uint8_t DigiChannel(uint8_t ch);
 void Servo(uint8_t ch, int16_t position);
 void DigiServo(uint8_t ch, uint8_t position);
 uint8_t Failsafe(void);
 void PassthroughSet(int mode);
 int PassthroughRet(void);
 void UpdateServos(void);
 void UpdateChannels(void);
 void FeedLine(void);
 private:
 SerialPort<PORTNUMBER,RXBUFFER,TXBUFFER> port0;
 uint8_t byte_in_sbus;
 uint8_t bit_in_sbus;
 uint8_t ch;
 uint8_t bit_in_channel;
 uint8_t bit_in_servo;
 uint8_t inBuffer[25];
 int bufferIndex;
 uint8_t inData;
 //uint32_t baud = 99000;
 int feedState;

};

#endif
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Nov 04, 2014, 11:22 am
I am talking about the files from the link I gave in reply #36


https://github.com/mikeshub/FUTABA_SBUS/tree/master/FUTABA_SBUS (https://github.com/mikeshub/FUTABA_SBUS/tree/master/FUTABA_SBUS)

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: crchisholm on Nov 04, 2014, 08:19 pm
My bad!   I thought I was getting the files from the location you gave me, but obviously not.  Now I has the files you suggested and made the change to line 12 as well.  I am down to one issue....

trying to use the example code (not included here, but will you it's needed) , I get an error on line 12 and because I don't at all understand the syntax of that line, I am not sure what I am being told.  The line is...

Code: [Select]

    Serial<<sBus.channels[0]<<","<<sBus.channels[1]<<","<<sBus.channels[2]<<"\r\n";


the error is....
 
Code: [Select]

sbus_example.ino: In function 'void loop()':
sbus_example:19: error: invalid operands of types 'int' and 'const char [2]' to binary 'operator<<'

Can you help me understand this syntax and the error that it is generating?

Sorry to be such a block head.  This is one of those cases where I am a bit over my head, but don't want to go back to the shallows.

Charlie
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Nov 04, 2014, 09:47 pm
The example are for a Mega which have more than one serial port.

You could use SoftwareSerial as suggested in reply #34 or use my test sketch that use a servo.

Code: [Select]

#include <FUTABA_SBUS.h>
#include <Servo.h>

FUTABA_SBUS sBus;
Servo myservo;

void setup(){
  sBus.begin();
  myservo.attach(3);
}

void loop(){
  sBus.FeedLine();
  if (sBus.toChannels == 1){
    sBus.UpdateServos();
    sBus.UpdateChannels();
    sBus.toChannels = 0;
    myservo.writeMicroseconds(sBus.channels[1]+800);
  }
}
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: lorbass on Dec 15, 2014, 10:23 am
Errors during compilation

I have the same issues like m_marc() at #11 which where not answered.

And the following message with the example of the mentionned libray on github...
for the line:

 Serial<<sBus.channels[0]<<","<<sBus.channels[1]<<","<<sBus.channels[2]<<"\r\n";

invalid operands of types 'int' and 'const char[2]' to binary 'operator<<'


My target is to decode the Output from DJI Lightbridge which is only available as S-Bus Signal.
Therefore no other functions (camera, gimbals, landing gears) are possible.
And the Signal is too "week" to feed standard decoders on the market.
All I request to proceed are the values of the Tx/Rx Channels.

I think there is a lot of Brain behind the library for not to use it.
Thanks a lot for help

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Dec 16, 2014, 12:38 pm
You could try this instead.
It dosn't use any librarys and it just works.

http://openrcforums.com/forum/viewtopic.php?f=84&t=6361
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: codeforge on Jan 16, 2015, 11:43 pm
Hi,
i try to  make a sbus signal to control a sbus controler. Could you give me an example to make it write instead of read from sbus?

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: dtsonchev on Feb 05, 2015, 11:59 am
Hello
I have receiver FrSKY 4RSB connected SBUS to NAZA M V2.
By Arduino, I want to on/off a LED from  the remote control channel 9.
Can you help me?

Thanks

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Feb 05, 2015, 01:48 pm
Have you tried the sketch in reply #44 ?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: miodand4 on Mar 24, 2015, 04:19 am
Hi,

I am using Taranis and X8R to communicate with an arduino nano, and for some reason something is not working. (Note even the example from the library)


I built an inverter with a BC337 and two resistors, and I plugged it into the serial port, but nothing happens.
Maybe I need a pull-up resistor in the output of the inverter?

Thanks in advance!
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Mar 24, 2015, 03:32 pm

This is the inverter I use.
Both resistors are 1k

(http://www.ernstc.dk/arduino/pic/inverter_sbus.jpg)
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mikesbaker on May 04, 2015, 10:56 pm
Hey everyone. I have made some big updates to the code. I have make a new sketch that autodetects betwen SBUS, DSM serial (10 or 11 bit), PPM and PWM. The code is a bit more readable now as well. It is set up to run on an arduino mega.

https://github.com/FunkyFlier/RC_sig_new_rc_type/
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: m0rph3us on Jul 25, 2015, 01:06 am
In order to get started, I am trying to replicate what Soler did with a Futaba R7008SB receiver.

I'm feeding +5V from the same Arduino Uno to a 74HC14 Hex Inverter but I'm still not getting any kind of signal being read in the program.  I've also tried the +3.3V port and still could not detect the correct output.

I verified that the serial port on my Arduino Uno is actually receiving data (looked at it through a program called XTCU) but I can't seem to trigger the "sBus.toChannels == 1" condition in the code.

What am I missing?



My code is:

Code: [Select]
#include "FUTABA_SBUS.h"
#include <Servo.h>

FUTABA_SBUS sBus;
Servo myservo;

void setup(){
  sBus.begin();
  Serial.begin(100000);
  Serial.println("Initialized!");
 
  pinMode(13, OUTPUT);    //LED
  digitalWrite(13, LOW);  //LED

  myservo.attach(3);       //attach a servo to pin 3
  myservo.writeMicroseconds(1500); //centered
}

void loop(){
  sBus.FeedLine();             
  if (sBus.toChannels == 1) {   
    digitalWrite(13, HIGH);
    delay(3000);
    sBus.UpdateServos();
    sBus.UpdateChannels();   
    sBus.toChannels = 0;      //why would this be updated???
   
    myservo.writeMicroseconds(1000);
}



I also tried Erni's code in post #31 with a 3.3V from the arduino (and 5V for the receiver from the same Arduino and still nothing)...any ideas...?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Degsky on Jul 30, 2015, 04:06 pm
Hi Guys,
first of all big thanks to mikesbaker for the great work!
I plan to port the code for a Tiva TM4C123GH6PM Microcontroller for my new Projekt.
And I have a stupid Question, perhaps you can help me:
I want to buy a receiver with S.Bus and read the Channels into the Microcontroller.
Do you know if the receiver put the Channel Information all the time on the S.Bus or do I have to "ask" the receiver over the S.Bus to put the Channel Information on the Bus?
If the receiver puts the Information unasked on the bus, do you know what's the time period between the publications?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Jul 30, 2015, 07:57 pm
Quote
Do you know if the receiver put the Channel Information all the time
The channel information is sent all the time, you don't need to ask.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Jul 30, 2015, 08:03 pm
@Degsky,

Using the below solution has the big advantage that the author mstrens is very active on the  openrcforum so you can ask him if you have any problems


http://openrcforums.com/forum/viewtopic.php?f=84&t=6361
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Degsky on Jul 31, 2015, 09:54 am
@Erni

Thanks for the quick reply!
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: ardued on Aug 17, 2015, 11:07 pm
Hi, thanks for nice work on this code :)
I have tried the code, made transistor signal inverter and i read the values of ch 1-8.

Arduino ProMicro 16Mhz
Reciever = Futaba R6303SB
Transmitter = Futaba 10C

Any idea on why dont i get values from channel 9 and 10?
ch9 stays solid on value 1023
ch10 stays solid on value 0

Solution:
Well i found it so i leave this post here if someone else wonders.
In the libraryfile "FUTABA_SBUS.h" i removed "//" before #define ALL_CHANNELS
Now it works perfectly and prints all channels :)
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: JuzARandomGuy on Sep 21, 2015, 11:04 am
https://github.com/mikeshub/FUTABA_SBUS
Hi guys, Im making use of the code above to use in my project of receiving and transmitting sbus signals to pixhawk. I can get the received signal to be displayed on to the serial monitor but i can't get the arduino to output any signal to the pixhawk. Much help is appreciated.:)
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Glowtape on Nov 17, 2015, 09:49 pm
This is the inverter I use.
Both resistors are 1k

(http://www.ernstc.dk/arduino/pic/inverter_sbus.jpg)
Nice to know this'll work instead of going with an 74HC14 or something.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: CrossRoads on Nov 17, 2015, 10:06 pm
That's also good as a 12V driver for P-channel MOSFET to switch on higher voltage/current loads.
Pull up to 12V tho.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Glattnos on Dec 21, 2015, 03:46 pm
Hi

I have problem to get this work properly. I get nothing back on the serial-port when I try this code:
Code: [Select]

#include <FUTABA_SBUS.h>
#include <Streaming.h>

FUTABA_SBUS sBus;

void setup(){
  sBus.begin();
  Serial.begin(115200);
}

void loop(){
  sBus.FeedLine();
    if (sBus.toChannels == 1){
    sBus.UpdateServos();
    sBus.UpdateChannels();
    sBus.toChannels = 0;
    Serial<<sBus.channels[0]<<","<<sBus.channels[1]<<","<<sBus.channels[2]<<"\r\n";
  }
}

But when I change in the end of the FUTABA_SBUS.ccp file from this:
Code: [Select]

        if (bufferIndex == 24){
          feedState = 0;
          if (inBuffer[0]==0x0f && inBuffer[24] == 0x00){
            memcpy(sbusData,inBuffer,25);
            toChannels = 1;
          }
        }

to this where I comment out the "&& inBuffer[24] == 0x00" like this:
Code: [Select]

        if (bufferIndex == 24){
          feedState = 0;
          if (inBuffer[0]==0x0f){                 // && inBuffer[24] == 0x00){
            memcpy(sbusData,inBuffer,25);
            toChannels = 1;
          }
        }


It works

I guess the "&& inBuffer[24] == 0x00" statement is to check the end of the string to be sure that it is changed to 0x00, it is earlier in the code set to 0xFF like this:
Code: [Select]

else{
          bufferIndex = 0;
          inBuffer[bufferIndex] = inData;
          inBuffer[24] = 0xff;
          feedState = 1;
        }


I have a Futaba R7008SB-reciver. What can be wrong? Someone that have any idea?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Glattnos on Dec 22, 2015, 07:05 pm
After sending the whole string I see that it looks like this:
Code: [Select]

0F E5 43 9F FA 02 08 16 18 02 10 80 00 04 20 00 01 08 07 38 00 10 80 00 04
0F E5 43 9F FA 02 08 16 18 02 10 80 00 04 20 00 01 08 07 38 00 10 80 00 14
0F E5 43 9F FA 02 08 16 18 02 10 80 00 04 20 00 01 08 07 38 00 10 80 00 24
0F E5 43 9F FA 02 08 16 18 02 10 80 00 04 20 00 01 08 07 38 00 10 80 00 34
0F E5 43 9F FA 02 08 16 18 02 10 80 00 04 20 00 01 08 07 38 00 10 80 00 04
0F E5 43 9F FA 02 08 16 18 02 10 80 00 04 20 00 01 08 07 38 00 10 80 00 14
0F E5 43 9F FA 02 08 16 18 02 10 80 00 04 20 00 01 08 07 38 00 10 80 00 24
0F E5 43 9F FA 02 08 16 18 02 10 80 00 04 20 00 01 08 07 38 00 10 80 00 34

0F in the begining is the start bit, the next 22 bytes are the channels(22bytes x 8bits=176bits, 176bits/11-bits = 16 11-bit channels), then the next byte is 00 all the time, but that is in this case byte 23 and not 24 so I changed to this:
Code: [Select]
if (inBuffer[0]==0x0f && inBuffer[23] == 0x00) //Changed to 23 instead of 24
That works!

But the last byte, it is going 04, 14, 24, 34 all the time. Anyone know why it is like that?

Edit: Hmmm byte 23 is the failsafe-bit so thats why that one is 00, if failsafe will activate it will change. So why is the last byte changing like that?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Becherraecher on Jan 10, 2016, 12:33 am
...

But the last byte, it is going 04, 14, 24, 34 all the time. Anyone know why it is like that?

Edit: Hmmm byte 23 is the failsafe-bit so thats why that one is 00, if failsafe will activate it will change. So why is the last byte changing like that?
Don't actually know what that byte is exactly. Am using FrSky and Spektrum.
But Have you recognized that your byte is always cycling '04, 14, 24, 34, 04, ...'?
Seem like a rolling counter or something. Maybe some watchdog functionality for receiving bus members?
Maybe only first byte is counter '0x, 1x, ...' and second byte is something like a status byte 'y4, (y+1)4, ...' and changing when receiver is connected to TX or in binded state or something else?

Just my late night thoguths :)

Regards
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: dsones on Jan 18, 2016, 12:29 am
Hi guys,

It is pretty cool this works!
Now that its know how it works is there any wat to reverse this and use it to send the sbus data from the arduino to a transmitter? something like a frsky xjt transmitter?

I would love to make a transmitter that way, send button or pulse signals to the arduino and finally send them converted in sbus to the xjt transmitter!

Sorry if my english is confusing im from the netherlands and not that good with this language..

Also pretty new to this forum lol!


Hope somebody had a idea/anwser to this, or maybe work something out together?


Cheers!
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Jan 18, 2016, 05:59 pm
Quote
is there any wat to reverse this and use it to send the sbus data from the arduino
You can genrate the SBUS data on an Arduino by using this sketch:

rcgroups (http://www.rcgroups.com/forums/showthread.php?t=2420473)

If you want to make a FrSky like transmitter, you could just Flash OpenTX on an Arduino Mega:

rcgroups (http://www.rcgroups.com/forums/showthread.php?t=2406337)
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: dsones on Jan 18, 2016, 08:51 pm
Thank you very much erni.
You gave me so much good info!

I will take a look at it and if i come any furter i will update you.

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: i3dm on Feb 07, 2016, 04:16 pm
Hello guys,

i read some posts in this thread, and focused on the HW side - seems like a logic inverter is needed.
is there a way to run Sbus codes on a Pro Mini with no external HW?
i know the pro mini can do at least 2 PWM outputs, but im actually looking at going a different way and use the Arduino Pro mini to gather serial data from Jetcat ECU and convert it to SBUS protocol for telemtry.

i already did the Jetcat serial communication side when i did my mini GSU project:
https://www.youtube.com/watch?v=0nNGnf0DVl8
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: dally on Feb 07, 2016, 08:31 pm
is there a way to run Sbus codes on a Pro Mini with no external HW?
I am afraid the answer is no
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: WhiteWind on May 20, 2016, 06:58 pm
Hi everyone! I am trying to use the described method to read my x4rsb receiver for my project. I was able from time to time read good values, but often I was received just a bunch of lost frames and errors. So I was trying to dig in that, and first of all I found, that not all the time 0F is the first byte, sometimes it's in the middle of the row:

Code: [Select]
0F E4 EB 1E 2B B2 C7 0A F1 B1 82 15 AC 18 1F F8 C0 07 3E F0 81 0F 7C 0 0
0F E4 E3 1E 2B B2 C7 0A F1 B1 82 15 AC 10 1F F8 C0 07 3E F0 81 0F 7C 0 0
0F E4 E3 1E 2B B2 C7 0A F1 B1 82 15 AC 08 1F F8 C0 07 3E F0 81 0F 7C 0 0
0F E4 EB 1E 2B B0 C7 8A F0 B1 82 15 AC 18 1F F8 C0 07 3E F0 81 0F 7C 0 0
0F E4 EB 1E 2B B2 C7 0A F1 B1 82 15 AC 10 1F F8 C0 07 3E F0 81 0F 7C 0 0


Ok, not the worse, but I decided to make a snake-line class, that will eat bytes one by one and pop them,if there is no place inside. I don't know, is there something ready for that, but it's really easy to implement. The goal was to catch byte row and check, if first and last byte are start and stop bytes. So, if true, we can decode the bytes the way it's done in the sbus library mentioned above;


my sbus.cpp
Code: [Select]
#include "SBUS2.h"
#include <Arduino.h>

void SBUS::begin() {
SBUS::begin(true);
}

void SBUS::begin(bool useTimer) {
//wiffer.begin();
if (useTimer) {
noInterrupts();
/*TCCR2A  = 0;
TCCR2B  = 0;
TCNT2   = 0;
OCR2A   = 249;
TCCR2A |= (1 << WGM21);
TCCR2B |= (1 << CS22);
TIMSK2 |= (1 << OCIE2A);*/
interrupts();
}

for (byte i = 0; i<18; i++) {
_channels[i]      = 0;
}

_goodFrames         = 0;
_lostFrames         = 0;
_decoderErrorFrames = 0;
_failsafe           = SBUS_FAILSAFE_INACTIVE;

_serial.begin(100000, SERIAL_8E1_RXINV_TXINV);
}

void SBUS::process() {
static byte buffer[25];
static byte buffer_index = 0;
wiffer.begin();//reset wiffer again
while (_serial.available()) {
byte rx = _serial.read();
wiffer.push(rx);

    for (int i = 0; i < WIFFER_LENGTH; ++i)
    {
    Serial.print(String(wiffer.get(i), HEX));
    Serial.print(' ');
    }
    Serial.println('--');
if (!wiffer.full()){
continue;
}
if (wiffer.first() == SBUS_STARTBYTE && wiffer.last() == SBUS_ENDBYTE){
Serial.println('???');
for (int i = 1; i < 25; ++i)
{
buffer[i] = wiffer.get(i);
}
_decoderErrorFrames += wiffer.lost();
_goodFrames += 26;
wiffer.begin();

_bytes=' ';
for (int i = 0; i < 25; ++i)
{
_bytes= _bytes + ' ' + String(buffer[i], HEX);
}

_channels[0]  = ((buffer[1]    |buffer[2]<<8)                 & 0x07FF);
_channels[1]  = ((buffer[2]>>3 |buffer[3]<<5)                 & 0x07FF);
_channels[2]  = ((buffer[3]>>6 |buffer[4]<<2 |buffer[5]<<10)  & 0x07FF);
_channels[3]  = ((buffer[5]>>1 |buffer[6]<<7)                 & 0x07FF);
_channels[4]  = ((buffer[6]>>4 |buffer[7]<<4)                 & 0x07FF);
_channels[5]  = ((buffer[7]>>7 |buffer[8]<<1 |buffer[9]<<9)   & 0x07FF);
_channels[6]  = ((buffer[9]>>2 |buffer[10]<<6)                & 0x07FF);
_channels[7]  = ((buffer[10]>>5|buffer[11]<<3)                & 0x07FF);
_channels[8]  = ((buffer[12]   |buffer[13]<<8)                & 0x07FF);
_channels[9]  = ((buffer[13]>>3|buffer[14]<<5)                & 0x07FF);
_channels[10] = ((buffer[14]>>6|buffer[15]<<2|buffer[16]<<10) & 0x07FF);
_channels[11] = ((buffer[16]>>1|buffer[17]<<7)                & 0x07FF);
_channels[12] = ((buffer[17]>>4|buffer[18]<<4)                & 0x07FF);
_channels[13] = ((buffer[18]>>7|buffer[19]<<1|buffer[20]<<9)  & 0x07FF);
_channels[14] = ((buffer[20]>>2|buffer[21]<<6)                & 0x07FF);
_channels[15] = ((buffer[21]>>5|buffer[22]<<3)                & 0x07FF);

((buffer[23])      & 0x0001) ? _channels[16] = 2047: _channels[16] = 0;
((buffer[23] >> 1) & 0x0001) ? _channels[17] = 2047: _channels[17] = 0;

if ((buffer[23] >> 3) & 0x0001) {
_failsafe = SBUS_FAILSAFE_ACTIVE;
} else {
_failsafe = SBUS_FAILSAFE_INACTIVE;
}

if ((buffer[23] >> 2) & 0x0001) {
_lostFrames++;
}

_lastGoodFrame = millis();
}
}
}

int SBUS::getChannel(int channel) {
if (channel < 1 or channel > 18) {
return 0;
} else {
return _channels[channel - 1];
}
}

int SBUS::getNormalizedChannel(int channel) {
if (channel < 1 or channel > 18) {
return 0;
} else {
return (int) lround(_channels[channel - 1] / 9.92) - 100; //9.92 or 10.24?
}
}

int SBUS::getFailsafeStatus() {
return _failsafe;
}

int SBUS::getFrameLoss() {
return (int) ((_lostFrames + _decoderErrorFrames) * 100 / (_goodFrames + _lostFrames + _decoderErrorFrames));
}

long SBUS::getGoodFrames() {
return _goodFrames;
}

long SBUS::getLostFrames() {
return _lostFrames;
}

long SBUS::getDecoderErrorFrames() {
return _decoderErrorFrames;
}

long long SBUS::getLastTime() {
return _lastGoodFrame;
}


String SBUS::getBytes() {
return _bytes;
}



//WIFFER

void WIFFER::begin(){
  _pointer = -1;
  _count = 0;
  _eternal = 0;
  for (int i = 0; i < WIFFER_LENGTH; ++i)
  {
  _data[i] = 0;
  }
}
void WIFFER::push(byte item){
  _pointer++;
  _eternal++;
  if (_count<WIFFER_LENGTH){
  _count++;
  }
  if (_pointer == WIFFER_LENGTH){
  _pointer = 0;
  }
  _data[_pointer] = item;
}
byte WIFFER::get(int index){
int target = (_pointer + 1 + index) % WIFFER_LENGTH;
return _data[target];
}
byte WIFFER::first(){
  if (_count<WIFFER_LENGTH){
  return _data[0];
  }else{
  if (_pointer + 1 < WIFFER_LENGTH){
  return _data[_pointer + 1];
  }else{
return _data[0];
  }
  }
}
byte WIFFER::last(){
return _data[_pointer];
}

int WIFFER::length(){
return _count;
}

bool WIFFER::full(){
return (_count == WIFFER_LENGTH);
}

unsigned long WIFFER::lost(){
return _eternal - _count;
}



Don't be surprised, the code is used on teensy board, so I have a little bit different hardware;
Whoa, it's working, but I am not sure about counting good and bad frames (i am counting bytes instead).
Lastly, I uploaded the code, and found that strange thing (0F is replaced to -- for the ease of reading).
Code: [Select]
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 8F 15 00 00
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 8F 15 00 00
-- E4 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 8F 15 00 00
-- E4 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 8F 15 00 00
-- E4 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 8F 15 00 00
-- E4 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 8F 15 00 00
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 8F 15 00 --
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 F0 00 -- E5 E3 1E 2B
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E 15 -- E5 E3 1E 2B
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 8F 00 -- E5
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 8F 00 -- E5 E3
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 8F -- E5 E3 1E
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 15 -- E4 E3
-- E4 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 15 -- E4 E3
-- E4 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 00 -- E5 E3
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 00 -- E5 E3
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 8F 00 -- E5 E3
-- E5 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 8F -- E5 E3 1E
-- E5 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 15 -- E5 E3
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 15 -- E5 E3
-- E5 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 00 -- E5 D3
-- E5 D3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 00 -- E5 D3
-- E5 D3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 8F 00 -- E4 E3
-- E4 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 15 -- E4 E3 1E
-- E4 E3 1E 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 15 -- E4 E3
-- E4 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 00 -- E4 E3
-- E4 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 00 -- E5 03
-- E5 03 1F 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 81 00 -- E5 03
-- E5 03 1F 2B AE C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 8F 00 -- E5 E3
-- E5 E3 1E 2B B0 C7 0A 56 B0 82 15 AC 60 05 F8 C0 07 3E F0 8F -- E5 E3 1E


Any ideas, why it's shorter? Why the length is not constant (but there is clearly an order in that), and what should I do with that stuff now?
Can someone tell me, if I am doing something wrong, or am I messed with the code?
May be there is something in frsky sbus, that is not described?  :o 
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: WhiteWind on May 20, 2016, 11:06 pm
I solved all the problems and, at last, my code is working good, as expected.
The problem was in too fast buffer polling (I downclocked the timer) and mostly in some kind of buffer overflow, as the reading buffer to the end on the starting of lost frame avalanche is making it work again.

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: SignalAudio on Jul 03, 2016, 03:26 pm
Hi all,

I have a fairly simple application but I'm not using these RC parts most of you appear to be using; so can I ask that you first clarify a few things:

1. Is the bus full duplex over one wire (like the I2C data line)? If so, am I simply tying the input and output of two different inverters (from a 74HC14) together on the S.Bus side?
2. Most of you appear to be reading the S.Bus, not writing to it. If the answer to my first question is yes, then do I need to read from the bus in order to be able to write to it (so it knows when to listen and when to talk..)?

@mikesbaker has posted a library zip file in #5, uploaded a library to github in #8, posted what appears to be half a library to pastebin in #29 and posted another library to a different Github account in #52 (!). I've toyed with the two different libraries posted to Github and while both have an example sketch, neither is marked-up, and neither appears to have an example of writing to a channel.

I mean no offense, @mikesbaker - you are clearly the authority on all this! It just would be lovely to have a cohesive "If you want to read s.bus try this, if you want to write to s.bus try this.."

So, this is my scenario. A newish camera from Blackmagic Design - the Micro Studio Camera - has a s.bus connection on it's expansion port breakout. The menu on the camera allows you to assign s.bus channels to different functions (iris, focus, white balance etc). I just want to get in and tell it what to do. There is just one s.bus pin with an accompanying ground wire, so it's either Rx only, or it's full duplex.

Answers to questions 1 and 2 above will get me a long way, and perhaps a pointer to the best library and some tips on establishing if I've got comms would be great. I have a 74HC14 inverter and a voltage level shifter (not yet sure if level shift will be necessary) at the ready and I know these are working and the polarity is correct.

Many thanks in advance..
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: seanxsj on Sep 30, 2016, 03:24 am
Thank you for sharing your amazing work! I have a question, may be it is already being answered, please bare with me I am new to this :) . From my understanding, the Sbus Protocol is a 25bytes data with 12 bits per byte and 12 X 25= 300 bits. I am trying to make Arduino communicating with NAZE 32 flight controller by using Sbus. Basically, if a ultra-sonic sensor is being used to measure the height and id it is below certain preset value, it will send a signal to increase the throttle automatically. It is a little bit confuse here, since many of the post mentioned that the Sbus data is something like this:
0x0F5C9126377FA46AAB00108000042000010870000210800C00 this is not 300 bits data and where is the start bit, paritybit and stop bit?



S-BUS protocol

The protocol is 25 Byte long and is send every 14ms (analog mode) or 7ms (highspeed mode).
One Byte = 1 startbit + 8 databit + 1 paritybit + 2 stopbit (8E2), baudrate = 100'000 bit/s
The highest bit is send first. The logic is inverted (Level High = 1)

[startbyte] [data1] [data2] .... [data22] [flags][endbyte]

startbyte = 11110000b (0xF0)

data 1-22 = [ch1, 11bit][ch2, 11bit] .... [ch16, 11bit] (ch# = 0 bis 2047)
channel 1 uses 8 bits from data1 and 3 bits from data2
channel 2 uses last 5 bits from data2 and 6 bits from data3
etc.

flags = bit7 = ch17 = digital channel (0x80)
bit6 = ch18 = digital channel (0x40)
bit5 = Frame lost, equivalent red LED on receiver (0x20)
bit4 = failsafe activated (0x10)
bit3 = n/a
bit2 = n/a
bit1 = n/a
bit0 = n/a

endbyte = 00000000b

I have tried the code in this link http://www.rcgroups.com/forums/showthread.php?t=2420473 However, it will only output 16 random hex number. I do not have any control to it.

Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: caiopoit on Jan 19, 2017, 02:34 pm
Has anyone here managed to get a working SBUS to PPM servo HUB with a nano or ProMini? Or this has absolutely nothing to do with anyone's intention in these posts? Because I've searched for some time and I noticed that this is a frequently requested code and so far I couldn't manage to find an organized project about this.

This would be the reference for what I mean exactly:http://www.banggood.com/16CH-Receiver-PWMPPMSBUSDBUS-To-Signal-Converter-Module-For-DJI-NAZA-Zero-Flight-Controller-p-996918.html?rmmds=search (http://www.banggood.com/16CH-Receiver-PWMPPMSBUSDBUS-To-Signal-Converter-Module-For-DJI-NAZA-Zero-Flight-Controller-p-996918.html?rmmds=search)
That would be awesome to use with this:http://www.banggood.com/2_4G-8CH-Compatible-Receiver-for-Futaba-T6J-T8J-T10J-T14SG-S-FHSS-S-SBUS-p-1050812.html?rmmds=search (http://www.banggood.com/2_4G-8CH-Compatible-Receiver-for-Futaba-T6J-T8J-T10J-T14SG-S-FHSS-S-SBUS-p-1050812.html?rmmds=search)

I really hope to see something about this because a nano board is much cheaper than this converter!
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: joe147 on Feb 02, 2017, 05:02 am
Hi all,


I am trying to implement a sensor to a drone to avoid obstacles. I want to control the pitch channel so that when the drone senses an obstacle in front, the Arduino will overwrite the pitch channel, the drone will pitch up, and move back to avoid the obstacle.

I am using a 8 channel Futaba R2008SB radio receiver. I downloaded the Arduino libraries:

FUTABA_SBUS library: https://github.com/mikeshub/FUTABA_SBUS
Streaming library: http://arduiniana.org/libraries/streaming/

I used a 74LS14 hex inverter.
I connected the SBUS signal of the radio receiver to input of an inverter, the output of the inverter to the RX of the Arduino.
The TX of the Arduino connected to the input of another inverter, the output of the inverter to the RC signal of the Pixhawk.

I opened the serial monitor and set it to 115200 baud, however, there is no numbers displayed on the serial monitor.

I am wondering if the code is suitable for 8 channels, or am I required to modify the code to suit 8 channels? Does the code work if some of the channels between the radio transmitter and the radio receiver are inverted? Also, I am not sure whether my circuit connections are correct.

I do not understand SBUS protocol. I am interested to learn about how the bytes affect the channels.

I hope to receive help please, I would appreciate your help. Thanks.

Below is the code:

Code: [Select]
#include <FUTABA_SBUS.h>
#include <Streaming.h>


FUTABA_SBUS sBus;


void setup(){
  sBus.begin();
  Serial.begin(115200);
}

void loop(){
  sBus.FeedLine();
  if (sBus.toChannels == 1){
    sBus.UpdateServos();
    sBus.UpdateChannels();
    sBus.toChannels = 0;
    Serial<<sBus.channels[0]<<","<<sBus.channels[1]<<","<<sBus.channels[2]<<"\r\n";
  }
}
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Eagle71 on Mar 19, 2017, 07:44 pm
Hello

@caiopoit  here is a Project you search for. But it is in German:

http://fpv-community.de/showthread.php?32899-FrSky-TARANIS-Hardware-Mods&p=477461&viewfull=1#post477461

You have to download the LIB's too, because they where modified for the MICRO!
And copy the Futaba-sbus and RC Dir's into your Arduino-Libs-Dir


The Inverter with npn-Transistor on Top of Page 5 do his work! I Use about 12kohm Pullup and 5,7kohm Basis resistor.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: mturneruk on Apr 15, 2017, 10:24 am

Hey all..

I would be very grateful anyone can help.

I have been using the fantastic Futaba SBUS Library on an Arduino Mega to read channel data from a  FRSky X8R / Taranis. I am using the inverter described here (http://www.ernstc.dk/arduino/sbus.html).

I get frequent Lockups, where the transmitter will stop responding and my robot will just going until i reset the Arduino. Sometimes after 20 seconds, sometimes after 5 mins. I have built several robots which use this library and I have experienced the same problem on all.

I am using the stock FUTABA_SBUS_h Library and RX SerialPort 3 on the Mega to receive the Sbus Data.

It's starting to drive me crazy. Any help much appreciated.
I have no idea how to debug.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: jbarchuk on Apr 15, 2017, 05:02 pm
using the fantastic Futaba SBUS Library on an Arduino Mega to read channel data from a  FRSky X8R / Taranis.
...several robots which use this library and I have experienced the same problem on all.
Have you tried a Futaba Tx/Rx? If not you've bet the farm on the skills of the Chinese reverse engineering department. They're notorious for de-engineering things, lowering parts specs, leaving parts out, and changing critical circuit points just to save a few nickels. Which often leads to failure
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: szabi on May 18, 2017, 02:45 pm
Hey guys.

I know it's an older thread, but I thought I'll post a version of my Futaba S-BUS Library. It might be useful for some.

The library can be cloned (the latest version) here (https://gitlab.hacking.hu/szabolcs/arduino-futaba-sbus.git).


I've attached the latest build, but try and use the one from the above link always as that's going to be the latest version.


Szabi
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Dagroid on Aug 20, 2017, 06:53 pm
Hi, thanks for nice work on this code :)
I have tried the code, made transistor signal inverter and i read the values of ch 1-8.

Arduino ProMicro 16Mhz
Reciever = Futaba R6303SB
Transmitter = Futaba 10C

Any idea on why dont i get values from channel 9 and 10?
ch9 stays solid on value 1023
ch10 stays solid on value 0

Solution:
Well i found it so i leave this post here if someone else wonders.
In the libraryfile "FUTABA_SBUS.h" i removed "//" before `1
Now it works perfectly and prints all channels :)
Thanks for posting this...now I've got all 16 channels of my Taranis after uncommenting #define ALL_CHANNELS.  Before this, I was only able to see channels 1-8 changing.

Next step for me is to pass along some of these values to a Pololu Servo Maestro controller.

Here is my updated serial display line with all channels
Code: [Select]
    Serial<<sBus.channels[0]<<"\t"<<sBus.channels[1]<<"\t"<<sBus.channels[2]<<"\t"<<sBus.channels[3]<<"\t"<<sBus.channels[4]<<"\t"<<sBus.channels[5]<<"\t"<<sBus.channels[6]<<"\t"<<sBus.channels[7]<<"\t"<<sBus.channels[8]<<"\t"<<sBus.channels[9]<<"\t"<<sBus.channels[10]<<"\t"<<sBus.channels[11]<<"\t"<<sBus.channels[12]<<"\t"<<sBus.channels[13]<<"\t"<<sBus.channels[14]<<"\t"<<sBus.channels[15]<<"\r\n";


And of course, thanks to Mike for the library!
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Eurcka on Aug 21, 2017, 07:59 am
Hi,

I am new the arduino and uav.
Currently my project requires me to have arduino communicate with f3 fc.
Knowing f3 supports Uart, how can I use arduino to simulate sbus/ibus RX and TX serial input to f3 fc
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: DocStein99 on Oct 06, 2017, 07:49 am
I am also looking for a project or example too, trying to generate the sBus signal - not RECEIVE the signal. 
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Oct 06, 2017, 01:33 pm
Here is an example for sending SBUS signal

www.rcgroups.com (https://www.rcgroups.com/forums/showthread.php?2420473-Arduino-S-BUS-Packet-Generator-Code)
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: DocStein99 on Oct 07, 2017, 05:15 am
Thank you Erni.  I recently discovered, the sBus signal is generated at the RX module level.  I was under the impression it was generated at the transmitter, and sent through RF modules - but that is not the case.

Do you know if there is a transmitter library / project I can learn to connect to a TX module, to bind to an RX sBus (or iBus) ?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: Erni on Oct 07, 2017, 11:40 am
You could take a looke at the opentx project:

http://www.open-tx.org/ (http://www.open-tx.org/)

They have a version for Arduino Mega.

This is the forum if you have any questions:


http://openrcforums.com/ (http://openrcforums.com/forum/index.php)
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: robweidner on Nov 12, 2017, 04:16 pm
I am also struggling with this sketch.  I am using the Elegoo Mega1560 and keep getting the

##avrdude: stk500v2_ReceiveMessage(): timeout

errors when trying to upload.  Usually, I can unplug the RX0 which is going to my inverted SBUS signal, and the sketch then uploads, but then when I plug it back in and open up serial monitor, I don't get proper values.  Using http://www.ernstc.dk/arduino/pic/inverter_sbus.jpg as my inverter with 1 10k and 1 5k resistor and a PN2222A transistor.  can't burn bootloader to mega board either.  Thinking it might be the board, and possibly will switch to an Uno.  Any suggestions?
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: DocStein99 on Nov 13, 2017, 12:36 am
I am also struggling with this sketch.  I am using the Elegoo Mega1560 and keep getting the

##avrdude: stk500v2_ReceiveMessage(): timeout

I never seen a ellego mega1560 before.  If that works same way as meg2560, my advice is to remove your custom ciruitry first.  Then try compile and upload a test led blinker sketch.  If that works, try compile and upload the futaba compiled sketch.

Once you knos you csn upload a sketch to the bare board, then move on to adding circuits to test the software that it runs.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: robweidner on Nov 18, 2017, 04:22 pm
So I have wired up my 2x 1k resistor inverter and have managed to get the upload to complete, but when I open up the serial monitor, nothing shows up...
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: DocStein99 on Dec 01, 2017, 07:46 pm
Ok, my next advice would be to upload a test sketch, and make sure you can see serial data in the monitor.  Send "hello world" to serial port on loop.
Title: Re: Futaba SBUS reverse engineered to work with Arduino
Post by: osmancns on Feb 27, 2018, 07:08 pm
Hello. i have a big problem i need yours help.
i use RB7008SB and arduino. i made a inverter circuit.
i see SBUS protocol data on putty no problem but data frame is different.
data frame problem same like this post:
@Glattnos --> #63
here is my sbus output on putty
http://i63.tinypic.com/2emmve8.jpg