用于在嵌入式CPU和PC之间进行通信的协议

时间:2022-06-04 03:47:34

I am building a small device with its own CPU (AVR Mega8) that is supposed to connect to a PC. Assuming that the physical connection and passing of bytes has been accomplished, what would be the best protocol to use on top of those bytes? The computer needs to be able to set certain voltages on the device, and read back certain other voltages.

我正在构建一个带有自己的CPU(AVR Mega8)的小型设备,它应该连接到PC。假设已完成物理连接和字节传递,那么在这些字节之上使用的最佳协议是什么?计算机需要能够在设备上设置某些电压,并回读某些其他电压。

At the moment, I am thinking a completely host-driven synchronous protocol: computer send requests, the embedded CPU answers. Any other ideas?

目前,我正在考虑一个完全由主机驱动的同步协议:计算机发送请求,嵌入式CPU应答。还有其他想法吗?

8 个解决方案

#1


6  

Modbus might be what you are looking for. It was designed for exactly the type of problem you have. There is lots of code/tools out there and adherence to a standard could mean easy reuse later. It also support human readable ASCII so it is still easy to understand/test.

Modbus可能就是你想要的。它专为您所遇到的问题而设计。有很多代码/工具,遵守标准可能意味着以后可以轻松重用。它还支持人类可读的ASCII,因此它仍然易于理解/测试。

See FreeModBus for windows and embedded source.

有关Windows和嵌入式源,请参阅FreeModBus。

#2


6  

There's a lot to be said for client-server architecture and synchronous protocols. Simplicity and robustness, to start. If speed isn't an issue, you might consider a compact, human-readable protocol to help with debugging. I'm thinking along the lines of modem AT commands: a "wakeup" sequence followed by a set/get command, followed by a terminator.

对于客户端 - 服务器架构和同步协议,有很多要说的。简单和强大,开始。如果速度不是问题,您可以考虑使用紧凑的,人类可读的协议来帮助调试。我正在思考调制解调器AT命令:“唤醒”序列,后跟set / get命令,后跟一个终结符。

Host -->  [V02?]      // Request voltage #2
AVR  -->  [V02=2.34]  // Reply with voltage #2
Host -->  [V06=3.12]  // Set voltage #6
AVR  -->  [V06=3.15]  // Reply with voltage #6

Each side might time out if it doesn't see the closing bracket, and they'd re-synchronize on the next open bracket, which cannot appear within the message itself.

如果它没有看到结束括号,则每一方都可能超时,并且它们会在下一个打开的括号上重新同步,这不会出现在消息本身中。

Depending on speed and reliability requirements, you might encode the commands into one or two bytes and add a checksum.

根据速度和可靠性要求,您可以将命令编码为一个或两个字节并添加校验和。

It's always a good idea to reply with the actual voltage, rather than simply echoing the command, as it saves a subsequent read operation.

用实际电压回复总是一个好主意,而不是简单地回显命令,因为它节省了后续的读操作。

Also helpful to define error messages, in case you need to debug.

如果需要调试,还可以帮助定义错误消息。

#3


5  

My vote is for the human readable.

我的投票是为了人类可读。

But if you go binary, try to put a header byte at the beginning to mark the beginning of a packet. I've always had bad luck with serial protocols getting out of sync. The header byte allows the embedded system to re-sync with the PC. Also, add a checksum at the end.

但是如果你使用二进制文件,请尝试在开头添加一个标头字节来标记数据包的开头。串口协议不同步,我总是运气不好。标题字节允许嵌入式系统与PC重新同步。另外,最后添加校验和。

#4


4  

I've done stuff like this with a simple binary format

我用简单的二进制格式完成了这样的事情

struct PacketHdr
{
  char syncByte1;
  char syncByte2;
  char packetType;
  char bytesToFollow;  //-or- totalPacketSize
};

struct VoltageSet
{ 
   struct PacketHdr;
   int16 channelId;
   int16 voltageLevel; 
   uint16 crc;
};

struct VoltageResponse
{
   struct PacketHdr;
   int16 data[N];  //Num channels are fixed
   uint16 crc;
}

The sync bytes are less critical in a synchronous protocol than in an asynchronous one, but they still help, especially when the embedded system is first powering up, and you don't know if the first byte it gets is the middle of a message or not.

同步字节中的同步字节不像异步字节那么重要,但它们仍然有用,特别是当嵌入式系统首次启动时,你不知道它得到的第一个字节是消息的中间还是不。

The type should be an enum that tells how to intepret the packet. Size could be inferred from type, but if you send it explicitly, then the reciever can handle unknown types without choking. You can use 'total packet size', or 'bytes to follow'; the latter can make the reciever code a little cleaner.

该类型应该是一个枚举,告诉如何解释数据包。可以从类型推断出大小,但如果您明确发送它,那么接收方可以处理未知类型而不会出现阻塞。您可以使用“总数据包大小”或“要跟随的字节数”;后者可以使接收器代码更清洁。

The CRC at the end adds more assurance that you have valid data. Sometimes I've seen the CRC in the header, which makes declaring structures easier, but putting it at the end lets you avoid an extra pass over the data when sending the message.

最后的CRC增加了对有效数据的更多保证。有时我在标题中看到了CRC,这使得声明结构更容易,但是将它放在最后可以避免在发送消息时额外传递数据。

The sender and reciever should both have timeouts starting after the first byte of a packet is recieved, in case a byte is dropped. The PC side also needs a timeout to handle the case when the embedded system is not connected and there is no response at all.

如果丢弃了一个字节,发送方和接收方都应该在收到数据包的第一个字节后开始超时。当嵌入式系统未连接且根本没有响应时,PC端也需要超时来处理这种情况。

If you are sure that both platforms use IEEE-754 floats (PC's do) and have the same endianness, then you can use floats as the data type. Otherwise it's safer to use integers, either raw A/D bits, or a preset scale (i.e. 1 bit = .001V gives a +/-32.267 V range)

如果您确定两个平台都使用IEEE-754浮点数(PC的)并具有相同的字节序,那么您可以使用浮点数作为数据类型。否则,使用整数,原始A / D位或预设标度(即1位= .001V给出+/- 32.267 V范围)更安全

#5


3  

Adam Liss makes a lot of great points. Simplicity and robustness should be the focus. Human readable ASCII transfers help a LOT while debugging. Great suggestions.

Adam Liss提出了许多重要观点。应该关注简单性和稳健性。人类可读的ASCII传输在调试时帮助很多。很棒的建议。

They may be overkill for your needs, but HDLC and/or PPP add in the concept of a data link layer, and all the benefits (and costs) that come with a data link layer. Link management, framing, checksums, sequence numbers, re-transmissions, etc... all help ensure robust communications, but add complexity, processing and code size, and may not be necessary for your particular application.

它们可能对您的需求有些过分,但HDLC和/或PPP增加了数据链路层的概念,以及数据链路层带来的所有好处(和成本)。链路管理,成帧,校验和,序列号,重传等......都有助于确保强大的通信,但增加了复杂性,处理和代码大小,对于您的特定应用可能不是必需的。

#6


1  

USB bus will answer all your requirements. It might be very simple usb device with only control pipe to send request to your device or you can add an interrupt pipe that will allow you to notify host about changes in your device. There is a number of simple usb controllers that can be used, for example Cypress or Microchip.

USB总线将满足您的所有要求。它可能是非常简单的USB设备,只有控制管道向您的设备发送请求,或者您可以添加一个中断管道,允许您通知主机有关设备的更改。可以使用许多简单的USB控制器,例如赛普拉斯或Microchip。

Protocol on top of the transfer is really about your requirements. From your description it seems that simple synchronous protocol is definitely enough. What make you wander and look for additional approach? Share your doubts and we will try to help :).

转移顶部的协议实际上是关于您的要求。从您的描述看来,简单的同步协议似乎就足够了。是什么让你徘徊并寻找其他方法?分享您的疑虑,我们将尽力帮助:)。

