Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Current »

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);
};
  • No labels