Giter Club home page Giter Club logo

sbus's Introduction

License: MIT

Bolder Flight Systems Logo     Arduino Logo

Sbus

This library communicates with SBUS receivers and servos and is compatible with Arduino and CMake build systems.

Description

SBUS is a bus protocol for receivers to send commands to servos. Unlike PWM, SBUS uses a bus architecture where a single serial line can be connected with up to 16 servos with each receiving a unique command.

The SBUS protocol uses an inverted serial logic with a baud rate of 100000, 8 data bits, even parity, and 2 stop bits. The SBUS packet is 25 bytes long consisting of:

  • Byte[0]: SBUS header, 0x0F
  • Byte[1 -22]: 16 servo channels, 11 bits each
  • Byte[23]
    • Bit 0: channel 17 (0x01)
    • Bit 1: channel 18 (0x02)
    • Bit 2: frame lost (0x04)
    • Bit 3: failsafe activated (0x08)
  • Byte[24]: SBUS footer

Note that lost frame is indicated when a frame is lost between the transmitter and receiver. Failsafe activation typically requires that many frames are lost in a row and indicates that the receiver has moved into failsafe mode. Packets are sent approximately every 10 ms or 20 ms, depending on the system configuration.

A variation on SBUS called "Fast SBUS" has started to be used. This uses a baudrate of 200000 and a quicker update rate.

Note on CH17 and CH18: Channel 17 and channel 18 are digital on/off channels. These are not universally available on all SBUS receivers and servos.

FrSky receivers will output a range of 172 - 1811 with channels set to a range of -100% to +100%. Using extended limits of -150% to +150% outputs a range of 0 to 2047, which is the maximum range acheivable with 11 bits of data.

Because SBUS is a digital bus format, it is an excellent means of receiving pilot commands from a transmitter and an SBUS capable receiver. If SBUS servos are used in the aircraft, SBUS is also an excellent means of sending actuator commands - servo commands can often be sent with lower latency and, by only using a single pin to command up to 16 servos, additional microcontroller pins are freed for other uses.

Inverted Serial

SBUS uses an inverted serial protocol, which is not commonly supported in Arduino. This library is able to use inverted serial for the following microcontrollers:

  • Teensy 3.x
  • Teensy 4.x
  • Teensy LC
  • STM32L496xx
  • STM32L476xx
  • STM32L433xx
  • STM32L432xx
  • ESP32

For all other microcontrollers, you must use a serial inverter. If you've modified this library to work with other microcontrollers, please submit a pull request.

Installation

Arduino

Simply clone or download and extract the zipped library into your Arduino/libraries folder. The library is added as:

#include "sbus.h"

An example is located in examples/arduino/sbus_example/sbus_example.ino. This library is tested with Teensy 3.x, 4.x, and LC devices and should work with other Arduino devices.

CMake

CMake is used to build this library, which is exported as a library target called sbus. The header is added as:

#include "sbus.h"

The library can be also be compiled stand-alone using the CMake idiom of creating a build directory and then, from within that directory issuing:

cmake .. -DMCU=MK66FX1M0
make

This will build the library and example executable called sbus_example. The example executable source file is located at examples/cmake/sbus_example.cc. Notice that the cmake command includes a define specifying the microcontroller the code is being compiled for. This is required to correctly configure the code, CPU frequency, and compile/linker options. The available MCUs are:

  • MK64FX512
  • MK66FX1M0
  • MKL26Z64
  • IMXRT1062_T40
  • IMXRT1062_T41
  • IMXRT1062_MMOD

These are known to work with the same packages used in Teensy products. Also switching packages is known to work well, as long as it's only a package change.

The sbus_example target creates an executable for communicating with sbus receivers and servos. This target also has a _hex for creating the hex file and an _upload for using the Teensy CLI Uploader to flash the Teensy. Instructions for setting up your build environment can be found in our build-tools repo.

Namespace

This library is within the namespace bfs.

SbusData

This struct defines SBUS data that can be read and returned by the SbusRx object or set and sent by the SbusTx object.

Data Members

bool lost_frame Whether a frame has been lost.

bool failsafe Whether the receiver has entered failsafe mode or to command servos to enter failsafe mode.

bool ch17, ch18 State of channel 17 and channel 18.

static constexpr int8_t NUM_CH = 16 The number of SBUS channels.

int16_t ch[NUM_CH] An array of SBUS channel data.

SbusRx

This class is used for receiving SBUS data from an SBUS capable receiver.

SbusRx(HardwareSerial *bus) Creates an SbusRx object. A pointer to the Serial object corresponding to the serial port used is passed. The RX pin of the serial port will receive SBUS packets.

bfs::SbusRx sbus(&Serial1);

