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)
Related
I'm reading data in from a machine to windows 7. Using python, I read the serial port, process the data then write the data to a different serial port. Using com0com null modem emulator, the data is sent to another program. Here is the code I'm using:
import serial
import time
ser = serial.Serial(port='COM7', baudrate=9600)
ser2 = serial.Serial(port='COM8', baudrate=9600)
value_one = None
while (True):
# Check if incoming bytes are waiting to be read from the serial input
# buffer.
# NB: for PySerial v3.0 or later, use property `in_waiting` instead of
# function `inWaiting()` below!
if (ser.in_waiting > 16):
# read the bytes and convert from binary array to ASCII
data_str = ser.read(ser.in_waiting).decode('ascii')
if (value_one == None):
time.sleep(1)
print(data_str)
value_one_parse = data_str[7:9]
print(value_one_parse)
value_one = float(value_one_parse)
print(value_one)
else:
time.sleep(1)
print(data_str)
value_two_parse = data_str[7:9]
print(value_two_parse)
value_two = float(value_two_parse)
print(value_two)
avg = ((value_one + value_two)/2)
print(avg)
avgprep = str(avg) + '\r\n'
print(avgprep)
ser2.write(avgprep.encode('utf-8'))
value_one = None
value_two = None
time.sleep(0.01)
So if avgprep = 71.1, why am I only receiving the first digit 7 to the program?
I changed ser.in_waiting > 16 to ser.in_waiting > 0 and put a time.sleep(5) after that.
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 am using a BananaPi to read UART data coming from a device. I know for sure what is the data generated by the device, it's the same 40 byte sequence sent in a loop, I know for sure because I mesure it with an oscilloscope. The data sent looks like(on the oscilloscope): 6A000496ED47.... 6A000496ED47....
I want to read this data in the BananaPi and I write a python script that looks like:
import serial
import time
if __name__ == '__main__':
connection = serial.Serial()
connection.port = "/dev/ttyS2"
connection.baudrate = 4000000
connection.timeout = 1
try:
connection.open()
print("serial port open")
idx = 0
while(idx < 10):
data = connection.read(size=40)
newData = data.encode('hex')
print newData
idx += 1
connection.close()
except:
print("Opening serial error")
The output is:
b777fbdc63e76....
So I get different sets of 40 bytes data on every of the 10 while loops.
Any ideea what might be wrong?
The serial setup is the same as in the oscilloscope meaning the baudrate is 4000000
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 trying to the first time to send and receive information through serial port. The manual for the device with which I am trying to talk can be found here. I am trying for a start to send a set of hexadecimals to ask about the condition of the system and my purpose is to ask in real time about the temperature and store it. Until now my code is this:
import serial
import time
#import serial.tools.list_ports
#ports = list(serial.tools.list_ports.comports())
#for p in ports:
# print p
ser = serial.Serial(port= '/dev/ttyUSB0',
baudrate=9600,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS, timeout=0, xonxoff=1, rtscts=1, dsrdtr=1)
command = "\x10\xFF\x29\x2C\x16"
command = command.decode("hex")
ser.write(command)
print command
#time.sleep(10)
ReceivedData = "\n nothing"
while ser.inWaiting() > 0:
ReceivedData = ser.read()
print ReceivedData
The problem is that I cannot get any response.
EDIT:
So I solved the communication problem. It turned out I was using an extension cable so the T and R channels were not correctly connected. Now The response that I receive is "\x00\x10\xFF\x29\x2C\x16" which is the same that I put in only with a \x00 in the front. Does this mean it is an error message? How do I calculate the 4th bit? Until now I am using an example from the manual.
dont use command = command.decode("hex")
just
command = "\x10\xFF\x29\x2C\x16"
ser.write(command)
should work i am sure it expects bytes like this
to put it differently
START_BYTE = "\x10"
ADDR_BYTE = "\xff"
FN_BYTE = "\x29"
CS_BYTE = "\x2C" # We assume you have calculated this right
END_BYTE = "\x16"
msg = START_BYTE+ADDR_BYTE+FN_BYTE+CS_BYTE+END_BYTE
ser.write(msg)
you can abstract this out since start and end and address are always the same
def send_fn(ser,FN_CMD):
START_BYTE = "\x10"
ADDR_BYTE = "\xff"
END_BYTE = "\x16"
CS_BYTE = chr((ord(ADDR_BYTE) + ord(FN_CMD))&0xFF)
msg = START_BYTE+ADDR_BYTE+FN_CMD+CS_BYTE+END_BYTE
ser.write(msg)