Giter Site home page Giter Site logo

raspberry-sbus's Introduction

Raspberry Pi/Linux SBUS Driver

C++ SBUS library working on the Raspberry Pi and possibly any linux system with a serial port.

You can use the built-in UART on the pi or a USB-Serial adapter. For FTDI adapters use setLowLatencyMode(true).

Also, don't forget to use an inverter to invert the SBUS signal! Something like this works well. I use 10k resistors.

Most receivers use 5V so be careful when plugging directly into the GPIOs on the pi and use a level converter.

Features:

  • Non-blocking and blocking modes
  • Send & Receive
  • All channels from 1 - 16
  • Binary channels 17 and 18
  • Failsafe and frame lost bits
  • Automatic recovery from hardware failures like broken wiring
  • FTDI low latency support

SBUS protocol specification and original decoding function: https://github.com/bolderflight/SBUS

Getting started

  • Create an empty project folder
  • git clone https://github.com/Carbon225/raspberry-sbus inside your project folder
  • Create a CMakeLists.txt inside project folder
cmake_minimum_required(VERSION 3.9)
project(my-sbus-project)

set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 11)

# This is what you cloned previously.
# After this line a libsbus target is available for linking
add_subdirectory(raspberry-sbus)

# Create a new executable target with a single source file main.cpp
# and link it with the library
add_executable(main main.cpp)
target_link_libraries(main PUBLIC libsbus)
  • Create main.cpp and paste code from one of the examples
  • Your project should look like this:
- project_folder/
  - CMakeLists.txt
  - raspberry-sbus/
  - main.cpp
  • Open your project in a CMake compatible IDE (CLion, VS, ...)
  • or build manually:
    • cmake -B build -S . <- don't forget the dot
    • cmake --build build
    • run with ./build/main

Usage:

Raspberry Pi UART setup

To use built-in UART on Raspberry Pi 3/4

  • sudo systemctl disable hciuart - disable bluetooth as we will steal its UART
  • add dtoverlay=disable-bt to /boot/config.txt
  • reboot and use /dev/ttyAMA0

To use additional UARTs only on Raspberry Pi 4

  • add dtoverlay=uartX to /boot/config.txt where X is 2, 3, 4 or 5 to enable another UART
  • reboot and use /dev/ttyAMAY where Y will be assigned sequentially for the new UART

Look at https://www.raspberrypi.org/documentation/configuration/uart.md for more info.

The Code

Setup

  • #include <SBUS.h>
  • Create SBUS sbus object
  • sbus.install("/path/to/tty", blocking_mode) to init the serial port
  • sbus.setLowLatencyMode(true) if you have an FTDI adapter

Receive

  • Define packet callback void packetCallback(const sbus_packet_t &packet) {/* handle packet */}
  • Set packet callback with sbus.onPacket(packetCallback)
  • Call sbus.read() as often as possible to process buffered data from the serial port (non-blocking) or at least once per packet (blocking mode). In blocking mode read will block and wait for data to arrive while non-blocking mode only checks if any data is available and returns immediately.

Send

  • Create sbus_packet_t myPacket object and populate its fields
  • sbus.write(myPacket) to send an SBUS packet

Look at examples folder for more.

Blocking vs. Non-blocking

In blocking mode the read function blocks until some data is available. This mode is best used when your code contains a main loop that does not need to process anything when there are no packets. You can also create a separate thread for reading.

In non-blocking mode read processes only available bytes (or nothing if none are available) and returns immediately. You have to call read as often as possible to make sure you don't skip any bytes. The most common use case is when your main loop does other things and only processes SBUS packets when one arrives.

Low latency mode

FTDI adapters have weird buffering that makes packets send in batches and not right after calling write(). Enabling low latency mode fixes this by doing some magic even I don't understand. Credit goes to https://github.com/projectgus/hairless-midiserial.

Note: only supported on linux.

raspberry-sbus's People

Contributors

carbon225 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

Watchers

 avatar  avatar  avatar  avatar

raspberry-sbus's Issues

