From 8fff2d2b036cb918d7b2175678281f1078d92a1c Mon Sep 17 00:00:00 2001 From: Tristan Hearn Date: Fri, 10 Aug 2012 15:20:39 -0400 Subject: [PATCH] edits --- MIT license.txt | 38 +-- README.md | 282 +++++++++--------- arduino/__init__.py | 10 +- arduino/arduino.py | 612 +++++++++++++++++++++++----------------- arduino/examples.py | 150 +++++----- prototype/prototype.ino | 76 ++++- 6 files changed, 671 insertions(+), 497 deletions(-) diff --git a/MIT license.txt b/MIT license.txt index 0e1f20e..366ef45 100644 --- a/MIT license.txt +++ b/MIT license.txt @@ -1,19 +1,19 @@ -Copyright (c) 2012-2013 Tristan A. Hearn - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +Copyright (c) 2012-2013 Tristan A. Hearn + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index a3ca4ac..e2eb869 100644 --- a/README.md +++ b/README.md @@ -1,132 +1,152 @@ -# Python Arduino Command API - -> © 2012-2013 Tristan A. Hearn -> under the MIT License - -Based in part on the Python Arduino Prototyping API by Akash Manohar (https://github.com/HashNuke/Python-Arduino-Prototyping-API/). - -The Python Arduino Command API is a light-weight Python package for communicating with Arduino microcontroller boards. It is written -using a custom protocol, similar to Firmata (http://firmata.org/wiki/Main_Page). This allows a user to quickly protoype programs -for Arduino or to simply read and control harware connected to an Arduino from a host computer, without having to reload sketches onto an Arduino board. - -Method names within the Python Arduino Command API are designed to be as close as possible to their Arduino programming language counterparts. - -## Usage example -```python -#!/usr/bin/env python -""" - Blinks an LED on digital pin 13 - in 1 second intervals -""" - -from arduino import Arduino -import time - -board = Arduino('9600') - -while True: - board.digitalWrite(13, "LOW") - time.sleep(1) - board.digitalWrite(13, "HIGH") - time.sleep(1) -``` -Python-Arduino-Command-API -For more examples, see arduino/examples.py. This file contains methods which replicate -the functionality of many Arduino demo sketches. - -#### Requirements: -* Python 2.3 or higher (Python 3.x not yet tested) -* PySerial -* Arduino compatible microcontroller with at least 14KB of memory - -#### Setup: -1. Verify that your Arduino board communicates at the baud rate specified in the setup() function in prototype.ino. Change it if necessary. -1. Load the sketch prototype.ino onto your Arduino board. -2. Import the included arduino library into your python script. - - -## Classes -*Arduino(baud)* - Set up communication with currently connected and powered Arduino. -```python -board = Arduino("9600") #Example -``` -The device name / COM port of the connected Arduino will be auto-detected. If there are more than one Arduino boards connected, -the desired COM port can be also be passed as an optional argument: -```python -board = Arduino("9600", port = "COM3") #Windows example -``` -```python -board = Arduino("9600", port = "/dev/tty.usbmodemfa141") #OSX example -``` -A time-out for reading from the Arduino can also be specified as an optional argument: -```python -board = Arduino("9600", timeout = 2) #Serial reading functions will wait for no more than 2 seconds -``` - -*SoftwareSerial()* - A class for handling software serial functionality. Is used internally by the Arduino class, and should not be called directly. - -## Methods - -**Digital I/O** - -* *Arduino.digitalWrite(pin_number, state)* - turn digital pin on/off -* *Arduino.digitalRead(pin_number)* - read state of a digital pin - -```python -#Digital read / write example -board.digitalWrite(13, "HIGH") #Set digital pin 13 voltage -state_1 = board.digitalRead(13) #Will return integer 1 -board.digitalWrite(13, "LOW") #Set digital pin 13 voltage -state_2 = board.digitalRead(13) #Will return integer 0 -``` - -* *Arduino.pinMode(pin_number, io_mode)* - set pin I/O mode -* *Arduino.pulseIn(pin_number, state)* - measures a pulse -* *Arduino.pulseIn_set(pin_number, state)* - measures a pulse, with preconditioning - -```python -#Digital mode / pulse example -board.pinMode(7, "INPUT") #Set digital pin 7 mode to INPUT -duration = board.pulseIn(7, "HIGH") #Return pulse width measurement on pin 7 -``` - -**Analog I/O** - -* *Arduino.analogRead(pin_number)* - returns the analog value -* *Arduino.analogWrite(pin_number, value)* - sets the analog value - -```python -#Analog I/O examples -val=board.analogRead(5) #Read value on analog pin 5 (integer 0 to 1023) -val = val / 4 # scale to 0 - 255 -board.analogWrite(11) #Set analog value (PWM) based on analog measurement -``` - -**Software Serial Functionality** - -* *Arduino.SoftwareSerial.begin(ss_rxPin,ss_txPin,ss_device_baud)* - initialize software serial device on -specified pins. -Only one sofware serial device can be used at a time. Existing software serial instance will -be be overwritten by calling this method, both in Python and on the arduino board. -* *Arduino.SoftwareSerial.write(data)* - send data using the arduino 'write' function to the existing software serial connection. -* *Arduino.SoftwareSerial.read()* - returns one byte from the existing software serial connection - -```python -#Software serial example -board.SoftwareSerial.begin(0,7,"19200") # Start software serial for transmit only (tx on pin 7) -board.SoftwareSerial.write(" test ") #Send some data -response_char = board.SoftwareSerial.read() #read response character -``` - -**Misc** - -* *Arduino.close()* - closes serial connection to the Arduino. - -## To-do list: -* Expand software serial functionality (print() and println()) -* Add simple reset functionality that zeros out all pin values -* Add I2C / TWI function support (Arduino Wire.h commands) -* Add Servo support (Arduino Servo.h commands) -* Add tone() / noTone() squarewave generator support for piezo type speakers -* Include a wizard which generates 'prototype.ino' with selected serial baud rate and Arduino function support (to help reduce memory requirements). +# Python Arduino Command API + +> © 2012-2013 Tristan A. Hearn +> under the MIT License + +Based in part on the Python Arduino Prototyping API by Akash Manohar (https://github.com/HashNuke/Python-Arduino-Prototyping-API/). + +The Python Arduino Command API is a light-weight Python package for communicating with Arduino microcontroller boards. It is written +using a custom protocol, similar to Firmata (http://firmata.org/wiki/Main_Page). This allows a user to quickly protoype programs +for Arduino or to simply read and control harware connected to an Arduino from a host computer, without having to reload sketches onto an Arduino board. + +Method names within the Python Arduino Command API are designed to be as close as possible to their Arduino programming language counterparts. + +## Usage example +```python +#!/usr/bin/env python +""" + Blinks an LED on digital pin 13 + in 1 second intervals +""" + +from arduino import Arduino +import time + +board = Arduino('9600') + +while True: + board.digitalWrite(13, "LOW") + time.sleep(1) + board.digitalWrite(13, "HIGH") + time.sleep(1) +``` +Python-Arduino-Command-API +For more examples, see arduino/examples.py. This file contains methods which replicate +the functionality of many Arduino demo sketches. + +#### Requirements: +* Python 2.3 or higher (Python 3.x not yet tested) +* PySerial +* Arduino compatible microcontroller with at least 14KB of memory + +#### Setup: +1. Verify that your Arduino board communicates at the baud rate specified in the setup() function in prototype.ino. Change it if necessary. +1. Load the sketch prototype.ino onto your Arduino board. +2. Import the included arduino library into your python script. + + +## Classes +*Arduino(baud)* - Set up communication with currently connected and powered Arduino. +```python +board = Arduino("9600") #Example +``` +The device name / COM port of the connected Arduino will be auto-detected. If there are more than one Arduino boards connected, +the desired COM port can be also be passed as an optional argument: +```python +board = Arduino("9600", port = "COM3") #Windows example +``` +```python +board = Arduino("9600", port = "/dev/tty.usbmodemfa141") #OSX example +``` +A time-out for reading from the Arduino can also be specified as an optional argument: +```python +board = Arduino("9600", timeout = 2) #Serial reading functions will wait for no more than 2 seconds +``` + +*SoftwareSerial()* - A class for handling software serial functionality. Is used internally by the Arduino class, and should not be called directly. + +## Methods + +**Digital I/O** + +* *Arduino.digitalWrite(pin_number, state)* - turn digital pin on/off +* *Arduino.digitalRead(pin_number)* - read state of a digital pin + +```python +#Digital read / write example +board.digitalWrite(13, "HIGH") #Set digital pin 13 voltage +state_1 = board.digitalRead(13) #Will return integer 1 +board.digitalWrite(13, "LOW") #Set digital pin 13 voltage +state_2 = board.digitalRead(13) #Will return integer 0 +``` + +* *Arduino.pinMode(pin_number, io_mode)* - set pin I/O mode +* *Arduino.pulseIn(pin_number, state)* - measures a pulse +* *Arduino.pulseIn_set(pin_number, state)* - measures a pulse, with preconditioning + +```python +#Digital mode / pulse example +board.pinMode(7, "INPUT") #Set digital pin 7 mode to INPUT +duration = board.pulseIn(7, "HIGH") #Return pulse width measurement on pin 7 +``` + +**Analog I/O** + +* *Arduino.analogRead(pin_number)* - returns the analog value +* *Arduino.analogWrite(pin_number, value)* - sets the analog value + +```python +#Analog I/O examples +val=board.analogRead(5) #Read value on analog pin 5 (integer 0 to 1023) +val = val / 4 # scale to 0 - 255 +board.analogWrite(11) #Set analog value (PWM) based on analog measurement +``` + +**Servo Library Functionality** +Support is included for up to 8 servos. + +* *Arduino.Servo.attach(pin, min = 544, max = 2400)* - Create servo instance. Only 8 servos can be used at one time. +* *Arduino.Servo.read(pin)* - Returns the angle of the servo attached to the specified pin +* *Arduino.Servo.write(pin, angle)* - Move an attached servo on a pin to a specified angle +* *Arduino.Servo.writeMicroseconds(pin, uS)* - Write a value in microseconds to the servo on a specified pin +* *Arduino.Servo.detach(pin)* - Detaches the servo on the specified pin + +```python +#Servo example +board.Servo.attach(9) #declare servo on pin 9 +board.Servo.attach(10) #declare servo on pin 10 +board.Servo.write(9, 0) +board.Servo.write(10, 180) +angle_1 = board.Servo.read(9) # should be 0 +angle_2 = board.Servo.read(10) # should be 180 +board.Servo.detach(9) #free pin 9 +board.Servo.detach(10) #free pin 10 +``` + +**Software Serial Functionality** + +* *Arduino.SoftwareSerial.begin(ss_rxPin,ss_txPin,ss_device_baud)* - initialize software serial device on +specified pins. +Only one sofware serial device can be used at a time. Existing software serial instance will +be be overwritten by calling this method, both in Python and on the arduino board. +* *Arduino.SoftwareSerial.write(data)* - send data using the arduino 'write' function to the existing software serial connection. +* *Arduino.SoftwareSerial.read()* - returns one byte from the existing software serial connection + +```python +#Software serial example +board.SoftwareSerial.begin(0,7,"19200") # Start software serial for transmit only (tx on pin 7) +board.SoftwareSerial.write(" test ") #Send some data +response_char = board.SoftwareSerial.read() #read response character +``` + +**Misc** + +* *Arduino.close()* - closes serial connection to the Arduino. + +## To-do list: +* Expand software serial functionality (print() and println()) +* Add simple reset functionality that zeros out all pin values +* Add I2C / TWI function support (Arduino Wire.h commands) +* Add tone() / noTone() squarewave generator support for piezo type speakers +* Include a wizard which generates 'prototype.ino' with selected serial baud rate and Arduino function support (to help reduce memory requirements). * Multi-serial support for Arduino mega (Serial1.read(), etc) \ No newline at end of file diff --git a/arduino/__init__.py b/arduino/__init__.py index aa0476b..e440668 100644 --- a/arduino/__init__.py +++ b/arduino/__init__.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python - - -from arduino import Arduino - +#!/usr/bin/env python + + +from arduino import Arduino + diff --git a/arduino/arduino.py b/arduino/arduino.py index 1922721..1a02874 100644 --- a/arduino/arduino.py +++ b/arduino/arduino.py @@ -1,265 +1,347 @@ -#!/usr/bin/env python -from serial.tools import list_ports -import serial, time - -class SoftwareSerial(object): - """ - Class for Arduino software serial functionality - """ - def __init__(self,board): - self.board=board - self.connected = False - - def begin(self,p1,p2,baud): - """ - Create software serial instance on - specified tx,rx pins, at specified baud - """ - cmd_str=''.join(["@ss%",str(p1),"%",str(p2),"%",str(baud),"$!"]) - self.board.sr.write(cmd_str) - self.board.sr.flush() - response= self.board.sr.readline().replace("\r\n","") - if response == "ss OK": - self.connected = True - return True - else: - self.connected = False - return False - - def write(self,data): - """ - sends data to existing software serial instance - using Arduino's 'write' function - """ - if self.connected: - cmd_str=''.join(["@sw%",str(data),"$!"]) - self.board.sr.write(cmd_str) - self.board.sr.flush() - response= self.board.sr.readline().replace("\r\n","") - if response == "ss OK": - return True - else: - return False - - def read(self): - """ - returns first character read from - existing software serial instance - """ - if self.connected: - cmd_str=''.join(["@sr%$!"]) - self.board.sr.write(cmd_str) - self.board.sr.flush() - response= self.board.sr.readline().replace("\r\n","") - if response: - return response - else: - return False - -class Arduino(object): - def __init__(self,baud,port="",timeout=2): - """ - Initializes serial communication with Arduino. - Attempts to self-select COM port, if not specified. - """ - self.baud = baud - self.timeout = timeout - self.ss_connected=False - self.SoftwareSerial = SoftwareSerial(self) - if port == "": - self.findPort() - self.sr = serial.Serial(self.port, self.baud,timeout =self.timeout) - time.sleep(2) - - def findPort(self): - """ - Returns first Arduino found - in system's device list - """ - for pt in list_ports.comports(): - if ("FTDIBUS" in pt[-1]) or ("usbserial" in pt[-1]): - self.port = pt[0] - return - - def digitalWrite(self,pin,val): - """ - Sends digitalWrite command - to digital pin on Arduino - ------------- - inputs: - pin : digital pin number - val : either "HIGH" or "LOW" - """ - if val=="LOW": - pin_ = -pin - else: - pin_ = pin - cmd_str=''.join(["@dw%",str(pin_),"$!"]) - try: - self.sr.write(cmd_str) - self.sr.flush() - except: - pass - - def analogWrite(self,pin,val): - """ - Sends analogWrite pwm command - to pin on Arduino - ------------- - inputs: - pin : pin number - val : integer 0 (off) to 255 (always on) - """ - if val>255: - val=255 - elif val<0: - val=0 - cmd_str=''.join(["@aw%",str(pin),"%",str(val),"$!"]) - try: - self.sr.write(cmd_str) - self.sr.flush() - except: - pass - - def analogRead(self,pin): - """ - Returns the value of a specified - analog pin. - inputs: - pin : analog pin number for measurement - returns: - value: integer from 1 to 1023 - """ - cmd_str=''.join(["@ar%",str(pin),"$!"]) - try: - self.sr.write(cmd_str) - self.sr.flush() - except: - pass - rd = self.sr.readline().replace("\r\n","") - try: - return int(rd) - except: - return 0 - - - def pinMode(self,pin,val): - """ - Sets I/O mode of pin - inputs: - pin: pin number to toggle - val: "INPUT" or "OUTPUT" - """ - if val=="INPUT": - pin_ = -pin - else: - pin_ = pin - cmd_str=''.join(["@pm%",str(pin_),"$!"]) - try: - self.sr.write(cmd_str) - self.sr.flush() - except: - pass - - def pulseIn(self,pin,val): - """ - Reads a pulse from a pin - - inputs: - pin: pin number for pulse measurement - returns: - duration : pulse length measurement - - """ - if val=="LOW": - pin_ = -pin - else: - pin_ = pin - cmd_str=''.join(["@pi%",str(pin_),"$!"]) - try: - self.sr.write(cmd_str) - self.sr.flush() - except: - pass - rd = self.sr.readline().replace("\r\n","") - try: - return float(rd) - except: - return -1 - - def pulseIn_set(self,pin,val): - """ - Sets a digital pin value, then reads the response - as a pulse width. - Useful for some ultrasonic rangefinders, etc. - - inputs: - pin: pin number for pulse measurement - val: "HIGH" or "LOW". Pulse is measured - when this state is detected - returns: - duration : pulse length measurement - - This method will automatically toggle - I/O modes on the pin and precondition the - measurment with a clean LOW/HIGH pulse. - Arduino.pulseIn_set(pin,"HIGH") is - equivalent to the Arduino sketch code: - - pinMode(pin, OUTPUT); - digitalWrite(pin, LOW); - delayMicroseconds(2); - digitalWrite(pin, HIGH); - delayMicroseconds(5); - digitalWrite(pin, LOW); - pinMode(pin, INPUT); - long duration = pulseIn(pin, HIGH); - """ - if val=="LOW": - pin_ = -pin - else: - pin_ = pin - cmd_str=''.join(["@ps%",str(pin_),"$!"]) - try: - self.sr.write(cmd_str) - self.sr.flush() - except: - pass - rd = self.sr.readline().replace("\r\n","") - try: - return float(rd) - except: - return -1 - - def close(self): - self.sr.close() - - def digitalRead(self,pin): - """ - Returns the value of a specified - digital pin. - inputs: - pin : digital pin number for measurement - returns: - value: 0 for "LOW", 1 for "HIGH" - """ - cmd_str=''.join(["@dr%",str(pin),"$!"]) - try: - self.sr.write(cmd_str) - self.sr.flush() - except: - pass - rd = self.sr.readline().replace("\r\n","") - try: - return 1 - int(rd) - except: - return 0 - - -if __name__=="__main__": - board=Arduino(9600) - while True: - time.sleep(0.01) - val=board.analogRead(5)/4 - board.analogWrite(11,val) - \ No newline at end of file +#!/usr/bin/env python +from serial.tools import list_ports +import serial, time + +class Servos(object): + """ + Class for Arduino servo support + """ + def __init__(self, board): + self.board = board + self.sr = board.sr + self.servo_pos = {} + + def attach(self,pin,min = 544, max = 2400): + cmd_str=''.join(["@sva%",str(pin),"%",str(min),"%",str(max),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + rd = self.sr.readline().replace("\r\n","") + try: + position = int(rd) + self.servo_pos[pin] = position + return 1 + except: + return 0 + + def detach(self,pin): + cmd_str=''.join(["@svd%",str(position),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + del self.servo_pos[pin] + + def write(self,pin,angle): + cmd_str=''.join(["@svw%",str(position),"%",str(angle),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + + def writeMicroseconds(self,pin,uS): + cmd_str=''.join(["@svw%",str(position),"%",str(uS),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + + def read(self,pin): + if pin not in servo_pos.keys(): + self.attach(pin) + position = self.servo_pos[pin] + cmd_str=''.join(["@svr%",str(position),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + rd = self.sr.readline().replace("\r\n","") + try: + angle = int(rd) + return angle + except: + return None + +class SoftwareSerial(object): + """ + Class for Arduino software serial functionality + """ + def __init__(self,board): + self.board=board + self.sr = board.sr + self.connected = False + + def begin(self,p1,p2,baud): + """ + Create software serial instance on + specified tx,rx pins, at specified baud + """ + cmd_str=''.join(["@ss%",str(p1),"%",str(p2),"%",str(baud),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + response= self.sr.readline().replace("\r\n","") + if response == "ss OK": + self.connected = True + return True + else: + self.connected = False + return False + + def write(self,data): + """ + sends data to existing software serial instance + using Arduino's 'write' function + """ + if self.connected: + cmd_str=''.join(["@sw%",str(data),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + response= self.sr.readline().replace("\r\n","") + if response == "ss OK": + return True + else: + return False + + def read(self): + """ + returns first character read from + existing software serial instance + """ + if self.connected: + cmd_str=''.join(["@sr%$!"]) + self.sr.write(cmd_str) + self.sr.flush() + response= self.sr.readline().replace("\r\n","") + if response: + return response + else: + return False + +class Arduino(object): + def __init__(self,baud,port="",timeout=2): + """ + Initializes serial communication with Arduino. + Attempts to self-select COM port, if not specified. + """ + self.baud = baud + self.timeout = timeout + self.ss_connected=False + self.SoftwareSerial = SoftwareSerial(self) + self.Servos = Servos(self) + if port == "": + self.findPort() + self.sr = serial.Serial(self.port, self.baud,timeout =self.timeout) + time.sleep(2) + + def findPort(self): + """ + Returns first Arduino found + in system's device list + """ + for pt in list_ports.comports(): + if ("FTDIBUS" in pt[-1]) or ("usbserial" in pt[-1]): + self.port = pt[0] + return + + def digitalWrite(self,pin,val): + """ + Sends digitalWrite command + to digital pin on Arduino + ------------- + inputs: + pin : digital pin number + val : either "HIGH" or "LOW" + """ + if val=="LOW": + pin_ = -pin + else: + pin_ = pin + cmd_str=''.join(["@dw%",str(pin_),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + + def analogWrite(self,pin,val): + """ + Sends analogWrite pwm command + to pin on Arduino + ------------- + inputs: + pin : pin number + val : integer 0 (off) to 255 (always on) + """ + if val>255: + val=255 + elif val<0: + val=0 + cmd_str=''.join(["@aw%",str(pin),"%",str(val),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + + def analogRead(self,pin): + """ + Returns the value of a specified + analog pin. + inputs: + pin : analog pin number for measurement + returns: + value: integer from 1 to 1023 + """ + cmd_str=''.join(["@ar%",str(pin),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + rd = self.sr.readline().replace("\r\n","") + try: + return int(rd) + except: + return 0 + + + def pinMode(self,pin,val): + """ + Sets I/O mode of pin + inputs: + pin: pin number to toggle + val: "INPUT" or "OUTPUT" + """ + if val=="INPUT": + pin_ = -pin + else: + pin_ = pin + cmd_str=''.join(["@pm%",str(pin_),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + + def pulseIn(self,pin,val): + """ + Reads a pulse from a pin + + inputs: + pin: pin number for pulse measurement + returns: + duration : pulse length measurement + + """ + if val=="LOW": + pin_ = -pin + else: + pin_ = pin + cmd_str=''.join(["@pi%",str(pin_),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + rd = self.sr.readline().replace("\r\n","") + try: + return float(rd) + except: + return -1 + + def pulseIn_set(self,pin,val): + """ + Sets a digital pin value, then reads the response + as a pulse width. + Useful for some ultrasonic rangefinders, etc. + + inputs: + pin: pin number for pulse measurement + val: "HIGH" or "LOW". Pulse is measured + when this state is detected + returns: + duration : pulse length measurement + + This method will automatically toggle + I/O modes on the pin and precondition the + measurment with a clean LOW/HIGH pulse. + Arduino.pulseIn_set(pin,"HIGH") is + equivalent to the Arduino sketch code: + + pinMode(pin, OUTPUT); + digitalWrite(pin, LOW); + delayMicroseconds(2); + digitalWrite(pin, HIGH); + delayMicroseconds(5); + digitalWrite(pin, LOW); + pinMode(pin, INPUT); + long duration = pulseIn(pin, HIGH); + """ + if val=="LOW": + pin_ = -pin + else: + pin_ = pin + cmd_str=''.join(["@ps%",str(pin_),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + rd = self.sr.readline().replace("\r\n","") + try: + return float(rd) + except: + return -1 + + def close(self): + self.sr.close() + + def digitalRead(self,pin): + """ + Returns the value of a specified + digital pin. + inputs: + pin : digital pin number for measurement + returns: + value: 0 for "LOW", 1 for "HIGH" + """ + cmd_str=''.join(["@dr%",str(pin),"$!"]) + try: + self.sr.write(cmd_str) + self.sr.flush() + except: + pass + rd = self.sr.readline().replace("\r\n","") + try: + return 1 - int(rd) + except: + return 0 + + +if __name__=="__main__": + board=Arduino(9600) + board.Servos.attach(9) + time.sleep(.1) + print board.Servos.read(9) + board.Servos.write(100) + time.sleep(.1) + print board.Servos.read(9) + board.Servos.write(0) + time.sleep(.1) + print board.Servos.read(9) + board.Servos.write(100) + time.sleep(.1) + print board.Servos.read(9) + board.Servos.write(0) \ No newline at end of file diff --git a/arduino/examples.py b/arduino/examples.py index 6945175..1174e9b 100644 --- a/arduino/examples.py +++ b/arduino/examples.py @@ -1,76 +1,76 @@ -#!/usr/bin/env python -from arduino import Arduino -import time - -def Blink(led_pin,baud): - """ - Blinks an LED in 1 sec intervals - """ - board = Arduino(baud) - while True: - board.digitalWrite(led_pin,"LOW") - print board.digitalRead(led_pin) #confirm LOW (0) - time.sleep(1) - board.digitalWrite(led_pin,"HIGH") - print board.digitalRead(led_pin) #confirm HIGH (1) - time.sleep(1) - -def softBlink(led_pin,baud): - """ - Fades an LED off and on, using - Arduino's analogWrite (PWM) function - """ - board=Arduino(baud) - i=0 - while True: - i+=1 - k=i%510 - if k%5==0: - if k>255: - k=510-k - board.analogWrite(led_pin,k) - -def adjustBrightness(pot_pin,led_pin,baud): - """ - Adjusts brightness of an LED using a - potentiometer - """ - board=Arduino(baud) - while True: - time.sleep(0.01) - val=board.analogRead(pot_pin)/4 - print val - board.analogWrite(led_pin,val) - - -def PingSonar(pw_pin,baud): - """ - Gets distance measurement from Ping))) - ultrasonic rangefinder connected to pw_pin - """ - board = Arduino(baud) - pingPin=pw_pin - while True: - duration = board.pulseIn(pingPin, "HIGH") - inches = duration/72./2. - cent = duration/29./2. - print inches,"inches" - time.sleep(0.1) - -def LCD(tx,baud,ssbaud,message): - """ - Prints to two-line LCD connected to - pin tx - """ - board = Arduino(baud) - board.SoftwareSerial.begin(0,tx,ssbaud) - while True: - board.SoftwareSerial.write(" test ") - - - - -if __name__=="__main__": - #LCD(5,9600,9600," test ") - adjustBrightness(5,11,9600) +#!/usr/bin/env python +from arduino import Arduino +import time + +def Blink(led_pin,baud): + """ + Blinks an LED in 1 sec intervals + """ + board = Arduino(baud) + while True: + board.digitalWrite(led_pin,"LOW") + print board.digitalRead(led_pin) #confirm LOW (0) + time.sleep(1) + board.digitalWrite(led_pin,"HIGH") + print board.digitalRead(led_pin) #confirm HIGH (1) + time.sleep(1) + +def softBlink(led_pin,baud): + """ + Fades an LED off and on, using + Arduino's analogWrite (PWM) function + """ + board=Arduino(baud) + i=0 + while True: + i+=1 + k=i%510 + if k%5==0: + if k>255: + k=510-k + board.analogWrite(led_pin,k) + +def adjustBrightness(pot_pin,led_pin,baud): + """ + Adjusts brightness of an LED using a + potentiometer + """ + board=Arduino(baud) + while True: + time.sleep(0.01) + val=board.analogRead(pot_pin)/4 + print val + board.analogWrite(led_pin,val) + + +def PingSonar(pw_pin,baud): + """ + Gets distance measurement from Ping))) + ultrasonic rangefinder connected to pw_pin + """ + board = Arduino(baud) + pingPin=pw_pin + while True: + duration = board.pulseIn(pingPin, "HIGH") + inches = duration/72./2. + cent = duration/29./2. + print inches,"inches" + time.sleep(0.1) + +def LCD(tx,baud,ssbaud,message): + """ + Prints to two-line LCD connected to + pin tx + """ + board = Arduino(baud) + board.SoftwareSerial.begin(0,tx,ssbaud) + while True: + board.SoftwareSerial.write(" test ") + + + + +if __name__=="__main__": + #LCD(5,9600,9600," test ") + adjustBrightness(5,11,9600) #softBlink(11,9600) \ No newline at end of file diff --git a/prototype/prototype.ino b/prototype/prototype.ino index ff381f4..0048aa2 100644 --- a/prototype/prototype.ino +++ b/prototype/prototype.ino @@ -3,7 +3,8 @@ #include SoftwareSerial *sserial = NULL; - +Servo servos[8]; +int servo_pins[] = {0, 0, 0, 0, 0, 0, 0, 0}; boolean connected = false; int Str2int (String Str_value) @@ -121,6 +122,62 @@ void pulseInSHandler(String data){ Serial.println(duration); } +void SV_add(String data) { + String sdata[3]; + split(sdata,3,data,'%'); + int pin = Str2int(sdata[0]); + int min = Str2int(sdata[1]); + int max = Str2int(sdata[2]); + int position = -1; + for (int i = 0; i<8;i++) { + if (servo_pins[i] == pin) { //reset in place + servos[position].detach(); + servos[position].attach(pin, min, max); + servo_pins[position] = pin; + Serial.println(position); + return; + } + } + for (int i = 0; i<8;i++) { + if (servo_pins[i] == 0) {position = i;break;} // find spot in servo array + } + if (position == -1) {;} //no array position available! + else { + servos[position].attach(pin, min, max); + servo_pins[position] = pin; + Serial.println(position); + } +} + +void SV_remove(String data) { + int position = Str2int(data); + servos[position].detach(); + servo_pins[position] = 0; +} + +void SV_read(String data) { + int position = Str2int(data); + angle = servos[position].read(); + Serial.println(angle); +} + +void SV_write(String data) { + String sdata[2]; + split(sdata,2,data,'%'); + int position = Str2int(sdata[0]); + int angle = Str2int(sdata[1]); + angle = servos[position].write(angle); +} + +void SV_write_ms(String data) { + String sdata[2]; + split(sdata,2,data,'%'); + int position = Str2int(sdata[0]); + int uS = Str2int(sdata[1]); + angle = servos[position].writeMicroseconds(uS); +} + + void SerialParser(void) { char readChar[64]; Serial.readBytesUntil(33,readChar,64); @@ -162,7 +219,22 @@ void SerialParser(void) { } else if (cmd == "sr") { SS_read(data); - } + } + else if (cmd == "sva") { + SV_add(data); + } + else if (cmd == "svr") { + SV_read(data); + } + else if (cmd == "svw") { + SV_write(data); + } + else if (cmd == "svwm") { + SV_write_ms(data); + } + else if (cmd == "svd") { + SV_remove(data); + } }