Futaba SBUS reverse engineered to work with Arduino
hi guys,
http://www.futaba-rc.com/sbus/index.html
i needed use both regular servos , sbus servos project have going on right now. sbus interesting thing. uses 100000 baud inverted uart 25 byte transmission. each channel transmitted using 11 bits of data. there start end byte. use 2 stop bits , parity. fun comes in. signal transmitted big endian, each of individual bytes little endian. had figured stuff out when stumbled upon gem:
http://mbed.org/users/digixx/notebook/futaba-s-bus-controlled-by-mbed/
not did have confirm reverse engineering suspicions, had made great algorithm bit bang transmission correct format. due user fat16lib excellent serial library allows things changing parity , stop bits. modified code guys on @ mbed had done , used hex inverter , results perfect. wrote none of code , did allow free redistribution go nuts. imo ability use sbus pretty big arduino. if feel motivated i'll turn proper library. is. if can read code, way thing works pretty self explanatory:
http://www.youtube.com/watch?v=_qelbebtsdw
http://www.futaba-rc.com/sbus/index.html
i needed use both regular servos , sbus servos project have going on right now. sbus interesting thing. uses 100000 baud inverted uart 25 byte transmission. each channel transmitted using 11 bits of data. there start end byte. use 2 stop bits , parity. fun comes in. signal transmitted big endian, each of individual bytes little endian. had figured stuff out when stumbled upon gem:
http://mbed.org/users/digixx/notebook/futaba-s-bus-controlled-by-mbed/
not did have confirm reverse engineering suspicions, had made great algorithm bit bang transmission correct format. due user fat16lib excellent serial library allows things changing parity , stop bits. modified code guys on @ mbed had done , used hex inverter , results perfect. wrote none of code , did allow free redistribution go nuts. imo ability use sbus pretty big arduino. if feel motivated i'll turn proper library. is. if can read code, way thing works pretty self explanatory:
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 send servos
sbus_passthrough = mode;
}
int passthroughret(void) {
// return current passthrough mode
return sbus_passthrough;
}
void update_servos(void) {
// send data 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
(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
(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);
(i=0;i<25;i++) {
port0.write(sbus_data[i]);
}
}
void update_channels(void) {
uint8_t i;
uint8_t sbus_pointer = 0;
// clear channels[]
(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
(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;
}
}
}
it took me while find fat16lib serialport library you've used (probably because i'm new @ this), here's link:
http://arduino.cc/forum/index.php/topic,85207.0.html
http://arduino.cc/forum/index.php/topic,85207.0.html
Arduino Forum > Community > Exhibition / Gallery > Futaba SBUS reverse engineered to work with Arduino
arduino
Comments
Post a Comment