SbusRx(HardwareSerial *bus, const bool inv) Creates an SbusRx object. A pointer to the Serial object corresponding to the serial port used is passed along with a second parameter, inv, which sets whether inverted serial is used. If inv is true, the signal is the standard inverted SBUS, otherwise it is non-inverted SBUS.

bfs::SbusRx sbus(&Serial1, false);

SbusRx(HardwareSerial *bus, const bool inv, const bool fast) Same as the constructor above, but enables selecting the fast SBUS baudrate (200000) if fast is true.

(ESP32 ONLY) SbusRx(HardwareSerial *bus, const int8_t rxpin, const int8_t txpin, const bool inv) Creates an SbusRx object. A pointer to the Serial object corresponding to the serial port used is passed along with the RX pin number (rxpin), TX pin number (txpin), and whether inverted serial is used (inv). If inv is true, the signal is the standard inverted SBUS, otherwise it is non-inverted SBUS.

(ESP32 ONLY) SbusRx(HardwareSerial *bus, const int8_t rxpin, const int8_t txpin, const bool inv, const bool fast) Same as the constructor above, but enables selecting the fast SBUS baudrate (200000) if fast is true.

void Begin() Initializes SBUS communication.

sbus.Begin();

bool Read() Parses SBUS packets, returns true on successfully receiving an SBUS packet.

if (sbus.Read()) {
  // Do something with the received data
}

SbusData data() Returns the SbusData structure, populated with data from the last received packet.

if (sbus.Read()) {
  bfs::SbusData data = sbus.data();
}

SbusTx

This class is used for transmitting SBUS data to SBUS capable servos.

SbusTx(HardwareSerial *bus) Creates an SbusTx object. A pointer to the Serial object corresponding to the serial port used is passed. The TX pin of the serial port will receive SBUS packets.

bfs::SbusTx sbus(&Serial1);

SbusTx(HardwareSerial *bus, const bool inv) Creates an SbusTx object. A pointer to the Serial object corresponding to the serial port used is passed along with a second parameter, inv, which sets whether inverted serial is used. If inv is true, the signal is the standard inverted SBUS, otherwise it is non-inverted SBUS.

bfs::SbusTx sbus(&Serial1, false);

(ESP32 ONLY) SbusTx(HardwareSerial *bus, const int8_t rxpin, const int8_t txpin, const bool inv) Creates an SbusTx object. A pointer to the Serial object corresponding to the serial port used is passed along with the RX pin number (rxpin), TX pin number (txpin), and whether inverted serial is used (inv). If inv is true, the signal is the standard inverted SBUS, otherwise it is non-inverted SBUS.

void Begin() Initializes SBUS communication.

sbus.Begin();

void Write() Writes an SBUS packet. The packet is written immediately, you should regulate timing of sending packets to servos to maintain a frequency of approximately 100 Hz or 50 Hz, depending on the setup of the SBUS system.

sbus.Write();

void data(const SbusData &data) Sets the SBUS data, which will be transmitted on the next Write method.

bfs::SbusData data;
data.ch[0] = 900;
sbus.data(data);

SbusData data() Returns the SBUS data buffered in the SbusTx object, which will be transmitted on the next Write method.

bfs::SbusData data = sbus.data();

sbus's People

Contributors

daniel-1276 avatar daz avatar flybrianfly avatar functionpointer avatar kanishkegb avatar scottduckworth avatar sheariley avatar simondlevy avatar yongyew avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sbus's Issues

Stop Byte is not always 0x00

Hi there,

I understand that according to this mbed post, the stop byte at the end of every packet is supposed to be 0x00. However, another site suggests that the stop byte can be 0x04, 0x14, 0x24 or 0x34 to represent different sections of data.

This tallies with my findings after using this library in my project. Here is some sample data I have:

00 FE B3 5F 14 17 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 4
00 FE B3 5F 14 17 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 14
00 FE B3 5F 14 13 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 24
00 FE B3 5F 14 13 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 34
00 FE B3 5F 14 13 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 4
00 FE B3 5F 14 13 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 14
00 FE B3 5F 14 13 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 24
00 FE B3 5F 14 13 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 34
00 FE B3 5F 14 13 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 4
00 FE B3 5F 14 17 8 77 0 42 2 EE 90 80 4 0 1 8 40 0 2 10 80 0 14

As a solution, I replaced line 201 of SBUS.cpp with

