'Uart problem with diferences between Python and Micropython
I have a wind gauge that sends data once every second. Im using a while loop that loops for 1 second that reads the uart port and grabs the data. In Python on both windows and raspberyPi it works perfectly. I am trying to run the same code on a Pyboard running micropython. in python while in the loop whey there is no data present on the uart it returns an empty byte- b'' until it receives data. In MicroPython while in the loop instead of an empty byte it returns None this is when the error messages occur. TypeError: object of type 'NoneType' has no len() view code bellow for both python and MicroPython
Python code works perfectly:
import serial
from statistics import mean
import time
#import utime
ser_gauge = serial.Serial('COM6', timeout=0.1)
ser_gauge.baudrate = 9600 # set Baud rate
ser_gauge.bytesize = 8 # Number of data bits = 8
ser_gauge.parity = 'E' # No parity
ser_gauge.stopbits = 1 # Number of Stop bits = 1
start_reading = True
if start_reading:
t0 = time.time()
while time.time() - t0 <1:
print(t0)
print(time.time() - t0)
data = ser_gauge.readline()
print(data)
if len(data) > 0:
command = data
print(command)
Returns after 1 second loop notice empty byte when no data is there. 1597162713.5983248 0.0 b'' 1597162713.5983248 0.10153698921203613 b'' 1597162713.5983248 0.20209956169128418 b'' 1597162713.5983248 0.30266332626342773 b'' 1597162713.5983248 0.4032254219055176 b'' 1597162713.5983248 0.503786563873291 b'' 1597162713.5983248 0.6043491363525391 b'' 1597162713.5983248 0.7049119472503662 b'$WIMWV,82,R,3.1,M,A06\r\n' b'$WIMWV,82,R,3.1,M,A06\r\n' 1597162713.5983248 0.7820417881011963 b'' 1597162713.5983248 0.8826048374176025 b'' 1597162713.5983248 0.9831666946411133 b''
MicroPython code:
from statistics import mean
import time
import utime
from pyb import UART
ser_gauge = UART(4, 9600)
ser_gauge.init(9600, bits=7, parity=None, stop=1, timeout=100)
start_reading = True
if start_reading:
t0 = time.ticks_ms()
while time.ticks_ms()/1000 - t0 <1:
print(t0)
print(time.ticks_ms() - t0)
data = ser_gauge.readline()
print(data)
if len(data) > 0:
#TypeError: object of type 'NoneType' has no len()
command = data
print(command)
If I continue the loop the data looks like this: 113412 2078 b'$WIMWV,82,R,3.2,M,A05\r\n' b'$WIMWV,82,R,3.2,M,A05\r\n' 113412 2178 None None 113412 2278 None None 113412 2378 None None 113412 2478 None None 113412 2578 None None 113412 2678 None None 113412 2778 None None Im very green at programming any help would be appreciated. I have tried alot of different variety of if statements to bypass None without success.
Solution 1:[1]
I found the answer to the None Issue above. None is like null, so it doesn’t respond to normal operands like == So you have to use the word is. If data is none: then use the pass Statement. Then the script will continue.
t0 = time.ticks_ms()
while time.ticks_ms()/1000 - t0 <1:
print(t0)
print(time.ticks_ms() - t0)
data = ser_gauge.readline()
if data is None:
Pass
print(data)
elif len(data) > 0:
command = data
print(command)
Solution 2:[2]
Your Python code sets the serial port as 9600, 8, E, 1
but the uPy code uses 9600, 7, None, 1
is that a deliberate change in the port parameters? Has the external device port settings also been changed?
Solution 3:[3]
Micropython is frugal on memory. Conceptually an empty bytearray len()==0 is what you expect when there's nothing ready. But None takes up less memory than a bytearray.
None is a special value in the same spirit as True, False, ...
It's often used to mean "nothing". No fault, no data, no argument, use default.
Best way to test: if val is None:
command = None
data = ser_gauge.readline()
if data is not None: # if data is None nothing received
if not len(data): # Should never receive 0 length data
raise Exception('impossible')
command = data.decode('utf-8')
print(command)
Note that I decode the bytearray into a utf-8 str assuming it's text not binary.
And initialize command to None so we know the difference between nothing and a received command.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | Francis Cagney |