SBUS2 Telemetry

SBUS2 is just sbus but with added telemetry similar to f.port. From what I've read it looks like this:

[0-23] - Normal sbus frame
[24] - sensor slot range identifier (instead of 0x00 frame end marker in sbus)
next, up to 8 sensor slots where each is:
[0] - slot id (sensor type?)
[1-2] - data (little or big endian depending on the sensor)

The 'slot range identifier' specifies which 8 of the 32 total slots can be transmitted next.

0x04 - slots 0-7
0x14 - slots 8-15
0x24 - slots 16-23
0x34 - slots 24 - 31

During the telemetry period, a sensor calculates the current slot id from the slot range identifier byte + elapsed time/slot time (roughly).
If the slot id matches the sensor's id, it sends 3 bytes of data (first one being sensor id or something like that).
It's most likely impossible to implement sending such a protocol with all the kernel abstractions, but just monitoring an external connection should be possible.

The sbus2 branch has all the code already, I just need to try it on real hardware.

Standalone device driver

Could create a daemon that manages the SBUS connection and lets other programs read packets over a socket for example.
Users could run one instance for each SBUS port and control them from many programs.

Just use threads

No point having blocking and non-blocking modes since no one knows how to use them.
Just create a thread for managing the SBUS connection and give the user a get_last_packet() function.

Can this software act as a transmitter?

Good day! Thanks for your efforts! I need to emulate a receiver on Linux and connect via a UART converter to the flight controller. I want to transmit control actions via SBUS, which will be synthesized on Linux. Am I correct in understanding that your software can act as both a receiver and a transmitter?

Bad timing with outgoing SBUS packets

I'm trying to feed SBUS instructions from a Jetson Nano into an F4 flight controller using betaflight. Betaflight itsn't detecting any sort of output.

I used a logic analyzer to check the output and the output rate is super low, but when I adjust the example code send_to_self.cpp to play with timing (the current method only triggers every second) the data occasionally sends twice back-to-back.

This could be an issue with betaflight but the output rate from this library is also an issue. Has there been a successful experience with trying to control a flight controller with this library?

Readme - aditional uarts on rpi4

To use additional UARTs only on Raspberry Pi 4
add dtoverlay=uartX to /boot/config.txt where X is 2, 3, 4 or 5 to enable another UART
reboot and use /dev/ttyAMAX where X is the UART you chose

In case of using UART1 and another, for example UART3, the ttyAMAx is numbered sequentially.
So, in this case, ttyAMA0 is for UART0 and ttyAMA1 is for UART3.

Doesn't compile on Raspberry Pi 4.

I've tried everything. Even #undef termios to no avail.

In file included from ../src/sbus_driver.c:8:
In file included from /usr/include/arm-linux-gnueabihf/asm/termbits.h:1:
/usr/include/asm-generic/termbits.h:12:8: error: redefinition of 'termios'
struct termios {
       ^
/usr/include/arm-linux-gnueabihf/bits/termios.h:28:8: note: previous definition is here
struct termios
       ^
In file included from demo.cpp:9:
../src/sbus_driver.c:26:14: error: cannot initialize a variable of type 'uint8_t *' (aka 'unsigned char *') with an rvalue
      of type 'const uint8_t *' (aka 'const unsigned char *')
    uint8_t *payload = packet + 1;
             ^         ~~~~~~~~~~
2 errors generated.

Unstructured device specific defines.

The devices specific code is a bit of a mess. Ideally use the adapter pattern per device and use #defines to choose an adapter.
I'm unable to create a PR because I can't get it to compile on Raspberry pi 4.

How to do the connection from Rasberry Pi 4 to sbus?

@Carbon225
I am new to this , might feel like a silly question :).
This is what i understood, connect the sbus tx to the Rasbeery Pi 4 GPIO14 .
Is there any need to use inverter in between the above two ?
What i am trying to do is to control blackmagic studio camera settings through sbus , which i need to send control signals to appropriate channels in the sbus.
Will be a great help if you can guide me how to test it out with what you have made.
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.