I am in the process of building a robot that is remote controlled using Python to send control messages via the Internet through a simple GUI.
I have gotten part of my code working pretty well, the GUI and control systems, but I am stuck. I am trying to use a parallax ping sensor to get distance to objects information from an Arduino Mega, and send that value to my Python control script to be displayed on the remote GUI.
The main problem that I am having is how to integrate Python code that will use the already established COM port with the Arduino and send a message to tell the Arduino to poll the ping sensor and then send to a Python program which will receive the value, and then let me insert that value into my GUI.
I already have this code to control the Arduino, and it works, with my simple GUI.
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600)
from PythonCard import model
class MainWindow(model.Background):
def on_SpdBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
def on_FBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('F')
ser.write(chr(spd))
def on_BBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('B')
ser.write(chr(spd))
def on_LBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('L')
ser.write(chr(spd))
def on_RBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('R')
ser.write(chr(spd))
def on_SBtn_mouseClick(self, event):
spd = self.components.SpdSpin.value
ser.write('@')
ser.write('S')
ser.write('0')
def on_PngDisBtn_mouseClick(self, event):
ser.write('~')
ser.write('P1')
ser.write('p2')
app = model.Application(MainWindow)
app.MainLoop()
What I would really like to do is improve the above code and add a button to click to tell Python to send a message to the Arduino to check the ping sensor and return the value.
I am very literate with the Arduino code, but I just started playing with Python in the last two weeks.
Basically, you'd just send a suitable command to the Arduino, much like you're already doing, but then wait for the Arduino to send something back; the python end of it might look something like this
ser.write('foo')
retval = ser.readline() # read a complete line (\r\n or \n terminated),
#or you could use read(n) where n is the number of bytes you want (default=1)
ping_data = retval.strip() # strip out the newline, if you read an entire line
of course, that'll get you a string, you'll probably want to convert it to an int or float in order to use it in calculations later (use int(ping_data) or float(ping_data) for strings, or struct.unpack in case its a byte sequence that needs unpacking to something sane first, but it all depends on how you represent the sensor data).
Maybe check out the Pyduino project:
pyduino is a library which allows you to communicate with Arduino boards loaded with the Firmata protocol from within Python. It currently supports version 2 of the Firmata protocol.
First, let me say that the prior answers are good, helpful, and directly relevant. My comments are more general and apply to anyone implement a bidirectional data flow to and from an Arduino. The basic idea is to design your data flow so that it is human typeable for the data going to the Arudino sketch and human readable for the data coming from the Arduino sketch. This won't always be possible, but frequently it is.
The key idea is to run your Arduino sketch with the Serial Monitor a few times. You can find the Serial Monitor under Tools in the IDE menu. You can also type Ctrl-Shift-M to invoke the Serial Monitor.
The Serial Monitor displays what the Arduino sketch sends back to you. However, it also lets you type in data that gets sent to the Arduino sketch. In other words you test and debug both sides of the serial data flow, just using the Serial Monitor.
Look at what shows up. It will frequently be quite helpful assuming your sketch tries to send data back via Serial.print(). A few notes. Make absolutely sure that the baud rate set inside the Serial Monitor exactly matches the baud rate in your sketch (9600 is a good choice in almost all cases).
The second note is critical. Bringing up the Serial Monitor forces a reset on the Arduino board. Your sketch starts over (always). This is a good thing because it gives you a fresh run each time. Note that you can force a reset, just by setting the baud rate to 9600 (even if it is already 9600). This lets you run many tests inside the Serial Monitor without having to restart the Serial Monitor each time