if ((c & 0x0F) == 0x04) {

to look for 0xX4 in the lower nibble of the serial packet instead of _sbusFooter which is 0x00.

My setup involves a Futaba T10J and a Futaba R3008SB, with data being read from a Teensy 3.2.

Failing to recieive

Using an Arduino Mega 2560 with a FrySky R-XSR. I am using the SBUS_example.ino (as a base) on Serial2 (Pin 17 RX) and verified the program starts and the main loop runs but I never get inside the if

if(x8r.read(&channels[0], &failSafe, &lostFrame)){

    Serial.print("working");
  }

I put some return statements to shortcircuit SBUS read and it looks like the if (parse()) { on line 66 of SBUS.cpp is returning false.
I used an oscilloscope to verify that my inverting circuit is working so I'm not sure why the packet isn't coming through correctly.

#include "SBUS.h"

// a SBUS object, which is on hardware
// serial port 1
SBUS x8r(Serial2);

// channel, fail safe, and lost frames data
uint16_t channels[16];
bool failSafe;
bool lostFrame;

void setup() {
  // begin the SBUS communication
  x8r.begin();
  Serial.begin(115200);
  Serial.println("start");
  

}

void loop() {

  // look for a good SBUS packet from the receiver
  Serial.println("polling: ");
  if(x8r.read(&channels[0], &failSafe, &lostFrame)){

    Serial.print("working");
  }
  
}

Support NRF52 / Arduino Nano 33 BLE

Found a way to get the library to work on the Arduino Nano 33 BLE.

By default the UART on the NRF52 does not support custom baud rates or UART config other than the default but these can be configured using registers.

Basically I did something like this:

At the start of sbus.cpp after the includes:

#if defined(ARDUINO_ARCH_NRF52840) // Arduino Nano 33 BLE

#define UARTE0_BASE_ADDR 0x40002000
#define UARTE1_BASE_ADDR 0x40028000
#define UART_BAUDRATE_REG_OFFSET 0x524
#define UART_CONFIG_REG_OFFSET 0x56C
#define UART_CONFIG_8E2 0x000000F
#define UART_BAUD_100000 0x19114A7
#define UART0_BAUDRATE_REGISTER (((unsigned int *)(UARTE0_BASE_ADDR + UART_BAUDRATE_REG_OFFSET)))
#define UART1_BAUDRATE_REGISTER (((unsigned int *)(UARTE1_BASE_ADDR + UART_BAUDRATE_REG_OFFSET)))
#define UART0_CONFIG_REGISTER (((unsigned int *)(UARTE0_BASE_ADDR + UART_CONFIG_REG_OFFSET)))
#define UART1_CONFIG_REGISTER (((unsigned int *)(UARTE1_BASE_ADDR + UART_CONFIG_REG_OFFSET)))

#endif

Added custom Begin signature for the NRF52840 to support both UART0 and UART1:

#elif defined(ARDUINO_ARCH_NRF52840)
    void Begin(int uart = 0);
#else

And then added custom initialization in Begin:

#elif defined(ARDUINO_ARCH_NRF52840) // Arduino Nano 33 BLE
  uart_->begin(9600);

  if (uart == 0)
  {
    *UART0_BAUDRATE_REGISTER = UART_BAUD_100000;
    *UART0_CONFIG_REGISTER = UART_CONFIG_8E2;
  }
  else if (uart == 1)
  {
    *UART1_BAUDRATE_REGISTER = UART_BAUD_100000;
    *UART1_CONFIG_REGISTER = UART_CONFIG_8E2;
  }
/* Everything else, with a hardware inverter */
#else

The same could be done for SbusTx.

Tested with Frsky R-XSR using the uninverted sbus signal from the B-pad and it works great.

image

Would be cool if this support was included in the library and if not then maybe it helps someone who finds this issue :)

Does not compile on arduino uno/nano

Arduino: 1.8.18 (Windows Store 1.8.55.0) (Windows 10), Board: "Arduino Uno"

In file included from C:\Users\sebas\OneDrive\Dokumente\Arduino\libraries\Bolder_Flight_Systems_SBUS-7.0.0\examples\arduino\sbus_example\sbus_example.ino:36:0:

C:\Users\sebas\OneDrive\Dokumente\Arduino\libraries\Bolder_Flight_Systems_SBUS-7.0.0\src/sbus.h:34:10: fatal error: cstddef: No such file or directory

#include

      ^~~~~~~~~

compilation terminated.

exit status 1

Error compiling for board Arduino Uno.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Unable to pass Sercom Serial object into SBUS RX

I'm working on a project where I need to use a Sercom Serial port on a Feather M4 to decode and process a SBUS Stream. Passing the created Serial2 object into bfs::SbusRx sbus_rx(&Serial2) compiles, but does not function. I believe the issue is caused by the library expecting a hardware serial port, but the Sercom port being a different type, but I'm not sure how to approach this, and any help would be appreciated. My full code is below:
sercom.txt

Thanks in advance,

Teensy 4.0 compatibility issue

First let me thank for the good work. On Teensy 3.2 it works like a charm.

But on Teensy 4.0 I can see no output signal. Do you have a chance to test this on Teensy 4?

Do you have another example ino

Hi,
Do you have an example ino file that shows how to use this library to read analog pins (pots and switches) and output the sbus stream?

update package

First of all thanks for developing a handy lib. I've been using this on a teensy 4 + x8r successfully by installing the package through platformio.

I ran into a bug today and after checking with the github repo to find a fix, I noticed that I was running version 1.0.1 which is pretty old. However its the latest version that is available through the platformio package manager:

https://platformio.org/lib/show/5622/Bolder%20Flight%20Systems%20SBUS

Is there any chance of updating the package to the current release?

SBUS2

this library is compatible with SBUS2? or just SBUS?

Second, if SBUS2 is not supported, how are you sending data to the transmitter?

Sending SBUS packets on mega 2560 doesn't seem to work.

I connected the TX pin of Serial1 to the base of transistor and the SBUS RX pin of my flight controller to the collector. And I tried to send SBUS packets to the FC by using the example sketch, which didn't work.

I tried to read the source code the "write" function and wrote the sketch below.

sketch_apr12a.zip

It did make a difference on the receiver setup page (apm, mission planner). I noticed that the value of each channel did change correspondingly when the value was changed in my sketch. Sadly I could never sent the desired values. I took note of what I wanted to send and the results.

900-1444
1000-1506
1024-1521
2000-2100
2046-2100
994-1502
1500-1818

And when I was using the F4 flight controller, it didn't seem to receive anything...

[Question] SBUS to PWM converter

Would this library be suitable for creating an SBUS to PWM converter to control 5 servos on an airplane?

There doesn't seem to be many options for compact 5 (or 6) channel PWM receivers. The DR4 is the right size but only 4 channels while the 8 channel RX is physically too big for my model.

I'm contemplating using an XSR along with a Trinket (or something similar) to get 5 channels in a smallish footprint.

Arduino Mega: hang on setReadCal

Thank you bolderflight for making this library--been very useful.

I am using a RadioLink R7FG to control an RC car through the Arduino Mega (hope to move to Micro later). However, when attempting to call setReadCal, the program seems to hang... most of the time. About 10% of the time it will setReadCal properly and it seems to be boot dependent (shutting the Mega off/ on might fix it sometimes, random). When it does work, it might do so on a channel or two before hanging. Adding delays() before/ after setReadCal() or additional print statements does not change anything.

I've attached the code that's been giving me a hard time, using one of the examples as guidance. Commenting out the setReadCal in the for loop allows the visualization to work, just not on the bounds I need (standard PWM [1000,2000]).

`
// channel, fail safe, and lost frames data
//uint8_t channels[16]; //for my_sbus.read()
float channels[16];
float cal[2] = {500, 1500};
uint8_t l = 2;
bool failSafe;
bool lostFrame;

void setup() {
// begin the SBUS communication
my_sbus.begin();

// set channel range 1000-2000
for (uint8_t i = 0; i < ch_num; i++) {
my_sbus.setReadCal(i, cal, l); //##############hangs here##################
}
// begin serial monitor/ plotter if active
Serial.begin(115200);
while (!Serial) { //wait for serial to properly begin
;
}
}

void loop() {
// look for a good SBUS packet from the receiver
if (my_sbus.readCal(&channels[0], &failSafe, &lostFrame)) {
Serial.println(mode);
for (int i = 0; i < 4; i++) {
Serial.print(channels[i]);
int bar_len = floor(channels[i] / 50);
for (int j = 0; j <= bar_len; j++) {
Serial.print("#");
}
Serial.println();
}
Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
`

Compile Error with Arduino

Trying to use this repo with an Arduino (Mega).

However, Arduino IDE fails to compile successfully, because it says it cannot find these libraries:

#include <cstddef>
#include <cstdint>
#include <cmath>
#include <array>

The "array" library seems to be a major stumbling block

Can you advise?

ESP32 Compilation Error

Hi, I'm trying to compile for ESP32 s2 and use pin 14 as SBUS input to display sbus output. I'm using the sbus_example script as is and it isn't working. Any help would be greatly appreciated. Thanks!

Error: sbus_example.ino:30:22: error: 'Serial2' was not declared in this scope
bfs::SbusRx sbus_rx(&Serial2);
^~~~~~~

Arduino ... another problem (error)

Hello again ... during compilation I get an error..SbusRx / SbusTx does not name a type ... why? I would like to ask for an explanation as a child because I am very beginner ... best regards :-)
(I added the etl library!)
IMAG0124

