Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Writing commands to serial
#1
Hello,

I use this code to send command to an Arduino using this code from here:https://tungweilin.wordpress.com/2015/01/04/python-serial-port-communication/

import serial
 
port = "COM4"
baud = 38400
 
ser = serial.Serial(port, baud, timeout=1)
    # open the serial port
if ser.isOpen():
     print(ser.name + ' is open...')
 
while True:
    #cmd = raw_input("Enter command or 'exit':")
        # for Python 2
    cmd = input("Enter command or 'exit':")
        # for Python 3
    if cmd == 'exit':
        ser.close()
        exit()
    else:
        ser.write(cmd.encode('ascii')+'\r\n')
        out = ser.read()
        print('Receiving...'+out)
But I get this error:


    
ser.write(cmd.encode('ascii')+'\r\n')
TypeError: can't concat bytes to str
I tried many changes, among which is this:

 
while True:
    #cmd = raw_input("Enter command or 'exit':")
        # for Python 2
    cmd = input("Enter command or 'exit':")
        # for Python 3
    if cmd == 'exit':
        ser.close()
        exit()
    else:
        ser.write(cmd.encode('UTF-8')+ b"\n")
        out = ser.read()
        print('Receiving...'+out)
But I get this error:

    print('Receiving...'+out)
TypeError: Can't convert 'bytes' object to str implicitly
How can I send the command correctly?
Reply
#2
I haven't tried this, but what if you changed '\r' and '\n' to their decimal equivilents?

So this line:
ser.write(cmd.encode('ascii')+'\r\n')
becomes:
ser.write(cmd.encode('ascii') + b'13' + b'10')
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply
#3
You can not concatenate bytes with strings.
Just concatenate them, when they are still str:

cmd = input("Enter command or 'exit':") + '\r\n'
...
ser.write(cmd.encode())
PS: cmd.encode('ascii') + b'13' + b'10' is wrong.

You have following possibilities:
your_str.encode() + b'\x0d' + b'\x0a'
your_str.encode() + bytes([13, 10])
your_str.encode() + bytes([0x0d, 0x0a])

or with a str:

end = '\x0d\x0a'
cmd.encode() + end.encode()


I think the best way is, to do all formatting and concatenation with strings and when you need them to send them as bytes, do it at this place directly without any additional stuff like concatenation.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#4
I stand corrected and learned a new method. Thanks.
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply
#5
Thank you, I managed to make it send command, but not to make the

        out = ser.read()
        print('Receiving...'+out)
work. What I am trying to do is this: I wrote a code to read from Arduino through Serial, and I want to send commands to the Arduino through serial (by typing the commands through the keyboard). The code I am using is this:

import serial,time
ser = serial.Serial(
    port='COM4',
    baudrate=38400,
    bytesize=serial.EIGHTBITS,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    xonxoff=False
)
line = ser.readline();

while line:
     line = ser.readline()
     print(line)
     ser.reset_input_buffer()
     cmd = input("Enter command or 'exit':") + '\r\n'
     if len(cmd)>0:
        ser.write(cmd.encode())
     else:
        continue
but what I see is that the code blocks, until I print something. I want to read continuously from Serial what Arduino sends and if I type a command from keyboard, to write it to the serial. I am trying changes and I read the pyserial documentation but I cannot figure out something...
Reply
#6
Maybe you need to add back in the timeout=1 arg in the serial.Serial() constructor? Otherwise the call to ser.readline() will block (i.e., not return) until data is received (specifically an EOF).
Reply
#7
As mentioned ser.readline() is a blocking call. You try to read a reply before you have sent a request.

Maybe you think about the concept.

  1. You switch your Arduino on
  2. You switch your PC on
  3. You start the program on the PC
  4. Program is waiting for input from serial which should magically come from the Arduino

The point is, the Arduino does not know when there is a new connection.
The program should on the Arduino work as follows:
  • Arduino runs in a loop.
  • A blocking call reads the received data (readline).
  • When the request has been received, it executes the program.
  • The Arduino answers the request with a reply.

On the other side your program should do following in a loop:
  • Connects to serial
  • Inside a loop
    • Reads the input from user
    • if no command, break out of the loop to close the program
    • Reads the received data from serial
    • Prints it to console
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#8
I am learning Python new and i want send to date and time but i have some problem.
When i write to input method something, i can send to my message.But the message been date and time on windows ,cannot send to arduino. Screen output become like that b' ' . I need to year,month,day,hour,minute and second data.

import serial
import time
import datetime
 	

ser = serial.Serial('COM3', 9600, timeout=0)
ser.reset_input_buffer()
time.sleep(1.5)

now=datetime.datetime.now()

#str_now=now.strftime("%Y.%m.%d.%H.%M.%S")+'\r\n'

year = now.strftime("%Y")+'\r\n'
#print("year:", year)

#month = now.strftime("%m")+'\r\n'
#print("month:", month)

#day = now.strftime("%d")+'\r\n'
#print("day:", day)

#hour = now.strftime("%H")+'\r\n'
#print("hour:", hour)

#minute = now.strftime("%M")+'\r\n'
#print("minute:", minute)

#second = now.strftime("%S")+'\r\n'
#print("second:", second)

#var = input("Enter something: ")+'\r\n'

ser.write(year.encode())

while 1:
    try:
        print (ser.readline())
        time.sleep(1.5)
    except ser.SerialTimeoutException:
        print('Data could not be read')
Arduino code:
int incomingByte = 0;
 
void setup(){
// Open serial connection.
Serial.begin(9600);
 
}
 
void loop(){
if (Serial.available() > 0) {
 
 // read the incoming byte:
 incomingByte = Serial.read();
 
 // say what you got:
 Serial.print("I got: "); // ASCII printable characters
 Serial.println(incomingByte,DEC);
}
 
}
Output:

[Image: 1pcuo0.jpg]

How to change python code and send to date and time datas
Reply
#9
Thank you for this useful reply. However -

I am afraid that the result of your illustration is ambiguous. You have included so many brackets and quote marks that I have no idea how cmd ends up, so what pyserial encodes and sends. You cannot assume that the naive user (me) understands the detailed syntax or how it is interpreted by the compiler, especially as the questioner also failed to understand the syntax.

Is cmd = "Enter command or 'exit':"\r\n
or cmd = input("Enter command or 'exit':")\r\n
or cmd = Enter command or 'exit':\r\n
or cmd = what?

And if cmd1 = G0 X11.4158 Y0.5132
rtnl = \r\n
can I state
cmd2 = cmd1 + rtnl
to create
cmd2 = G0 X11.4158 Y0.5132\r\n

and is that the same as
cmd2 = 'G0 X11.4158 Y0.5132' + '\r\n'
?

(Jan-30-2018, 04:25 PM)DeaD_EyE Wrote: You can not concatenate bytes with strings.
Just concatenate them, when they are still str:

cmd = input("Enter command or 'exit':") + '\r\n'
...
ser.write(cmd.encode())
PS: cmd.encode('ascii') + b'13' + b'10' is wrong.

You have following possibilities:
your_str.encode() + b'\x0d' + b'\x0a'
your_str.encode() + bytes([13, 10])
your_str.encode() + bytes([0x0d, 0x0a])

or with a str:

end = '\x0d\x0a'
cmd.encode() + end.encode()


I think the best way is, to do all formatting and concatenation with strings and when you need them to send them as bytes, do it at this place directly without any additional stuff like concatenation.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  pyserial/serial "has no attribute 'Serial' " gowb0w 9 3,292 Aug-24-2023, 07:56 AM
Last Post: gowb0w
  Trouble writing over serial EngineerNeil 1 2,582 Apr-07-2019, 08:17 PM
Last Post: j.crater

Forum Jump:

User Panel Messages

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