1

I'm realy sorry for asking another question here in a day.

The new problem in detail: I connected an Laser Range Finder from HOKUYO onto my RaspBerryPi.

Connection etc works find, thanks to the serial.py

My only Problem ist, wenn I'm sending a command, I get an echo and a timestamp + \n back.

The data in the buffer looks like this:

MD000007200001\n
2Dh1\n
\n\n

After this, the sensor transmits the measurement, which locks like

MD000007200001\n
2Dh1\n
0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C\n
0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C\n
0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C\n
0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C\n
.....
...
0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C\n
\n\n

to read these data, at the moment I use readall(). Also tried readlines(). In both cases I got the problem, that have to wait until the timeout, which was set to 1. This takes too much time for a realtime application and the fact, that this sensor can measure every 120ms. If I set the timeout to 0 I often miss some data and everything collapses, because I need the whole dataset for my caluclation.

I also read, that there was an option to set the EOL of readline like readline(eof='\n\n') but with Python 3.x this won't work.

There seems to be a 2nd Option, writing my own readline-function.

But I'm an absolute beginner in python. so I don't know where I should start.

Propably there are some additional options.

Best regards, A.

AndyA
  • 25
  • 1
  • 3
  • shd be easy to adapt the answers at http://stackoverflow.com/questions/16470903/pyserial-2-6-specify-end-of-line-in-readline -- those were looking for an EOL of `\r`, you're looking for `\n\n`, but otherwise it seems the same problem. Do you need it more fully spelled out? – Alex Martelli Dec 23 '14 at 18:46
  • that would be cool, yes. i allready read that answer, but was not able to implement my own readline() function; – AndyA Dec 23 '14 at 20:05

2 Answers2

3

Adapting the answer at pySerial 2.6: specify end-of-line in readline() (which also offers alternatives), one could write a function such as:

def readline(a_serial, eol=b'\n\n'):
    leneol = len(eol)
    line = bytearray()
    while True:
        c = a_serial.read(1)
        if c:
            line += c
            if line[-leneol:] == eol:
                break
        else:
            break
    return bytes(line)

a_serial must be a serial.Serial instance built with the proper parameters, of course -- e.g, the default timeout of None could cause this to block indefinitely if the required eol marker is not forthcoming. This does not appear to be a problem for the OP if I read the question correctly, but, it is something to be aware of in general cases.

Community
  • 1
  • 1
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • Thx, that's it. Seems that i missunderstood the answer from pySerial 2.6: specify end-of-line in readline(); I thought I had to change the existing function readline from the pyserial lib. – AndyA Dec 24 '14 at 12:43
0

You should set the timeout to 0.12 (or whatever you'd like to make it "realtime") and use readall(). Then, you have a number of choices:

  1. If you want both \n and \n\n to count as a delimiter, call replace("\n\n", "\n") on the data from readall() and divide it up into lines yourself by calling split("\n").
  2. If you want only \n\n to count as a delimiter, just call split("\n\n") on the data from readall().
Thomas Hobohm
  • 645
  • 4
  • 9
  • thx for that information, but the point is, I don't want any time-dependencis; the best way would be, when there is any possibility to read from the buffer with readline until an \n\n. – AndyA Dec 23 '14 at 19:22
  • Well then set the `timeout` to 0. See the docs: http://pyserial.sourceforge.net/pyserial_api.html#serial.Serial.__init__ – Thomas Hobohm Dec 23 '14 at 19:30