#7


1  

If I wasn't expecting to need to do efficient binary transfers, I'd go for the terminal-style interface already suggested.

如果我不期望需要进行有效的二进制传输,我会选择已建议的终端式界面。

If I do want to do a binary packet format, I tend to use something loosely based on the PPP byte-asnc HDLC format, which is extremely simple and easy to send receive, basically:

如果我想做二进制数据包格式,我倾向于使用基于PPP字节asnc HDLC格式的松散的东西,它非常简单,易于发送接收,基本上:

Packets start and end with 0x7e You escape a char by prefixing it with 0x7d and toggling bit 5 (i.e. xor with 0x20) So 0x7e becomes 0x7d 0x5e and 0x7d becomes 0x7d 0x5d

数据包以0x7e开始和结束通过在前面添加0x7d并切换第5位(即xor为0x20)来转义字符,因此0x7e变为0x7d 0x5e,0x7d变为0x7d 0x5d

Every time you see an 0x7e then if you've got any data stored, you can process it.

每当你看到一个0x7e,那么如果你有任何数据存储,你可以处理它。

I usually do host-driven synchronous stuff unless I have a very good reason to do otherwise. It's a technique which extends from simple point-point RS232 to multidrop RS422/485 without hassle - often a bonus.

我通常做主机驱动的同步东西,除非我有充分的理由不这样做。这是一种技术,从简单的点对点RS232扩展到多点RS422 / 485,没有麻烦 - 通常是一个奖励。

#8


1  

As you may have already determined from all the responses not directly directing you to a protocol, that a roll your own approach to be your best choice.

正如您可能已经从所有响应中确定的那样,没有直接指导您使用协议,那么您可以选择自己的方法作为最佳选择。

So, this got me thinking and well, here are a few of my thoughts --

所以,这让我思考得很好,这里有一些我的想法 -

Given that this chip has 6 ADC channels, most likely you are using Rs-232 serial comm (a guess from your question), and of course the limited code space, defining a simple command structure will help, as Adam points out -- You may wish to keep the input processing to a minimum at the chip, so binary sounds attractive but the trade off is in ease of development AND servicing (you may have to trouble shoot a dead input 6 months from now) -- hyperterminal is a powerful debug tool -- so, that got me thinking of how to implement a simple command structure with good reliability.

鉴于这个芯片有6个ADC通道,很可能你正在使用Rs-232串行通信(从你的问题猜测),当然有限的代码空间,定义一个简单的命令结构将有所帮助,正如亚当指出 - 你可能希望在芯片上将输入处理保持在最低限度,因此二进制听起来很有吸引力但是易于开发和维护(你可能不得不在6个月后发现死输入的麻烦) - 超级终端是强大的调试工具 - 这让我想到了如何实现一个具有良好可靠性的简单命令结构。

A few general considerations --

一些一般性的考虑 -

keep commands the same size -- makes decoding easier.

保持命令大小相同 - 使解码更容易。

Framing the commands and optional check sum, as Adam points out can be easily wrapped around your commands. (with small commands, a simple XOR/ADD checksum is quick and painless)

正如Adam所指出的那样构建命令和可选的校验和可以很容易地围绕命令。 (使用小命令,简单的XOR / ADD校验和快速且无痛)

I would recommend a start up announcement to the host with the firmware version at reset - e.g., "HELLO; Firmware Version 1.00z" -- would tell the host that the target just started and what's running.

我建议在重置时使用固件版本向主机发起启动通知 - 例如,“HELLO;固件版本1.00z” - 会告诉主机目标刚刚启动并且正在运行什么。

If you are primarily monitoring, you may wish to consider a "free run" mode where the target would simply cycle through the analog and digital readings -- of course, this doesn't have to be continuous, it can be spaced at 1, 5, 10 seconds, or just on command. Your micro is always listening so sending an updated value is an independent task.

如果您主要是监控,您可能希望考虑“*运行”模式,其中目标只是循环通过模拟和数字读数 - 当然,这不必是连续的,它可以间隔为1, 5,10秒,或只是命令。您的微观总是在监听,因此发送更新的值是一项独立的任务。

