Go Down

Topic: Arduino-Python bridge (Read 7716 times) previous topic - next topic

dylpkls91

Jan 02, 2008, 02:38 am Last Edit: Jan 02, 2008, 02:41 am by dylpkls91 Reason: 1
Here is a Python library that I cooked up to replace Firmata/Pyduino, which I could not get working with my Diecimila. The library is based on the Simple Message System protocol, an Arduino library intended to facilitate simple i/o control between computer and microcontroller (it can be found here: http://www.arduino.cc/playground/Code/SimpleMessageSystem). My Python library is pretty self-explanatory (just make sure you have the SMS example sketch loaded on your Arduino), feel free to use it with whatever you want  :)

Code: [Select]


# Pyduino SMS
# by Dylan V, free to copy/edit/distribute
# A simple[r] Python-Arduino bridge, based on the Simple Message System protocol.
# Requires SMS library and SMS example sketch to be loaded on board.
# For USB Arduinos, please change baudrate in sketch to 115200.

import serial, atexit

__version__ = "0.2"
# This is alpha code, written by a novice. Syntax/structure changes are extremely welcome.
debug = True
global comm

class arduino:
  def __init__(self, port, baudrate=115200):
     try: self.comm = serial.Serial(port, baudrate, timeout=0.25)
     except: print "Could not connect to Arduino at specified port."
     if debug: print "Serial connection established at port %s." % port
     atexit.register(self.disconnect)

  def read_digital(self, pin):
     if pin in range(2, 14):
        self.comm.write("r d\r")
        result = self.comm.readline().split()[1:][pin - 2]
        if debug: print "Read digital pin %s, value was %s" % (str(pin), result)
        if result == "": return None
        else: return int(result)

  def read_analog(self, pin):
     if pin in range(6):
        self.comm.write("r a\r")
        result = self.comm.readline().split()[1:][pin]
        if debug: print "Read analog pin %s, value was %s" % (str(pin), result)
        if result == "": return None
        else: return int(result)

  def write_digital(self, pin, val):
     if pin in range(2, 14) and val in [0, 1]:
        self.comm.write("w d %s %s\r" % (pin, str(val)))
        if debug: print "Wrote value %s to digital pin %s" % (str(val), pin)

  def write_analog(self, pin, val):
     if pin in [3, 5, 6, 9, 10, 11] and val in range(256):
        self.comm.write("w a %s %s\r" % (pin, str(val)))
        if debug: print "Wrote value %s to pwm pin %s" % (str(val), pin)

  def disconnect(self):
     if self.comm: self.comm.close()
     if debug: print "Serial connection closed."


wrybread

#1
Jan 17, 2008, 07:27 am Last Edit: Jan 17, 2008, 07:27 am by wrybread Reason: 1
I'm having some trouble with this in Windows XP / Python 2.4 / Arduino NG Rev C.  Can anyone see what I'm doing wrong?

I'm brand new to the Arduino so it's entirely possible I'm doing something very stupid.

I have this sketch successfully loaded onto the Arduino:
http://www.arduino.cc/playground/Code/SimpleMessageSystem

My Arduino is installed as Com4 under Windows, and I set it's buardrate in Device Manager to be 115200 (it installed as 9600, but the change doesn't seem to have affected it).

For simplicity I extracted the relevant parts of the above code:

Code: [Select]
import serial, time

baudrate = 115200

comm = serial.Serial(3, baudrate, timeout=0.25)

for i in range(10):
   comm.write("r d\r")
   o = comm.readline()

   if len(o) == 0: print "no response..."
   else: print o

   time.sleep(.5)


With pins GRD and 11 jumpered I get the following output when running the above:

Quote
d 0 0 0 1 1 1 1 1 1 0 0 0
d 0 0 0 1 1 1 1 1 1 0 0 0
d 0 0 0 1 1 1 0 1 0 0 0 0
d 0 0 0 1 1 1 0 1 0 0 0 0
d 0 0 0 1 1 1 0 1 0 0 0 0
no response...
no response...
d 0 0 0 1 1 1 1 1 0 0 0 0
d 0 0 0 1 1 1 1 1 0 0 0 0
no response...


With all pins open (no jumpers) I get the following:

Quote
no response...
d 0 1 0 1 1 1 0 1 1 1 0 0
d 0 1 0 1 1 1 0 1 1 1 0 0
d 0 1 0 1 1 1 0 1 1 1 0 0
d 0 1 0 1 1 1 0 1 1 1 0 0
no response...
no response...
no response...
d 0 0 0 1 1 1 0 1 1 1 0 0
d 0 1 0 1 1 1 1 1 1 1 0 0


Ok, so far so good, the digit 3rd from the right is Pin 11 and it's indicating its status well. However, if I attach a button across the two pins and press and release I get this:

Quote
no response...
d 0 0 0 1 1 1 1 1 0 0 0 0
d 0 0 0 1 1 1 0 1 0 0 0 0
no response...
no response...
d 0 0 0 1 1 1 1 1 0 0 0 0
no response...
d 0 0 0 1 1 1 1 1 0 0 0 0
d 0 0 0 1 1 1 1 1 0 0 0 0
d 0 0 0 1 1 1 1 1 0 0 0 0


Three questions:

1) How do I make it update faster? When I was pressing that button its status never changed. I have a feeling its reading from a buffer. Do I need to clear that buffer when I read from it? If so, how?

2) Is it normal to get no response from the Arduino when querying it? Even when I increased the timeout to 1 I still get the no responses...

3) And on a minor note, why were the other pins fluctuating even when nothing was attached to them?

Thanks for any help.

dylpkls91

I'm really sorry, but I'm afraid I don't have the answers to your questions!!!

I'm really a novice Python programmer; I only made this solution as a workaround to Firmata and Pyduino, which wasn't working for me. But it's working now, see this link for details:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1198961581/all-0

This is a much more robust Python<->Arduino solution, which I recommend you use  :)

kiki_1

Erm, stupid question, but this should work just fine if I have a Duemilanove, right?

Go Up