I am trying to develop gui with wxpython by using serial port. But I need to use serial port resource concurrency for saving data all times and plotting graphics. For this, I used wx.Timer but couldnt succeed on it. The below code just sample:
import serial
ser = serial.Serial('COM9',9600)
def update(self, event):
global ser
timerId = event.GetId()
if timerId == TIMER_ID1:
print("hello")
for line in ser:
print(line)
print("world")
else:
x=[]
x1=[]
x2=[]
y=[]
y1=[]
y2=[]
i=0
#fig = plt.figure()
def sV_sat(i):
for line in ser:
data=line.split(b",")
if data[0] == b"$GPGSV":
print("c")
sView_GP = data[3]
sNumber_GP = data[4]
i=i+1
x.append(i)
#x=[i]
y.append(float(sView_GP))
ax.set_title("GPS")
ax1.set_title("GPS-GLO")
ax1.set_ylim(0,20)
ax.bar(i,y,color='green') #only GPS #option 2
ax1.plot(x,y,'g') #GPS ve ...
#time.sleep(0.1)
ani8 = animation.FuncAnimation(fig,sV_sat)
plt.legend()
#pyplot.show()
plt.show()
print (time.ctime())
The above code gave me graphics but it couldn't give print(line):(9th line)
print("hello")
for line in ser:
print(line)
print("world")
Just print: hello and world with graphics
hello
world
The second serial line(line 21) give me graphics. Thats ok. Why first one(line 8) is skipped? Any helps will be appreciated. Thanks a lot.
Just reading the documentation for pySerial suggests that you have to read the serial port.
i.e.
Open named port at “19200,8,N,1”, 1s timeout:
>>> import serial
>>> with serial.Serial('/dev/ttyS1', 19200, timeout=1) as ser:
... x = ser.read() # read one byte
... s = ser.read(10) # read up to ten bytes (timeout)
... line = ser.readline() # read a '\n' terminated line
Open port at “38400,8,E,1”, non blocking HW handshaking:
>>> import serial
>>> ser = serial.Serial('COM3', 38400, timeout=0,
... parity=serial.PARITY_EVEN, rtscts=1)
>>> s = ser.read(100) # read up to one hundred bytes
... # or as much is in the buffer
Related
I am using 2 XBee pro S1, I want to read the packets received by the co-ordinator on my PC , it is enabled with API_2 and all other connections are done properly, I can see the packets with XCTU, I am using the python xbee library , but it gives no output :
The Code :
import serial.tools.list_ports
from xbee import XBee
import serial
ports = list(serial.tools.list_ports.comports())
for p in ports: #print the list of ports
print p
def toHex(s):
lst = []
for ch in s:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0'+hv
hv = '0x' + hv
lst.append(hv)
def decodeReceivedFrame(data):
source_addr_long = toHex(data['source_addr_long'])
source_addr = toHex(data['source_addr'])
id = data['id']
samples = data['samples']
options = toHex(data['options'])
return [source_addr_long, source_addr, id, samples]
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
ser = serial.Serial(PORT, BAUD_RATE)
print "Serial ports initialised...."
xbee = XBee(ser,escaped=True)
print "XBee object created"
while True:
try:
response = xbee.wait_read_frame()
sleep(0.5)
decodedData = decodeReceivedFrame(response)
print decodedData
print "data decoded"
except KeyboardInterrupt:
break
ser.close()
The port number and baudrate are connect, I change it to the appropriate portnumber every time I replug the coordinator to my PC.
My output looks like :
Serial ports initialised....
XBee object created
It stays like that and gives no output, even if I see the RX led blinking.
Below is the code written with only pyserial :
import serial
from time import sleep
port = '/dev/ttyUSB0'
baud = 9600
ser = serial.Serial(port, baud)
data = ""
while True:
try:
while ser.in_waiting:
sleep(1)
data = ser.read()
print data
except KeyboardInterrupt:
break
ser.close()
It gives the following output.
Could someone kindly help.
Are you sure you have the correct serial port and baud rate? Does the xbee package support API mode 2? It might only work with API mode 1.
Does that package have methods for accessing the raw byte stream instead of trying to read frames? Can you configure it to throw exceptions on parsing errors?
I would start with just printing response until you see that you're receiving data. And why include the sleep() call in that loop?
I'm not sure what you're trying to accomplish in toHex() but you might want to look at the Python method struct.unpack() or replace all of the work you do on hv with '0x%02X' % ord(ch).
I have an Arduino that reports time (in seconds), voltage, current and joules ever 60 seconds. In the serial monitor like this:
time,voltage,current,joules
60,1.45,0.39,0.57
120,1.45,0.39,1.13
180,1.45,0.39,1.70
240,1.45,0.39,2.26
...
However the following python script I don't get this result:
import serial
ser = serial.Serial('COM5', 9600)
logfile = open("batterytest.log", 'w')
while True:
if ser.readline() == b'Test Complete!':
logfile.close()
exit()
logfile.write(ser.readline().decode("utf-8"))
logfile.flush()
Instead I see results every 120 seconds:
time,voltage,current,joules
120,1.13,0.02,0.05
240,1.13,0.02,0.09
360,1.13,0.02,0.14
480,1.13,0.02,0.19
....
Looks like it may miss the in-between data point due to some timing issue. You can try to use putty to see if your arduino in fact output the right data points.
For your PySerial program, I would add a variable "data" to store your serial readline first, then perform your logic on it.
import serial
ser = serial.Serial('COM5', 9600)
logfile = open("batterytest.log", 'w')
while True:
data = ser.readline()
if data == b'Test Complete!':
logfile.close()
exit()
logfile.write(data.decode("utf-8"))
logfile.flush()
Also, depending on your Arduino output timing, you may consider adding a timeout value for your serial read by:
ser = serial.Serial('COM5', 9600, timeout = 1 )
# Here the time out is 1 second
I am aiming to write a code that will be indefinitely listening and reading from to a serial port that will have this output produced every few seconds
serial port output:
aaaa::abcd:0:0:0
//printf("%d\n",data[0]);
2387
//printf("%d\n",data[1]);
14
-9
244
-44
108
I want the data to be appended in a list like this, python supposed output
[abcd::abcd:0:0:0, 2387, 14, -9, 244, -44, 108]
I tried this code amongst many others but nothing worked, I keep on getting no output
EDIT- the code below gives me this output
'''[['abcd::', 'abcd::', 'abcd::', 'abcd::', 'abcd::']] #or
[['abcd::abcd:0:0:c9\n', '2406\n', '14\n', '-7\n']] # and so on, different output for each iteration'''
#[['aaaa::c30c:0:0:c9\n', '2462\n', '11\n', '-9\n', '242\n', '-45\n', '106\n']] apparently it worked only once.
ser = serial.Serial('/dev/ttyUSB1',115200, timeout=10)
print ser.name
while True:
data = []
data.append(ser.readlines())
print data
# further processing
# send the data somewhere else etc
print data
ser.close()
readline will keep reading data until read a terminator(new line). please try: read.
UPDATED:
use picocom -b 115200 /dev/ttyUSB0 or putty(serial model) to detect the port and baud-rate is right. I got two different ports in your two questions.if open error port, read() will keep waiting until read a byte. like this:
import serial
# windows 7
ser = serial.Serial()
ser.port = 'COM1'
ser.open()
ser.read() # COM1 has no data, read keep waiting until read one byte.
if you type this code in console, console will no output like this:
>>> import serial
>>> ser = serial.Serial()
>>> ser.port = 'COM1'
>>> ser.open()
>>> ser.read()
_
we need add timeout for read to fix it.
you can try this:
import serial
import time
z1baudrate = 115200
z1port = '/dev/ttyUSB0' # set the correct port before run it
z1serial = serial.Serial(port=z1port, baudrate=z1baudrate)
z1serial.timeout = 2 # set read timeout
# print z1serial # debug serial.
print z1serial.is_open # True for opened
if z1serial.is_open:
while True:
size = z1serial.inWaiting()
if size:
data = z1serial.read(size)
print data
else:
print 'no data'
time.sleep(1)
else:
print 'z1serial not open'
# z1serial.close() # close z1serial if z1serial is open.
This is my current code, it does not seem to handle writes very well. It seems to be stuttering.
import serial
ser = serial.Serial(port='/dev/tty1', baudrate=115200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1)
while True:
line = ser.readline()
print line,
if line == "":
var = raw_input()
if var != "":
ser.write(var)
I am trying to read several paragraphs of text, with a blank line separating each paragraph. when all the paragraphs are read, my pyserial script will then write a command to the serial channel, and then more paragraphs will be read, and so on.
How do I improve this?
---EDIT---------
Instead of raw_input(), I am now using select. Writing to the serial channel is ok now.
but for the reading, somehow it just refuses to read/print the last paragraph.
Can anyone help?
import serial
import select
import sys
ser = serial.Serial(port='/dev/tty1', baudrate=115200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1)
while True:
line = ser.readline()
print line,
while sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
lineIn = sys.stdin.readline()
if lineIn:
ser.write(lineIn)
else:
continue
Why not follow-up on Joran Beasley's suggestion?
import serial
ser = serial.Serial(
port='/dev/tty1',
baudrate=115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1)
while True:
line = ser.readline()
if not line.strip(): # evaluates to true when an "empty" line is received
var = raw_input()
if var:
ser.write(var)
else:
print line,
It's more pythonic and readable than binding sys.stdin in a while construct... O_o
I am trying to read bytes from a digital meter via PySerial. It all works with Processing/Java. But i need it to port to Raspberry Pi.
While Java receives the correct bytes, Python does not receive anything at all. The digital meter simply sends 16 bytes delimited by 13.
Working Java / Processing code (receives byte array):
import processing.serial.*;
String portName = "/dev/tty.PL2303-00001004";
myPort = new Serial(this, portName, 9600);
...
if ( myPort.available() > 0)
{
byte[] inBuffer = new byte[16];
myPort.readBytesUntil(13, inBuffer);
println("Buffer: " + inBuffer.length);
}
Not working Python code (receives nothing / ''):
import serial
import time
ser = serial.Serial('/dev/tty.PL2303-00001004', 9600, timeout=None) # tried different timeout
print(ser.isOpen())
while True:
tmp = ser.read()
print tmp
print tmp.__len__()
time.sleep(1)
Reading an Arduino Board with this Python code works fine.
Solution: ser.setDTR(1) got it working!
ser.setDTR(1) got it working! Thanks!
import serial
import time
ser = serial.Serial('/dev/tty.PL2303-00001004', 9600, timeout=None) # tried different timeout
ser.setDTR(1)
print(ser.isOpen())
while True:
tmp = ser.read()
print tmp
print tmp.__len__()
time.sleep(1)