Terminating each output line with a CR (or other character) makes synchronization at the host straight forward.

使用CR(或其他字符)终止每个输出行可以在主机上直接进行同步。

for example your micro could simply output the strings;

例如,你的micro可以简单地输出字符串;

  V0=3.20
  V1=3.21
  V2= ...
  D1=0
  D2=1
  D3=...
  and then start over -- 

Also, commands could be really simple --

而且,命令可能非常简单 -

? - Read all values -- there's not that many of them, so get them all.

? - 阅读所有价值 - 其中没有那么多,所以全部搞清楚。

X=12.34 - To set a value, the first byte is the port, then the voltage and I would recommend keeping the "=" and the "." as framing to ensure a valid packet if you forgo the checksum.

X = 12.34 - 要设置一个值,第一个字节是端口,然后是电压,我建议保持“=”和“。”。如果您放弃校验和,则确定有效数据包的框架。

Another possibility, if your outputs are within a set range, you could prescale them. For example, if the output doesn't have to be exact, you could send something like

另一种可能性,如果您的输出在设定范围内,您可以对它们进行预分频。例如,如果输出不必精确,您可以发送类似的内容

5=0 
6=9
2=5  

which would set port 5 off, port 6 to full on, and port 2 to half value -- With this approach, ascii and binary data are just about on the same footing in regards to computing/decoding resources at the micro. Or for more precision, make the output 2 bytes, e.g., 2=54 -- OR, add an xref table and the values don't even have to be linear where the data byte is an index into a look-up table ...

将端口5关闭,端口6设置为全开,端口2设置为半值 - 使用这种方法,ascii和二进制数据在微观计算/解码资源方面几乎处于相同的基础。或者为了获得更高的精度,输出2个字节,例如2 = 54 - 或者,添加一个外部参照表,这些值甚至不必是线性的,其中数据字节是查找表的索引。 。

As I like to say; simple is usually better, unless it's not.

我想说;简单通常更好,除非它不是。

Hope this helps a bit.

希望这个对你有帮助。


Had another thought while re-reading; adding a "*" command could request the data wrapped with html tags and now your host app could simply redirect the output from your micro to a browser and wala, browser ready --

重读的时候还有另一个想法;添加“*”命令可以请求包含html标签的数据,现在您的主机应用程序可以简单地将您的微型输出重定向到浏览器和wala,浏览器就绪 -

:)

#1


6  

Modbus might be what you are looking for. It was designed for exactly the type of problem you have. There is lots of code/tools out there and adherence to a standard could mean easy reuse later. It also support human readable ASCII so it is still easy to understand/test.

Modbus可能就是你想要的。它专为您所遇到的问题而设计。有很多代码/工具,遵守标准可能意味着以后可以轻松重用。它还支持人类可读的ASCII,因此它仍然易于理解/测试。

See FreeModBus for windows and embedded source.

有关Windows和嵌入式源,请参阅FreeModBus。

#2


6  

There's a lot to be said for client-server architecture and synchronous protocols. Simplicity and robustness, to start. If speed isn't an issue, you might consider a compact, human-readable protocol to help with debugging. I'm thinking along the lines of modem AT commands: a "wakeup" sequence followed by a set/get command, followed by a terminator.

对于客户端 - 服务器架构和同步协议,有很多要说的。简单和强大,开始。如果速度不是问题,您可以考虑使用紧凑的,人类可读的协议来帮助调试。我正在思考调制解调器AT命令:“唤醒”序列,后跟set / get命令,后跟一个终结符。

Host -->  [V02?]      // Request voltage #2
AVR  -->  [V02=2.34]  // Reply with voltage #2
Host -->  [V06=3.12]  // Set voltage #6
AVR  -->  [V06=3.15]  // Reply with voltage #6

Each side might time out if it doesn't see the closing bracket, and they'd re-synchronize on the next open bracket, which cannot appear within the message itself.

如果它没有看到结束括号,则每一方都可能超时,并且它们会在下一个打开的括号上重新同步,这不会出现在消息本身中。

Depending on speed and reliability requirements, you might encode the commands into one or two bytes and add a checksum.

根据速度和可靠性要求,您可以将命令编码为一个或两个字节并添加校验和。

It's always a good idea to reply with the actual voltage, rather than simply echoing the command, as it saves a subsequent read operation.

用实际电压回复总是一个好主意,而不是简单地回显命令,因为它节省了后续的读操作。

Also helpful to define error messages, in case you need to debug.

如果需要调试,还可以帮助定义错误消息。

#3


5  

My vote is for the human readable.

我的投票是为了人类可读。

But if you go binary, try to put a header byte at the beginning to mark the beginning of a packet. I've always had bad luck with serial protocols getting out of sync. The header byte allows the embedded system to re-sync with the PC. Also, add a checksum at the end.

但是如果你使用二进制文件,请尝试在开头添加一个标头字节来标记数据包的开头。串口协议不同步,我总是运气不好。标题字节允许嵌入式系统与PC重新同步。另外,最后添加校验和。

#4


4  

I've done stuff like this with a simple binary format

我用简单的二进制格式完成了这样的事情

struct PacketHdr
{
  char syncByte1;
  char syncByte2;
  char packetType;
  char bytesToFollow;  //-or- totalPacketSize
};

struct VoltageSet
{ 
   struct PacketHdr;
   int16 channelId;
   int16 voltageLevel; 
   uint16 crc;
};

struct VoltageResponse
{
   struct PacketHdr;
   int16 data[N];  //Num channels are fixed
   uint16 crc;
}

The sync bytes are less critical in a synchronous protocol than in an asynchronous one, but they still help, especially when the embedded system is first powering up, and you don't know if the first byte it gets is the middle of a message or not.

同步字节中的同步字节不像异步字节那么重要,但它们仍然有用,特别是当嵌入式系统首次启动时,你不知道它得到的第一个字节是消息的中间还是不。

The type should be an enum that tells how to intepret the packet. Size could be inferred from type, but if you send it explicitly, then the reciever can handle unknown types without choking. You can use 'total packet size', or 'bytes to follow'; the latter can make the reciever code a little cleaner.

该类型应该是一个枚举,告诉如何解释数据包。可以从类型推断出大小,但如果您明确发送它,那么接收方可以处理未知类型而不会出现阻塞。您可以使用“总数据包大小”或“要跟随的字节数”;后者可以使接收器代码更清洁。

The CRC at the end adds more assurance that you have valid data. Sometimes I've seen the CRC in the header, which makes declaring structures easier, but putting it at the end lets you avoid an extra pass over the data when sending the message.

最后的CRC增加了对有效数据的更多保证。有时我在标题中看到了CRC,这使得声明结构更容易,但是将它放在最后可以避免在发送消息时额外传递数据。

The sender and reciever should both have timeouts starting after the first byte of a packet is recieved, in case a byte is dropped. The PC side also needs a timeout to handle the case when the embedded system is not connected and there is no response at all.

如果丢弃了一个字节,发送方和接收方都应该在收到数据包的第一个字节后开始超时。当嵌入式系统未连接且根本没有响应时,PC端也需要超时来处理这种情况。

