简体   繁体   中英

PySerial. Unable to make any input during serial reading

So, I am trying to use serial communication with Arduino using python by using pyserial library. I have a while True loop where I am reading data sent from the Arduino, however, I want to be able to send something as well from Arduino by using ser.write, However, I am unable to do so.

import serial
import sys
import time
import pynput


from pynput import keyboard


ser = serial.Serial('COM4', baudrate = 9600, timeout = 20)





while True:

        print(ser.readline().decode('utf-8'))






def on_press(key):
    try:
        print('alphanumeric key {0} pressed'.format(
            key.char))
    except AttributeError:
        print('special key {0} pressed'.format(
            key))

def on_release(key):
    print('{0} released'.format(
        key))
    if key == keyboard.Key.esc:
        return False


with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()

listener = keyboard.Listener(
    on_press=on_press,
    on_release=on_release)
listener.start()

I am also using pynput library to look for keys pressed on the keyboard which I will modify later for example if key 0 is pressed ser.write something and etc. I just can't get it to work so it will print whatever key I am pressing its always waiting for ser.readline. Could anybody help me fix this?

In conclusion, I want to be able to input some key during serial reading.

Thanks

Your problem is basically that the code below the while True loop is never executed, since the loop never ends. So you basically have to use something called threading where you split your process into parts and run the parts in seperate threads. Below you can see an example of threading which you can use as is. The KeyboardThread handles all keyboard input and the SerialReaderThread handles the serial read calls.

from pynput import keyboard
import threading
import time
import serial
import sys

class SerialReaderThread(threading.Thread):
    def run(self):
        ser = serial.Serial('COM4', baudrate = 9600, timeout = 20)
        while True:
            print(ser.readline().decode('utf-8'))

class KeyboardThread(threading.Thread):
    def run(self):
        def on_press(key):
            try:
                print('alphanumeric key {0} pressed'.format(key.char))

                # quit when q is pressed
                if key.char == "q":
                    exit()
            except AttributeError:
                print('special key {0} pressed'.format(key))

        def on_release(key):
            print('{0} released'.format(
                key))
            if key == keyboard.Key.esc:
                return False


        with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
            listener.join()

        listener = keyboard.Listener(on_press=on_press, on_release=on_release)
        listener.start()

serial_thread = SerialReaderThread()
keyboard_thread = KeyboardThread()

serial_thread.start()
keyboard_thread.start()
serial_thread.join()
keyboard_thread.join()

You can learn more about threading and how to use it here: https://www.tutorialspoint.com/python3/python_multithreading.htm

So I modified the code provided by vincentscode by just adding option to serial write something indicated by asterisks in code. And now I am getting a lot of errors for some reason. I tried running the same code but omitting the SerialReaderThread and it works just fine with the serial write function however doesn't work together.

from pynput import keyboard
import threading
import time
import serial
import sys

class SerialReaderThread(threading.Thread):
    def run(self):
        ser = serial.Serial('COM4', baudrate = 9600, timeout = 20)
        while True:
            print(ser.readline().decode('utf-8'))

class KeyboardThread(threading.Thread):
    def run(self):
        def on_press(key):
            try:
                print('alphanumeric key {0} pressed'.format(key.char))


                if key.char == "3":
                    **ser.write(b'3\r\n') #serial write - 3**
            except AttributeError:
                print('special key {0} pressed'.format(key))

        def on_release(key):
            print('{0} released'.format(
                key))
            if key == keyboard.Key.esc:
                return False


        with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
            listener.join()

        listener = keyboard.Listener(on_press=on_press, on_release=on_release)
        listener.start()

serial_thread = SerialReaderThread()
keyboard_thread = KeyboardThread()

serial_thread.start()
keyboard_thread.start()
serial_thread.join()
keyboard_thread.join()

error

Error pasted as a code:

Unhandled exception in listener callback
Traceback (most recent call last):
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pynput\_util\__init__.py", line 162, in inner
    return f(self, *args, **kwargs)
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pynput\keyboard\_win32.py", line 280, in _process
    self.on_press(key)
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pynput\_util\__init__.py", line 78, in inner
    if f(*args) is False:
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\project\koko.py", line 21, in on_press
    ser.write(b'3\r\n')
NameError: name 'ser' is not defined
Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
    self.run()
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\project\koko.py", line 33, in run
    listener.join()
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pynput\_util\__init__.py", line 210, in join
    six.reraise(exc_type, exc_value, exc_traceback)
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\site-packages\six.py", line 702, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pynput\_util\__init__.py", line 162, in inner
    return f(self, *args, **kwargs)
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pynput\keyboard\_win32.py", line 280, in _process
    self.on_press(key)
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pynput\_util\__init__.py", line 78, in inner
    if f(*args) is False:
  File "C:\Users\Tsotne\AppData\Local\Programs\Python\Python38-32\project\koko.py", line 21, in on_press
    ser.write(b'3\r\n')
NameError: name 'ser' is not defined

I don't have any ideas what could be the problem...

EDIT: I found the solution by searching stack overflow, just declared ser as None in the beginning like ser = None, and then just declared ser as global variable in every class by just writing global ser.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM