[PD-cvs] externals/hardware/arduino/Pd_firmware Pd_firmware.pde, 1.22, 1.23

Hans-Christoph Steiner eighthave at users.sourceforge.net
Tue Feb 20 07:25:58 CET 2007


Update of /cvsroot/pure-data/externals/hardware/arduino/Pd_firmware
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32323

Modified Files:
	Pd_firmware.pde 
Log Message:
stripped down to nothing and started to rebuild from scratch; got digital output working

Index: Pd_firmware.pde
===================================================================
RCS file: /cvsroot/pure-data/externals/hardware/arduino/Pd_firmware/Pd_firmware.pde,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -d -r1.22 -r1.23
*** Pd_firmware.pde	6 Dec 2006 03:29:06 -0000	1.22
--- Pd_firmware.pde	20 Feb 2007 06:25:56 -0000	1.23
***************
*** 1,22 ****
! /* Copyright (C) 2006 Hans-Christoph Steiner 
   *
!  * This library is free software; you can redistribute it and/or
!  * modify it under the terms of the GNU Lesser General Public
!  * License as published by the Free Software Foundation; either
!  * version 2.1 of the License, or (at your option) any later version.
   *
!  * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
!  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
!  * Lesser General Public License for more details.
   *
!  * You should have received a copy of the GNU Lesser General
!  * Public License along with this library; if not, write to the
!  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
!  * Boston, MA  02111-1307  USA
   *
!  * -----------------------------
!  * Firmata, the Arduino firmware
!  * -----------------------------
   * 
   * Firmata turns the Arduino into a Plug-n-Play sensorbox, servo
--- 1,24 ----
! /*
!  * Copyright (C) 2006 Free Software Foundation
   *
!  * This program is free software; you can redistribute it and/or
!  * modify it under the terms of the GNU General Public License
!  * as published by the Free Software Foundation; either version 2
!  * of the License, or (at your option) any later version.
   *
!  * See file LICENSE for further informations on licensing terms.
!  *
!  * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
!  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!  * GNU General Public License for more details.
   *
!  * You should have received a copy of the GNU General Public License
!  * along with this program; if not, write to the Free Software Foundation,
!  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   *
!  * -----------------------------------------------------------
!  * Firmata, the general purpose sensorbox firmware for Arduino
!  * -----------------------------------------------------------
   * 
   * Firmata turns the Arduino into a Plug-n-Play sensorbox, servo
***************
*** 29,34 ****
   * do serial communications.
   *
!  * @authors: Hans-Christoph Steiner <hans at at.or.at>
!  *   help with protocol redesign: Jamie Allen <jamie at heavyside.net>
   *   key bugfixes: Georg Holzmann <grh at mur.at>
   *                 Gerda Strobl <gerda.strobl at student.tugraz.at>
--- 31,36 ----
   * do serial communications.
   *
!  * @author: Hans-Christoph Steiner <hans at at.or.at>
!  *   help with initial protocol redesign: Jamie Allen <jamie at heavyside.net>
   *   key bugfixes: Georg Holzmann <grh at mur.at>
   *                 Gerda Strobl <gerda.strobl at student.tugraz.at>
***************
*** 40,194 ****
  
  /* 
   * 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
!  * TODO: 
   * TODO: add "pinMode all 0/1" command
   * TODO: add cycle markers to mark start of analog, digital, pulseIn, and PWM
!  * TODO: convert to MIDI protocol using SysEx for longer messages
   */
  
  /* cvs version: $Id$ */
  
! /* Version numbers for the protocol.  The protocol is still changing, so these
!  * version numbers are important.  This number can be queried so that host
!  * software can test whether it will be compatible with the currently
!  * installed firmware. */
! #define MAJOR_VERSION 0  // for non-compatible changes
! #define MINOR_VERSION 3  // for backwards compatible changes
  
! /* firmata protocol
!  * =============== 
!  * data: 0-127   
!  * control: 128-255
   */
