I got lt-1400(water level transmitter), output(RS485), I send this(b'\x01\x04\x00\x02\x00\x02\xd0\x0b\x00\x00\x00') to USB to TTL max485 and I resiveing tis kind of data (b'\x01\x04\x04\x3f\x9f\xae\x80\xba\x7e').how can I translate it.
receiving and sending data I am using python script||||||||
`
import serial
import time # import the module
while True:
ComPort = serial.Serial('COM11') # open COM3
ComPort.baudrate = 9600 # set Baud rate to 9600
ComPort.bytesize = 8 # Number of data bits = 8
ComPort.parity = 'N' # No parity
ComPort.stopbits = 1 # Number of Stop bits = 1
data = bytearray(b'\x01\x04\x00\x02\x00\x02\xd0\x0b\x00\x00\x00')
No = ComPort.write(data)
print (ComPort.isOpen())
#print(data) # print the data
dataIn = ComPort.read(8) # Wait and read data
print(dataIn)
ComPort.close() # print the received data
#time.sleep(2)
ComPort.close() # Close the Com port `
||||||||||||||||||||||
translating data python script|||||||
`
import struct
data = bytearray(b'\x01\x04\x04\x3f\x9f\xae\x80\xba\x7e')
number = struct.unpack('hhl', data)
number=str(number)
print(number)
#print(num2)
`
however, I have everything still I don't get the necessary data please help me If you can I would be happy
Related
I have light detector sensors connected to a data acquisition box and it is connected to my laptop via RS232 usb cable. I have stabilized serial communication to that port in python. But when I try to read the data it just keeps on running and it doesn't display any value. I have tried this same think in MATALB and it works properly, so I know that port and sensors are working fine. I am just not able to read the data in python. I have three ways(shown below in python code) but nothing works. Please help me.
Here is my python code:
import serial
from serial import Serial
s = serial.Serial('COM3') # open serial port
print(ser.name)
# Set the serial port to desired COM
s = serial.Serial(port = 'COM3', bytesize = serial.EIGHTBITS, parity = serial.PARITY_NONE, baudrate = 9600, stopbits = serial.STOPBITS_ONE)
# Read the data(method 1)
while 1:
while (s.inWaiting() > 0):
try:
inc = s.readline().strip()
print(inc)
# Read the data(method 2)
data = str(s.read(size = 1))
print(data)
# Read all the data(method 3)
while i <10:
b = s.readlines(100) # reading all the lines
in matlab it gave values with a space but in same line
That indicates there are no newline characters sent by the device.
I've never used your device or the Python serial module. But from the docs, this is what I would do:
from time import sleep
while s.is_open():
n = s.in_waiting()
if n == 0:
print "no data"
sleep(1)
continue
try:
inc = s.read(n)
print(inc)
catch serial.SerialException as oops:
print(oops)
catch serial.SerialTimeoutException as oops:
print(oops)
print("serial port closed")
This gives you feedback for each condition: port open/closed, data ready/not, and the data, if any. From there you can figure out what to do.
The documentation says inWaiting is deprecated, so I used in_waiting.
I wouldn't be surprised if the problem lies in configuring the serial port in the first place. Serial ports are tricky like that.
I'm trying to write test code for sending data via UART on my Raspberry PI 3 b+ , but I cannot receive back the data I've sent . Raspberry is connected via UART module to my laptop , so I can see in Putty results. Anyone can tell me what Am I doing wrong?
I've checked if port isOpen and it returned True , msg=b'Hello' returned Hello showed hello , but no bytes received . Sending single bytes give also no bytes detected . Erasing the timeout showed that it is reached.
Edit: did little testing if port's are working properly
from __future__ import print_function
import serial
test_string = "Testing 1 2 3 4".encode('utf-8')
#test_string = b"Testing 1 2 3 4" ### Will also work
port_list = ["/dev/serial0", "/dev/ttyS0"]
for port in port_list:
try:
serialPort = serial.Serial(port, 9600, timeout = 2)
serialPort.flushInput()
serialPort.flushOutput()
print("Opened port", port, "for testing:")
bytes_sent = serialPort.write(test_string)
print ("Sent", bytes_sent, "bytes")
loopback = serialPort.read(bytes_sent)
if loopback == test_string:
print ("Received", len(loopback), "valid bytes, Serial port", port, "working \n")
else:
print ("Received incorrect data", loopback, "over Serial port", port, "loopback\n")
serialPort.close()
except IOError:
print ("Failed at", port, "\n")
That give me information that tty0 is not working properly but , also got absolutly no answer about correctness on port serial0
import serial
import struct
import time
port = serial.Serial("/dev/ttyS0", baudrate=115200, timeout=2.0)
i = 0
while True:
msg = struct.pack('>HBBB', 3000, 243, 234, 254)
port.write(msg)
time.sleep(0.3)
bytesToRead = port.inWaiting()
print("Found {} bytes in serial".format(bytesToRead))
if bytesToRead == 5:
rcv = port.read(5)
# port.write('\r\nYou sent:' + repr(rcv))
for i in range(5):
print('\r {} - {}'.format(i, bytes(rcv[i])))
idCode = struct.pack('BB', rcv[0], rcv[1])
idCode = struct.unpack('>H', idCode)
idCode = idCode[0]
# value = struct.unpack_from('HBBB', decode)
i += 1
if i == 4:
exit()
Expected Results:
Found 5 bytes in serial
(index) - (byte at that index)
Got:
Found 0 bytes in serial
Solved. It was just matter of wiring .
If someone in future would like to run test like that - they must remember to connect RX with TX line . Or if it connected with laptop there's it should be better to create code responsible for communication on it (but instead of ttyS0 or Serial0 , port should be set to proper COM e.g. "COM3")
I'm trying to write a simple Python program (using this wrapper: https://github.com/gotthardp/python-mercuryapi) that can store rfid properties. I did this successfully using a dictionary, but I would like to make my own class so I could add more information to the class instead of just a key and value as is the case with the python dictionary. The tag epc (electronic product code) is used as the "key", and the rssi-value (the signal strength) is used as the "value" in the dictionary.
This is my code thusfar:
# Importing modules
from __future__ import print_function
import time
import mercury
# Variables
protocol = "GEN2"
region = "EU3"
reader_power = 2000
count = 0
all_reads = {}
final_reads = []
# Trying different USB connections for the RFID-reader, gives an error if nothing is found
try:
reader = mercury.Reader("tmr:///dev/ttyACM1", baudrate=115200)
except TypeError:
try:
reader = mercury.Reader("tmr:///dev/ttyACM0", baudrate=115200)
except TypeError:
reader = mercury.Reader("tmr:///dev/ttyAMA0", baudrate=115200)
except:
raise TypeError('RFID-reader not found, check ls /dev/')
def test_func(tag):
if str(tag.epc) not in all_reads.keys():
all_reads[str(tag.epc)] = int(tag.rssi)
else:
if int(tag.rssi) > all_reads[str(tag.epc)]:
print("should update for epc = ", tag.epc, "old rssi = ", all_reads[str(tag.epc)], "with new rssi = ", tag.rssi)
all_reads.update({str(tag.epc): int(tag.rssi)})
# Mandatory sets for the reader
reader.set_region(region) # Setting the correct region
reader.set_read_powers([1, 2], [reader_power, reader_power]) # Setting the reader power
reader.set_read_plan([1, 2], protocol) # Setting the correct RFID-reading protocol
#Start rfid Reading
reader.start_reading(lambda tag: test_func(tag))
time.sleep(5)
reader.stop_reading()
print(all_reads)
Most parts of the code aren't really that interesting, they are just mandatory parts so the rfid-reader can function. Like importing the correct libraries, trying to connect to the correct usb device etc. The function definition: test_func(tag) is where the logic really starts. It first checks if the newly read epc is available as a key in the dictionary all_reads. If it isn't available, then the epc is added as a key in combination with the rssi-value as a value to the dictionary. If the epc is already in the dictionary, then the program checks if a new better rssi value is found, and updates the dictionary if this is the case. This outputs something along the lines of:
should update for epc = b'E20000000000000000000003' old rssi = -46 with new rssi = -45
should update for epc = b'E20000000000000000000000' old rssi = -50 with new rssi = -49
should update for epc = b'E20000000000000000000002' old rssi = -41 with new rssi = -40
should update for epc = b'E20000000000000000000001' old rssi = -36 with new rssi = -35
should update for epc = b'E20000000000000000000000' old rssi = -49 with new rssi = -47
should update for epc = b'E20000000000000000000000' old rssi = -47 with new rssi = -43
{"b'E20000000000000000000003'": -45, "b'E20000000000000000000002'": -40, "b'E20000000000000000000000'": -43, "b'E20000000000000000000001'": -35}
This all works fine, you get one object with individual epc with the best rssi value, but I would like to have the option to add more information per epc "key". So I thought that the solution would be creating my own class. I tried recreating me previously described code behaviour with a self made class: This is my attempt at doing that:
class tags:
def __init__(self, epc, rssi):
self.epc = epc
self.rssi = rssi
How could I recreate behaviour with a selfmade class? Storing the "tags" classes in a similar fashion way as with the dictionary?
Any helps is much appreciated!
I am trying to establish a two-way communication via Python3. There is a laser range finder plugged into one of my USB ports and I'd like to send/receive commands to that. I have a sheet of commands which can be sent and what they would return, so this part is already there.
What I need is a convenient way to do it in real-time. So far I have the following code:
import serial, time
SERIALPORT = "/dev/ttyUSB0"
BAUDRATE = 115200
ser = serial.Serial(SERIALPORT, BAUDRATE)
ser.bytesize = serial.EIGHTBITS #number of bits per bytes
ser.parity = serial.PARITY_NONE #set parity check: no parity
ser.stopbits = serial.STOPBITS_ONE #number of stop bits
ser.timeout = None #block read
ser.xonxoff = False #disable software flow control
ser.rtscts = False #disable hardware (RTS/CTS) flow control
ser.dsrdtr = False #disable hardware (DSR/DTR) flow control
ser.writeTimeout = 0 #timeout for write
print ("Starting Up Serial Monitor")
try:
ser.open()
except Exception as e:
print ("Exception: Opening serial port: " + str(e))
if ser.isOpen():
try:
ser.flushInput()
ser.flushOutput()
ser.write("1\r\n".encode('ascii'))
print("write data: 1")
time.sleep(0.5)
numberOfLine = 0
while True:
response = ser.readline().decode('ascii')
print("read data: " + response)
numberOfLine = numberOfLine + 1
if (numberOfLine >= 5):
break
ser.close()
except Exception as e:
print ("Error communicating...: " + str(e))
else:
print ("Cannot open serial port.")
So in the above code I am sending "1" which should trigger "getDistance()" function of the laser finder and return the distance in mm. I tried this on Putty and it works, returns distances up to 4 digits. However, when I launch the above Python script, my output is only the following:
Starting Up Serial Monitor
Exception: Opening serial port: Port is already open.
write data: 1
read data:
and it goes forever. There is no read data or whatsoever.
Where am I mistaken?
Apparently much more simpler version of the code solved the issue.
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout = 1) # ttyACM1 for Arduino board
readOut = 0 #chars waiting from laser range finder
print ("Starting up")
connected = False
commandToSend = 1 # get the distance in mm
while True:
print ("Writing: ", commandToSend)
ser.write(str(commandToSend).encode())
time.sleep(1)
while True:
try:
print ("Attempt to Read")
readOut = ser.readline().decode('ascii')
time.sleep(1)
print ("Reading: ", readOut)
break
except:
pass
print ("Restart")
ser.flush() #flush the buffer
Output, as desired:
Writing: 1
Attempt to Read
Reading: 20
Restart
Writing: 1
Attempt to Read
Reading: 22
Restart
Writing: 1
Attempt to Read
Reading: 24
Restart
Writing: 1
Attempt to Read
Reading: 22
Restart
Writing: 1
Attempt to Read
Reading: 26
Restart
Writing: 1
Attempt to Read
Reading: 35
Restart
Writing: 1
Attempt to Read
Reading: 36
It seems to me that your ser.timeout = None may be causing a problem here. The first cycle of your while loop seems to go through fine, but your program hangs when it tries ser.readline() for the second time.
There are a few ways to solve this. My preferred way would be to specify a non-None timeout, perhaps of one second. This would allow ser.readline() to return a value even when the device does not send an endline character.
Another way would be to change your ser.readline() to be something like ser.read(ser.in_waiting) or ser.read(ser.inWaiting()) in order to return all of the characters available in the buffer.
try this code
try:
ser = serial.Serial("/dev/ttyS0", 9600) #for COM3
ser_bytes = ser.readline()
time.sleep(1)
inp = ser_bytes.decode('utf-8')
print (inp)
except:
pass
I have been trying to send a value from a Python program via serial to an Arduino, but I have been unable to get the Arduino to store and echo back the value to Python. My code seems to match that I've found in examples online, but for whatever reason, it's not working.
I am using Python 3.5 on Windows 10 with an Arduino Uno. Any help would be appreciated.
Arduino code:
void readFromPython() {
if (Serial.available() > 0) {
incomingIntegrationTime = Serial.parseInt();
// Collect the incoming integer from PySerial
integration_time = incomingIntegrationTime;
Serial.print("X");
Serial.print("The integration time is now ");
// read the incoming integer from Python:
// Set the integration time to what you just collected IF it is not a zero
Serial.println(integration_time);
Serial.print("\n");
integration_time=min(incomingIntegrationTime,2147483648);
// Ensure the integration time isn't outside the range of integers
integration_time=max(incomingIntegrationTime, 1);
// Ensure the integration time isn't outside the range of integers
}
}
void loop() {
readFromPython();
// Check for incoming data from PySerial
delay(1);
// Pause the program for 1 millisecond
}
Python code:
(Note this is used with a PyQt button, but any value could be typed in instead of self.IntegrationTimeInputTextbox.text() and the value is still not receieved and echoed back by Arduino).
def SetIntegrationTime(self):
def main():
# global startMarker, endMarker
#This sets the com port in PySerial to the port with the Genuino as the variable arduino_ports
arduino_ports = [
p.device
for p in serial.tools.list_ports.comports()
if 'Genuino' in p.description
]
#Set the proper baud rate for your spectrometer
baud = 115200
#This prints out the port that was found with the Genuino on it
ports = list(serial.tools.list_ports.comports())
for p in ports:
print ('Device is connected to: ', p)
# --------------------------- Error Handling ---------------------------
#Tell the user if no Genuino was found
if not arduino_ports:
raise IOError("No Arduino found")
#Tell the user if multiple Genuinos were found
if len(arduino_ports) > 1:
warnings.warn('Multiple Arduinos found - using the first')
# ---------------------------- Error Handling ---------------------------
#=====================================
spectrometer = serial.Serial(arduino_ports[0], baud)
integrationTimeSend = self.IntegrationTimeInputTextbox.text()
print("test value is", integrationTimeSend.encode())
spectrometer.write(integrationTimeSend.encode())
for i in range(10): #Repeat the following 10 times
startMarker = "X"
xDecoded = "qq"
xEncoded = "qq"
while xDecoded != startMarker: #Wait for the start marker (X))
xEncoded = spectrometer.read() #Read the spectrometer until 'startMarker' is found so the right amound of data is read every time
xDecoded = xEncoded.decode("UTF-8");
print(xDecoded);
line = spectrometer.readline()
lineDecoded = line.decode("UTF-8")
print(lineDecoded)
#=====================================
spectrometer.close()
#===========================================
#WaitForArduinoData()
main()
First, this is a problem:
incomingValue = Serial.read();
Because read() returns the first byte of incoming serial data reference. On the Arduino the int is a signed 16-bit integer, so reading only one byte of it with a Serial.read() is going to give you unintended results.
Also, don't put writes in between checking if data is available and actual reading:
if (Serial.available() > 0) {
Serial.print("X"); // Print your startmarker
Serial.print("The value is now ");
incomingValue = Serial.read(); // Collect the incoming value from
That is bad. Instead do your read immediately as this example shows:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
That's two big issues there. Take care of those and let's take a look at it after those fundamental issues are corrected.
PART 2
Once those are corrected, the next thing to do is determine which side of the serial communication is faulty. Generally what I like to do is determine one side is sending properly by having its output show up in a terminal emulator. I like TeraTerm for this.
Set your python code to send only and see if your sent values show up properly in a terminal emulator. Once that is working and you have confidence in it, you can attend to the Arduino side.