Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Put Serial data to list
#1
The value send from arduino is 10x12
the data coming to the python slell is b'10x12\r\n'
Dear I need to decode the carriage return from the data coming from Arduino Serial port . So I decode it
Therefore I used
arduino = serial.Serial('COM15',9600)
arduino_data = arduino.readline()
print(arduino_data)

// the value is from arduino_data
 b'10x12\r\n'// the result is showing in python shell
after decode the arduino_data

values = str(arduino_data[0:len(arduino_data)].decode("utf-8"))
print(values)
10x12 / the result is showing in the python shell
// The print of "value" is 10x12 after decode that is what I need
//Then I split it by x to found 10 and 12 because x is my data separator

list_values = values.split('x')
print(list_values)
After split the list_value is ['10', '12\r\n']

It is come back \r\n to the second value '12\r\n']
Please advice
---------------------------
full code
ist_values = []
value = []
import serial
arduino = serial.Serial('COM15',9600)
arduino_data = arduino.readline()
print(arduino_data)
values = str(arduino_data[0:len(arduino_data)].decode("utf-8"))
print(values)
list_values = values.split('x')
print(list_values)
value_1 = (list_values[0:2])
value_2 = (list_values[0:1])
print(value_1)
print(value_2)
Reply
#2
This line is horrible:
values = str(arduino_data[0:len(arduino_data)].decode("utf-8"))
It should be replaced by this:
values = arduino_data.decode() # utf8 is implicit the default
arduino = serial.Serial('COM15',9600)

arduino_data = arduino.readline()
# arduino_data reads and writes bytes

values = arduino_data.split(b"x")
# split at "x", but x must be bytes, if
# you work with bytes

int_values = list(map(int, values))
  • read() and readline() return bytes
  • int and float can convert str and bytes, if the value is valid, otherwise they raise a ValueError
  • int and float strips white space automatically away. They are not interpreted, if they are not between values. Example:
    print(int(b"\n\n\n10\r\n   \t\t\t\r\n"))
    Output:
    10
  • map calls the function (first argument) for each item in the iterable (second argument). The computation is lazy, so the map object must be consumed. I did it with a list.
  • if you need to do text prcessing, then convert the bytes into a str.
    my_line = b"This are Bytes without encoding"
    my_str = my_line.decode()  # utf8
    my_str = my_line.decode("ascii") # will raise UnicodeDecodeError, if it's not in range of ASCII 0-128, so 128 is out of ASCII definition
  • sometimes you've to convert int's and float's from binary data from C or other languages. Then use the struct module.

By the way, the example allows more than 2 values. If you want to be very strict, you can limit the amount of split: "10x10x10".split("x", maxsplit=1) and you can do it also from the right side and count from there: "10x10x10".rsplit("x", maxsplit=1). Of couse int or float will fail, if you put "10x10" into it, it will raise a ValueError. Just try it with some examples in the python repl.

If only two factors are needed, you can replace the map function with:

value1 = int(arduino_data[0])
value2 = int(arduino_data[1]) 
# arduino_data[1] == "10\r\n"
# there is still the carriage return and the newline
# but they are not required to strip away
Then you can do math with your values.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
Dear DeaD Grate thanks for the detailed reply

My posted code with this line
values = str(arduino_data[0:len(arduino_data)].decode("utf-8"))
I just add -2 to the (arduino_data)-2 now it is working

values = str(arduino_data[0:len(arduino_data)-2].decode("utf-8"))
But I know that the way you have point out is the accurate way
Reply
#4
Serial.readline waits for a newline character ('\n'). Since you did not specify a timeout value for serial.open, and your program does not wait forever, it must be receiving a newline and that is why there is a newline at the end of you string/bytes/whatever. I am not sure why you are also getting the carriage return ('\r'). It must be part of the message that was sent or an artifact of how the message was sent.

Use strip() to remove trailing blank space characters like carriage return and new line.
arduino_data = arduino.readline().strip()
Reply
#5
(Aug-30-2020, 02:43 PM)deanhystad Wrote: Serial.readline waits for a newline character ('\n'). Since you did not specify a timeout value for serial.open, and your program does not wait forever, it must be receiving a newline and that is why there is a newline at the end of you string/bytes/whatever. I am not sure why you are also getting the carriage return ('\r'). It must be part of the message that was sent or an artifact of how the message was sent.

Use strip() to remove trailing blank space characters like carriage return and new line.
arduino_data = arduino.readline().strip()


Dear deanhystad Thanks for the repy
It is very clear me what you have point out
This is the arduino code
int x = 10;
int temp = 10;
int hum = 12;
void setup() {
  Serial.begin(9600);
}

void loop() {
  temp++;
  hum++;
  delay(10);
  Serial.print(temp);
  Serial.print("x");
  Serial.println(hum);
  delay(2000);
}
in above code Serial.println(hum);code ( Line number 14 )have println ln is carriage return but the first code Serial.print(temp);( Line number 12 )do not have carriage return but it is showing in the output

Please advice

About timeout I will check and update here

yes your point out is very accurate and technical

I change the code as follows

arduino = serial.Serial('COM15',9600 , timeout = 1)
Arduino code also change by removing carriage return
void loop() {
  temp++;
  hum++;
  delay(10);
  Serial.print(temp);
  Serial.print("x");
  Serial.print(hum);
  delay(2000);
}
Now it is working
Grate thanks
Reply
#6
From the Serial.println documentation

Prints data to the serial port as human-readable ASCII text followed by a carriage return character (ASCII 13, or '\r')and a newline character (ASCII 10, or '\n'). This command takes the same forms as Serial.print().

You get the \r\n from the println. Read the manual. When you have a problem it should be the first place you look. It would have saved you a week or more.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Help with to check an Input list data with a data read from an external source sacharyya 3 318 Mar-09-2024, 12:33 PM
Last Post: Pedroski55
  pyserial/serial "has no attribute 'Serial' " gowb0w 9 3,317 Aug-24-2023, 07:56 AM
Last Post: gowb0w
  Help reading data from serial RS485 korenron 8 13,596 Nov-14-2021, 06:49 AM
Last Post: korenron
  Why changing data in a copied list changes the original list? plumberpy 3 2,190 Aug-14-2021, 02:26 AM
Last Post: plumberpy
  Reading Serial data Moris526 6 5,282 Dec-26-2020, 04:04 PM
Last Post: Moris526
  Taking serial data to perform key.press functions ausbollinger13 1 2,265 Sep-04-2020, 10:26 PM
Last Post: bowlofred
  Reading serial data and saving to a file Mohan 1 7,441 May-25-2020, 04:18 PM
Last Post: pyzyx3qwerty
  Read Data from Serial Port PA3040 3 3,128 Feb-16-2020, 04:54 AM
Last Post: PA3040
  Reading data from serial port as byte array vlad93 1 11,981 May-18-2019, 05:26 AM
Last Post: heiner55
  How can I only receive data from selected serial numbers MasterCATZ 7 3,466 Apr-20-2019, 08:35 AM
Last Post: MasterCATZ

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020