-   
- /* computer<->Arduino commands
-  * -------------------- */
- /* 128-129 // UNASSIGNED */
- #define SET_PIN_ZERO_TO_IN      130 // set digital pin 0 to INPUT
- #define SET_PIN_ONE_TO_IN       131 // set digital pin 1 to INPUT
- #define SET_PIN_TWO_TO_IN       132 // set digital pin 2 to INPUT
- #define SET_PIN_THREE_TO_IN     133 // set digital pin 3 to INPUT
- #define SET_PIN_FOUR_TO_IN      134 // set digital pin 4 to INPUT
- #define SET_PIN_FIVE_TO_IN      135 // set digital pin 5 to INPUT
- #define SET_PIN_SIX_TO_IN       136 // set digital pin 6 to INPUT
- #define SET_PIN_SEVEN_TO_IN     137 // set digital pin 7 to INPUT
- #define SET_PIN_EIGHT_TO_IN     138 // set digital pin 8 to INPUT
- #define SET_PIN_NINE_TO_IN      139 // set digital pin 9 to INPUT
- #define SET_PIN_TEN_TO_IN       140 // set digital pin 10 to INPUT
- #define SET_PIN_ELEVEN_TO_IN    141 // set digital pin 11 to INPUT
- #define SET_PIN_TWELVE_TO_IN    142 // set digital pin 12 to INPUT
- #define SET_PIN_THIRTEEN_TO_IN  143 // set digital pin 13 to INPUT
- /* 144-149 // UNASSIGNED */
- #define DISABLE_DIGITAL_INPUTS  150 // disable reporting of digital inputs
- #define ENABLE_DIGITAL_INPUTS   151 // enable reporting of digital inputs
- /* 152-159 // UNASSIGNED */
- #define ZERO_ANALOG_INS         160 // disable reporting on all analog ins
- #define ONE_ANALOG_IN           161 // enable reporting for 1 analog in (0)
- #define TWO_ANALOG_INS          162 // enable reporting for 2 analog ins (0,1)
- #define THREE_ANALOG_INS        163 // enable reporting for 3 analog ins (0-2)
- #define FOUR_ANALOG_INS         164 // enable reporting for 4 analog ins (0-3)
- #define FIVE_ANALOG_INS         165 // enable reporting for 5 analog ins (0-4)
- #define SIX_ANALOG_INS          166 // enable reporting for 6 analog ins (0-5)
- #define SEVEN_ANALOG_INS        167 // enable reporting for 6 analog ins (0-6)
- #define EIGHT_ANALOG_INS        168 // enable reporting for 6 analog ins (0-7)
- #define NINE_ANALOG_INS         169 // enable reporting for 6 analog ins (0-8)
- /* 170-199 // UNASSIGNED */
- #define SET_PIN_ZERO_TO_OUT     200 // set digital pin 0 to OUTPUT
- #define SET_PIN_ONE_TO_OUT      201 // set digital pin 1 to OUTPUT
- #define SET_PIN_TWO_TO_OUT      202 // set digital pin 2 to OUTPUT
- #define SET_PIN_THREE_TO_OUT    203 // set digital pin 3 to OUTPUT
- #define SET_PIN_FOUR_TO_OUT     204 // set digital pin 4 to OUTPUT
- #define SET_PIN_FIVE_TO_OUT     205 // set digital pin 5 to OUTPUT
- #define SET_PIN_SIX_TO_OUT      206 // set digital pin 6 to OUTPUT
- #define SET_PIN_SEVEN_TO_OUT    207 // set digital pin 7 to OUTPUT
- #define SET_PIN_EIGHT_TO_OUT    208 // set digital pin 8 to OUTPUT
- #define SET_PIN_NINE_TO_OUT     209 // set digital pin 9 to OUTPUT
- #define SET_PIN_TEN_TO_OUT      210 // set digital pin 10 to OUTPUT
- #define SET_PIN_ELEVEN_TO_OUT   211 // set digital pin 11 to OUTPUT
- #define SET_PIN_TWELVE_TO_OUT   212 // set digital pin 12 to OUTPUT
- #define SET_PIN_THIRTEEN_TO_OUT 213 // set digital pin 13 to OUTPUT
- /* 214-228 // UNASSIGNED */
- #define OUTPUT_TO_DIGITAL_PINS  229 // next two bytes set digital output data 
- /* 230-239 // UNASSIGNED */
- #define REPORT_VERSION          240 // return the firmware version
- /* 240-248 // UNASSIGNED */
- #define SET_PIN_STATE           249 // set a digital pit to INPUT or OUTPUT
- #define DISABLE_PWM             250 // next byte sets pin # to disable
- #define ENABLE_PWM              251 // next two bytes set pin # and duty cycle
- #define RESET                   254 // reset if receive 8 of these bytes
- /* 255 // UNASSIGNED */
  
