1
votes

I would like to store in database one data that another raspberry pi send to me :

The problem is that during the sending, some data get lost. So I send 20 times the same data to be sure that my rapsberry receives correctly the data. However I want to store only one time my data

Here my sending code :

import serial
import time

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=.5)

for x in range(0, 20)
    ser.flushInput()
    ser.flushOutput()
    ser.write(' Hello world ! \r\n')
    ser.flush()

Here my listening code :

import serial

ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=.5)
data_fresh = " "
data_old = " "

while True:
    if ser.inWaiting() > 0:
        bytesToRead = ser.inWaiting()
        data_fresh = ser.readline()
        print(--- new data ---)
        print(bytesToRead)
    if data_fresh != data_old:
        data_old = data_fresh
        print(data_fresh)
        # Store in db

here one result :

--- new data ---
8
H▒Hello world !  // The same bug that in my result

--- new data ---
8
Hello world !

--- new data ---
1
--- new data ---
2
--- new data ---
3
--- new data ---
4
--- new data ---
5
--- new data ---
6
--- new data ---
7
--- new data ---
1
...

As you see new data is called but I recieved nothing (bytesToRead > 0 which is weird) ... Moreover the first data that the listerner receives is corrupted.

I'm not famaliar with serial method.

Anyone know how I can solve th problem of buffer which not sending correclty my string and how to store only one data in db ?

1
Why reinvent the wheel? Run kermit.stark
So your problem is, that when reading from serial port, you get sometime some extra data you do not expect. It is probably caused by receiving side, which has initially some older data in the buffer. One option is to introduce some packet format (with clear start and end delimiters) including error correction.Jan Vlcinsky
@stark What's kermit ? Can you explain yourself please.onedkr
And communicate without delay ? Use 0.3 delay on @9600 bps. @onedkrdsgdfg
@dsgdfg No same error :/onedkr

1 Answers

0
votes

There are two scenarios for your task:

  • bi-directional serial link
  • uni-directional serial link

With bi-directional link one can expect the receiving side to confirm, that the data were properly received.

With uni-directional link one cannot talk back to provider. This is common e.g. when the data go over sattelite to RDS encoders.

I will describe strategy used by UECP protocol as it works well on uni-directional links.

Encode data into frame

The data to transmit must be encoded into frame, which allows error detection.

Data frame often limits maximal length of data to transfer.

Use frame delimiters

STA and STP of the frame must be marked by agreed delimiter, e.g.

  • STA: FE
  • STP: FF

Escape delimiters in sent data

In case, the data to send contains delimiter bytes, they must be escaped before sending out. They must be also decoded back when received. For this purpose one can use e.g. FD byte as escape and use following translation:

  • FD -> FD 00
  • FE -> FD 01
  • FF -> FD 02

Use error correction code (e.g. CRC)

Include in the data frame CRC so that you have a chance to detect, the data were corrupted.

Include SQC number in frames

Each frame shall contain SQC field, which is changed with each packet.

Typically the values go in sequence of 01, 02, 03..., FF, 01, 02...

Send each frame 2 or 3 times

Each frame is sent 2 or 3 times with exactly the same content. SEQ is not being changed changed.

Throw away anything, what is incomplete

Any frame, which does not pass CRC check or any other rules for integrity shall be thrown away.

Accept only frames, which are twice received with the same content

Do accept only frames, which are received twice with exactly the same content. This includes the SQC number.

Implementation

Implementation is not trivial, this I leave to you.

Note, that even the rules shown above do not prevent erroneous data.