SBUS Driver in Simple System Manager

This page is all about the configuration of SBUS driver and how to use it in the Simple System Manager.

IOC. Config

Key Parameter Setting

DMA Setting

  • Enable both rx and tx DMA line

  • Set the Mode to be “Circular“

  • Enable the NVIC uart global interrupt

 

Examplation

The uart used here is USART2, but it can be any uart connectivity as long as the code stays coherent with itself.

One uart is configured such that the rx is used for the receiver and tx is used for the sender. Both receiver and sender sharing the same uart wouldn’t cause any collision.

The driver also allows the user to use separate uarts for the receiver and sender. It just needs an appropriate reason to use two uarts.

Struct

SBus

struct SBus{ uint16_t ch[SBUS_INPUT_CHANNELS]; //value from 192 - 1792, can be littel off bool lost_frame; bool failsafe; bool ch17, ch18; bool new_data; };

The SBus struct contains the data for 16 different RC channels with other flags. This is a representation of the unprocessed sbus data

 

RCControl

//the background work that allows a variable name refer to the same memory to an array element template<uint8_t Index, class T> struct ControlRef { operator T&() // allows: double d = object.Member; { return ((T*)(this))[Index]; } T &operator=(T const &rhs) // allows: object.member = 1.0; { T &me = ((T*)(this))[Index]; me = rhs; return me; } T* operator&() // allows: double *p = &object.Member; { return &((T*)(this))[Index]; } bool operator<(T const &rhs) // allows: if(object.Member < 1.0) { return ((T*)(this))[Index] < rhs; } }; /* a struct for control signal channel mapping and attribute values*/ /* for now, the value range is 0 to 100 float*/ struct RCControl{ union{ float ControlSignals[16]; ControlRef<0, float> roll; ControlRef<1, float> pitch; ControlRef<2, float> throttle; ControlRef<3, float> yaw; ControlRef<4, float> arm; ControlRef<5, float> vtx; ControlRef<6, float> led; ControlRef<7, float> mode; ControlRef<8, float> nonconfigch9; ControlRef<9, float> nonconfigch10; ControlRef<10, float> nonconfigch11; ControlRef<11, float> nonconfigch12; ControlRef<12, float> nonconfigch13; ControlRef<13, float> nonconfigch14; ControlRef<14, float> nonconfigch15; ControlRef<15, float> nonconfigch16; }; float &operator[] (int i) { return ControlSignals[i]; } /* initial values*/ RCControl() { ControlSignals[0] = 50.0f; ControlSignals[1] = 50.0f; ControlSignals[2] = 0.0f; ControlSignals[3] = 50.0f; ControlSignals[4] = 0.0f; ControlSignals[5] = 0.0f; ControlSignals[6] = 0.0f; ControlSignals[7] = 0.0f; ControlSignals[8] = 0.0f; ControlSignals[9] = 0.0f; ControlSignals[10] = 0.0f; ControlSignals[11] = 0.0f; ControlSignals[12] = 0.0f; ControlSignals[13] = 0.0f; ControlSignals[14] = 0.0f; ControlSignals[15] = 0.0f; } };

This struct represents the RC Controller in percentage after mapping the value. I used some code from the internet so essentially what this long code does is that both the array index and a specific name point to the same address of the value. I hope by using this structure, it can be easier for the people who develop the software to use each of the parameters while being able to manipulate them as an array.

Methods

SBUS_Receiver

class SBUSReceiver{ public: /* serve for singleton structure application the code doesn't allow the class to make copy of its instance */ SBUSReceiver (const SBUSReceiver*) = delete; SBUSReceiver &operator= (const SBUSReceiver&) = delete; static SBUSReceiver* getInstance(UART_HandleTypeDef* uart); /* get the sbus data @return SBus struct */ SBus GetSBUS(); /* get the RCControl data that is parsed from sbus more readable data that varies from 0 to 100 @return RCControl struct */ RCControl GetRCControl(); void parse(); /* public variable */ uint8_t raw_sbus_[SBUS_FRAME_SIZE]; private: /* object constructor @param uart instance ie. &huart1 */ SBUSReceiver(UART_HandleTypeDef* uart); // member variables static SBUSReceiver* singleton_; UART_HandleTypeDef* uart_; SBus received_sbus_; RCControl received_rccontrol_; //private functions void read(); void cast_rccontrol(); float sbus_to_rccontrol(uint16_t channel_value); };

 

SBUS_Sender