!  
! /* two byte digital output data format
!  * ----------------------
!  * 0  set digital output bytes (229/OUTPUT_TO_DIGITAL_PINS)
!  * 1  digitalOut 7-13 bitmask 
!  * 2  digitalOut 0-6 bitmask
   */
  
! /* control PWM 
   * ----------------------
!  * 0  send digital input bytes (ENABLE_PWM)
!  * 1  pin # (0-127)
!  * 2  duty cycle expressed as 1 byte (255 = 100%)
   */
  
! /* digital input message format
   * ----------------------
!  * 0   digital input marker (255/11111111)
!  * 1   digital read from Arduino // 7-13 bitmask
!  * 2   digital read from Arduino // 0-6 bitmask
   */
  
! /* analog input message format
   * ----------------------
!  * 0   analog input marker (160 + pin number reported)
!  * 1   high byte from analog input
!  * 2   low byte from analog input
   */
  
  /* version report format
!  * Send a single byte 240, Arduino will reply with:
   * ----------------------
!  * 0  version report header (240)
!  * 1  major version (0-127)
!  * 2  minor version (0-127)
   */
  
! /* PROPOSED PROTOCOL ADDITIONS */
  
! /* set digital pin state (249/SET_PIN_STATE)
   * ----------------------
!  * 0  set digital pin state
!  * 1  pin number (0-127)
!  * 2  state (OUTPUT/INPUT, 0/1) */
  
! /* toggle analogIn reporting (249/SET_PIN_STATE)
   * ----------------------
!  * 0  analogIn reporting mode
!  * 1  pin number (0-127)
!  * 2  state (0/1)
   */
  
! /* control PWM 14-bit
   * ----------------------
!  * 0  send digital input bytes (ENABLE_PWM)
!  * 1  pin # (0-127)
!  * 2  duty cycle, high bits (8-13)
!  * 3  duty cycle, low bits (0-7)
   */
  
! 
! /* pulseIn (uses 32-bit value)
   * ----------------------
!  * 0  pulseIn
!  * 1  bits 24-31 (most significant byte)
!  * 2  bits 16-23
!  * 3  bits 8-15
!  * 4  bits 0-7 (least significant byte)
   */
  
  #define TOTAL_DIGITAL_PINS 14
  
--- 42,173 ----
  
  /* 
+  * 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
!  * TODO: add protocol version reporting
!  * TODO: add device type reporting (i.e. some firmwares will use the Firmata
!  *       protocol, but will only support specific devices, like ultrasound 
!  *       rangefinders or servos)
   * TODO: add "pinMode all 0/1" command
   * 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$ */
  
