首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用S总线协议从RadioLink R12DS接收机读取数据

用S总线协议从RadioLink R12DS接收机读取数据
EN

Stack Overflow用户
提问于 2018-12-21 18:44:38
回答 3查看 1.2K关注 0票数 1

我的目标非常简单:我想通过使用桌面控制台应用程序从RadioLink R12DS接收器读取信息,并在C#上编写。

在12通道模式下,我使用AT9S发射机与接收器一起盲。我在Pixhawk飞行控制器上测试过。那里一切都很好,检索数据没有任何问题。

我设计了一个基于调查文章的控制台应用程序。下面是其中最有价值的几个:

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

我的应用程序一个接一个地从COM端口接收字节流,并尝试捕获消息头"0x0F",但它没有出现。

SBUS协议采用倒置串行逻辑,波特率为100000,数据比特为8位,奇偶校验位为2位,停止位为2位。SBUS数据包有25个字节长,包括:

  • 字节: SBUS头,0x0F
  • 1-22: 16伺服通道,每个伺服通道11位
  • Byte23
  • 位7:数字通道17 (0x80)
  • 位6:数字频道18 (0x40)
  • 位5:帧丢失(0x20)
  • Bit 4:启动故障安全(0x10)
  • 位0- 3: n/a
  • Byte24: SBUS结束字节,0x00

一个表映射到伺服通道的字节1-22是包含

下面是我的代码清单:

代码语言:javascript
复制
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;
    }

我脑子里有想法,我想问一个问题。

有可能,RadioLink使用不同的、修改的或自己的S总线实现,而不是Futaba和我还没有找到合适的文档。

任何在这一领域有经验的人,请提出任何建议。看来,我被卡住了。

谢谢!

EN

回答 3

Stack Overflow用户

发布于 2019-06-26 18:20:27

我对接收到的数据流进行了一些调查,发现RadioLink设备使用"0x1F“作为"0x0F”中的帧开始字节。另一个连接和消息属性是相同的。

代码语言:javascript
复制
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);
            }
        }
票数 0
EN

Stack Overflow用户

发布于 2020-09-24 01:08:01

已经晚了两年了,但我刚刚注意到,在你回答的代码中,你设置了一个停止位,而不是2个。这可能可以解释0x1F而不是0x0F,并以其他方式移动数据。

票数 0
EN

Stack Overflow用户

发布于 2021-06-16 08:51:18

我正在尝试做同样的操作,拦截来自herelink无线电控制器的Sbus信号,到目前为止,我发现数据中有一个移位,并且我的开始字节被识别为0x1E的值。此外,当观察示波器时,数据似乎非常嘈杂,由于信号的质量差和从0到1的坡道,可能会丢失大约1。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53889460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档