I am using a script in Python to collect data from a PIC microcontroller via serial port at 2Mbps. The PIC works with perfect timing at 2Mbps, also the FTDI usb-serial port works great at 2Mbps (both verified with oscilloscope) Im sending messages (size of about 15 chars) about 100-150x times a second and the number there increments (to check if i have messages being lost and so on) On my laptop I have Xubuntu running as virtual machine, I can read the serial port via Putty and via my script (python 2.7 and pySerial) The problem:. When opening the serial port via Putty I see all messages (the counter in the message increments 1 by 1). When opening the serial port via pySerial I see all messages but instead of receiving 100-150x per second i receive them at about 5 per second (still the message increments 1 by 1) but they are probably stored in some buffer as when I power off the PIC, i can go to the kitchen and come back and im still receiving messages. Here is the code (I omitted most part of the code, but the loop is the same): ser = serial.Serial('/dev/ttyUSB0', 2000000, timeout=2, xonxoff=False, rtscts=False, dsrdtr=False) #Tried with and without the last 3 parameters, and also at 1Mbps, same happens.
Ser.flushInput ser.flushOutput While True: dataraw = ser.readline print(dataraw) Anyone knows why pySerial takes so much time to read from the serial port till the end of the line? I want to have this in real time. You can use inWaiting to get the amount of bytes available at the input queue.
Then you can use read to read the bytes, something like that: While True: bytesToRead = ser.inWaiting ser.read(bytesToRead) Why not to use readline at this case from Docs: Read a line which is terminated with end-of-line (eol) character ( n by default) or until timeout. You are waiting for the timeout at each reading since it waits for eol. The serial input Q remains the same it just a lot of time to get to the 'end' of the buffer, To understand it better: you are writing to the input Q like a race car, and reading like an old car:). Yes I understand, but since my messages are something like: 213531 n 616516 n 516861 n I would think it would read quite fast. Anyway my timeout was 2 seconds and the messages were arriving on my script faster than that (printed on screen after readline).
Meaning that it was never reaching the timeout. Even adding r n did not solve anything. Setting timeout=0 did not change anything, same speed, same everything (except that it was locking when I was turning OFF the PIC) – Nov 11 '13 at 15:22.
I've got a simple program to test serial functionality. My serial device reacts to two inputs. If the user enters 'a', it responds with 'fg'. If the user enters anything other character/byte, it responds with 'z'. If I send 'b' to the serial device, it will return 'z' just fine.
When I send 'a', it should return both 'f' and 'g', so two bytes instead of one. See code below.
#!/usr/bin/env python import serial ser = serial.Serial( port = '/dev/ttyUSB0', baudrate = 9600, parity = serial.PARITYNONE, stopbits = serial.STOPBITSONE, bytesize = serial.EIGHTBITS ) ser.write('a') byteData = ser.read(1) # read one, blocking moreBytes = ser.inWaiting if moreBytes: byteData = byteData + ser.read(moreBytes) print byteData print byteData ser.close The output is: user@ubuntu:/code/native$./serialTesting.py f inWaiting gives the value of 0, thus it never reads the second byte. If I do a small change to the code, and manually read the two expected bytes, it works fine.
#!/usr/bin/env python import serial ser = serial.Serial( port = '/dev/ttyUSB0', baudrate = 9600, parity = serial.PARITYNONE, stopbits = serial.STOPBITSONE, bytesize = serial.EIGHTBITS ) ser.write('a') byteData = ser.read(2) # read two expected bytes for the result 'fg' print byteData ser.close The output is as expected: user@ubuntu:/code/native$./serialTesting.py fg. There are two decent solutions for this. For either, you'll need to set a timeout like jramirez already suggested: ser = serial.Serial( port = '/dev/ttyUSB0', baudrate = 9600, parity = serial.PARITYNONE, stopbits = serial.STOPBITSONE, bytesize = serial.EIGHTBITS, timeout=0.5, # IMPORTANT, can be lower or higher interbytetimeout=0.1 # Alternative ) Solution 1: Simple and effective byteData = ser.read(size=800) #Set size to something high This will read up to 800 bytes and will take no more time than the timeout you've set.
If you've instead set an interbytetimeout, read will wait up to that amount of time for each single byte. This is a quick solution that will work for cases where you only receive a chunk of data of known maximum size. Solution 2: The proper way def readall(port, chunksize=200): 'Read all characters on the serial port and return them.' ' if not port.timeout: raise TypeError('Port needs to have a timeout set!' ) readbuffer = b' while True: # Read in chunks.
Each chunk will wait as long as specified by # timeout. Increase chunksize to fail quicker bytechunk = port.read(size=chunksize) readbuffer += bytechunk if not len(bytechunk) chunksize: break return readbuffer The code snippet above is licensed under. And then, to read: byteData = readall(ser) Basically, this will read your data in chunks and wait every time to see if new characters appeared. If less characters were read in the time set by timeout, the transmission is considered finished. This solution will always work, even when you receive a lot of data or if you receive it very slowly.
It could be because the baudrate is really slow. You are processing the inwaiting call before the second byte gets to the buffer.
When you do ser.read(2) it waits(blocks) until 2 bytes have been received thus why it works. Try setting a timeout of 1 second, that should fix your problem. Ser = serial.Serial( port = '/dev/ttyUSB0', baudrate = 9600, parity = serial.PARITYNONE, stopbits = serial.STOPBITSONE, bytesize = serial.EIGHTBITS, timeout=1 # add this ) ser.write('a') byteData = ser.read(1) # read one, blocking byteData += ser.read(ser.inWaiting) print byteData ser.close.
Hi, I use the pyserial to read data from a serial port. My code is in window Xp and python 2.4. When I use Hyperteminal I can read data without try and try again that it is not the case with pyserial library. Anyone can help me?
Hi, I never found the need to flush anything and I always use inWaiting prior to reader. A+ Philippe Mimi wrote: Hi, I use the pyserial to read data from a serial port. My code is in window Xp and python 2.4.
Python Serial In Raspberry
When I use Hyperteminal I can read data without try and try again that it is not the case with pyserial library. Anyone can help me? Few notes from the Python beginner:) HTH. I do not understand what do you mean by the expression: '. I can read data without try and try again.' Can you be more specific please. I do not understand what do you exactly mean.
AFIK the pyserial is waiting while the data occur on the serial port (so called blocking read) so it is not necessary to do some 'polling' (checking the serial port periodically). Asrock drivers for windows 7. Following snippets of code is running in infinitive loop, but it is not necessary too be worried about processor utilization because the readline waits for the data on the serial port and the code continues to run when data occurs or when timeout passes. Import serial s = serial.Serial(port=0,baudrate=4800, timeout=20) while 1: line = s.readline # byte = s.read(1) # or you can read No. Of bytes according your needs Alternatively you can monitor buffer of the serial port and while data in it, you can read it.
Kadi roya karenga naseebo lal video download. While fd.inWaiting!= 0: s.read(1) you can find plenty of examples about pyserial here What I am not able to figure out is why are you trying to print out input and output buffers (print self.ser.flushInput) Does it print out something? Thanks Peter, because you have understood my need: a little understanding of readlines function. # Following snippets of code is running in infinitive loop, but it is not necessary too be worried about processor utilization because the readline waits for the data on the serial port and the code continues to run when data occurs or when timeout passes.
# my python script tries to read a lot of data (the histograms) and that can take many times (3 min) to download one file. And data do not arrived in the same time you can wait few seconds between data ( data response for the same command). Do you think that readlines function will wait until all data are arrived or when the timeout expired? If the data take more time, the readlines will wait or will break on the timeout? With hyperterminal the data are echoed when they arrived and you can see that they do not arrived all the same time. The timeout is reset when the first data arrived or it is only ignored?
I can recommend you to read pyserial documentation and look to the examples. Browsing through this discussion group can help you a lot as well.
Generally if the timeout is set to 0 (zero) the code will wait and wait and wait till the data will arrive to the serial port (if there is not data on the serial port, you can wait 'forever' and you can think your code is 'frozen':) ) Because of that, you can set the timeout, so after some time of waiting for the data (when the data do not arrive) the code continues on the next line. Try to experiment a little bit with some simple and short code first, so you will be able to understand how to communicate with the serial port.
HTH Petr Jakes.
I would like to read from the USB serial port from time to time in a loop. I can open the port and read data with: import serial ser = serial.Serial('/dev/ttyACM0', 9600) while 1: ser.readline An Arduino Uno is connected to the USB port of the RPi. The Arduino acts as a sensor and it will constantly produce readings.
I need some help in adding timing features to the above code. I want to open the port and read from it for a certain period of time. After that period of time, the port closes and the received data will be analysed. After a pause of several minutes, the port will reopen and the RPi will read data from it again. This continues in a loop. Any help is much appreciated.
All you would need to add, aside from closing the port when you're done;), is import time and then use: import serial, time ser = serial.Serial('/dev/ttyACM0', 9600) while 1: serialline = ser.readline print(serialline) # If using Python 2.x use: print serialline # Do some other work on the data time.sleep(300) # sleep 5 minutes # Loop restarts once the sleep is finished ser.close # Only executes once the loop exits I don't know if pySerial is buffered (data sent while sleeping is stored or simply dropped), but I usually prefer to use a generator, if you don't explicitly need to wait. They seem a bit more flexible (in my opinion): def serialdata(port, baudrate) ser = serial.Serial(port, baudrate) while True: yield ser.readline ser.close for line in serialdata('/dev/ttyACM0', 9600):.transform data. You might also be able to use the with syntax instead of the while, but I'm not too sure how that'd work with pySerial. I was just editing my comment to clarify, but locked after 5 minutes:/ The ser.close never runs until the while loop is done (which doesn't really ever occur since it's while 1/ while true), so the serial port isn't actually closed between readline calls. Since simply having a pySerial port open isn't blocking, that shouldn't be an issue.
If the while loop only ran x number of times, and then you wanted to work on that the port again, just leave the port open until done (move ser.close after all code that interacts with the port). – Apr 30 '14 at 19:01.
I am relatively new to raspberry and I'm trying to connect it to an Arduino using the raspberry USB. I spoke too soon.
It worked for a short time. Now it is back the way it was when I reported the issue - ie not working. I have verified that the script works one line at a time in Python console and I have also confirmed that I can send the same data back and forth between the arduino and raspberry in Minicom.
Why doesn't the Python script work as expected? The script runs without error but prints a blank line (line feed) instead of the expected result. I have fitted an LED on the arduino which flashes when receiving data from raspberry. It flashes as expected when I run the python script from raspberry with the ser.write statement. Looks (here ) like the open is not required.
Can you verify what exactly the Arduino returns as reponse (especially is there a newline character included)? And how fast does it respond? And might be worth checking the communication speed is the correct one. As read reads only one byte, it's most likely not the best choice - readline expects a newline at end of line, but with the timeout defined when opening the port should work (returns when newline read or timed out) - maybe try a bit longer timeout in case Arduino is slow to respond. I'm not sure what Arduino you've got, but you may find that opening the serial port is causing it to reset - and for a time (500ms or more) after reset the Arduino bootloader will be running, not your temperature-reading sketch.
If you're typing things in at the console, you won't notice this because the bootloader will have finished before you got to read anything. So I'd try putting a time.sleep(2.0), after you've opened the port, before you try to talk to your sketch. If that helps, you may find the time delay can be reduced, depending on what bootloader you've got. Also, you may find you need to call flushInput on the serial port at the start, to discard old data left lying about in the buffers by whatever was running previously. Hi, i have raspberry pi zero w and am working with SIM800l.
My problem is i have connected sim800l with pi zero using gpio pins (2 pin-5v, 6 pin-gnd,8 pin-RX of sim800l & 10pin-TX of sim800l) and able to send/receive sms and calls using minicom AT commands. Now, i have to run AT commands using python code. I have tried this code for 1 AT command as AT: import serial ser = serial.Serial('/dev/ttyS0', 115200, timeout=5) ser.write('AT r') response = ser.read(2) print response ser.close Problem is code is running without error but there is no response for AT. There should be OK response i should get but unable to get it. I have tried r n in ser.write also ser.readline but no use whats the problem?? Thank you for help.
Display posts from previous: Sort.
Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |