diff options
Diffstat (limited to 'Pd_firmware/Pd_firmware.pde')
-rw-r--r-- | Pd_firmware/Pd_firmware.pde | 180 |
1 files changed, 91 insertions, 89 deletions
diff --git a/Pd_firmware/Pd_firmware.pde b/Pd_firmware/Pd_firmware.pde index 392fb05..b0c1056 100644 --- a/Pd_firmware/Pd_firmware.pde +++ b/Pd_firmware/Pd_firmware.pde @@ -28,20 +28,30 @@ * used with other programs like Max/MSP, Processing, or whatever can * do serial communications. * - * @authors: Hans-Christoph Steiner <hans@at.or.at> and Jamie Allen <jamie@heavyside.net> + * @authors: Hans-Christoph Steiner <hans@at.or.at> + * help with protocol redesign: Jamie Allen <jamie@heavyside.net> + * key bugfixes: Georg Holzmann <grh@mur.at> + * Gerda Strobl <gerda.strobl@student.tugraz.at> * @date: 2006-05-19 - * @location: STEIM, Amsterdam, Netherlands and New York, NY - * + * @locations: STEIM, Amsterdam, Netherlands + * IDMI/Polytechnic University, Brookyn, NY, USA + * Electrolobby Ars Electronica, Linz, Austria */ /* - * TODO: get digitalInput working * TODO: add pulseIn functionality * 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 "outputMode all 0/1" command * TODO: add cycle markers to mark start of analog, digital, pulseIn, and PWM */ +/* firmware version numbers. The protocol is still changing, so these version + * numbers are important */ +#define MAJOR_VERSION 0 +#define MINOR_VERSION 1 + /* firmata protocol * =============== * data: 0-127 @@ -69,13 +79,13 @@ #define DISABLE_DIGITAL_INPUTS 150 // disable reporting of digital inputs #define ENABLE_DIGITAL_INPUTS 151 // enable reporting of digital inputs /* 152-159 // UNUSED */ -#define DISABLE_ALL_ANALOG_INS 160 // disable reporting on all analog ins -#define ENABLE_ONE_ANALOG_IN 161 // enable reporting for 1 analog in (0) -#define ENABLE_TWO_ANALOG_INS 162 // enable reporting for 2 analog ins (0,1) -#define ENABLE_THREE_ANALOG_INS 163 // enable reporting for 3 analog ins (0-2) -#define ENABLE_FOUR_ANALOG_INS 164 // enable reporting for 4 analog ins (0-3) -#define ENABLE_FIVE_ANALOG_INS 165 // enable reporting for 5 analog ins (0-4) -#define ENABLE_SIX_ANALOG_INS 166 // enable reporting for 6 analog ins (0-5) +#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) /* 167-199 // UNUSED */ #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 @@ -93,21 +103,22 @@ #define SET_PIN_THIRTEEN_TO_OUT 213 // set digital pin 13 to OUTPUT /* 214-228 // UNUSED */ #define OUTPUT_TO_DIGITAL_PINS 229 // next two bytes set digital output data -/* 230-249 // UNUSED */ +/* 230-239 // UNUSED */ +#define REPORT_VERSION 240 // return the firmware version +/* 240-249 // UNUSED */ #define DISABLE_PWM 250 // next byte sets pin # to disable #define ENABLE_PWM 251 // next two bytes set pin # and duty cycle #define DISABLE_SOFTWARE_PWM 252 // next byte sets pin # to disable #define ENABLE_SOFTWARE_PWM 253 // next two bytes set pin # and duty cycle #define SET_SOFTWARE_PWM_FREQ 254 // set master frequency for software PWMs -/* 252-254 // UNUSED */ -#define INPUT_CYCLE_MARKER 255 // input cycle marker +/* 255 // UNUSED */ /* two byte digital output data format * ---------------------- * 0 get ready for digital input bytes (229) - * 1 digitalOut 0-6 bitmask - * 2 digitalOut 7-13 bitmask + * 1 digitalOut 7-13 bitmask + * 2 digitalOut 0-6 bitmask */ /* two byte PWM data format @@ -117,31 +128,34 @@ * 2 duty cycle expressed as 1 byte (255 = 100%) */ - -/* Arduino->Computer byte cycle +/* 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 start of cycle marker (255/11111111) - * 1 digital read from Arduino // 0-6 bitmask - * 2 digital read from Arduino // 7-13 bitmask - * 3 low byte from analog input pin 0 - * 4 high byte from analog input pin 0 - * 5 low byte from analog input pin 1 - * 6 high byte from analog input pin 1 - * 7 low byte from analog input pin 2 - * 8 high byte from analog input pin 2 - * 9 low byte from analog input pin 3 - * 10 high byte from analog input pin 3 - * 11 low byte from analog input pin 4 - * 12 high byte from analog input pin 4 - * 13 low byte from analog input pin 5 - * 14 high byte from analog input pin 5 + * 0 analog input marker + * 1 high byte from analog input pin 0 + * 2 low byte from analog input pin 0 + * 3 high byte from analog input pin 1 + * 4 low byte from analog input pin 1 + * 5 high byte from analog input pin 2 + * 6 low byte from analog input pin 2 + * 7 high byte from analog input pin 3 + * 8 low byte from analog input pin 3 + * 9 high byte from analog input pin 4 + * 10 low byte from analog input pin 4 + * 11 high byte from analog input pin 5 + * 12 low byte from analog input pin 5 */ #define TOTAL_DIGITAL_PINS 14 // for comparing along with INPUT and OUTPUT #define PWM 2 -#define SOFTPWM 3 // maximum number of post-command data bytes #define MAX_DATA_BYTES 2 @@ -185,13 +199,13 @@ void transmitDigitalInput(byte startPin) { 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 - }*/ +// 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); transmitByte = transmitByte + ((1 << i) * digitalData); @@ -220,25 +234,18 @@ void setPinMode(int pin, int mode) { else if( (mode == PWM) && (pin >= 9) && (pin <= 11) ) { digitalPinStatus = digitalPinStatus | (1 << pin); pwmStatus = pwmStatus | (1 << pin); - softPwmStatus = softPwmStatus &~ (1 << pin); pinMode(pin,OUTPUT); } - else if(mode == SOFTPWM) { - digitalPinStatus = digitalPinStatus | (1 << pin); - pwmStatus = pwmStatus &~ (1 << pin); - softPwmStatus = softPwmStatus | (1 << pin); - pinMode(pin,OUTPUT); - } } void setSoftPwm (int pin, byte pulsePeriod) { byte i; /* for(i=0; i<7; ++i) { - mask = 1 << i; - if(digitalPinStatus & mask) { - digitalWrite(i, inputData & mask); - } - } + mask = 1 << i; + if(digitalPinStatus & mask) { + digitalWrite(i, inputData & mask); + } + } */ //read timer type thing @@ -294,7 +301,7 @@ void processInput(byte inputData) { setPinMode(storedInputData[0],INPUT); break; case ENABLE_SOFTWARE_PWM: - setPinMode(storedInputData[1],SOFTPWM); + setPinMode(storedInputData[1],PWM); setSoftPwm(storedInputData[1], storedInputData[0]); break; case DISABLE_SOFTWARE_PWM: @@ -308,24 +315,24 @@ void processInput(byte inputData) { } } else if(inputData < 128) { - if(firstInputByte) { // - for(i=0; i<7; ++i) { - mask = 1 << i; - if(digitalPinStatus & mask) { - digitalWrite(i, inputData & mask); - } - } - firstInputByte = false; - } - else { // + if(firstInputByte) { // output data for pins 7-13 for(i=7; i<TOTAL_DIGITAL_PINS; ++i) { mask = 1 << i; - if( (digitalPinStatus & mask) && !(pwmStatus & mask) && !(softPwmStatus & mask) ) { + 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 { @@ -368,14 +375,14 @@ void processInput(byte inputData) { case ENABLE_DIGITAL_INPUTS: // all digital inputs on digitalInputsEnabled = true; break; - case DISABLE_ALL_ANALOG_INS: // analog input off - case ENABLE_ONE_ANALOG_IN: // analog 0 on - case ENABLE_TWO_ANALOG_INS: // analog 0,1 on - case ENABLE_THREE_ANALOG_INS: // analog 0-2 on - case ENABLE_FOUR_ANALOG_INS: // analog 0-3 on - case ENABLE_FIVE_ANALOG_INS: // analog 0-4 on - case ENABLE_SIX_ANALOG_INS: // analog 0-5 on - analogInputsEnabled = inputData - DISABLE_ALL_ANALOG_INS; + 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 + analogInputsEnabled = inputData - ZERO_ANALOG_INS; break; case ENABLE_PWM: waitForData = 2; // 2 bytes needed (pin#, dutyCycle) @@ -400,6 +407,11 @@ void processInput(byte inputData) { case OUTPUT_TO_DIGITAL_PINS: // bytes to send to digital outputs firstInputByte = true; break; + case REPORT_VERSION: + printByte(REPORT_VERSION); + printByte(MAJOR_VERSION); + printByte(MINOR_VERSION); + break; } } } @@ -423,31 +435,21 @@ void loop() { // read all digital pins, in enabled if(digitalInputsEnabled) { - transmitDigitalInput(0); - checkForInput(); + printByte(ENABLE_DIGITAL_INPUTS); transmitDigitalInput(7); checkForInput(); - } - else if(analogInputsEnabled) { - // filler bytes, since the first thing sent is always the digitalInputs - printByte(0); - printByte(0); - checkForInput(); + transmitDigitalInput(0); + checkForInput(); } - /* get analog in, for the number enabled - */ + /* 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 in Pd // the higher bits should be zeroed so that the 8th bit doesn't get set - printByte(analogData % 128); // mod by 32 for the small byte + printByte(ONE_ANALOG_IN + analogPin); printByte(analogData >> 7); // bitshift the big stuff into the output byte + printByte(analogData % 128); // mod by 32 for the small byte checkForInput(); } - - /* end with the cycle marker, if any of the inputs are enabled */ - if( digitalInputsEnabled || analogInputsEnabled) { - printByte(255); - } } |