! /*==========================================================================
!  * 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.
!  *
!  * MIDI format: http://www.harmony-central.com/MIDI/Doc/table1.html
!  * 
!  *                              MIDI       
!  * type                command  channel    first byte            second byte 
!  * -----------------------------------------------------------------------------
!  * analog I/O            0xE0   pin #      LSB(bits 0-6)         MSB(bits 7-13)
!  * digital I/O           0x90   port base  LSB(bits 0-6)         MSB(bits 7-13)
!  * report analog pin     0xC0   pin #      disable/enable(0/1)   - n/a -
!  * report digital ports  0xD0   port base  disable/enable(0/1)   - n/a -
!  *
!  * digital pin mode(I/O) 0xF4   - n/a -    pin # (0-63)          pin state(0=in)
!  * firmware version      0xF9   - n/a -    minor version         major version
!  * system reset          0xFF   - n/a -    - n/a -               - n/a -
!  *
   */
  
! /* 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                        
   */
  
! /*----------------------------------------------------------------------------
!  * DATA MESSAGES */
! 
! /* two byte digital data format
   * ----------------------
!  * 0  digital data, 0x90-0x9F, (x & 0x0F) to get port base number
!  * 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
!  * 1  analog least significant 7 bits
!  * 2  analog most significant 7 bits
   */
  
! /* pulseIn/Out (uses 32-bit value)
   * ----------------------
!  * 0  START_SYSEX (0xF0)
!  * 1  pulseIn (0xFD)
!  * 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)
   */
  
  /* 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)
   */
  
! /*----------------------------------------------------------------------------
!  * 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) 
   */
  
! /* request version report
   * ----------------------
!  * 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
+  * software can test whether it will be compatible with the currently
+  * installed firmware. */
+ #define MAJOR_VERSION 1  // for non-compatible changes
+ #define MINOR_VERSION 0  // for backwards compatible changes
+ 
+ /* total number of digital pins supported */  
  #define TOTAL_DIGITAL_PINS 14
  
***************
*** 196,200 ****
  #define PWM 2
  
! // maximum number of post-command data bytes
  #define MAX_DATA_BYTES 2
  // this flag says the next serial input will be data
--- 175,195 ----
  #define PWM 2
  
! #define DIGITAL_MESSAGE         0x90 // send data for a digital pin
! #define ANALOG_MESSAGE          0xE0 // send data for an analog pin (or PWM)
! //#define PULSE_MESSAGE           0xA0 // proposed pulseIn/Out message (SysEx)
! //#define SHIFTOUT_MESSAGE        0xB0 // proposed shiftOut message (SysEx)
! #define REPORT_ANALOG_PIN       0xC0 // enable analog input by pin #
! #define REPORT_DIGITAL_PORTS    0xD0 // enable digital input by port pair
! #define START_SYSEX             0xF0 // start a MIDI SysEx message
! #define SET_DIGITAL_PIN_MODE    0xF4 // set a digital pin to INPUT or OUTPUT 
! #define END_SYSEX               0xF7 // end a MIDI SysEx message
! #define REPORT_VERSION          0xF9 // report firmware version
! #define SYSTEM_RESET            0xFF // reset from MIDI
! 
! /*==========================================================================
!  * GLOBAL VARIABLES
!  *==========================================================================*/
! 
! // maximum number of post-command data bytes (non-SysEx)
  #define MAX_DATA_BYTES 2
  // this flag says the next serial input will be data
***************
*** 203,216 ****
  byte storedInputData[MAX_DATA_BYTES] = {0,0}; // multi-byte data
  
- // this flag says the first data byte for the digital outs is next
- boolean firstInputByte = false;
- 
- /* store the previously sent digital inputs to compare against the current
-  * digital inputs.  If there is no change, do not transmit. */ 
- byte previousDigitalInputHighByte = 0;
- byte previousDigitalInputLowByte = 0;
- byte digitalInputHighByte = 0;
- byte digitalInputLowByte = 0;
- 
  /* this int serves as a bit-wise array to store pin status
   * 0 = INPUT, 1 = OUTPUT  */
--- 198,201 ----
***************
*** 222,293 ****
  int pwmStatus = 0;
  