If you are sure that both platforms use IEEE-754 floats (PC's do) and have the same endianness, then you can use floats as the data type. Otherwise it's safer to use integers, either raw A/D bits, or a preset scale (i.e. 1 bit = .001V gives a +/-32.267 V range)

如果您确定两个平台都使用IEEE-754浮点数(PC的)并具有相同的字节序,那么您可以使用浮点数作为数据类型。否则,使用整数,原始A / D位或预设标度(即1位= .001V给出+/- 32.267 V范围)更安全

#5


3  

Adam Liss makes a lot of great points. Simplicity and robustness should be the focus. Human readable ASCII transfers help a LOT while debugging. Great suggestions.

Adam Liss提出了许多重要观点。应该关注简单性和稳健性。人类可读的ASCII传输在调试时帮助很多。很棒的建议。

They may be overkill for your needs, but HDLC and/or PPP add in the concept of a data link layer, and all the benefits (and costs) that come with a data link layer. Link management, framing, checksums, sequence numbers, re-transmissions, etc... all help ensure robust communications, but add complexity, processing and code size, and may not be necessary for your particular application.

它们可能对您的需求有些过分,但HDLC和/或PPP增加了数据链路层的概念,以及数据链路层带来的所有好处(和成本)。链路管理,成帧,校验和,序列号,重传等......都有助于确保强大的通信,但增加了复杂性,处理和代码大小,对于您的特定应用可能不是必需的。

#6


1  

USB bus will answer all your requirements. It might be very simple usb device with only control pipe to send request to your device or you can add an interrupt pipe that will allow you to notify host about changes in your device. There is a number of simple usb controllers that can be used, for example Cypress or Microchip.

USB总线将满足您的所有要求。它可能是非常简单的USB设备,只有控制管道向您的设备发送请求,或者您可以添加一个中断管道,允许您通知主机有关设备的更改。可以使用许多简单的USB控制器,例如赛普拉斯或Microchip。

Protocol on top of the transfer is really about your requirements. From your description it seems that simple synchronous protocol is definitely enough. What make you wander and look for additional approach? Share your doubts and we will try to help :).

转移顶部的协议实际上是关于您的要求。从您的描述看来,简单的同步协议似乎就足够了。是什么让你徘徊并寻找其他方法?分享您的疑虑,我们将尽力帮助:)。

#7


1  

If I wasn't expecting to need to do efficient binary transfers, I'd go for the terminal-style interface already suggested.

如果我不期望需要进行有效的二进制传输,我会选择已建议的终端式界面。

If I do want to do a binary packet format, I tend to use something loosely based on the PPP byte-asnc HDLC format, which is extremely simple and easy to send receive, basically:

如果我想做二进制数据包格式,我倾向于使用基于PPP字节asnc HDLC格式的松散的东西,它非常简单,易于发送接收,基本上:

Packets start and end with 0x7e You escape a char by prefixing it with 0x7d and toggling bit 5 (i.e. xor with 0x20) So 0x7e becomes 0x7d 0x5e and 0x7d becomes 0x7d 0x5d

数据包以0x7e开始和结束通过在前面添加0x7d并切换第5位(即xor为0x20)来转义字符,因此0x7e变为0x7d 0x5e,0x7d变为0x7d 0x5d

Every time you see an 0x7e then if you've got any data stored, you can process it.

每当你看到一个0x7e,那么如果你有任何数据存储,你可以处理它。

I usually do host-driven synchronous stuff unless I have a very good reason to do otherwise. It's a technique which extends from simple point-point RS232 to multidrop RS422/485 without hassle - often a bonus.

我通常做主机驱动的同步东西,除非我有充分的理由不这样做。这是一种技术,从简单的点对点RS232扩展到多点RS422 / 485,没有麻烦 - 通常是一个奖励。

#8


1  

As you may have already determined from all the responses not directly directing you to a protocol, that a roll your own approach to be your best choice.

正如您可能已经从所有响应中确定的那样,没有直接指导您使用协议,那么您可以选择自己的方法作为最佳选择。

So, this got me thinking and well, here are a few of my thoughts --

所以,这让我思考得很好,这里有一些我的想法 -

Given that this chip has 6 ADC channels, most likely you are using Rs-232 serial comm (a guess from your question), and of course the limited code space, defining a simple command structure will help, as Adam points out -- You may wish to keep the input processing to a minimum at the chip, so binary sounds attractive but the trade off is in ease of development AND servicing (you may have to trouble shoot a dead input 6 months from now) -- hyperterminal is a powerful debug tool -- so, that got me thinking of how to implement a simple command structure with good reliability.

