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
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
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
//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
class SBUSSender{ public: /* public variable */ uint8_t send_buf_[SBUS_FRAME_SIZE]; /* serve for singleton structure application the code doesn't allow the class to make copy of its instance */ SBUSSender (const SBUSSender*) = delete; SBUSSender &operator= (const SBUSSender&) = delete; static SBUSSender* getInstance(UART_HandleTypeDef* uart); /* select the channel from 1 - 16 set the value from 0 to 100 float as percentage */ void SetChannelValue(uint8_t channel, float value); /* directly setup a whole sbus message */ void SetSBusValue(SBus values); /* setup channel percentage values and parse it to sbus message */ void SetRCControlValue(RCControl values); void assemble_packet(); /* send out the configured data as an UART/SBUS message */ //void SendData(); //deleted because now it uses dma to send automatically private: /* constructor*/ SBUSSender(UART_HandleTypeDef* uart); // member variables static SBUSSender* singleton_; UART_HandleTypeDef* uart_; SBus send_sbus_; //helping functions uint16_t rccontrol_to_sbus(float rccontrol); };
Add Comment