Using hardware inverter with ESP8266 UART RX/TX pins

I'm basically running the example code (without the TX part) with a hardware serial inverter (built from a NPN transistor and a couple resistors), but while it works with a Raspberry Pico (with two different Arduino cores), it doesn't work with an ESP8266 NodeMCU dev board.

I'm not using the USB/Serial input/output, besides programming the device, of course, and have the output of the serial inverter connected to the RX pin of the ESP8266.
I know that there is something coming in, since esptool.py can't connect, until I unplug the RX pin.

It seems, that sbus_rx.Read() is never true and therefore the code inside the if statement (toggling some LEDs based on the channel data) never runs.

I've also tried without USB cable at all, just powered by an external power supply on VIN. Everything seems to work (receiver and radio connect, buttons show PWM output on the radio), but the data isn't received or read correctly.

As I initially mentioned, if I connect the same hardware to a Pico, only changing the Pin numbers, the same sketch works (can toggle LEDs on/off by pressing the assigned buttons on the radio). Of course the latter has a separated USB/serial connection. But shouldn't it still work with a ESP8266, if the UART1 isn't used by anything else? Does maybe the serial bridge IC somehow interfere?

Possible failure in parse function

In the following code, when the end byte is checked, no byte is read. The first if is verified with the last information byte, and the second if is immediately verified without read any byte. Therefore, if the last byte doesn't match with the end byte, the parse function will return false and the read will fail