- boolean digitalInputsEnabled = true;
- // TODO: convert this to a bit array int, 1=report, 0=no report
- byte analogInputsEnabled = 6;
- 
- byte analogPin;
- int analogData;
- 
- // -------------------------------------------------------------------------
- byte transmitDigitalInput(byte startPin) {
- 	byte i;
- 	byte digitalPin;
- //  byte digitalPinBit;
- 	byte returnByte = 0;
- 	byte digitalData;
- 
- 	for(i=0;i<7;++i) {
- 		digitalPin = i+startPin;
- /*    digitalPinBit = OUTPUT << digitalPin;
- // only read the pin if its set to input
- if(digitalPinStatus & digitalPinBit) {
- digitalData = 0; // pin set to OUTPUT, don't read
- }
- else if( (digitalPin >= 9) && (pwmStatus & (1 << digitalPin)) ) {
- digitalData = 0; // pin set to PWM, don't read
- }*/
- 		if( !(digitalPinStatus & (1 << digitalPin)) ) {
- 			digitalData = (byte) digitalRead(digitalPin);
- 			returnByte = returnByte + ((1 << i) * digitalData);
- 		}
- 	}
- 	return(returnByte);
- }
- 
- 
- 
- // -------------------------------------------------------------------------
- /* 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
-  */
- void setPinMode(int pin, int mode) {
- 	if(mode == INPUT) {
- 		digitalPinStatus = digitalPinStatus &~ (1 << pin);
- 		pwmStatus = pwmStatus &~ (1 << pin);
- 		pinMode(pin,INPUT);
- 	}
- 	else if(mode == OUTPUT) {
- 		digitalPinStatus = digitalPinStatus | (1 << pin);
- 		pwmStatus = pwmStatus &~ (1 << pin);
- 		pinMode(pin,OUTPUT);
- 	}
- 	else if( (mode == PWM) && (pin >= 9) && (pin <= 11) ) {
- 		digitalPinStatus = digitalPinStatus | (1 << pin);
- 		pwmStatus = pwmStatus | (1 << pin);
- 		pinMode(pin,OUTPUT);
- 	}
- // TODO: save status to EEPROM here, if changed
- }
  
  
  /* -------------------------------------------------------------------------
!  * this function checks to see if there is data waiting on the serial port 
!  * then processes all of the stored data
   */
! void checkForInput() {
! 	if(Serial.available()) {  
! 		while(Serial.available()) {
! 			processInput( (byte)Serial.read() );
! 		}
  	}
  }
--- 207,229 ----
  int pwmStatus = 0;
  
  
+ /*==========================================================================
+  * FUNCTIONS                                                                
+  *==========================================================================*/
  
  /* -------------------------------------------------------------------------
!  * output digital bytes received from the serial port
   */
! void outputDigitalBytes(byte pin0_6, byte pin7_13) {
! 	int i;
! 	int mask;
! 	int twoBytesForPorts;
! 	
! 	twoBytesForPorts = pin0_6 + (pin7_13 << 7);
! 	for(i=0; i<14; ++i) {
! 		mask = 1 << i;
! 		if( (digitalPinStatus & mask) && !(pwmStatus & mask) ) {
! 			digitalWrite(i, twoBytesForPorts & mask);
! 		} 
  	}
  }
***************
*** 295,411 ****
  /* -------------------------------------------------------------------------
   * processInput() is called whenever a byte is available on the
!  * Arduino's serial port.  This is where the comm1ands are handled.
   */
