For reading: Let's write out everything the arduino says to a text file. This way we'll have an exact record of what happened. Other programs can parse this file for the results so far.
For writing: This was a little more difficult. I wanted a general interface that could be used by a human or another script to communicate with the Python chatting script. I decided to use a named pipe, which is similar to a file. Anything that is written to this file-like object will be picked up by the chatting script and communicated to the Arduino, line by line.
Here's the old code as well as the new code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## From device to user | |
def read_from_device(device): | |
"""Receives information from device and appends""" | |
new_lines = device.readlines() | |
return new_lines | |
def write_to_user(buffer, data): | |
"""Write `data` to the user via `buffer` | |
`buffer` : a file | |
""" | |
# No matter what, pipe new_lines to savefile here | |
for line in data: | |
buffer.write(line) | |
buffer.flush() | |
## From user to device | |
def read_from_user(buffer, buffer_size=1024): | |
"""Read what the user wrote and returns it | |
`buffer`: a named pipe | |
""" | |
try: | |
data = os.read(buffer, buffer_size) | |
except OSError as err: | |
# Test whether this is the expected error | |
if (err.errno == errno.EAGAIN or | |
err.errno == errno.EWOULDBLOCK): | |
# Expected error when nothing arrives | |
data = None | |
else: | |
# Unexpected error | |
raise | |
return data | |
def write_to_device(device, data): | |
if data is not None: | |
device.write(data) |
The syntax for reading from the pipe is a little clunky. I wanted it to be non-blocking, because otherwise the program halts if there is nothing to read. But the non-blocking read will raise an error whenever no data is found. So we catch that exception and ignore it.
To create the pipe named TO_DEV, we just need to run:
os.mkfifo('TO_DEV')
Now you can write to the pipe, either from another terminal like so:
echo "MESSAGE" > TO_DEV
This automatically appends a newline.
Or from another Python script:
pipeout = os.open('TO_DEV', os.O_WRONLY)
os.write(pipeout, 'MESSAGE\n')
Here you have to add your own newline.
Next time I'll package this up into a complete script and demonstrate it.
To create the pipe named TO_DEV, we just need to run:
os.mkfifo('TO_DEV')
Now you can write to the pipe, either from another terminal like so:
echo "MESSAGE" > TO_DEV
This automatically appends a newline.
Or from another Python script:
pipeout = os.open('TO_DEV', os.O_WRONLY)
os.write(pipeout, 'MESSAGE\n')
Here you have to add your own newline.
Next time I'll package this up into a complete script and demonstrate it.