Hello all
I'm totally new to python and try to walk before I can crawl.
The intention of the below code is to save serial input (received from an Arduino) to a file for as long as the application runs. The application can be interrupted by a keypress.
import sys
import serial
import keyboard
try:
ser = serial.Serial('COM4', baudrate=57600)
ser.flushInput()
while True:
ser_bytes = ser.readline()
print(ser_bytes)
file = open("testfile.csv", "a")
file.write(str(ser_bytes))
file.close()
if keyboard.is_pressed('esc'):
break;
ser.close
except:
print("Unexpected error:", sys.exc_info()[0])
print("Unexpected error:", sys.exc_info()[1])
The output (containing the error)
Output:
C:\Users\sterretje\Documents\3_Development_Python>C:\Python34\py.exe serial_test.py
b'a,bc,def\r\n'
Unexpected error: <class 'AttributeError'>
Unexpected error: 'module' object has no attribute 'is_pressed'
The arduino currently sends
'a,bc,def\r\n', the 'b' is probably left over rubbish from arduino's bootloader or something python specific; that's currently not relevant.
The question is obviously where I went wrong? Running this on a Windows 8 system, ActivePython 3.4.1.
The keyboard library was downloaded from
https://github.com/boppreh/keyboard, extracted and copied to C:\Python34\Lib\site-packages.
Did you name your own script keyboard.py, or do you have another file with that name? That seem like a likely culprit.
Otherwise, I'd suggest that you try providing the output of this:
import keyboard
print(keyboard.__file__)
Thanks for the reply. The program is called serial_test.py and the output of the edprint command
Output:
C:\Users\sterretje\Documents\3_Development_Python>C:\Python34\py.exe serial_test.py
Traceback (most recent call last):
File "serial_test.py", line 9, in <module>
print(keyboard.__file__)
AttributeError: 'module' object has no attribute '__file__'
Based on that, I have a suspicion that I might have installed it the incorrect way. Maybe the complete Python install (ActivePython) is not quite right? Most install examples use pip and that does not work; I found a pip3.4.exe though in the Scripts directory and ran that as (if I recall correctly, shown below). That seemed to have solved the problem as the error is gone.
Output:
C:\Users\sterretje\Documents\3_Development_Python>c:\Python34\Scripts\pip3.4.exe install keyboard
Current code
#run with C:\Python34\py.exe serial_test.py
#modified for PY3 from https://www.tutorialspoint.com/python/python_command_line_arguments.htm
#added extra ()
import sys
import serial
import keyboard
print("keyboard.file start")
print(keyboard.__file__)
print("keyboard.file end")
try:
ser = serial.Serial('COM4', baudrate=57600)
ser.flushInput()
while True:
print("serial read start")
ser_bytes = ser.readline()
print("serial read end")
print(ser_bytes)
file = open("testfile.csv", "a")
file.write(str(ser_bytes))
file.close()
print("testing keypress start")
if keyboard.is_pressed('esc'):
break;
print("testing keypress end")
ser.close
except:
print("Unexpected error:", sys.exc_info()[0])
print("Unexpected error:", sys.exc_info()[1])
Output:
C:\Users\sterretje\Documents\3_Development_Python>C:\Python34\py.exe serial_test.py
keyboard.file start
C:\Python34\lib\site-packages\keyboard\__init__.py
keyboard.file end
serial read start
serial read end
b'a,bc,def\r\n'
testing keypress start
testing keypress end
serial read start
Thanks for the help.
I'm now going to look how to write non-blocking serial read because the application hangs on the serial input and hence can't terminate when I press 'esc'. That is however subject for another thread (if needed

)
Quote:The arduino currently sends 'a,bc,def\r\n', the 'b' is probably left over rubbish from arduino's bootloader or something python specific; that's currently not relevant.
It was relevant; it was the result of how Python prints strings; it also ended up in the csv file
Old C knowledge eventually made me write the data as binary. Below updated code (in case somebody is looking for something similar).
#run with C:\Python34\py.exe serial_test.py
import sys
import serial
import keyboard
print("modules start")
print(keyboard.__file__)
print(serial.__file__)
print("modules end")
try:
# open the serial port; only do this once as most arduinos reset when the serial port is opened
ser = serial.Serial('COM4', baudrate=57600)
# e.g. remove remains of Arduino bootloader or old data while the application was not running
# not sure yet if it's 100% reliable
ser.flushInput()
while True:
# check if bytes received
numBytes = ser.inWaiting()
if(numBytes > 0):
serBytes = ser.readline()
print(serBytes)
# open file for binary (!) appending; not using binary results in
# 1) error telling you 'must be str, not bytes'
# 2) convering using str(ser_bytes) results in unwanted quotation marks in the file (as shown in the result of above print)
file = open('testfile.csv', 'ab')
file.write(serBytes)
file.close()
# check if <esc> was pressed; stop if so
if keyboard.is_pressed('esc'):
break;
# close serial port
ser.close
except:
print("Unexpected error:", sys.exc_info()[0])
print("Unexpected error:", sys.exc_info()[1])
# maybe todo: close serial port; this might need a little rework of above code moving 'ser = serial.Serial('COM4', baudrate=57600)' to outside the try
Outstanding now is command line parameters for comport, baudrate and output file