I have an USB connection to a device that emitts serial information. When I run my Python script below (in a Jupyter Notebook) I gett weird information out of it.
import serial
ser = serial.Serial(port='COM3', baudrate=115200, bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE, timeout=1)
ser.flushInput()
while True:
print(ser.read())
When I set the baudrate to 115200 then I get the following information: b'\xe0'b'\xe0'b'\x00'b'\x00'b'\xe0'b'\x00'b'\x00'b'\xe0' ...
At 9200 I get this: b'\x08'b'\x9e'b'\x1d'b'\xca'b'L'b'k'b'\x84'b'\xff'b'\x90'b'\x8c'b'G'b'\x9b'
Does anyone know how to get real data? I should be getting information about a solar chargecontroller like
V: 12
A: 1
etc.
Edit: I have the following right now which is not giving any prints: 1st cell:
import os, serial, argparse
class vedirect:
def __init__(self, serialport, timeout):
self.serialport = serialport
self.ser = serial.Serial(serialport, 19200, timeout=timeout)
self.header1 = '\r'
self.header2 = '\n'
self.hexmarker = ':'
self.delimiter = '\t'
self.key = ''
self.value = ''
self.bytes_sum = 0;
self.state = self.WAIT_HEADER
self.dict = {}
(HEX, WAIT_HEADER, IN_KEY, IN_VALUE, IN_CHECKSUM) = range(5)
def input(self, byte):
if byte == self.hexmarker and self.state != self.IN_CHECKSUM:
self.state = self.HEX
if self.state == self.WAIT_HEADER:
self.bytes_sum += ord(byte)
if byte == self.header1:
self.state = self.WAIT_HEADER
elif byte == self.header2:
self.state = self.IN_KEY
return None
elif self.state == self.IN_KEY:
self.bytes_sum += ord(byte)
if byte == self.delimiter:
if (self.key == 'Checksum'):
self.state = self.IN_CHECKSUM
else:
self.state = self.IN_VALUE
else:
self.key += byte
return None
elif self.state == self.IN_VALUE:
self.bytes_sum += ord(byte)
if byte == self.header1:
self.state = self.WAIT_HEADER
self.dict[self.key] = self.value;
self.key = '';
self.value = '';
else:
self.value += byte
return None
elif self.state == self.IN_CHECKSUM:
self.bytes_sum += ord(byte)
self.key = ''
self.value = ''
self.state = self.WAIT_HEADER
if (self.bytes_sum % 256 == 0):
self.bytes_sum = 0
return self.dict
else:
print ('Malformed packet')
self.bytes_sum = 0
elif self.state == self.HEX:
self.bytes_sum = 0
if byte == self.header2:
self.state = self.WAIT_HEADER
else:
raise AssertionError()
def read_data(self):
while True:
byte = self.ser.read(1)
packet = self.input(byte)
def read_data_single(self):
while True:
byte = self.ser.read(1)
packet = self.input(byte)
if (packet != None):
return packet
def read_data_callback(self, callbackFunction):
while True:
byte = self.ser.read(1)
if byte:
packet = self.input(byte)
if (packet != None):
callbackFunction(packet)
else:
break
def print_data_callback(data):
print (data)
#print(ve.read_data_single())
2nd:
ve = vedirect("COM3", 1)
Thrid which STILL runs [*] forever:
print(ve.read_data_single())
Meanwhile I got this
When I message[0] I get \t but there are no more values in it
If you're trying to use the VE-Direct protocol, according to the manual:
On power up, a VE.Direct interface will always be in Text-mode, and continuously transmits all runtime fields. As soon as it receives a valid HEX-message, it will switch to HEX-mode. It will stay in HEXmode as long as HEX-messages are frequently received. After a product has not received any valid HEX-messages for several seconds, it will switch back to Text-mode and start to auto transmit the run-time fields periodically again. Some products will send Asynchronous HEX-messages, starting with “:A” and ending with a newline ‘\n’, on their own. These messages can interrupt a regular Text-mode frame.
It seems that your problem is you are not setting the baudrate correctly, which by default is 19200
.
If you want to work on HEX mode you can do that with Python 3.x, just decode the HEX message:
received_hex=ser.read()
received_utf=received_hex.decode()
print(received_utf)
You can find some good pointers on this particular problem in other questions. Take a look at this, as an example.
You might need to check page 4 on the manual and the firmware version of your device to see if you have support for the VE-Direct protocol
If you're not sure about settings (baudrates stop bits, etc.) it might make more sense to start connecting your device using a terminal program like putty (which you seem to be using already). If you're on Windows I think RealTerm is easier to use and you can easily switch from HEX to ASCII.
EDIT: As it turns out, there is quite a lot of useful stuff done for this particular protocol. This script looks very promising.
If you want to run this script open a DOS terminal (make sure your Python folder C:\Python3.x\bin
is in your path, move to the folder where you stored the script (C:\Example
) and type:
C:\Example\python vedirect.py --port COM3
Looking at the comments below, it seems you already have your script working but it still needs some work to make it usable. Right now you can see the output of your device if you just change your loop a bit:
message=""
while True:
message += ser.read()
print(message)
The output is obviously quite ugly, but with a bit of work you can make it look like the script above. There are also some good pointers on how to read data for these devices on the manual. Take a look and see if you can put it together. Now, depending on your needs you might prefer to work on your own script or start from the other one. If you're learning, try to do it yourself before you look at the solution, if you need to have a solution ASAP then I think the github script is the place to go.