鉴于这个芯片有6个ADC通道,很可能你正在使用Rs-232串行通信(从你的问题猜测),当然有限的代码空间,定义一个简单的命令结构将有所帮助,正如亚当指出 - 你可能希望在芯片上将输入处理保持在最低限度,因此二进制听起来很有吸引力但是易于开发和维护(你可能不得不在6个月后发现死输入的麻烦) - 超级终端是强大的调试工具 - 这让我想到了如何实现一个具有良好可靠性的简单命令结构。

A few general considerations --

一些一般性的考虑 -

keep commands the same size -- makes decoding easier.

保持命令大小相同 - 使解码更容易。

Framing the commands and optional check sum, as Adam points out can be easily wrapped around your commands. (with small commands, a simple XOR/ADD checksum is quick and painless)

正如Adam所指出的那样构建命令和可选的校验和可以很容易地围绕命令。 (使用小命令,简单的XOR / ADD校验和快速且无痛)

I would recommend a start up announcement to the host with the firmware version at reset - e.g., "HELLO; Firmware Version 1.00z" -- would tell the host that the target just started and what's running.

我建议在重置时使用固件版本向主机发起启动通知 - 例如,“HELLO;固件版本1.00z” - 会告诉主机目标刚刚启动并且正在运行什么。

If you are primarily monitoring, you may wish to consider a "free run" mode where the target would simply cycle through the analog and digital readings -- of course, this doesn't have to be continuous, it can be spaced at 1, 5, 10 seconds, or just on command. Your micro is always listening so sending an updated value is an independent task.

如果您主要是监控,您可能希望考虑“*运行”模式,其中目标只是循环通过模拟和数字读数 - 当然,这不必是连续的,它可以间隔为1, 5,10秒,或只是命令。您的微观总是在监听,因此发送更新的值是一项独立的任务。

Terminating each output line with a CR (or other character) makes synchronization at the host straight forward.

使用CR(或其他字符)终止每个输出行可以在主机上直接进行同步。

for example your micro could simply output the strings;

例如,你的micro可以简单地输出字符串;

  V0=3.20
  V1=3.21
  V2= ...
  D1=0
  D2=1
  D3=...
  and then start over -- 

Also, commands could be really simple --

而且,命令可能非常简单 -

? - Read all values -- there's not that many of them, so get them all.

? - 阅读所有价值 - 其中没有那么多,所以全部搞清楚。

X=12.34 - To set a value, the first byte is the port, then the voltage and I would recommend keeping the "=" and the "." as framing to ensure a valid packet if you forgo the checksum.

X = 12.34 - 要设置一个值,第一个字节是端口,然后是电压,我建议保持“=”和“。”。如果您放弃校验和,则确定有效数据包的框架。

Another possibility, if your outputs are within a set range, you could prescale them. For example, if the output doesn't have to be exact, you could send something like

另一种可能性,如果您的输出在设定范围内,您可以对它们进行预分频。例如,如果输出不必精确,您可以发送类似的内容

5=0 
6=9
2=5  

which would set port 5 off, port 6 to full on, and port 2 to half value -- With this approach, ascii and binary data are just about on the same footing in regards to computing/decoding resources at the micro. Or for more precision, make the output 2 bytes, e.g., 2=54 -- OR, add an xref table and the values don't even have to be linear where the data byte is an index into a look-up table ...

将端口5关闭,端口6设置为全开,端口2设置为半值 - 使用这种方法,ascii和二进制数据在微观计算/解码资源方面几乎处于相同的基础。或者为了获得更高的精度,输出2个字节,例如2 = 54 - 或者,添加一个外部参照表,这些值甚至不必是线性的,其中数据字节是查找表的索引。 。

As I like to say; simple is usually better, unless it's not.

我想说;简单通常更好,除非它不是。

Hope this helps a bit.

希望这个对你有帮助。


Had another thought while re-reading; adding a "*" command could request the data wrapped with html tags and now your host app could simply redirect the output from your micro to a browser and wala, browser ready --

重读的时候还有另一个想法;添加“*”命令可以请求包含html标签的数据,现在您的主机应用程序可以简单地将您的微型输出重定向到浏览器和wala,浏览器就绪 -

:)