// strip off the data
			if ((_parserState-1) < _payloadSize) {
				_payload[_parserState-1] = _curByte;
				_parserState++;
			}
			// check the end byte
			if ((_parserState-1) == _payloadSize) {
				if ((_curByte == _sbusFooter) || ((_curByte & _sbus2Mask) == _sbus2Footer)) {
					_parserState = 0;
					return true;
				} else {
					_parserState = 0;
					return false;
				}
			}

STM32 Support

Do you think this could work on an adafruit STM32F405 Feather Board? https://www.adafruit.com/product/4382
If there are known issues with this if you could direct me to them so i can decide whether or not it's worth it to switch board or SBUS library for my project that would be great.
I am aware that i will need some sort of 5v -> 3.3v level converter.
Exact chip on the board: STM32F405 Cortex M4 with FPU and 1MB Flash, 168MHz speed

Use PWM servo

Hello,
I try to use your code with a X8R and a Pro Mini.
I try this code:
`/*
SBUS_example.ino
Brian R Taylor
[email protected]

Copyright (c) 2016 Bolder Flight Systems

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

// This example reads an SBUS packet from an
// SBUS receiver (FrSky X8R) and then takes that
// packet and writes it back to an SBUS
// compatible servo. The SBUS out capability (i.e.
// writing a command to the servo) could be generated
// independently; however, the packet timing would need
// to be controlled by the programmer, the write function
// simply generates an SBUS packet and writes it to the
// servos. In this case the packet timing is handled by the
// SBUS receiver and waiting for a good packet read.

#include "SBUS.h"

#include <Rcul.h>
#include <TinyPinChange.h> /* Needed for library */
#include <SoftRcPulseOut.h>
#include <Streaming.h>

#include <SoftSerial.h>
// software SettingsPort #1: RX = digital pin 10, TX = digital pin 11
SoftSerial MyConsole(10,11);

// a SBUS object, which is on hardware
// serial port 1
SBUS x8r(Serial);

// channel, fail safe, and lost frames data
uint16_t channels[16];
bool failSafe;
bool lostFrame;

SoftRcPulseOut Servo1;

void setup() {

MyConsole.begin(57600);
delay(500);
MyConsole << "OK" << endl;

Servo1.attach(4);

// begin the SBUS communication
x8r.begin();
}

void loop() {

uint8_t Width_us =1500;
// look for a good SBUS packet from the receiver
if(x8r.read(&channels[0], &failSafe, &lostFrame)){

// write the SBUS packet to an SBUS compatible servo
x8r.write(&channels[0]);
MyConsole << _DEC(&channels[0]) << endl;

Width_us = map(&channels[0], -100, +100, 900, 2100);
Servo1.write_us(Width_us);
SoftRcPulseOut::refresh(1);

}
}`

But the console return me always 434.
Can you explain me how to map a channel please ?
I use a NPN transistor for invert x8r SBUS signal.

Thanks for this share

Pierre

Problem on STM32F103C8T6

Hi
I need to handler sbus signal by stm32f103c8t6 and Interrupt. I use SBUS_example.ino, but it wasn't successful! Arduino compiler shows : C:\Users\user\AppData\Local\Temp\arduino_build_27820/SBUS_example.ino.elf section .text' will not fit in region rom'

Channel 17 and 18

Hey Brian,

Firstly, great work :) Secondly, what is the purpose of channels 17 and 18 and how and what do you write to them?

Cheers,

Phil

FrSky 24 Channels

I have Tandem X18 and it's possible to use 24 channels instead of 16/17/18. Do anyone have an idea how to get values from 24th byte?

Why esp8266 isn't supported

