aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Pd_firmware/Makefile8
-rw-r--r--Pd_firmware/Pd_firmware.pde231
-rw-r--r--Pd_firmware/press.wavbin37568 -> 0 bytes
-rw-r--r--arduino.pd146
4 files changed, 230 insertions, 155 deletions
diff --git a/Pd_firmware/Makefile b/Pd_firmware/Makefile
index dada33c..0e4fdc7 100644
--- a/Pd_firmware/Makefile
+++ b/Pd_firmware/Makefile
@@ -43,7 +43,7 @@
# 7. Type "make upload", reset your Arduino board, and press enter to
# upload your program to the Arduino board.
#
-# $Id: Makefile,v 1.3 2007-02-28 04:10:41 eighthave Exp $
+# $Id: Makefile,v 1.4 2007-03-01 05:39:49 eighthave Exp $
PORT = /dev/tty.usbserial-1*
TARGET = Pd_firmware
@@ -95,7 +95,7 @@ AVRDUDE_PROGRAMMER = stk500
AVRDUDE_PORT = $(PORT)
AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
- -b $(UPLOAD_RATE)
+ -b $(UPLOAD_RATE) -q -V
# Program settings
CC = avr-gcc
@@ -123,7 +123,7 @@ ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: build
- qtplay press.wav
+ say "press the button"
make upload
build: applet_files elf hex
@@ -231,7 +231,7 @@ depend:
# for emacs
etags:
make etags_`uname -s`
- etags applet/*.cpp \
+ etags *.pde \
$(ARDUINO_SRC)/*.[ch] \
$(ARDUINO_SRC)/*.cpp \
$(ARDUINO)/lib/targets/libraries/*/*.[ch] \
diff --git a/Pd_firmware/Pd_firmware.pde b/Pd_firmware/Pd_firmware.pde
index a0ca913..775e010 100644
--- a/Pd_firmware/Pd_firmware.pde
+++ b/Pd_firmware/Pd_firmware.pde
@@ -42,8 +42,6 @@
/*
* TODO: debug hardware PWM
- * TODO: convert all non-frequent messages to SysEx (version, pinMode, report enable, etc)
- * TODO: convert to MIDI protocol using SysEx for longer messages
* TODO: add pulseOut functionality for servos
* TODO: add software PWM for servos, etc (servo.h or pulse.h)
* TODO: redesign protocol to accomodate boards with more I/Os
@@ -52,22 +50,25 @@
* protocol, but will only support specific devices, like ultrasound
* rangefinders or servos)
* TODO: add "pinMode all 0/1" command
+ * TODO: try using PIND to get all digitalIns at once
* TODO: add cycle markers to mark start of analog, digital, pulseIn, and PWM
* TODO: use Program Control to load stored profiles from EEPROM
*/
-/* cvs version: $Id: Pd_firmware.pde,v 1.24 2007-02-22 06:16:43 eighthave Exp $ */
+/* cvs version: $Id: Pd_firmware.pde,v 1.25 2007-03-01 05:39:49 eighthave Exp $ */
-/*==========================================================================
+/*==============================================================================
* MESSAGE FORMATS
- *==========================================================================*/
+ *============================================================================*/
-/*----------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
* MAPPING DATA TO MIDI
*
* This protocol uses the MIDI message format, but does not use the whole
- * protocol. Most of the command mappings here will not make sense in terms
- * of MIDI controllers and synths.
+ * protocol. Most of the command mappings here will not be directly usable in
+ * terms of MIDI controllers and synths. It should co-exist with MIDI without
+ * trouble and can be parsed by standard MIDI interpreters. Just some of the
+ * message data is used differently.
*
* MIDI format: http://www.harmony-central.com/MIDI/Doc/table1.html
*
@@ -87,67 +88,78 @@
/* proposed extensions using SysEx
*
- * type SysEx start command data bytes SysEx stop
- * ---------------------------------------------------------------------------
- * pulse I/O 0xF0 0xA0 five 7-bit chunks, LSB first 0xF7
- * shiftOut 0xF0 0xB0
+ * type SysEx start command data bytes SysEx stop
+ * -----------------------------------------------------------------------------
+ * pulse I/O 0xF0 0xA0 five 7-bit chunks, LSB first 0xF7
+ * shiftOut 0xF0 0xF5 dataPin; clockPin; 7-bit LSB; 7-bit MSB 0xF7
*/
-/*----------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
* DATA MESSAGES */
/* two byte digital data format
- * ----------------------
- * 0 digital data, 0x90-0x9F, (x & 0x0F) to get port base number
+ * ----------------------------
+ * 0 digital data, 0x90-0x9F, (MIDI NoteOn, but different data usage)
* 1 digital pins 0-6 bitmask
* 2 digital pins 7-13 bitmask
*/
/* analog 14-bit data format
- * ----------------------
- * 0 analog pin, 0xE0-0xEF, (x & 0x0F) for pin number
+ * -------------------------
+ * 0 analog pin, 0xE0-0xEF, (MIDI Pitch Wheel)
* 1 analog least significant 7 bits
* 2 analog most significant 7 bits
*/
+/* version report format
+ * Send a single byte 0xF9, Arduino will reply with:
+ * -------------------------------------------------
+ * 0 version report header (0xF9) (MIDI Undefined)
+ * 1 minor version (0-127)
+ * 2 major version (0-127)
+ */
+
/* pulseIn/Out (uses 32-bit value)
- * ----------------------
- * 0 START_SYSEX (0xF0)
- * 1 pulseIn (0xFD)
+ * -------------------------------
+ * 0 START_SYSEX (0xF0) (MIDI System Exclusive)
+ * 1 pulseIn/Out (0xA0-0xAF)
* 2 bits 0-6 (least significant byte)
* 3 bits 7-13
* 4 bits 14-20
* 5 bits 21-27
* 6 bits 28-34 (most significant byte)
- * 7 END_SYSEX (0xF7)
+ * 7 END_SYSEX (0xF7) (MIDI End of SysEx - EOX)
*/
-/* version report format
- * Send a single byte 0xF9, Arduino will reply with:
- * ----------------------
- * 0 version report header (0xF9) (MIDI Undefined)
- * 1 minor version (0-127)
- * 2 major version (0-127)
+/* shiftIn/Out (uses 8-bit value)
+ * ------------------------------
+ * 0 START_SYSEX (0xF0)
+ * 1 shiftOut (0xF5)
+ * 2 dataPin (0-127)
+ * 3 clockPin (0-127)
+ * 4 bits 0-6 (least significant byte)
+ * 5 bit 7 (most significant bit)
+ * 6 END_SYSEX (0xF7)
*/
-/*----------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
* CONTROL MESSAGES */
/* set digital pin mode
- * ----------------------
+ * --------------------
* 1 set digital pin mode (0xF4) (MIDI Undefined)
* 2 pin number (0-127)
* 3 state (INPUT/OUTPUT, 0/1)
*/
/* toggle analogIn reporting by pin
- * ----------------------
+ * --------------------------------
* 0 toggle digitalIn reporting (0xC0-0xCF) (MIDI Program Change)
* 1 disable(0)/enable(non-zero)
*/
/* toggle digitalIn reporting by port pairs
- * ----------------------
+ * ----------------------------------------
* 0 toggle digitalIn reporting (0xD0-0xDF) (MIDI Aftertouch)
* 1 disable(0)/enable(non-zero)
*/
@@ -157,9 +169,9 @@
* 0 request version report (0xF9) (MIDI Undefined)
*/
-/*==========================================================================
+/*==============================================================================
* MACROS
- *==========================================================================*/
+ *============================================================================*/
/* Version numbers for the protocol. The protocol is still changing, so these
* version numbers are important. This number can be queried so that host
@@ -169,7 +181,7 @@
#define MINOR_VERSION 0 // for backwards compatible changes
/* total number of pins currently supported */
-#define TOTAL_ANALOG_PINS 16
+#define TOTAL_ANALOG_PINS 6
#define TOTAL_DIGITAL_PINS 14
// for comparing along with INPUT and OUTPUT
@@ -187,9 +199,14 @@
#define REPORT_VERSION 0xF9 // report firmware version
#define SYSTEM_RESET 0xFF // reset from MIDI
-/*==========================================================================
+/*==============================================================================
* GLOBAL VARIABLES
- *==========================================================================*/
+ *============================================================================*/
+
+// circular buffer for receiving bytes from the serial port
+#define RINGBUFFER_MAX 64 // must be a power of 2
+byte ringBuffer[RINGBUFFER_MAX];
+byte readPosition=0, writePosition=0;
// maximum number of post-command data bytes (non-SysEx)
#define MAX_DATA_BYTES 2
@@ -198,9 +215,12 @@ byte waitForData = 0;
byte executeMultiByteCommand = 0; // command to execute after getting multi-byte data
byte storedInputData[MAX_DATA_BYTES] = {0,0}; // multi-byte data
-/* this int serves as a bit-wise array to store pin status
- * 0 = INPUT, 1 = OUTPUT */
-int digitalPinStatus = 0;
+byte previousDigitalInputHighByte = 0;
+byte previousDigitalInputLowByte = 0;
+byte digitalInputHighByte = 0;
+byte digitalInputLowByte = 0;
+unsigned int digitalPinStatus = 65535;// bit-wise array to store pin status 0=INPUT, 1=OUTPUT
+
/* this byte stores the status off whether PWM is on or not
* bit 9 = PWM0, bit 10 = PWM1, bit 11 = PWM2
@@ -208,14 +228,27 @@ int digitalPinStatus = 0;
int pwmStatus = 0;
/* bit-wise array to store pin reporting */
-unsigned int analogPinsToReport = 65536;
+unsigned int analogPinsToReport = 65535;
+/* for reading analogIns */
+byte analogPin = 0;
+int analogData;
+/* interrupt variables */
+volatile int int_counter = 0; // ms counter for scheduling
-/*==========================================================================
+/*==============================================================================
* FUNCTIONS
- *==========================================================================*/
+ *============================================================================*/
+/* -----------------------------------------------------------------------------
+ * output the version message to the serial port
+ */
+void printVersion() {
+ Serial.print(REPORT_VERSION, BYTE);
+ Serial.print(MINOR_VERSION, BYTE);
+ Serial.print(MAJOR_VERSION, BYTE);
+}
-/* -------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
* output digital bytes received from the serial port
*/
void outputDigitalBytes(byte pin0_6, byte pin7_13) {
@@ -223,6 +256,7 @@ void outputDigitalBytes(byte pin0_6, byte pin7_13) {
int mask;
int twoBytesForPorts;
+// this should be converted to use PORTs
twoBytesForPorts = pin0_6 + (pin7_13 << 7);
for(i=0; i<14; ++i) {
mask = 1 << i;
@@ -232,13 +266,13 @@ void outputDigitalBytes(byte pin0_6, byte pin7_13) {
}
}
-/* -------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
* processInput() is called whenever a byte is available on the
* Arduino's serial port. This is where the commands are handled.
*/
void processInput(int inputData) {
int command, channel;
-
+
// a few commands have byte(s) of data following the command
if( (waitForData > 0) && (inputData < 128) ) {
waitForData--;
@@ -250,10 +284,12 @@ void processInput(int inputData) {
channel = inputData & 0x0F; // get channel from command byte
break;
case DIGITAL_MESSAGE:
- outputDigitalBytes(storedInputData[1], storedInputData[0]);
- break;
+ outputDigitalBytes(storedInputData[1], storedInputData[0]); // (LSB, MSB)
+ break;
case SET_DIGITAL_PIN_MODE:
- setPinMode(storedInputData[1], storedInputData[0]);
+ setPinMode(storedInputData[1], storedInputData[0]); // (pin#, mode)
+ //if(storedInputData[0] == INPUT) // enable input if set to INPUT
+ // TODO: enable REPORT_DIGITAL_PORTS
break;
case REPORT_ANALOG_PIN:
break;
@@ -261,7 +297,7 @@ void processInput(int inputData) {
break;
}
executeMultiByteCommand = 0;
- }
+ }
} else {
// remove channel info from command byte if less than 0xF0
if(inputData < 0xF0) {
@@ -285,16 +321,14 @@ void processInput(int inputData) {
// this doesn't do anything yet
break;
case REPORT_VERSION:
- Serial.print(REPORT_VERSION, BYTE);
- Serial.print(MINOR_VERSION, BYTE);
- Serial.print(MAJOR_VERSION, BYTE);
+ printVersion();
break;
}
}
}
-/* -------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
* this function checks to see if there is data waiting on the serial port
* then processes all of the stored data
*/
@@ -304,11 +338,11 @@ void processInput(int inputData) {
* Therefore, it only checks for input once per cycle of the serial port.
*/
void checkForInput() {
- if(Serial.available())
- processInput( Serial.read() );
+ while(Serial.available())
+ processInput( Serial.read() );
}
-// -------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
/* this function sets the pin mode to the correct state and sets the relevant
* bits in the two bit-arrays that track Digital I/O and PWM status
*/
@@ -316,6 +350,7 @@ void setPinMode(byte pin, byte mode) {
if(mode == INPUT) {
digitalPinStatus = digitalPinStatus &~ (1 << pin);
pwmStatus = pwmStatus &~ (1 << pin);
+ digitalWrite(pin,LOW); // turn off pin before switching to INPUT
pinMode(pin,INPUT);
}
else if(mode == OUTPUT) {
@@ -331,27 +366,49 @@ void setPinMode(byte pin, byte mode) {
// TODO: save status to EEPROM here, if changed
}
-// =========================================================================
+// =============================================================================
// used for flashing the pin for the version number
void pin13strobe(int count, int onInterval, int offInterval) {
byte i;
+ pinMode(13, OUTPUT);
for(i=0; i<count; i++) {
+ delay(offInterval);
digitalWrite(13,1);
delay(onInterval);
digitalWrite(13,0);
- delay(offInterval);
}
}
-/*==========================================================================
+// -----------------------------------------------------------------------------
+/* handle timer interrupts - Arduino runs at 16 Mhz, so we have 1000 Overflows
+ * per second... 1/ ((16000000 / 64) / 256) = 1 / 1000 */
+ISR(TIMER2_OVF_vect) {
+ int_counter++;
+};
+
+/*==============================================================================
* SETUP()
- *==========================================================================*/
+ *============================================================================*/
void setup() {
byte i;
// TODO: load state from EEPROM here
- Serial.begin(115200); // 9600, 14400, 38400, 57600, 115200
+ Serial.begin(57600); // 9600, 14400, 38400, 57600, 115200
+
+ /* set up timer interrupt */
+ //Timer2 Settings: Timer Prescaler /64,
+ TCCR2 |= (1<<CS22);
+ TCCR2 &= ~((1<<CS21) | (1<<CS20));
+ // Use normal mode
+ TCCR2 &= ~((1<<WGM21) | (1<<WGM20));
+ // Use internal clock - external clock not used in Arduino
+ ASSR |= (0<<AS2);
+ //Timer2 Overflow Interrupt Enable
+ TIMSK |= (1<<TOIE2) | (0<<OCIE2);
+// RESET_TIMER2;
+ sei();
+
/* TODO: send digital inputs here, if enabled, to set the initial state on the
* host computer, since once in the loop(), the Arduino will only send data on
@@ -369,31 +426,47 @@ void setup() {
delay(500);
pin13strobe(10,5,20); // separator, a quick burst
delay(1000);
+ printVersion();
+
for(i=0; i<TOTAL_DIGITAL_PINS; ++i) {
setPinMode(i,OUTPUT);
}
}
-/*==========================================================================
+/*==============================================================================
* LOOP()
- *==========================================================================*/
+ *============================================================================*/
void loop() {
- int i; // counter for analog pins
- int analogData;
-
- checkForInput();
- /* get analog in, for the number enabled */
- for(i=0; i<TOTAL_ANALOG_PINS; ++i) {
- checkForInput();
- //if( analogPinsToReport & (1 << i) ) {
- analogData = analogRead(i);
- /* These two bytes get converted back into the whole number on host.
- Highest bits should be zeroed so the 8th bit doesn't get set */
- checkForInput();
- Serial.print(ANALOG_MESSAGE + i, BYTE);
- Serial.print(analogData % 128, BYTE); // mod by 32 for the small byte
- Serial.print(analogData >> 7, BYTE); // shift high bits into output byte
+
+/* DIGITALREAD - as fast as possible, check for changes and output them to the
+ * FTDI buffer using serialWrite) */
+
+// this should use _SFR_IO8()
+
+ if(int_counter > 3) {
+
+
+/* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle all
+ * serialReads at once, i.e. empty the buffer */
+ checkForInput();
+
+/* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over 60
+ * bytes. use a timer to sending an event character every 4 ms to trigger the
+ * buffer to dump. */
+
+/* ANALOGREAD - right after the event character, do all of the analogReads().
+ * These only need to be done every 4ms. */
+// for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
+ for(analogPin=0;analogPin<2;analogPin++) {
+ //if( analogPinsToReport & (1 << analogPin) ) {
+ analogData = analogRead(analogPin);
+ Serial.print(ANALOG_MESSAGE + analogPin, BYTE);
+ // These two bytes converted back into the 10-bit value on host
+ Serial.print(analogData & 127, BYTE); // same as analogData % 128
+ Serial.print(analogData >> 7, BYTE);
+ analogPin = (analogPin++) % TOTAL_ANALOG_PINS;
//}
- checkForInput();
+ }
+ int_counter = 0; // reset ms counter
}
}
diff --git a/Pd_firmware/press.wav b/Pd_firmware/press.wav
deleted file mode 100644
index dfb181b..0000000
--- a/Pd_firmware/press.wav
+++ /dev/null
Binary files differ
diff --git a/arduino.pd b/arduino.pd
index 2210291..bd3a913 100644
--- a/arduino.pd
+++ b/arduino.pd
@@ -1,18 +1,17 @@
-#N canvas 602 43 640 372 10;
+#N canvas 365 27 652 384 10;
#X obj 377 9 import hardware flatspace iemlib mapping;
#X text 321 336 released under the GNU GPL;
#X obj 61 19 inlet;
#X obj 61 297 outlet;
#X obj 544 297 outlet;
-#N canvas 382 102 653 373 command 0;
+#N canvas 405 22 673 393 command 0;
#X obj 24 7 inlet;
#X obj 281 289 outlet;
#X obj 210 93 clip 0 1;
#X obj 210 114 int;
-#N canvas 729 244 487 295 digital-out 0;
+#N canvas 729 244 495 303 digital-out 0;
#X obj 26 12 inlet;
#X obj 218 219 outlet;
-#X msg 404 92 229;
#X obj 181 137 trigger bang float;
#X obj 97 172 float;
#X obj 26 31 trigger anything bang;
@@ -21,62 +20,63 @@
#X obj 26 77 route 0 1 2 3 4 5 6 7 8 9 10 11 12 13;
#X obj 181 115 bytemask -----;
#X obj 27 115 bytemask ---------;
-#X connect 0 0 5 0;
-#X connect 2 0 1 0;
-#X connect 3 0 4 0;
-#X connect 3 1 7 0;
-#X connect 4 0 1 0;
-#X connect 5 0 8 0;
-#X connect 5 1 2 0;
-#X connect 6 0 4 0;
-#X connect 6 1 7 0;
-#X connect 7 0 1 0;
-#X connect 8 0 10 0;
-#X connect 8 1 10 1;
-#X connect 8 2 10 2;
-#X connect 8 3 10 3;
-#X connect 8 4 10 4;
-#X connect 8 5 10 5;
-#X connect 8 6 10 6;
-#X connect 8 7 9 0;
-#X connect 8 8 9 1;
-#X connect 8 9 9 2;
-#X connect 8 10 9 3;
-#X connect 8 11 9 4;
-#X connect 8 12 9 5;
-#X connect 8 13 9 6;
-#X connect 9 0 3 0;
-#X connect 10 0 6 0;
-#X restore 377 118 pd digital-out;
-#N canvas 49 547 528 335 pinMode 0;
-#X obj 60 11 inlet;
-#X obj 175 275 outlet;
-#X obj 175 87 unpack float float;
-#X obj 175 176 +;
-#X obj 175 197 + 130;
-#X obj 296 126 * 70;
-#X text 222 198 input commands = 130-143;
-#X text 334 127 output commands = 200-213;
-#X msg 61 229 151;
-#X obj 60 48 trigger bang anything;
-#X obj 61 182 float;
-#X text 142 86 pin#;
-#X text 312 87 mode;
-#X text 89 229 send 151/ENABLE_DIGITAL_INPUT whenever a pin is set
-to input;
-#X obj 61 202 select 0;
-#X connect 0 0 9 0;
+#X msg 404 92 144;
+#X connect 0 0 4 0;
#X connect 2 0 3 0;
-#X connect 2 1 5 0;
-#X connect 2 1 10 1;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 5 0 3 1;
-#X connect 8 0 1 0;
-#X connect 9 0 10 0;
-#X connect 9 1 2 0;
-#X connect 10 0 14 0;
-#X connect 14 0 8 0;
+#X connect 2 1 6 0;
+#X connect 3 0 1 0;
+#X connect 4 0 7 0;
+#X connect 4 1 10 0;
+#X connect 5 0 3 0;
+#X connect 5 1 6 0;
+#X connect 6 0 1 0;
+#X connect 7 0 9 0;
+#X connect 7 1 9 1;
+#X connect 7 2 9 2;
+#X connect 7 3 9 3;
+#X connect 7 4 9 4;
+#X connect 7 5 9 5;
+#X connect 7 6 9 6;
+#X connect 7 7 8 0;
+#X connect 7 8 8 1;
+#X connect 7 9 8 2;
+#X connect 7 10 8 3;
+#X connect 7 11 8 4;
+#X connect 7 12 8 5;
+#X connect 7 13 8 6;
+#X connect 8 0 2 0;
+#X connect 9 0 5 0;
+#X connect 10 0 1 0;
+#X restore 377 118 pd digital-out;
+#N canvas 310 221 536 343 pinMode 0;
+#X obj 190 11 inlet;
+#X obj 289 307 outlet;
+#X obj 60 91 unpack float float;
+#X text 27 90 pin#;
+#X text 177 92 mode;
+#X obj 60 146 moses 128;
+#X obj 165 144 select 0;
+#X msg 165 167 0;
+#X msg 210 167 1;
+#X text 54 125 do bounds checking to be safe;
+#X obj 190 35 trigger list bang;
+#X msg 289 256 244;
+#X obj 138 254 float;
+#X obj 36 202 trigger bang float;
+#X connect 0 0 10 0;
+#X connect 2 0 5 0;
+#X connect 2 1 6 0;
+#X connect 5 0 13 0;
+#X connect 6 0 7 0;
+#X connect 6 1 8 0;
+#X connect 7 0 12 1;
+#X connect 8 0 12 1;
+#X connect 10 0 2 0;
+#X connect 10 1 11 0;
+#X connect 11 0 1 0;
+#X connect 12 0 1 0;
+#X connect 13 0 12 0;
+#X connect 13 1 1 0;
#X restore 280 93 pd pinMode;
#X obj 139 133 + 160;
#X obj 210 135 + 150;
@@ -183,9 +183,8 @@ to input;
#X obj 319 19 inlet;
#X text 306 1 raw input;
#X text 57 1 processed input;
-#X obj 61 136 comport \$1 115200;
#X obj 410 88 loadbang;
-#N canvas 0 22 454 304 report 0;
+#N canvas 0 22 458 308 report 0;
#X obj 95 26 inlet;
#X obj 97 186 print [arduino];
#X msg 93 87 version_1.0;
@@ -204,7 +203,7 @@ to input;
#X connect 4 0 3 0;
#X restore 231 113 pd report firmware version;
#X text 335 299 DEBUG/RAW data (this will change);
-#N canvas 72 70 439 393 make 0;
+#N canvas 72 70 443 397 make 0;
#X obj 79 6 inlet;
#X obj 184 337 outlet;
#X obj 79 72 moses 128;
@@ -365,26 +364,29 @@ to input;
#X connect 9 1 5 0;
#X connect 11 0 1 0;
#X restore 62 199 pd make lists;
-#N canvas 0 22 454 304 check 0;
+#N canvas 0 22 501 245 check 0;
#X obj 47 62 inlet;
#X obj 47 88 route version;
#X obj 47 109 unpack float float;
#X obj 92 153 print [arduino]_WARNING_INCOMPATIBLE_FIRMWARE_VERSION
;
#X obj 47 131 select 1;
+#X text 102 132 <-- this sets the firmware version this is compatible
+with;
#X connect 0 0 1 0;
#X connect 1 0 2 0;
#X connect 2 0 4 0;
#X connect 4 1 3 0;
#X restore 92 242 pd check version;
#X text 10 337 (C) Copyright 2006 Free Software Foundation;
+#X obj 61 136 comport \$1 57600;
#X connect 2 0 5 0;
-#X connect 5 0 9 0;
-#X connect 6 0 9 0;
-#X connect 9 0 4 0;
-#X connect 9 0 14 0;
-#X connect 9 1 12 0;
-#X connect 10 0 11 0;
-#X connect 12 0 5 0;
-#X connect 14 0 15 0;
-#X connect 14 0 3 0;
+#X connect 5 0 16 0;
+#X connect 6 0 16 0;
+#X connect 9 0 10 0;
+#X connect 11 0 5 0;
+#X connect 13 0 14 0;
+#X connect 13 0 3 0;
+#X connect 16 0 4 0;
+#X connect 16 0 13 0;
+#X connect 16 1 11 0;