! void processInput(byte inputData) {
! 	int i;
! 	int mask;
!   
  	// a few commands have byte(s) of data following the command
! 	if( waitForData > 0) {  
  		waitForData--;
  		storedInputData[waitForData] = inputData;
! 
! 		if(executeMultiByteCommand && (waitForData==0)) {
  			//we got everything
  			switch(executeMultiByteCommand) {
! 			case ENABLE_PWM:
! 				setPinMode(storedInputData[1],PWM);
! 				analogWrite(storedInputData[1], storedInputData[0]);
  				break;
! 			case DISABLE_PWM:
! 				setPinMode(storedInputData[0],INPUT);
  				break;
  			}
  			executeMultiByteCommand = 0;
  		}
! 	}
! 	else if(inputData < 128) {
! 		if(firstInputByte) {
! 			// output data for pins 7-13
! 			for(i=7; i<TOTAL_DIGITAL_PINS; ++i) {
! 				mask = 1 << i;
! 				if( (digitalPinStatus & mask) && !(pwmStatus & mask) ) {
! 					// inputData is a byte and mask is an int, so align the high part of mask
! 					digitalWrite(i, inputData & (mask >> 7));
! 				}        
! 			}
! 			firstInputByte = false;
! 		}
! 		else { //
! 			for(i=0; i<7; ++i) {
! 				mask = 1 << i;
! 				if( (digitalPinStatus & mask) && !(pwmStatus & mask) ) {
! 					digitalWrite(i, inputData & mask);
! 				} 
! 			}
  		}
- 	}
- 	else {
  		switch (inputData) {
! 		case REPORT_VERSION:
! 			Serial.print(REPORT_VERSION, BYTE);
! 			Serial.print(MAJOR_VERSION, BYTE);
! 			Serial.print(MINOR_VERSION, BYTE);
! 			break;
! 		case ENABLE_PWM:
! 			waitForData = 2;  // 2 bytes needed (pin#, dutyCycle) 
  			executeMultiByteCommand = inputData;
  			break;
! 		case DISABLE_PWM:
! 			waitForData = 1;  // 1 byte needed (pin#)
  			executeMultiByteCommand = inputData;
- 			break;      
- 		case OUTPUT_TO_DIGITAL_PINS:   // bytes to send to digital outputs
- 			firstInputByte = true;
- 			break;
- 		case DISABLE_DIGITAL_INPUTS:   // all digital inputs off
- 			digitalInputsEnabled = false;
  			break;
! 		case ENABLE_DIGITAL_INPUTS:    // all digital inputs on
! 			digitalInputsEnabled = true;
! 			break;
! 		case ZERO_ANALOG_INS:   // analog input off
! 		case ONE_ANALOG_IN:     // analog 0 on  
! 		case TWO_ANALOG_INS:    // analog 0,1 on  
! 		case THREE_ANALOG_INS:  // analog 0-2 on  
! 		case FOUR_ANALOG_INS:   // analog 0-3 on  
! 		case FIVE_ANALOG_INS:   // analog 0-4 on  
! 		case SIX_ANALOG_INS:    // analog 0-5 on  
! 		case SEVEN_ANALOG_INS:  // analog 0-6 on  
! 		case EIGHT_ANALOG_INS:  // analog 0-7 on  
! 		case NINE_ANALOG_INS:   // analog 0-8 on  
! 			analogInputsEnabled = inputData - ZERO_ANALOG_INS;
! 			break;
! 		case SET_PIN_ZERO_TO_IN:       // set digital pins to INPUT
! 		case SET_PIN_ONE_TO_IN:
! 		case SET_PIN_TWO_TO_IN:
! 		case SET_PIN_THREE_TO_IN:
! 		case SET_PIN_FOUR_TO_IN:
! 		case SET_PIN_FIVE_TO_IN:
! 		case SET_PIN_SIX_TO_IN:
! 		case SET_PIN_SEVEN_TO_IN:
! 		case SET_PIN_EIGHT_TO_IN:
! 		case SET_PIN_NINE_TO_IN:
! 		case SET_PIN_TEN_TO_IN:
! 		case SET_PIN_ELEVEN_TO_IN:
! 		case SET_PIN_TWELVE_TO_IN:
! 		case SET_PIN_THIRTEEN_TO_IN:
! 			setPinMode(inputData - SET_PIN_ZERO_TO_IN, INPUT);
  			break;
! 		case SET_PIN_ZERO_TO_OUT:      // set digital pins to OUTPUT
! 		case SET_PIN_ONE_TO_OUT:
! 		case SET_PIN_TWO_TO_OUT:
! 		case SET_PIN_THREE_TO_OUT:
! 		case SET_PIN_FOUR_TO_OUT:
! 		case SET_PIN_FIVE_TO_OUT:
! 		case SET_PIN_SIX_TO_OUT:
! 		case SET_PIN_SEVEN_TO_OUT:
! 		case SET_PIN_EIGHT_TO_OUT:
! 		case SET_PIN_NINE_TO_OUT:
! 		case SET_PIN_TEN_TO_OUT:
! 		case SET_PIN_ELEVEN_TO_OUT:
! 		case SET_PIN_TWELVE_TO_OUT:
! 		case SET_PIN_THIRTEEN_TO_OUT:
! 			setPinMode(inputData - SET_PIN_ZERO_TO_OUT, OUTPUT);
  			break;
  		}
--- 231,288 ----
  /* -------------------------------------------------------------------------
   * 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--;
  		storedInputData[waitForData] = inputData;
! 		if( (waitForData==0) && executeMultiByteCommand ) {
  			//we got everything
  			switch(executeMultiByteCommand) {
! 			case ANALOG_MESSAGE:
! 				channel = inputData & 0x0F; // get channel from command byte
  				break;
! 			case DIGITAL_MESSAGE:
! 				outputDigitalBytes(storedInputData[1], storedInputData[0]);
! 				break;
! 			case SET_DIGITAL_PIN_MODE:
! 				setPinMode(storedInputData[1], storedInputData[0]);
! 				break;
! 			case REPORT_ANALOG_PIN:
! 				break;
! 			case REPORT_DIGITAL_PORTS:
  				break;
  			}
  			executeMultiByteCommand = 0;
  		}
! 	} else {
! 		// remove channel info from command byte if less than 0xF0
! 		if(inputData < 0xF0) {
! 			command = inputData & 0xF0;
! 		} else {
! 			command = inputData;
  		}
  		switch (inputData) {
! 		case ANALOG_MESSAGE:
! 		case DIGITAL_MESSAGE:
! 		case SET_DIGITAL_PIN_MODE:
! 			waitForData = 2; // two data bytes needed
  			executeMultiByteCommand = inputData;
  			break;
! 		case REPORT_ANALOG_PIN:
! 		case REPORT_DIGITAL_PORTS:
! 			waitForData = 1; // two data bytes needed
  			executeMultiByteCommand = inputData;
  			break;
! 		case SYSTEM_RESET:
! 			// this doesn't do anything yet
  			break;
! 		case REPORT_VERSION:
! 			Serial.print(REPORT_VERSION, BYTE);
! 			Serial.print(MAJOR_VERSION, BYTE);
! 			Serial.print(MINOR_VERSION, BYTE);
  			break;
  		}
***************
*** 414,426 ****
  
  
! // =========================================================================
  
  // -------------------------------------------------------------------------
  void setup() {
  	byte i;
  
  // TODO: load state from EEPROM here
! 
! 	Serial.begin(115200);	
  
  /* TODO: send digital inputs here, if enabled, to set the initial state on the
--- 291,352 ----
  
  
! /* -------------------------------------------------------------------------
!  * this function checks to see if there is data waiting on the serial port 
!  * then processes all of the stored data
!  */
! 
! /* TODO: switch this to a timer interrupt.  The timer is set in relation to
!  * the bitrate, when the interrupt is triggered, then it runs checkForInput().
!  * Therefore, it only checks for input once per cycle of the serial port.
!  */
! void checkForInput() {
! 	if(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
+  */
+ void setPinMode(byte pin, byte mode) {
+ 	if(mode == INPUT) {
+ 		digitalPinStatus = digitalPinStatus &~ (1 << pin);
+ 		pwmStatus = pwmStatus &~ (1 << pin);
+ 		pinMode(pin,INPUT);
+ 	}
+ 	else if(mode == OUTPUT) {
+ 		digitalPinStatus = digitalPinStatus | (1 << pin);
+ 		pwmStatus = pwmStatus &~ (1 << pin);
+ 		pinMode(pin,OUTPUT);
+ 	}
+ 	else if( mode == PWM ) {
+ 		digitalPinStatus = digitalPinStatus | (1 << pin);
+ 		pwmStatus = pwmStatus | (1 << pin);
+ 		pinMode(pin,OUTPUT);
+ 	}
+ // 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;
+ 	for(i=0; i<count; i++) {
+ 		digitalWrite(13,1);
+ 		delay(onInterval);
+ 		digitalWrite(13,0);
+ 		delay(offInterval);
+ 	}
+ }
+ 
+ /*==========================================================================
+  * SETUP()
+  *==========================================================================*/
  void setup() {
  	byte i;
  
  // TODO: load state from EEPROM here
! 	Serial.begin(115200); // 9600, 14400, 38400, 57600, 115200
  
  /* TODO: send digital inputs here, if enabled, to set the initial state on the
***************
*** 430,475 ****
  // flash the pin 13 with the protocol minor version (add major once > 0)
  	pinMode(13,OUTPUT);
! 	for(i-0; i<MINOR_VERSION; i++) {
! 		digitalWrite(13,1);
! 		delay(100);
! 		digitalWrite(13,0);
! 		delay(200);
! 	}
  	for(i=0; i<TOTAL_DIGITAL_PINS; ++i) {
! 		setPinMode(i,INPUT);
  	}
  }
  
! // -------------------------------------------------------------------------
  void loop() {
- 	checkForInput();  
-   
- 	// read all digital pins, in enabled
- 	if(digitalInputsEnabled) {
- 		digitalInputHighByte = transmitDigitalInput(7);
- 		checkForInput();  
- 		digitalInputLowByte = transmitDigitalInput(0);
- 		checkForInput();  
- 		// only send data if it has changed
- 		if( (digitalInputHighByte != previousDigitalInputHighByte) && 
- 			(digitalInputLowByte != previousDigitalInputLowByte) ) {
- 			Serial.print(ENABLE_DIGITAL_INPUTS, BYTE);
- 			Serial.print(digitalInputHighByte, BYTE);
- 			Serial.print(digitalInputLowByte, BYTE);
- 			previousDigitalInputHighByte = digitalInputHighByte;
- 			previousDigitalInputLowByte = digitalInputLowByte;
- 		}
- 		checkForInput();
- 	}
  
! 	/* get analog in, for the number enabled */
! 	for(analogPin=0; analogPin<analogInputsEnabled; ++analogPin) {
! 		analogData = analogRead(analogPin);
! 		/* 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 */
! 		Serial.print(ONE_ANALOG_IN + analogPin, BYTE);
! 		Serial.print(analogData >> 7, BYTE); // shift high bits into output byte
! 		Serial.print(analogData % 128, BYTE); // mod by 32 for the small byte
! 		checkForInput();
! 	}
  }
--- 356,379 ----
  // flash the pin 13 with the protocol minor version (add major once > 0)
  	pinMode(13,OUTPUT);
! 	pin13strobe(10,5,20); // separator, a quick burst
! 	delay(500);
! 	pin13strobe(MAJOR_VERSION, 200, 400);
! 	delay(500);
! 	pin13strobe(10,5,20); // separator, a quick burst
! 	delay(500);
! 	pin13strobe(MINOR_VERSION, 200, 400);
! 	delay(500);
! 	pin13strobe(10,5,20); // separator, a quick burst
! 	delay(1000);
  	for(i=0; i<TOTAL_DIGITAL_PINS; ++i) {
! 		setPinMode(i,OUTPUT);
  	}
  }
  
! /*==========================================================================
!  * LOOP()
!  *==========================================================================*/
  void loop() {
  
! 	checkForInput();
  }





More information about the Pd-cvs mailing list