I have esp8266 and I have tried to send values to sbus servo. But it doesn't work. I have already checked your code and found that esp8266 isn't supported. Why? Esp8266 has 1 HW serial port shared with USB. I think it is possible to use it.

SBUS on arduino-STM32L4

Brian,

I've been trying to modify your awesome SBUS library to work with the new line of Arduino-compatible STM32L4 boards from Tlera Corp, using the arduino-STM32L4 library. Testing with a FrSky XM SBUS receiver, I'm able to see a stream of incoming bytes on RX1, but I can't find a config mask for Serial1.begin() that allows me to see the expected sentinel 0X0F. I tried every possible combination of masks (inverted/non-inverted, SERIAL_8E1, SERIAL_8E2, even baud rates other than 100K, and still no luck.

If you're interested in taking a shot at this, I'll be happy to send you a couple of the receivers and Ladybug boards!

Thanks,
Simon

Inverted SBUS signal

I am making tests with FrSky XSR and ESP32, it works with uninverted XSR hack.

Regarding ESP32 Documentation is possible UART ports to be inverted. This will avoid soldering additional wires on the receiver.

uart.h file section

/**
 * @brief Set UART line inverse mode
 *
 * @param uart_num  UART_NUM_0, UART_NUM_1 or UART_NUM_2
 * @param inverse_mask Choose the wires that need to be inverted.
 *        Inverse_mask should be chosen from 
 *        UART_INVERSE_RXD / UART_INVERSE_TXD / UART_INVERSE_RTS / UART_INVERSE_CTS,
 *        combined with OR operation.
 *
 * @return
 *     - ESP_OK   Success
 *     - ESP_FAIL Parameter error
 */
esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask);

No Readings

Hey- Thanks a ton for creating this library. I am trying to connect my Futaba SBUS receiver to my Arduino Uno (I also have a Mega so have tried troubleshooting with that too). No matter what I do, I can’t get any readings to display on my OLED screen. I am using an I2C OLED screen to try to show the channel readings because I realize that the UNO only has 1 serial port, so it wouldn’t be feasible to view the channel outputs in a serial window if RX0 is tied up with the SBUS inputs.

I have followed the instructions and am just trying to adapt the example code to read out the first 4 channels to an Adafruit OLED screen but I am just getting 0’s. I am using a Futaba 10J transmitter with an R3008SB S.BUS receiver. I have confirmed that the SBUS channel of the receiver is indeed giving an output (I tested it with an S.BUS to PWM decoder and the channels worked as expected).

I am using a TTL inverter that uses a 2N3904 transistor a 10k and 4.7k resistor. Do you think there is any issue with using this type of transistor for the TTL inverter?

Any suggestions would be amazing!

Thanks

Teensy 3.2 - Reading from receiver & sending to USB -> 'deadlock' ?!

