Simple serial point-to-point communication protoco

2019-01-04 06:00发布

I need a simple communication protocol between two devices (a PC and a microcontroller). The PC must send some commands and parameters to the micro. The micro must transmit an array of bytes (data from sensor).

The data must be noise protected (besides parity checking, I think I need some other data correction method).

Is there any standard solution to do this? (I need only an idea, not the complete solution).

P.S. Any advice is appreciated. P.P.S Sorry for any grammar mistakes, I hope you understand.

Edit 1. I have not decided whether it will be master/slave protocol or both sides can initiate communication. The PC must know when micro have done a job and can send data. It can continuously poll the micro if data is ready, or the micro can send data, when a job is done. I don't know which is better and simpler.

Edit 2. Hardware and physical layer protocol. Since RS-232C serial standard used in the PC, I will use asynchronous communication. I will use only RxD, TxD and GND signals. I can't use additional wires because the microcontroller AFAIK doesn't support them. BTW I'm using the AVR ATmega128 chip.

So I will use fixed baud rate, 8 bits of data, 2 stop bits without parity checking (or with?).

Data link protocol. That's what my question primarily concerned about. Thanks for suggesting HDLC, PPP and Modbus protocols. I will research on it.

12条回答
唯我独甜
2楼-- · 2019-01-04 06:31

RS232 protocols are tricky. The suggestion to use HDLC, is a good one, but its not the entire solution. There are other things you need to decide:

  • How will the baud rate between the two devices be determined? Autobuad? Predefined, or set explicate?
  • Will you do flow control in software or hardware or both? Note, if you use hardware flow control then you must make sure, that the cables are built correctly.
  • Speaking of cables, this is a huge pain with RS233. Depending on the device, you may need to use a straight through cable, or a cross over cable, or a variant.
  • Using a software based flow control mechanism can be effective as it allows the most simple cable to be used - just three wired (TX, RX, and common).
  • Do you pick a 7 or 8 bit word?
  • HW parity or software error checking.

I suggest you go with 8 data bits, no hardware parity, 1 stop bit, and use software based flow control. You should use autobaud if your hardware supports it. If not, then autobaud is devilishly difficult to do in software.

查看更多
Emotional °昔
3楼-- · 2019-01-04 06:31

You can have a look at Telemetry and its associated desktop implementation in python Pytelemetry

Main features

It is a PubSub-based protocol, but unlike MQTT it is a point-to-point protocol, no broker.

As any pubsub protocol, you can publish from one end on a topic and be notified on the other end on that topic.

On the embedded side, publishing to a topic is as simple as :

publish("someTopic","someMessage")

For numbers:

publish_f32("foo",1.23e-4)
publish_u32("bar",56789)

This way of sending variables may seem limited, but the next milestone intends to add extra meaning to the topic's parsing by doing things like this :

// Add an indexing meaning to the topic
publish("foo:1",45) // foo with index = 1
publish("foo:2",56) // foo with index = 2

// Add a grouping meaning to the topic
publish("bar/foo",67) // foo is under group 'bar'

// Combine
publish("bar/foo:45",54)

This is good if you need to send arrays, complex data structures, etc.

Also, the PubSub pattern is great because of its flexibility. You can build master/slave applications, device to device, etc.

C library GitHub version

The C library is very simple to add on any new device as long as you have a decent UART library on it.

You just have to instanciate a data structure called TM_transport (defined by Telemetry), and assign the 4 function pointers read readable write writeable.

// your device's uart library function signatures (usually you already have them)
int32_t read(void * buf, uint32_t sizeToRead);
int32_t readable();
int32_t write(void * buf, uint32_t sizeToWrite);
int32_t writeable();

To use Telemetry, you just have to add the following code

// At the beginning of main function, this is the ONLY code you have to add to support a new device with telemetry
TM_transport transport;
transport.read = read;
transport.write = write;
transport.readable = readable;
transport.writeable = writeable;

// Init telemetry with the transport structure
init_telemetry(&transport);  

// and you're good to start publishing
publish_i32("foobar",...

Python library PyPI version

On the desktop side, there is the pytelemetry module that implements the protocol.

If you know python, the following code connects to a serial port, publishes once on topic foo, prints all received topics during 3 seconds then terminates.

import runner
import pytelemetry.pytelemetry as tm
import pytelemetry.transports.serialtransport as transports
import time

transport = transports.SerialTransport()
telemetry = tm.pytelemetry(transport)
app = runner.Runner(transport,telemetry)

def printer(topic, data):
    print(topic," : ", data)

options = dict()
options['port'] = "COM20"
options['baudrate'] = 9600

app.connect(options)

telemetry.subscribe(None, printer)
telemetry.publish('bar',1354,'int32')
time.sleep(3)

app.terminate()

If you don't know python, you can use the command line interface

Pytelemetry CLI PyPI version

The command line can be started with

pytlm

Then you can connect, ls(list) received topics, print data received on a topic, pub(publish) on a topic, or open a plot on a topic to display received data in real-time

enter image description here

enter image description here

查看更多
Anthone
4楼-- · 2019-01-04 06:33

SLIP and UDP. Seriously.

All PC's and similar devices speak it.

There is a good book and examples from TCP Lean

Jeremy Bentham has sneakily got a PIC doing working TCP/IP. An AVR is as good as a PIC right ?

I'd recommend UDP instead, it's pretty darn easy.

查看更多
看我几分像从前
5楼-- · 2019-01-04 06:36

maybe this question can be completely stupid but has anyone considered use of one of X/Y/Z MODEM protocols?

The main benefit of using one of above protocols is great availability of ready-to-use implementations in various programming environments.

查看更多
爷的心禁止访问
6楼-- · 2019-01-04 06:38

My suggestion is modbus. It's an efficient and easy standard protocol for communication with devices that has sensors and parameters (for example a PLC). You can get the specifications at http://www.modbus.org. It’s been around since 1979 and is gaining in popularity, you will have no problem finding examples and libraries.

查看更多
手持菜刀,她持情操
7楼-- · 2019-01-04 06:40

Here's an alternative protocol:

u8  Sync          // A constant value which always marks the start of a packet
u16 Length        // Number of bytes in payload
u8  Data[Length]  // The payload
u16 Crc           // CRC

Use RS232/UART, as the PC (serial port) and the processor (UART) can already handle that with minimum fuss (just need a MAX232 chip or similar to do the level shifting).

And using RS232/UART, you don't have to worry about master/slave if it's not relevant. Flow control is available if necessary.

Suggested PC software: either write your own, or Docklight for simple monitoring and control (evaluation version is free).

For greater error checking, simplest is parity checking, or if you need something more powerful, maybe convolutional coding.

In any case, whatever you do: keep it simple!

EDIT: Using RS232 with a PC is even easier than it used to be, as you can now get USB to RS232/TTL converters. One end goes into your PC's USB socket, and appears as a normal serial port; the other comes out to 5 V or 3.3 V signals that can be connected directly to your processor, with no level-shifting required.

We've used TTL-232R-3V3 from FDTI Chip, which works perfectly for this kind of application.

查看更多
登录 后发表回答