Evgeniy Aleksandrov
Evgeniy Aleksandrov

Reputation: 11

Reading data from RadioLink R12DS receiver by S-BUS protocol

My goal is pretty simple: I wanna read information from my RadioLink R12DS receiver by S-BUS protocol using desktop console application, written on C#.

I use AT9S transmitter blinded together with receiver in 12 channel mode. I tested it on Pixhawk flight controller. Everything was fine there, no any problem with retrieving data.

I designed a console application based on investigated articles. Here is a couple most valuable of them:

http://forum.fpv.kz/topic/303-frsky-x8r-sbus-v-cppm-konverter-na-arduino/ https://github.com/bolderflight/SBUS

My application receiving byte stream from a COM Port, one by one, and tries catch message header "0x0F", but it doesn't appear.

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

A table mapping bytes[1-22] to servo channels is included.

Here is listing of my code:

static void Main(String[] args)
    {
        var availablePorts = SerialPort.GetPortNames();
        using(var port = new SerialPort(availablePorts[0], 100000, Parity.Even, 8, StopBits.Two))
        {
            port.DataReceived += PortOnDataReceived;
            while(true)
            {
                if(!port.IsOpen)
                    TryReconnect(port);

                Thread.Sleep(1000);
            }
        }
    }


    // HANDLERS ///////////////////////////////////////////////////////////////////////////////
    private static void PortOnDataReceived(Object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
    {
        var serialPort = (SerialPort)sender;
        if(SbusConverter.TryReadMessage(serialPort, out var messageBuffer))
        {
            var message = SbusConverter.Convert(messageBuffer);

            Console.WriteLine(message.ServoChannels[0]);
        }
    }

public static Boolean TryReadMessage(SerialPort serialPort, out Byte[] messageBuffer)
    {
        const Int32 messageLength = 25;
        const Int32 endOfStream = -1;
        const Byte sBusMessageHeader = 0x0f;
        const Byte sBusMessageEndByte = 0x00;

        messageBuffer = new Byte[messageLength];

        if(serialPort.BytesToRead < messageLength)
            return false;

        do
        {
            var value = serialPort.ReadByte();
            if(value == endOfStream)
                return false;

            if(value == sBusMessageHeader)
            {
                messageBuffer[0] = (Byte)value;
                for(var i = 1; i < messageLength; i++)
                {
                    messageBuffer[i] = (Byte)serialPort.ReadByte();
                }

                if(messageBuffer[0] == sBusMessageHeader &&
                   messageBuffer[24] == sBusMessageEndByte)
                    return true;
            }

        } while(serialPort.BytesToRead > 0);

        return false;
    }

I have thoughts in my head and I want ask one question here.

It's possible, that RadioLink use different, modified or their own S-BUS implementation, than Futaba and I found no proper documentation yet.

Anybody, who experienced in that field, any suggestions please. It seems, I am stuck.

Thank you!

Upvotes: 1

Views: 2072

Answers (3)

Pierre Schoesetters
Pierre Schoesetters

Reputation: 1

I am trying to do the same kind of operation, intercepting Sbus signal from a herelink radio controller, so far I discovered a shift in the data and my start byte is recognised with the value of 0x1E. Moreover the data seems super noisy when looked at the oscilloscope, some 1 might be missing because of the poor quality of the signal and the ramp from 0 to 1.

Upvotes: 0

Jan Ringoš
Jan Ringoš

Reputation: 1

Two years too late, but I just noticed you have 1 stop bit set, instead of 2, in the code of your answer. That could probably explain 0x1F instead 0x0F and otherwise shifted data.

Upvotes: 0

Evgeniy Aleksandrov
Evgeniy Aleksandrov

Reputation: 11

I made some investigations of received data stream and uncovered that RadioLink devices uses "0x1F" as a frame start byte insted of "0x0F". Another connection and message properties are the same.

var availablePorts = SerialPort.GetPortNames();
        using(var port = new SerialPort(availablePorts[0], 100000, Parity.None, 8, StopBits.One)
        {
            Handshake = Handshake.None
        })
        {
            port.DataReceived += PortOnDataReceived;
            while(true)
            {
                if(!port.IsOpen)
                    OpenPort(port);

                Thread.Sleep(1000);
            }
        }

Upvotes: 0

Related Questions