A very simple test program seems to 'deadlock' [for lack of better understanding yet] mt Teensy 3.2. The Arduino Serial Monitor does reports a couple of lines (around eight) and then does not report new readings and it even has problems, closing. The Teensy does not like to accept a new program either afterwards:-( I usually disconnect the receiver and download a Blink sketch in between:-(
SBUS_t1.zip
Don't know iff it matters, the receiver is a FrSky XM+.

Trouble connecting FrSky XM+ receiver to ESP32

The XM+ operates with inverted Serial logic and this library should be capable of that but how to I enable it? Is inverted mode automatically detected? Also I'm having a hard time finding what the logic levels of the XM+ are. I hope they are 3.3v otherwise I've blown out that GPIO. If anyone knows let me know please.

Thanks !

Teensy 3.2 Compilation error with Teensyduino 1.58

Hello wanted to update my project my lib for sbus was on 2.x.x
i now get on Arduiono 1.8.5 and as well >2.x the following error
( i installed teensy via Arduino IDE 2 with adding the link to board manager https://www.pjrc.com/teensy/package_teensy_index.json)

see Teensy

c:/users/xx/appdata/local/arduino15/packages/
c:/users/xx/appdata/local/arduino15/packages/teensy/tools/teensy-compile/11.3.1/arm/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\xx\AppData\Local\Temp\arduino_modified_sketch_862059/sketch_apr16a.ino:44: undefined reference to `bfs::SbusTx::Begin()'
c:/users/xx/appdata/local/arduino15/packages/teensy/tools/teensy-compile/11.3.1/arm/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\xx\AppData\Local\Temp\arduino_build_556759\sketch\sketch_apr16a.ino.cpp.o: in function `loop':
C:\Users\xx\AppData\Local\Temp\arduino_modified_sketch_862059/sketch_apr16a.ino:48: undefined reference to `bfs::SbusRx::Read()'
c:/users/xx/appdata/local/arduino15/packages/teensy/tools/teensy-compile/11.3.1/arm/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\xx\AppData\Local\Temp\arduino_modified_sketch_862059/sketch_apr16a.ino:63: undefined reference to `bfs::SbusTx::Write()'
collect2.exe: error: ld returned 1 exit status

not sure where the issue is

nRF52840 Support like Arduno Nano 33 BLE or Adafruit nRF Feather Express

Hi, thank you for shaing your lib

It works very well on Teensy 3,1 , but i wan't to use Arduino Nano 33 BLE, Serial1 for Sbus input
i used with parameters like; "_bus->begin(_sbusBaud, SERIAL_8E2);". --> Without a result.
But according what was writen about changes for ESP32 , i asking if i need some type of inverter.
It would be even more nice if you can integrate native support for it like for the teensys board.
If not can you explain what i have to change in code , or will it be even more easier to youst use an hardware inverter ?

Thanks in advance

Marc

Please teach me how to use

i would like to use this library on my RPI but i dont know hot to use it. on your website you said how to use but it looks like it's for arduino and i tried so hard to run the code on RPI but it look like the RPI doesnt understand the serial protocol + it doesnt have any of arduino library. It would be very kind if you can teach me how you run this on your device.

Futaba S-bus protocol requires to send LSBit first

I have a FC Skystars F405 HD2 connected with a ESP32 (Arduino) by a serial link (100kbauds, parity even, 2 stop bits, inverted).
25 bytes are sent, starting with byte 0x0F and ending with byte 0x00.
The flight controler seems to catch the frame but does not decode it correctly. I spied the serial transmitter using Saleae Logic 16. I attached the capture of the first bytes sent. The first parameter sent is the throttle position (1498=101 1101 1010).
sbus inversé avec EPS32
According to Futaba S-bus protocol, the LSBit shall be transmitted first. So, that's why the throttle is not equal to 1498 but equal to 733 (010 1101 1101).
I've added the inversion in my ESP32 software because the sbus library doesnot do it. Can you confirm that the library does not and I have to do it in my software ?
And, finally, if you have any idea why the flight controller shows me the value 1338 for the throttle (observed in Betflight) instead of 1498, it would help me.
Thanks.

Trouble with an Arduino Mega

I'm not having any luck with an Arduino Mega and the sample code. I'm using an inverter that has worked with an MKR1010 and I'm have RX pinned to 17 (RX2).

#include "sbus.h"

/* SBUS object, reading SBUS */
bfs::SbusRx sbus_rx(&Serial2);
/* SBUS object, writing SBUS */
bfs::SbusTx sbus_tx(&Serial2);
/* SBUS data */
bfs::SbusData data;

void setup() {
  /* Serial to display data */
  Serial.begin(115200);
  while (!Serial) {}

  delay(2000);

  /* Begin the SBUS communication */
  Serial.println("Begin SBUS...");
  sbus_rx.Begin();
  sbus_tx.Begin();
}

void loop() {

  if (sbus_rx.Read()) {
    /* Grab the received data */
    data = sbus_rx.data();
    /* Display the received data */
    for (int8_t i = 0; i < data.NUM_CH; i++) {
      Serial.print(data.ch[i]);
      Serial.print("\t");
    }
    
    /* Display lost frames and failsafe data */
    Serial.print(data.lost_frame);
    Serial.print("\t");
    Serial.println(data.failsafe);
    /* Set the SBUS TX data to the received data */
    sbus_tx.data(data);
    /* Write the data to the servos */
    sbus_tx.Write();
  }
}

Occasionally I will receive data from sbus_rx.Read()

sbus-data

Arduino compatible...

Hello...
is this library compatible with Arduino boards (328p)? because I can't add the zip file to the Arduino IDE libraries ... it displays an error.

(sorry ... I'm a beginner ..: - /)

Problems with Teensy 4.1 but not with Teensy 3.2

Hi! Thanks for this great lib! I have noticed that sbus_rx.Read() lags a lot in Teensy 4.1 but works great with Teensy 3.2. I am currently using a receiver with already inverted signal Oversky XR602T-A2 running at 3.3V. No problems at all with Teensy 3.2 as said. I'm wondering if the Teensy 4.1 expects an non-already reversed input? Can I define this Option for Teensy 4.1?

image

Porting Requirements

Hi,
Is void SBUS::begin() the only place that requires addt'l platform info? I'm not 100% sure as to which chip I'll use yet, but I need to know where to tweak stuff up. I'll likely use a SAMD21. Thanks.

Seeeduino XIAO trouble

I'm not getting it to work on seeeduino XIAO. In the mega 2560 microcontroller it worked correctly, I decided to change the uC and even after many attempts to change the code, it doesn't work correctly

Will this work with an Adafruit Feather M0 and RadioLink R9DS receiver?

I'm just trying to read the value of the first channel, using the example from the README.

I've double and triple checked my inverter wiring against your example and several others (3.3v). I have the transistor collector pin connected to the Rx/0 pin on the Adafruit Feather M0, along with a 10k pull-up resistor from the Feather's 3.3v pin. Finally, I have the 5v signal from the RadioLink R9DS receiver's SBUS pin connected to the transistor's base pin through a 1k resistor.

I've made sure that the receiver is in SBUS mode; the blue light is on. The transmitter shows that its connected.

RadioLink_Feather_SBUS

It seems like this should work. Is there something different about the Feather's architecture that might be making it fail to read the SBUS signal?

Here is my Arduino code:

#include <SBUS.h>

// a SBUS object, which is on hardware
// serial port 1
SBUS x8r(Serial1);

// channel, fail safe, and lost frames data
uint16_t channels[16];
bool failSafe;
bool lostFrame;

void setup() {
  // begin the SBUS communication
  x8r.begin();
}

void loop() {
  // look for a good SBUS packet from the receiver
  if(x8r.read(&channels[0], &failSafe, &lostFrame)){
    Serial.print("Channel 1: ");
    Serial.println(channels[0]);
  }
}

Does not work

I have tried to use this on a Teensy LC, Teensy 3.1 and Teensy 3.2.

using your example arduino ino sketch,

sbus_rx.read() never returns true, regardless which serial hardware identifier i use, regardless of inv parameter of true or false.

I have tried this with the following sbus receivers:

Frsky x4r-sb
Frsky x8r
Frsky x6r
Jumper r8
Radiomaster r168-d16

in addition, i have verified that the s-bus ports on all the receivers work using the Frsky sbus to pwm decoder.

How to add Compatibility with the Arudino Micro and Arudino Leonardo

I have found a way to add compatibility with the Arduino Micro and Arduino Lenardo (ATMega32u4 based boards). According to the Arduino Serial Reference, the ATMega32u4 uses Serial1 as its main and only Serial port.

In SBUS.cpp, I added this line to the end of the SBUS::begin()

_bus->begin(_sbusBaud, SERIAL_8E2); //For ATMega32u4

And it works! That is the only modification you need to make to the library to make this compatible with ATMega32u4 boards, and I thought this would be a great addition to the library to support more boards.

Question. channels[0] to channels[1] ?

Good Day!
Please, correct me if I am wrong, but should that part of code:

void SBUS::write(uint16_t* channels)
.....
packet[1] = (uint8_t) ((channels[0] & 0x07FF));
packet[2] = (uint8_t) ((channels[0] & 0x07FF)>>8 | (channels[1] & 0x07FF)<<3);
packet[3] = (uint8_t) ((channels[1] & 0x07FF)>>5 | (channels[2] & 0x07FF)<<6);
packet[4] = (uint8_t) ((channels[2] & 0x07FF)>>2);

should be like that:

void SBUS::write(uint16_t* channels)
....
packet[1] = (uint8_t) ((channels[0] & 0x07FF));
packet[2] = (uint8_t) ((channels[1] & 0x07FF)>>8 | (channels[2] & 0x07FF)<<3);
packet[3] = (uint8_t) ((channels[2] & 0x07FF)>>5 | (channels[3] & 0x07FF)<<6);
packet[4] = (uint8_t) ((channels[3] & 0x07FF)>>2);

Thank you.

send packet

When i use the code like the example, all packets are sent correctly.
// look for a good SBUS packet from the receiver
if(x8r.read(&channels[0], &failSafe, &lostFrame)){
// write the SBUS packet to SBUS compatible servos
x8r.write(&channels[0]);
}
But if i write a packet what are not received of x8r, this doesn't works correctly, i trying all intervals for 1 ms~50ms of delay between packets.
I suppose it is a time issue between packages being sent.

sbus signal generated with this library has a non-standard length of 2.6ms instead of 3ms

I tested the sbus signal generated by the library has a non-standard signal length of 2.6ms instead of a standard length of 3ms. So the sbus signal cannot be recognized by betaflight controller which required 3ms length according to its source code.
The strange part is if I use the same code in the write() function and with correct serial port setup 100000 baud rate and 8SE2, my ESP32 will generate a 3ms signal and could be recognized by the controller.
I am confused about this phenomenon. Does anyone have any idea why this happened?
Thank you very much.

FrSky Receiver Range

Hi, thanks for creating an easy to use library for outputting SBUS signals.

I just had a question on the range of 172-1811 offset values from the Readme. 1 channel consists of 11 bits (0-2047) and the library uses the extended range of -150% ~ +150%, which would correspond to PWM values of 750-2250 microseconds.

Doing a linear mapping to 1000-2000 microseconds, wouldn't the required range for outputting these standard rx PWM values be 341-1705. How did you choose the range 172-1811? Could this be specified in the Readme?

Thanks !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.