Changeset 224 for rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples
- Timestamp:
- Apr 30, 2016, 11:29:25 PM (8 years ago)
- Location:
- rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples
- Files:
-
- 22 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.ino
r136 r224 23 23 int previousAnalogValues[TOTAL_ANALOG_PINS]; 24 24 25 byte portStatus[TOTAL_PORTS]; 25 byte portStatus[TOTAL_PORTS]; // each bit: 1=pin is digital input, 0=other/ignore 26 26 byte previousPINs[TOTAL_PORTS]; 27 27 … … 46 46 byte i, port, status; 47 47 48 Firmata.setFirmwareVersion( 0, 1);48 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 49 49 50 50 for (pin = 0; pin < TOTAL_PINS; pin++) { -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.ino
r136 r224 54 54 { 55 55 if (value == 0) { 56 analogInputsToReport = analogInputsToReport & ~ (1 << pin);56 analogInputsToReport = analogInputsToReport & ~ (1 << pin); 57 57 } 58 58 else { // everything but 0 enables reporting of that pin … … 67 67 void setup() 68 68 { 69 Firmata.setFirmwareVersion( 0, 2);69 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 70 70 Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); 71 71 Firmata.attach(REPORT_ANALOG, reportAnalogCallback); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/EchoString/EchoString.ino
r136 r224 22 22 23 23 24 void sysexCallback(byte command, byte argc, byte *argv)24 void sysexCallback(byte command, byte argc, byte *argv) 25 25 { 26 26 Firmata.sendSysex(command, argc, argv); … … 29 29 void setup() 30 30 { 31 Firmata.setFirmwareVersion( 0, 1);31 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 32 32 Firmata.attach(STRING_DATA, stringCallback); 33 33 Firmata.attach(START_SYSEX, sysexCallback); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino
r136 r224 56 56 void outputPort(byte portNumber, byte portValue) 57 57 { 58 portValue = portValue & ~ portStatus[portNumber];58 portValue = portValue & ~ portStatus[portNumber]; 59 59 if (previousPINs[portNumber] != portValue) { 60 60 Firmata.sendDigitalPort(portNumber, portValue); … … 73 73 if (reportPINs[i]) { 74 74 switch (i) { 75 case 0: outputPort(0, PIND & ~ B00000011); break; // ignore Rx/Tx 0/175 case 0: outputPort(0, PIND & ~ B00000011); break; // ignore Rx/Tx 0/1 76 76 case 1: outputPort(1, PINB); break; 77 77 case 2: outputPort(2, PINC); break; … … 105 105 case INPUT: 106 106 pinMode(pin, INPUT); 107 portStatus[port] = portStatus[port] & ~ (1 << (pin - offset));107 portStatus[port] = portStatus[port] & ~ (1 << (pin - offset)); 108 108 break; 109 109 case OUTPUT: … … 113 113 portStatus[port] = portStatus[port] | (1 << (pin - offset)); 114 114 break; 115 115 //case ANALOG: // TODO figure this out 116 116 default: 117 117 Firmata.sendString(""); … … 123 123 void analogWriteCallback(byte pin, int value) 124 124 { 125 setPinModeCallback(pin, P WM);125 setPinModeCallback(pin, PIN_MODE_PWM); 126 126 analogWrite(pin, value); 127 127 } … … 132 132 case 0: // pins 2-7 (don't change Rx/Tx, pins 0 and 1) 133 133 // 0xFF03 == B1111111100000011 0x03 == B00000011 134 PORTD = (value & ~ 0xFF03) | (PORTD & 0x03);134 PORTD = (value & ~ 0xFF03) | (PORTD & 0x03); 135 135 break; 136 136 case 1: // pins 8-13 (14,15 are disabled for the crystal) … … 151 151 { 152 152 if (value == 0) { 153 analogInputsToReport = analogInputsToReport & ~ (1 << pin);153 analogInputsToReport = analogInputsToReport & ~ (1 << pin); 154 154 } 155 155 else { // everything but 0 enables reporting of that pin … … 203 203 * host computer, since once in the loop(), this firmware will only send 204 204 * digital data on change. */ 205 if (reportPINs[0]) outputPort(0, PIND & ~ B00000011); // ignore Rx/Tx 0/1205 if (reportPINs[0]) outputPort(0, PIND & ~ B00000011); // ignore Rx/Tx 0/1 206 206 if (reportPINs[1]) outputPort(1, PINB); 207 207 if (reportPINs[2]) outputPort(2, PINC); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/ServoFirmata/ServoFirmata.ino
r136 r224 13 13 * included in Arduino 0017 14 14 * 15 * TODO add message to configure minPulse/maxPulse/degrees16 *17 15 * This example code is in the public domain. 18 16 */ … … 22 20 23 21 Servo servos[MAX_SERVOS]; 22 byte servoPinMap[TOTAL_PINS]; 23 byte servoCount = 0; 24 24 25 25 void analogWriteCallback(byte pin, int value) 26 26 { 27 if (IS_PIN_ SERVO(pin)) {28 servos[ PIN_TO_SERVO(pin)].write(value);27 if (IS_PIN_DIGITAL(pin)) { 28 servos[servoPinMap[pin]].write(value); 29 29 } 30 } 31 32 void systemResetCallback() 33 { 34 servoCount = 0; 30 35 } 31 36 … … 34 39 byte pin; 35 40 36 Firmata.setFirmwareVersion( 0, 2);41 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 37 42 Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); 43 Firmata.attach(SYSTEM_RESET, systemResetCallback); 38 44 45 Firmata.begin(57600); 46 systemResetCallback(); 47 48 // attach servos from first digital pin up to max number of 49 // servos supported for the board 39 50 for (pin = 0; pin < TOTAL_PINS; pin++) { 40 if (IS_PIN_SERVO(pin)) { 41 servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); 51 if (IS_PIN_DIGITAL(pin)) { 52 if (servoCount < MAX_SERVOS) { 53 servoPinMap[pin] = servoCount; 54 servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin)); 55 servoCount++; 56 } 42 57 } 43 58 } 44 45 Firmata.begin(57600);46 59 } 47 60 … … 51 64 Firmata.processInput(); 52 65 } 53 -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino
r136 r224 28 28 void setup() 29 29 { 30 Firmata.setFirmwareVersion( 0, 1);30 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 31 31 Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); 32 32 Firmata.begin(57600); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino
r136 r224 53 53 void setup() 54 54 { 55 Firmata.setFirmwareVersion( 0, 1);55 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 56 56 Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); 57 57 Firmata.attach(SET_PIN_MODE, setPinModeCallback); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/StandardFirmata/StandardFirmata.ino
r136 r224 1 1 /* 2 * Firmata is a generic protocol for communicating with microcontrollers 3 * from software on a host computer. It is intended to work with 4 * any host computer software package. 5 * 6 * To download a host software package, please clink on the following link 7 * to open the download page in your default browser. 8 * 9 * http://firmata.org/wiki/Download 10 */ 11 12 /* 2 Firmata is a generic protocol for communicating with microcontrollers 3 from software on a host computer. It is intended to work with 4 any host computer software package. 5 6 To download a host software package, please clink on the following link 7 to open the list of Firmata client libraries your default browser. 8 9 https://github.com/firmata/arduino#firmata-client-libraries 10 13 11 Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. 14 12 Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved. 15 13 Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. 16 Copyright (C) 2009-201 1Jeff Hoefs. All rights reserved.14 Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved. 17 15 18 16 This library is free software; you can redistribute it and/or … … 23 21 See file LICENSE.txt for further informations on licensing terms. 24 22 25 formatted using the GNU C formatting and indenting23 Last updated by Jeff Hoefs: January 10th, 2016 26 24 */ 27 28 /*29 * TODO: use Program Control to load stored profiles from EEPROM30 */31 25 32 26 #include <Servo.h> … … 34 28 #include <Firmata.h> 35 29 36 // move the following defines to Firmata.h? 37 #define I2C_WRITE B00000000 38 #define I2C_READ B00001000 39 #define I2C_READ_CONTINUOUSLY B00010000 40 #define I2C_STOP_READING B00011000 41 #define I2C_READ_WRITE_MODE_MASK B00011000 30 #define I2C_WRITE B00000000 31 #define I2C_READ B00001000 32 #define I2C_READ_CONTINUOUSLY B00010000 33 #define I2C_STOP_READING B00011000 34 #define I2C_READ_WRITE_MODE_MASK B00011000 42 35 #define I2C_10BIT_ADDRESS_MODE_MASK B00100000 43 44 #define MAX_QUERIES 8 45 #define MINIMUM_SAMPLING_INTERVAL 10 46 47 #define REGISTER_NOT_SPECIFIED -1 36 #define I2C_END_TX_MASK B01000000 37 #define I2C_STOP_TX 1 38 #define I2C_RESTART_TX 0 39 #define I2C_MAX_QUERIES 8 40 #define I2C_REGISTER_NOT_SPECIFIED -1 41 42 // the minimum interval for sampling analog input 43 #define MINIMUM_SAMPLING_INTERVAL 1 44 48 45 49 46 /*============================================================================== … … 51 48 *============================================================================*/ 52 49 50 #ifdef FIRMATA_SERIAL_FEATURE 51 SerialFirmata serialFeature; 52 #endif 53 53 54 /* analog inputs */ 54 55 int analogInputsToReport = 0; // bitwise array to store pin reporting … … 59 60 60 61 /* pins configuration */ 61 byte pinConfig[TOTAL_PINS]; // configuration of every pin62 62 byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else 63 int pinState[TOTAL_PINS]; // any value that has been written64 63 65 64 /* timer variables */ 66 65 unsigned long currentMillis; // store the current value from millis() 67 66 unsigned long previousMillis; // for comparison with currentMillis 68 int samplingInterval = 19;// how often to run the main loop (in ms)67 unsigned int samplingInterval = 19; // how often to run the main loop (in ms) 69 68 70 69 /* i2c data */ 71 70 struct i2c_device_info { 72 71 byte addr; 73 bytereg;72 int reg; 74 73 byte bytes; 74 byte stopTX; 75 75 }; 76 76 77 77 /* for i2c read continuous more */ 78 i2c_device_info query[ MAX_QUERIES];79 80 byte i2cRxData[ 32];78 i2c_device_info query[I2C_MAX_QUERIES]; 79 80 byte i2cRxData[64]; 81 81 boolean isI2CEnabled = false; 82 82 signed char queryIndex = -1; 83 unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom() 83 // default delay time between i2c read request and Wire.requestFrom() 84 unsigned int i2cReadDelayTime = 0; 84 85 85 86 Servo servos[MAX_SERVOS]; 87 byte servoPinMap[TOTAL_PINS]; 88 byte detachedServos[MAX_SERVOS]; 89 byte detachedServoCount = 0; 90 byte servoCount = 0; 91 92 boolean isResetting = false; 93 94 95 /* utility functions */ 96 void wireWrite(byte data) 97 { 98 #if ARDUINO >= 100 99 Wire.write((byte)data); 100 #else 101 Wire.send(data); 102 #endif 103 } 104 105 byte wireRead(void) 106 { 107 #if ARDUINO >= 100 108 return Wire.read(); 109 #else 110 return Wire.receive(); 111 #endif 112 } 113 86 114 /*============================================================================== 87 115 * FUNCTIONS 88 116 *============================================================================*/ 89 117 90 void readAndReportData(byte address, int theRegister, byte numBytes) { 118 void attachServo(byte pin, int minPulse, int maxPulse) 119 { 120 if (servoCount < MAX_SERVOS) { 121 // reuse indexes of detached servos until all have been reallocated 122 if (detachedServoCount > 0) { 123 servoPinMap[pin] = detachedServos[detachedServoCount - 1]; 124 if (detachedServoCount > 0) detachedServoCount--; 125 } else { 126 servoPinMap[pin] = servoCount; 127 servoCount++; 128 } 129 if (minPulse > 0 && maxPulse > 0) { 130 servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); 131 } else { 132 servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin)); 133 } 134 } else { 135 Firmata.sendString("Max servos attached"); 136 } 137 } 138 139 void detachServo(byte pin) 140 { 141 servos[servoPinMap[pin]].detach(); 142 // if we're detaching the last servo, decrement the count 143 // otherwise store the index of the detached servo 144 if (servoPinMap[pin] == servoCount && servoCount > 0) { 145 servoCount--; 146 } else if (servoCount > 0) { 147 // keep track of detached servos because we want to reuse their indexes 148 // before incrementing the count of attached servos 149 detachedServoCount++; 150 detachedServos[detachedServoCount - 1] = servoPinMap[pin]; 151 } 152 153 servoPinMap[pin] = 255; 154 } 155 156 void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX) { 91 157 // allow I2C requests that don't require a register read 92 158 // for example, some devices using an interrupt pin to signify new data available 93 159 // do not always require the register read so upon interrupt you call Wire.requestFrom() 94 if (theRegister != REGISTER_NOT_SPECIFIED) {160 if (theRegister != I2C_REGISTER_NOT_SPECIFIED) { 95 161 Wire.beginTransmission(address); 96 #if ARDUINO >= 100 97 Wire.write((byte)theRegister); 98 #else 99 Wire.send((byte)theRegister); 100 #endif 101 Wire.endTransmission(); 162 wireWrite((byte)theRegister); 163 Wire.endTransmission(stopTX); // default = true 102 164 // do not set a value of 0 103 165 if (i2cReadDelayTime > 0) { … … 112 174 113 175 // check to be sure correct number of bytes were returned by slave 114 if (numBytes == Wire.available()) { 115 i2cRxData[0] = address; 116 i2cRxData[1] = theRegister; 117 for (int i = 0; i < numBytes; i++) { 118 #if ARDUINO >= 100 119 i2cRxData[2 + i] = Wire.read(); 120 #else 121 i2cRxData[2 + i] = Wire.receive(); 122 #endif 123 } 124 } 125 else { 126 if (numBytes > Wire.available()) { 127 Firmata.sendString("I2C Read Error: Too many bytes received"); 128 } else { 129 Firmata.sendString("I2C Read Error: Too few bytes received"); 130 } 176 if (numBytes < Wire.available()) { 177 Firmata.sendString("I2C: Too many bytes received"); 178 } else if (numBytes > Wire.available()) { 179 Firmata.sendString("I2C: Too few bytes received"); 180 } 181 182 i2cRxData[0] = address; 183 i2cRxData[1] = theRegister; 184 185 for (int i = 0; i < numBytes && Wire.available(); i++) { 186 i2cRxData[2 + i] = wireRead(); 131 187 } 132 188 … … 173 229 174 230 // ----------------------------------------------------------------------------- 231 232 /* disable the i2c pins so they can be used for other functions */ 233 void disableI2CPins() { 234 isI2CEnabled = false; 235 // disable read continuous mode for all devices 236 queryIndex = -1; 237 } 238 239 /* sets bits in a bit array (int) to toggle the reporting of the analogIns 240 */ 241 //void FirmataClass::setAnalogPinReporting(byte pin, byte state) { 242 //} 243 void reportAnalogCallback(byte analogPin, int value) 244 { 245 if (analogPin < TOTAL_ANALOG_PINS) { 246 if (value == 0) { 247 analogInputsToReport = analogInputsToReport & ~ (1 << analogPin); 248 } else { 249 analogInputsToReport = analogInputsToReport | (1 << analogPin); 250 // prevent during system reset or all analog pin values will be reported 251 // which may report noise for unconnected analog pins 252 if (!isResetting) { 253 // Send pin value immediately. This is helpful when connected via 254 // ethernet, wi-fi or bluetooth so pin states can be known upon 255 // reconnecting. 256 Firmata.sendAnalog(analogPin, analogRead(analogPin)); 257 } 258 } 259 } 260 // TODO: save status to EEPROM here, if changed 261 } 262 263 // ----------------------------------------------------------------------------- 175 264 /* sets the pin mode to the correct state and sets the relevant bits in the 176 265 * two bit-arrays that track Digital I/O and PWM status … … 178 267 void setPinModeCallback(byte pin, int mode) 179 268 { 180 if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) { 269 if (Firmata.getPinMode(pin) == PIN_MODE_IGNORE) 270 return; 271 272 if (Firmata.getPinMode(pin) == PIN_MODE_I2C && isI2CEnabled && mode != PIN_MODE_I2C) { 181 273 // disable i2c so pins can be used for other functions 182 274 // the following if statements should reconfigure the pins properly 183 275 disableI2CPins(); 184 276 } 185 if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) { 186 servos[PIN_TO_SERVO(pin)].detach(); 277 if (IS_PIN_DIGITAL(pin) && mode != PIN_MODE_SERVO) { 278 if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) { 279 detachServo(pin); 280 } 187 281 } 188 282 if (IS_PIN_ANALOG(pin)) { 189 reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting283 reportAnalogCallback(PIN_TO_ANALOG(pin), mode == PIN_MODE_ANALOG ? 1 : 0); // turn on/off reporting 190 284 } 191 285 if (IS_PIN_DIGITAL(pin)) { 192 if (mode == INPUT ) {286 if (mode == INPUT || mode == PIN_MODE_PULLUP) { 193 287 portConfigInputs[pin / 8] |= (1 << (pin & 7)); 194 288 } else { … … 196 290 } 197 291 } 198 pinState[pin] = 0;292 Firmata.setPinState(pin, 0); 199 293 switch (mode) { 200 case ANALOG:294 case PIN_MODE_ANALOG: 201 295 if (IS_PIN_ANALOG(pin)) { 202 296 if (IS_PIN_DIGITAL(pin)) { 203 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 297 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 298 #if ARDUINO <= 100 299 // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6 204 300 digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups 205 } 206 pinConfig[pin] = ANALOG; 301 #endif 302 } 303 Firmata.setPinMode(pin, PIN_MODE_ANALOG); 207 304 } 208 305 break; 209 306 case INPUT: 210 307 if (IS_PIN_DIGITAL(pin)) { 211 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 308 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 309 #if ARDUINO <= 100 310 // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6 212 311 digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups 213 pinConfig[pin] = INPUT; 312 #endif 313 Firmata.setPinMode(pin, INPUT); 314 } 315 break; 316 case PIN_MODE_PULLUP: 317 if (IS_PIN_DIGITAL(pin)) { 318 pinMode(PIN_TO_DIGITAL(pin), INPUT_PULLUP); 319 Firmata.setPinMode(pin, PIN_MODE_PULLUP); 320 Firmata.setPinState(pin, 1); 214 321 } 215 322 break; … … 218 325 digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM 219 326 pinMode(PIN_TO_DIGITAL(pin), OUTPUT); 220 pinConfig[pin] = OUTPUT;221 } 222 break; 223 case P WM:327 Firmata.setPinMode(pin, OUTPUT); 328 } 329 break; 330 case PIN_MODE_PWM: 224 331 if (IS_PIN_PWM(pin)) { 225 332 pinMode(PIN_TO_PWM(pin), OUTPUT); 226 333 analogWrite(PIN_TO_PWM(pin), 0); 227 pinConfig[pin] = PWM; 228 } 229 break; 230 case SERVO: 231 if (IS_PIN_SERVO(pin)) { 232 pinConfig[pin] = SERVO; 233 if (!servos[PIN_TO_SERVO(pin)].attached()) { 234 servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); 235 } 236 } 237 break; 238 case I2C: 334 Firmata.setPinMode(pin, PIN_MODE_PWM); 335 } 336 break; 337 case PIN_MODE_SERVO: 338 if (IS_PIN_DIGITAL(pin)) { 339 Firmata.setPinMode(pin, PIN_MODE_SERVO); 340 if (servoPinMap[pin] == 255 || !servos[servoPinMap[pin]].attached()) { 341 // pass -1 for min and max pulse values to use default values set 342 // by Servo library 343 attachServo(pin, -1, -1); 344 } 345 } 346 break; 347 case PIN_MODE_I2C: 239 348 if (IS_PIN_I2C(pin)) { 240 349 // mark the pin as i2c 241 350 // the user must call I2C_CONFIG to enable I2C for a device 242 pinConfig[pin] = I2C; 243 } 351 Firmata.setPinMode(pin, PIN_MODE_I2C); 352 } 353 break; 354 case PIN_MODE_SERIAL: 355 #ifdef FIRMATA_SERIAL_FEATURE 356 serialFeature.handlePinMode(pin, PIN_MODE_SERIAL); 357 #endif 244 358 break; 245 359 default: … … 249 363 } 250 364 365 /* 366 * Sets the value of an individual pin. Useful if you want to set a pin value but 367 * are not tracking the digital port state. 368 * Can only be used on pins configured as OUTPUT. 369 * Cannot be used to enable pull-ups on Digital INPUT pins. 370 */ 371 void setPinValueCallback(byte pin, int value) 372 { 373 if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) { 374 if (Firmata.getPinMode(pin) == OUTPUT) { 375 Firmata.setPinState(pin, value); 376 digitalWrite(PIN_TO_DIGITAL(pin), value); 377 } 378 } 379 } 380 251 381 void analogWriteCallback(byte pin, int value) 252 382 { 253 383 if (pin < TOTAL_PINS) { 254 switch ( pinConfig[pin]) {255 case SERVO:256 if (IS_PIN_ SERVO(pin))257 servos[ PIN_TO_SERVO(pin)].write(value);258 pinState[pin] = value;384 switch (Firmata.getPinMode(pin)) { 385 case PIN_MODE_SERVO: 386 if (IS_PIN_DIGITAL(pin)) 387 servos[servoPinMap[pin]].write(value); 388 Firmata.setPinState(pin, value); 259 389 break; 260 case P WM:390 case PIN_MODE_PWM: 261 391 if (IS_PIN_PWM(pin)) 262 392 analogWrite(PIN_TO_PWM(pin), value); 263 pinState[pin] = value;393 Firmata.setPinState(pin, value); 264 394 break; 265 395 } … … 269 399 void digitalWriteCallback(byte port, int value) 270 400 { 271 byte pin, lastPin, mask = 1, pinWriteMask = 0;401 byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0; 272 402 273 403 if (port < TOTAL_PORTS) { … … 278 408 // do not disturb non-digital pins (eg, Rx & Tx) 279 409 if (IS_PIN_DIGITAL(pin)) { 280 // only write to OUTPUT and INPUT (enables pullup)281 410 // do not touch pins in PWM, ANALOG, SERVO or other modes 282 if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) { 283 pinWriteMask |= mask; 284 pinState[pin] = ((byte)value & mask) ? 1 : 0; 411 if (Firmata.getPinMode(pin) == OUTPUT || Firmata.getPinMode(pin) == INPUT) { 412 pinValue = ((byte)value & mask) ? 1 : 0; 413 if (Firmata.getPinMode(pin) == OUTPUT) { 414 pinWriteMask |= mask; 415 } else if (Firmata.getPinMode(pin) == INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) { 416 // only handle INPUT here for backwards compatibility 417 #if ARDUINO > 100 418 pinMode(pin, INPUT_PULLUP); 419 #else 420 // only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier 421 pinWriteMask |= mask; 422 #endif 423 } 424 Firmata.setPinState(pin, pinValue); 285 425 } 286 426 } … … 293 433 294 434 // ----------------------------------------------------------------------------- 295 /* sets bits in a bit array (int) to toggle the reporting of the analogIns296 */297 //void FirmataClass::setAnalogPinReporting(byte pin, byte state) {298 //}299 void reportAnalogCallback(byte analogPin, int value)300 {301 if (analogPin < TOTAL_ANALOG_PINS) {302 if (value == 0) {303 analogInputsToReport = analogInputsToReport &~ (1 << analogPin);304 } else {305 analogInputsToReport = analogInputsToReport | (1 << analogPin);306 }307 }308 // TODO: save status to EEPROM here, if changed309 }310 435 311 436 void reportDigitalCallback(byte port, int value) … … 313 438 if (port < TOTAL_PORTS) { 314 439 reportPINs[port] = (byte)value; 440 // Send port value immediately. This is helpful when connected via 441 // ethernet, wi-fi or bluetooth so pin states can be known upon 442 // reconnecting. 443 if (value) outputPort(port, readPort(port, portConfigInputs[port]), true); 315 444 } 316 445 // do not disable analog reporting on these 8 pins, to allow some … … 322 451 } 323 452 453 // ----------------------------------------------------------------------------- 454 455 void enableI2CPins() 456 { 457 byte i; 458 // is there a faster way to do this? would probaby require importing 459 // Arduino.h to get SCL and SDA pins 460 for (i = 0; i < TOTAL_PINS; i++) { 461 if (IS_PIN_I2C(i)) { 462 // mark pins as i2c so they are ignore in non i2c data requests 463 setPinModeCallback(i, PIN_MODE_I2C); 464 } 465 } 466 467 isI2CEnabled = true; 468 469 Wire.begin(); 470 } 471 324 472 /*============================================================================== 325 473 * SYSEX-BASED commands … … 329 477 { 330 478 byte mode; 479 byte stopTX; 331 480 byte slaveAddress; 332 byte slaveRegister;333 481 byte data; 482 int slaveRegister; 334 483 unsigned int delayTime; 335 484 … … 338 487 mode = argv[1] & I2C_READ_WRITE_MODE_MASK; 339 488 if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) { 340 Firmata.sendString("10-bit addressing mode is not yet supported");489 Firmata.sendString("10-bit addressing not supported"); 341 490 return; 342 491 } 343 492 else { 344 493 slaveAddress = argv[0]; 494 } 495 496 // need to invert the logic here since 0 will be default for client 497 // libraries that have not updated to add support for restart tx 498 if (argv[1] & I2C_END_TX_MASK) { 499 stopTX = I2C_RESTART_TX; 500 } 501 else { 502 stopTX = I2C_STOP_TX; // default 345 503 } 346 504 … … 350 508 for (byte i = 2; i < argc; i += 2) { 351 509 data = argv[i] + (argv[i + 1] << 7); 352 #if ARDUINO >= 100 353 Wire.write(data); 354 #else 355 Wire.send(data); 356 #endif 510 wireWrite(data); 357 511 } 358 512 Wire.endTransmission(); … … 364 518 slaveRegister = argv[2] + (argv[3] << 7); 365 519 data = argv[4] + (argv[5] << 7); // bytes to read 366 readAndReportData(slaveAddress, (int)slaveRegister, data);367 520 } 368 521 else { 369 522 // a slave register is NOT specified 523 slaveRegister = I2C_REGISTER_NOT_SPECIFIED; 370 524 data = argv[2] + (argv[3] << 7); // bytes to read 371 readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);372 525 } 526 readAndReportData(slaveAddress, (int)slaveRegister, data, stopTX); 373 527 break; 374 528 case I2C_READ_CONTINUOUSLY: 375 if ((queryIndex + 1) >= MAX_QUERIES) {529 if ((queryIndex + 1) >= I2C_MAX_QUERIES) { 376 530 // too many queries, just ignore 377 531 Firmata.sendString("too many queries"); 378 532 break; 379 533 } 534 if (argc == 6) { 535 // a slave register is specified 536 slaveRegister = argv[2] + (argv[3] << 7); 537 data = argv[4] + (argv[5] << 7); // bytes to read 538 } 539 else { 540 // a slave register is NOT specified 541 slaveRegister = (int)I2C_REGISTER_NOT_SPECIFIED; 542 data = argv[2] + (argv[3] << 7); // bytes to read 543 } 380 544 queryIndex++; 381 545 query[queryIndex].addr = slaveAddress; 382 query[queryIndex].reg = argv[2] + (argv[3] << 7); 383 query[queryIndex].bytes = argv[4] + (argv[5] << 7); 546 query[queryIndex].reg = slaveRegister; 547 query[queryIndex].bytes = data; 548 query[queryIndex].stopTX = stopTX; 384 549 break; 385 550 case I2C_STOP_READING: … … 390 555 queryIndex = -1; 391 556 } else { 557 queryIndexToSkip = 0; 392 558 // if read continuous mode is enabled for multiple devices, 393 559 // determine which device to stop reading and remove it's data from 394 560 // the array, shifiting other array data to fill the space 395 561 for (byte i = 0; i < queryIndex + 1; i++) { 396 if (query[i].addr = slaveAddress) {562 if (query[i].addr == slaveAddress) { 397 563 queryIndexToSkip = i; 398 564 break; … … 401 567 402 568 for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) { 403 if (i < MAX_QUERIES) {569 if (i < I2C_MAX_QUERIES) { 404 570 query[i].addr = query[i + 1].addr; 405 query[i].reg = query[i + 1]. addr;571 query[i].reg = query[i + 1].reg; 406 572 query[i].bytes = query[i + 1].bytes; 573 query[i].stopTX = query[i + 1].stopTX; 407 574 } 408 575 } … … 433 600 int maxPulse = argv[3] + (argv[4] << 7); 434 601 435 if (IS_PIN_SERVO(pin)) { 436 if (servos[PIN_TO_SERVO(pin)].attached()) 437 servos[PIN_TO_SERVO(pin)].detach(); 438 servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); 439 setPinModeCallback(pin, SERVO); 602 if (IS_PIN_DIGITAL(pin)) { 603 if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) { 604 detachServo(pin); 605 } 606 attachServo(pin, minPulse, maxPulse); 607 setPinModeCallback(pin, PIN_MODE_SERVO); 440 608 } 441 609 } … … 466 634 Firmata.write((byte)INPUT); 467 635 Firmata.write(1); 636 Firmata.write((byte)PIN_MODE_PULLUP); 637 Firmata.write(1); 468 638 Firmata.write((byte)OUTPUT); 469 639 Firmata.write(1); 470 640 } 471 641 if (IS_PIN_ANALOG(pin)) { 472 Firmata.write( ANALOG);473 Firmata.write(10); 642 Firmata.write(PIN_MODE_ANALOG); 643 Firmata.write(10); // 10 = 10-bit resolution 474 644 } 475 645 if (IS_PIN_PWM(pin)) { 476 Firmata.write(P WM);477 Firmata.write(8); 478 } 479 if (IS_PIN_ SERVO(pin)) {480 Firmata.write( SERVO);646 Firmata.write(PIN_MODE_PWM); 647 Firmata.write(8); // 8 = 8-bit resolution 648 } 649 if (IS_PIN_DIGITAL(pin)) { 650 Firmata.write(PIN_MODE_SERVO); 481 651 Firmata.write(14); 482 652 } 483 653 if (IS_PIN_I2C(pin)) { 484 Firmata.write(I2C); 485 Firmata.write(1); // to do: determine appropriate value 486 } 654 Firmata.write(PIN_MODE_I2C); 655 Firmata.write(1); // TODO: could assign a number to map to SCL or SDA 656 } 657 #ifdef FIRMATA_SERIAL_FEATURE 658 serialFeature.handleCapability(pin); 659 #endif 487 660 Firmata.write(127); 488 661 } … … 496 669 Firmata.write(pin); 497 670 if (pin < TOTAL_PINS) { 498 Firmata.write( (byte)pinConfig[pin]);499 Firmata.write((byte) pinState[pin]& 0x7F);500 if ( pinState[pin] & 0xFF80) Firmata.write((byte)(pinState[pin]>> 7) & 0x7F);501 if ( pinState[pin] & 0xC000) Firmata.write((byte)(pinState[pin]>> 14) & 0x7F);671 Firmata.write(Firmata.getPinMode(pin)); 672 Firmata.write((byte)Firmata.getPinState(pin) & 0x7F); 673 if (Firmata.getPinState(pin) & 0xFF80) Firmata.write((byte)(Firmata.getPinState(pin) >> 7) & 0x7F); 674 if (Firmata.getPinState(pin) & 0xC000) Firmata.write((byte)(Firmata.getPinState(pin) >> 14) & 0x7F); 502 675 } 503 676 Firmata.write(END_SYSEX); … … 512 685 Firmata.write(END_SYSEX); 513 686 break; 514 } 515 } 516 517 void enableI2CPins() 518 { 519 byte i; 520 // is there a faster way to do this? would probaby require importing 521 // Arduino.h to get SCL and SDA pins 522 for (i = 0; i < TOTAL_PINS; i++) { 523 if (IS_PIN_I2C(i)) { 524 // mark pins as i2c so they are ignore in non i2c data requests 525 setPinModeCallback(i, I2C); 526 } 527 } 528 529 isI2CEnabled = true; 530 531 // is there enough time before the first I2C request to call this here? 532 Wire.begin(); 533 } 534 535 /* disable the i2c pins so they can be used for other functions */ 536 void disableI2CPins() { 537 isI2CEnabled = false; 538 // disable read continuous mode for all devices 539 queryIndex = -1; 540 // uncomment the following if or when the end() method is added to Wire library 541 // Wire.end(); 542 } 687 688 case SERIAL_MESSAGE: 689 #ifdef FIRMATA_SERIAL_FEATURE 690 serialFeature.handleSysex(command, argc, argv); 691 #endif 692 break; 693 } 694 } 695 543 696 544 697 /*============================================================================== … … 548 701 void systemResetCallback() 549 702 { 703 isResetting = true; 704 550 705 // initialize a defalt state 551 706 // TODO: option to load config from EEPROM instead of default 707 708 #ifdef FIRMATA_SERIAL_FEATURE 709 serialFeature.reset(); 710 #endif 711 552 712 if (isI2CEnabled) { 553 713 disableI2CPins(); 554 714 } 715 555 716 for (byte i = 0; i < TOTAL_PORTS; i++) { 556 reportPINs[i] = false; 557 portConfigInputs[i] = 0; 717 reportPINs[i] = false; // by default, reporting off 718 portConfigInputs[i] = 0; // until activated 558 719 previousPINs[i] = 0; 559 720 } 560 // pins with analog capability default to analog input 561 // otherwise, pins default to digital output 721 562 722 for (byte i = 0; i < TOTAL_PINS; i++) { 723 // pins with analog capability default to analog input 724 // otherwise, pins default to digital output 563 725 if (IS_PIN_ANALOG(i)) { 564 726 // turns off pullup, configures everything 565 setPinModeCallback(i, ANALOG);566 } else {727 setPinModeCallback(i, PIN_MODE_ANALOG); 728 } else if (IS_PIN_DIGITAL(i)) { 567 729 // sets the output to 0, configures portConfigInputs 568 730 setPinModeCallback(i, OUTPUT); 569 731 } 732 733 servoPinMap[i] = 255; 570 734 } 571 735 // by default, do not report any analog inputs 572 736 analogInputsToReport = 0; 737 738 detachedServoCount = 0; 739 servoCount = 0; 573 740 574 741 /* send digital inputs to set the initial state on the host computer, … … 581 748 } 582 749 */ 750 isResetting = false; 583 751 } 584 752 585 753 void setup() 586 754 { 587 Firmata.setFirmwareVersion(FIRMATA_ MAJOR_VERSION, FIRMATA_MINOR_VERSION);755 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 588 756 589 757 Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); … … 592 760 Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); 593 761 Firmata.attach(SET_PIN_MODE, setPinModeCallback); 762 Firmata.attach(SET_DIGITAL_PIN_VALUE, setPinValueCallback); 594 763 Firmata.attach(START_SYSEX, sysexCallback); 595 764 Firmata.attach(SYSTEM_RESET, systemResetCallback); 596 765 766 // to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega, 767 // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this: 768 // Serial1.begin(57600); 769 // Firmata.begin(Serial1); 770 // However do not do this if you are using SERIAL_MESSAGE 771 597 772 Firmata.begin(57600); 773 while (!Serial) { 774 ; // wait for serial port to connect. Needed for ATmega32u4-based boards and Arduino 101 775 } 776 598 777 systemResetCallback(); // reset to default config 599 778 } … … 610 789 checkDigitalInputs(); 611 790 612 /* S ERIALREAD - processing incoming messagse as soon as possible, while still791 /* STREAMREAD - processing incoming messagse as soon as possible, while still 613 792 * checking digital inputs. */ 614 793 while (Firmata.available()) 615 794 Firmata.processInput(); 616 795 617 /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over 618 * 60 bytes. use a timer to sending an event character every 4 ms to 619 * trigger the buffer to dump. */ 796 // TODO - ensure that Stream buffer doesn't go over 60 bytes 620 797 621 798 currentMillis = millis(); … … 624 801 /* ANALOGREAD - do all analogReads() at the configured sampling interval */ 625 802 for (pin = 0; pin < TOTAL_PINS; pin++) { 626 if (IS_PIN_ANALOG(pin) && pinConfig[pin] ==ANALOG) {803 if (IS_PIN_ANALOG(pin) && Firmata.getPinMode(pin) == PIN_MODE_ANALOG) { 627 804 analogPin = PIN_TO_ANALOG(pin); 628 805 if (analogInputsToReport & (1 << analogPin)) { … … 634 811 if (queryIndex > -1) { 635 812 for (byte i = 0; i < queryIndex + 1; i++) { 636 readAndReportData(query[i].addr, query[i].reg, query[i].bytes); 637 } 638 } 639 } 640 } 813 readAndReportData(query[i].addr, query[i].reg, query[i].bytes, query[i].stopTX); 814 } 815 } 816 } 817 818 #ifdef FIRMATA_SERIAL_FEATURE 819 serialFeature.update(); 820 #endif 821 }
Note:
See TracChangeset
for help on using the changeset viewer.