From 946e622436abcc8dd308bd92ecf644dc1b29ba73 Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Fri, 1 Aug 2014 00:36:51 -0700 Subject: [PATCH 1/2] initial implementation of analog config protocol --- Firmata.h | 1 + examples/StandardFirmata/StandardFirmata.ino | 89 +++++++++++++++++++- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/Firmata.h b/Firmata.h index acb95691..2dcc9ae3 100644 --- a/Firmata.h +++ b/Firmata.h @@ -49,6 +49,7 @@ #define I2C_REQUEST 0x76 // send an I2C read/write request #define I2C_REPLY 0x77 // a reply to an I2C read request #define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins +#define ANALOG_CONFIG 0x7C // configure analog read and write resolution and reference voltage #define EXTENDED_ANALOG 0x6F // analog write (PWM, Servo, etc) to any pin #define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value #define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value diff --git a/examples/StandardFirmata/StandardFirmata.ino b/examples/StandardFirmata/StandardFirmata.ino index 7450c91a..07db2fd0 100644 --- a/examples/StandardFirmata/StandardFirmata.ino +++ b/examples/StandardFirmata/StandardFirmata.ino @@ -82,6 +82,15 @@ boolean isI2CEnabled = false; signed char queryIndex = -1; unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom() +byte analogReadRes = 10; // default - better to define in Boards.h? +byte analogWriteRes = 8; // default - better to define in Boards.h? +#ifdef DEFAULT +// DEFAULT is not always = 0 +byte analogReferenceVoltage = DEFAULT; // defined in Arduio core for AVRs only +#else +byte analogReferenceVoltage = 0 +#endif + Servo servos[MAX_SERVOS]; /*============================================================================== * FUNCTIONS @@ -448,6 +457,82 @@ void sysexCallback(byte command, byte argc, byte *argv) //Firmata.sendString("Not enough data"); } break; + case ANALOG_CONFIG: + if (argc > 1) { + switch (argv[0]) { + case 0: // set analog reference voltage + // currently analogReference is only definved for AVR boards + // see: http://arduino.cc/en/Reference/AnalogReference + switch (argv[1]) { + // note that the following 5 case values do not equal the actual + // value of the corresponding constant. The constant value may change + // by board type (Mega vs Uno, etc) +#ifdef DEFAULT + case 0: // DEFAULT (5v on 5v boards, 3.3v on 3.3v boards) + analogReference(DEFAULT); + analogReferenceVoltage = DEFAULT; + break; +#endif +#ifdef INTERNAL + case 1: // INTERNAL + analogReference(INTERNAL); + analogReferenceVoltage = INTERNAL; + break; +#endif +#ifdef INTERNAL1V1 + case 2: // INTERNAL1V1 + analogReference(INTERNAL1V1); + analogReferenceVoltage = INTERNAL1V1; + break; +#endif +#ifdef INTERNAL2V56 + case 3: // INTERNAL_2V56 + analogReference(INTERNAL2V56); + analogReferenceVoltage = INTERNAL2V56; + break; +#endif +#ifdef EXTERNAL + case 4: // EXTERNAL (0 to 5V applied to AREF pin) + analogReference(EXTERNAL); + analogReferenceVoltage = EXTERNAL; + break; +#endif + } + + break; + case 1: // query analog reference voltage + Firmata.write(START_SYSEX); + Firmata.write(ANALOG_CONFIG); + Firmata.write(1); // analog reference response + Firmata.write(analogReferenceVoltage); + Firmata.write(END_SYSEX); + break; +#if ARDUINO >= 150 + // to do: need to exclude AVRs + // only available for SAM core boards + // not available for all boards, but will safely default to proper + // resolution for unsupported boards + case 2: // set analog read resolution (defaults to 10 bits for AVR boards) + if (argv[1] > 0 && argv[1] < 33) { + // see: http://arduino.cc/en/Reference/analogReadResolution + // values above the boards capability are truncated + // values below the min supported resolution will be zero padded + analogReadResolution(argv[1]); + analogReadRes = argv[1]; + } + break; + case 3: // set analog write (pwm) resolution (defaults to 8 bits for AVR boards) + if (argv[1] > 0 && argv[1] < 33) { + // see: http://arduino.cc/en/Reference/analogWriteResolution + // values above the boards capability are truncated + // values below the min supported resolution will be zero padded + analogWriteResolution(argv[1]); + analogWriteRes = argv[1]; + } + break; +#endif + } + } case EXTENDED_ANALOG: if (argc > 1) { int val = argv[1]; @@ -468,11 +553,11 @@ void sysexCallback(byte command, byte argc, byte *argv) } if (IS_PIN_ANALOG(pin)) { Firmata.write(ANALOG); - Firmata.write(10); + Firmata.write(analogReadRes); } if (IS_PIN_PWM(pin)) { Firmata.write(PWM); - Firmata.write(8); + Firmata.write(analogWriteRes); } if (IS_PIN_SERVO(pin)) { Firmata.write(SERVO); From 3f09c8f88354ad8f17ef72794f116d3e22da4edd Mon Sep 17 00:00:00 2001 From: Jeff Hoefs Date: Fri, 1 Aug 2014 00:55:02 -0700 Subject: [PATCH 2/2] removed unnecessary ifdefs --- examples/StandardFirmata/StandardFirmata.ino | 9 --------- 1 file changed, 9 deletions(-) diff --git a/examples/StandardFirmata/StandardFirmata.ino b/examples/StandardFirmata/StandardFirmata.ino index 07db2fd0..4f750534 100644 --- a/examples/StandardFirmata/StandardFirmata.ino +++ b/examples/StandardFirmata/StandardFirmata.ino @@ -84,12 +84,7 @@ unsigned int i2cReadDelayTime = 0; // default delay time between i2c read reque byte analogReadRes = 10; // default - better to define in Boards.h? byte analogWriteRes = 8; // default - better to define in Boards.h? -#ifdef DEFAULT -// DEFAULT is not always = 0 byte analogReferenceVoltage = DEFAULT; // defined in Arduio core for AVRs only -#else -byte analogReferenceVoltage = 0 -#endif Servo servos[MAX_SERVOS]; /*============================================================================== @@ -467,12 +462,10 @@ void sysexCallback(byte command, byte argc, byte *argv) // note that the following 5 case values do not equal the actual // value of the corresponding constant. The constant value may change // by board type (Mega vs Uno, etc) -#ifdef DEFAULT case 0: // DEFAULT (5v on 5v boards, 3.3v on 3.3v boards) analogReference(DEFAULT); analogReferenceVoltage = DEFAULT; break; -#endif #ifdef INTERNAL case 1: // INTERNAL analogReference(INTERNAL); @@ -491,12 +484,10 @@ void sysexCallback(byte command, byte argc, byte *argv) analogReferenceVoltage = INTERNAL2V56; break; #endif -#ifdef EXTERNAL case 4: // EXTERNAL (0 to 5V applied to AREF pin) analogReference(EXTERNAL); analogReferenceVoltage = EXTERNAL; break; -#endif } break;