Go Down

Topic: Arduino-Python bridge (Read 8813 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy