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.
6 To download a host software package, please click on the following link
7 to open the list of Firmata client libraries in your default browser.
9 https://github.com/firmata/arduino#firmata-client-libraries
11 Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
12 Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
13 Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
14 Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved.
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of the GNU Lesser General Public
18 License as published by the Free Software Foundation; either
19 version 2.1 of the License, or (at your option) any later version.
21 See file LICENSE.txt for further informations on licensing terms.
23 Last updated August 17th, 2017
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
35 #define I2C_10BIT_ADDRESS_MODE_MASK B00100000
36 #define I2C_END_TX_MASK B01000000
38 #define I2C_RESTART_TX 0
39 #define I2C_MAX_QUERIES 8
40 #define I2C_REGISTER_NOT_SPECIFIED -1
42 // the minimum interval for sampling analog input
43 #define MINIMUM_SAMPLING_INTERVAL 1
46 /*==============================================================================
48 *============================================================================*/
50 #ifdef FIRMATA_SERIAL_FEATURE
51 SerialFirmata serialFeature;
55 int analogInputsToReport = 0; // bitwise array to store pin reporting
57 /* digital input ports */
58 byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence
59 byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent
61 /* pins configuration */
62 byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
65 unsigned long currentMillis; // store the current value from millis()
66 unsigned long previousMillis; // for comparison with currentMillis
67 unsigned int samplingInterval = 19; // how often to run the main loop (in ms)
70 struct i2c_device_info {
77 /* for i2c read continuous more */
78 i2c_device_info query[I2C_MAX_QUERIES];
81 boolean isI2CEnabled = false;
82 signed char queryIndex = -1;
83 // default delay time between i2c read request and Wire.requestFrom()
84 unsigned int i2cReadDelayTime = 0;
86 Servo servos[MAX_SERVOS];
87 byte servoPinMap[TOTAL_PINS];
88 byte detachedServos[MAX_SERVOS];
89 byte detachedServoCount = 0;
92 boolean isResetting = false;
94 // Forward declare a few functions to avoid compiler errors with older versions
95 // of the Arduino IDE.
96 void setPinModeCallback(byte, int);
97 void reportAnalogCallback(byte analogPin, int value);
98 void sysexCallback(byte, byte, byte*);
100 /* utility functions */
101 void wireWrite(byte data)
104 Wire.write((byte)data);
115 return Wire.receive();
119 /*==============================================================================
121 *============================================================================*/
123 void attachServo(byte pin, int minPulse, int maxPulse)
125 if (servoCount < MAX_SERVOS) {
126 // reuse indexes of detached servos until all have been reallocated
127 if (detachedServoCount > 0) {
128 servoPinMap[pin] = detachedServos[detachedServoCount - 1];
129 if (detachedServoCount > 0) detachedServoCount--;
131 servoPinMap[pin] = servoCount;
134 if (minPulse > 0 && maxPulse > 0) {
135 servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
137 servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin));
140 Firmata.sendString("Max servos attached");
144 void detachServo(byte pin)
146 servos[servoPinMap[pin]].detach();
147 // if we're detaching the last servo, decrement the count
148 // otherwise store the index of the detached servo
149 if (servoPinMap[pin] == servoCount && servoCount > 0) {
151 } else if (servoCount > 0) {
152 // keep track of detached servos because we want to reuse their indexes
153 // before incrementing the count of attached servos
154 detachedServoCount++;
155 detachedServos[detachedServoCount - 1] = servoPinMap[pin];
158 servoPinMap[pin] = 255;
164 // is there a faster way to do this? would probaby require importing
165 // Arduino.h to get SCL and SDA pins
166 for (i = 0; i < TOTAL_PINS; i++) {
168 // mark pins as i2c so they are ignore in non i2c data requests
169 setPinModeCallback(i, PIN_MODE_I2C);
178 /* disable the i2c pins so they can be used for other functions */
179 void disableI2CPins() {
180 isI2CEnabled = false;
181 // disable read continuous mode for all devices
185 void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX) {
186 // allow I2C requests that don't require a register read
187 // for example, some devices using an interrupt pin to signify new data available
188 // do not always require the register read so upon interrupt you call Wire.requestFrom()
189 if (theRegister != I2C_REGISTER_NOT_SPECIFIED) {
190 Wire.beginTransmission(address);
191 wireWrite((byte)theRegister);
192 Wire.endTransmission(stopTX); // default = true
193 // do not set a value of 0
194 if (i2cReadDelayTime > 0) {
195 // delay is necessary for some devices such as WiiNunchuck
196 delayMicroseconds(i2cReadDelayTime);
199 theRegister = 0; // fill the register with a dummy value
202 Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom
204 // check to be sure correct number of bytes were returned by slave
205 if (numBytes < Wire.available()) {
206 Firmata.sendString("I2C: Too many bytes received");
207 } else if (numBytes > Wire.available()) {
208 Firmata.sendString("I2C: Too few bytes received");
211 i2cRxData[0] = address;
212 i2cRxData[1] = theRegister;
214 for (int i = 0; i < numBytes && Wire.available(); i++) {
215 i2cRxData[2 + i] = wireRead();
218 // send slave address, register and received bytes
219 Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
222 void outputPort(byte portNumber, byte portValue, byte forceSend)
224 // pins not configured as INPUT are cleared to zeros
225 portValue = portValue & portConfigInputs[portNumber];
226 // only send if the value is different than previously sent
227 if (forceSend || previousPINs[portNumber] != portValue) {
228 Firmata.sendDigitalPort(portNumber, portValue);
229 previousPINs[portNumber] = portValue;
233 /* -----------------------------------------------------------------------------
234 * check all the active digital inputs for change of state, then add any events
235 * to the Serial output queue using Serial.print() */
236 void checkDigitalInputs(void)
238 /* Using non-looping code allows constants to be given to readPort().
239 * The compiler will apply substantial optimizations if the inputs
240 * to readPort() are compile-time constants. */
241 if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
242 if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
243 if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
244 if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
245 if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
246 if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
247 if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
248 if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
249 if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
250 if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
251 if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
252 if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
253 if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
254 if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
255 if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
256 if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
259 // -----------------------------------------------------------------------------
260 /* sets the pin mode to the correct state and sets the relevant bits in the
261 * two bit-arrays that track Digital I/O and PWM status
263 void setPinModeCallback(byte pin, int mode)
265 if (Firmata.getPinMode(pin) == PIN_MODE_IGNORE)
268 if (Firmata.getPinMode(pin) == PIN_MODE_I2C && isI2CEnabled && mode != PIN_MODE_I2C) {
269 // disable i2c so pins can be used for other functions
270 // the following if statements should reconfigure the pins properly
273 if (IS_PIN_DIGITAL(pin) && mode != PIN_MODE_SERVO) {
274 if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
278 if (IS_PIN_ANALOG(pin)) {
279 reportAnalogCallback(PIN_TO_ANALOG(pin), mode == PIN_MODE_ANALOG ? 1 : 0); // turn on/off reporting
281 if (IS_PIN_DIGITAL(pin)) {
282 if (mode == INPUT || mode == PIN_MODE_PULLUP) {
283 portConfigInputs[pin / 8] |= (1 << (pin & 7));
285 portConfigInputs[pin / 8] &= ~(1 << (pin & 7));
288 Firmata.setPinState(pin, 0);
290 case PIN_MODE_ANALOG:
291 if (IS_PIN_ANALOG(pin)) {
292 if (IS_PIN_DIGITAL(pin)) {
293 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
295 // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6
296 digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
299 Firmata.setPinMode(pin, PIN_MODE_ANALOG);
303 if (IS_PIN_DIGITAL(pin)) {
304 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
306 // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6
307 digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
309 Firmata.setPinMode(pin, INPUT);
312 case PIN_MODE_PULLUP:
313 if (IS_PIN_DIGITAL(pin)) {
314 pinMode(PIN_TO_DIGITAL(pin), INPUT_PULLUP);
315 Firmata.setPinMode(pin, PIN_MODE_PULLUP);
316 Firmata.setPinState(pin, 1);
320 if (IS_PIN_DIGITAL(pin)) {
321 if (Firmata.getPinMode(pin) == PIN_MODE_PWM) {
322 // Disable PWM if pin mode was previously set to PWM.
323 digitalWrite(PIN_TO_DIGITAL(pin), LOW);
325 pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
326 Firmata.setPinMode(pin, OUTPUT);
330 if (IS_PIN_PWM(pin)) {
331 pinMode(PIN_TO_PWM(pin), OUTPUT);
332 analogWrite(PIN_TO_PWM(pin), 0);
333 Firmata.setPinMode(pin, PIN_MODE_PWM);
337 if (IS_PIN_DIGITAL(pin)) {
338 Firmata.setPinMode(pin, PIN_MODE_SERVO);
339 if (servoPinMap[pin] == 255 || !servos[servoPinMap[pin]].attached()) {
340 // pass -1 for min and max pulse values to use default values set
342 attachServo(pin, -1, -1);
347 if (IS_PIN_I2C(pin)) {
348 // mark the pin as i2c
349 // the user must call I2C_CONFIG to enable I2C for a device
350 Firmata.setPinMode(pin, PIN_MODE_I2C);
353 case PIN_MODE_SERIAL:
354 #ifdef FIRMATA_SERIAL_FEATURE
355 serialFeature.handlePinMode(pin, PIN_MODE_SERIAL);
359 Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
361 // TODO: save status to EEPROM here, if changed
365 * Sets the value of an individual pin. Useful if you want to set a pin value but
366 * are not tracking the digital port state.
367 * Can only be used on pins configured as OUTPUT.
368 * Cannot be used to enable pull-ups on Digital INPUT pins.
370 void setPinValueCallback(byte pin, int value)
372 if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) {
373 if (Firmata.getPinMode(pin) == OUTPUT) {
374 Firmata.setPinState(pin, value);
375 digitalWrite(PIN_TO_DIGITAL(pin), value);
380 void analogWriteCallback(byte pin, int value)
382 if (pin < TOTAL_PINS) {
383 switch (Firmata.getPinMode(pin)) {
385 if (IS_PIN_DIGITAL(pin))
386 servos[servoPinMap[pin]].write(value);
387 Firmata.setPinState(pin, value);
391 analogWrite(PIN_TO_PWM(pin), value);
392 Firmata.setPinState(pin, value);
398 void digitalWriteCallback(byte port, int value)
400 byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0;
402 if (port < TOTAL_PORTS) {
403 // create a mask of the pins on this port that are writable.
404 lastPin = port * 8 + 8;
405 if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
406 for (pin = port * 8; pin < lastPin; pin++) {
407 // do not disturb non-digital pins (eg, Rx & Tx)
408 if (IS_PIN_DIGITAL(pin)) {
409 // do not touch pins in PWM, ANALOG, SERVO or other modes
410 if (Firmata.getPinMode(pin) == OUTPUT || Firmata.getPinMode(pin) == INPUT) {
411 pinValue = ((byte)value & mask) ? 1 : 0;
412 if (Firmata.getPinMode(pin) == OUTPUT) {
413 pinWriteMask |= mask;
414 } else if (Firmata.getPinMode(pin) == INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) {
415 // only handle INPUT here for backwards compatibility
417 pinMode(pin, INPUT_PULLUP);
419 // only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier
420 pinWriteMask |= mask;
423 Firmata.setPinState(pin, pinValue);
428 writePort(port, (byte)value, pinWriteMask);
433 // -----------------------------------------------------------------------------
434 /* sets bits in a bit array (int) to toggle the reporting of the analogIns
436 //void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
438 void reportAnalogCallback(byte analogPin, int value)
440 if (analogPin < TOTAL_ANALOG_PINS) {
442 analogInputsToReport = analogInputsToReport & ~ (1 << analogPin);
444 analogInputsToReport = analogInputsToReport | (1 << analogPin);
445 // prevent during system reset or all analog pin values will be reported
446 // which may report noise for unconnected analog pins
448 // Send pin value immediately. This is helpful when connected via
449 // ethernet, wi-fi or bluetooth so pin states can be known upon
451 Firmata.sendAnalog(analogPin, analogRead(analogPin));
455 // TODO: save status to EEPROM here, if changed
458 void reportDigitalCallback(byte port, int value)
460 if (port < TOTAL_PORTS) {
461 reportPINs[port] = (byte)value;
462 // Send port value immediately. This is helpful when connected via
463 // ethernet, wi-fi or bluetooth so pin states can be known upon
465 if (value) outputPort(port, readPort(port, portConfigInputs[port]), true);
467 // do not disable analog reporting on these 8 pins, to allow some
468 // pins used for digital, others analog. Instead, allow both types
469 // of reporting to be enabled, but check if the pin is configured
470 // as analog when sampling the analog inputs. Likewise, while
471 // scanning digital pins, portConfigInputs will mask off values from any
472 // pins configured as analog
475 /*==============================================================================
476 * SYSEX-BASED commands
477 *============================================================================*/
479 void sysexCallback(byte command, byte argc, byte *argv)
486 unsigned int delayTime;
490 mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
491 if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
492 Firmata.sendString("10-bit addressing not supported");
496 slaveAddress = argv[0];
499 // need to invert the logic here since 0 will be default for client
500 // libraries that have not updated to add support for restart tx
501 if (argv[1] & I2C_END_TX_MASK) {
502 stopTX = I2C_RESTART_TX;
505 stopTX = I2C_STOP_TX; // default
510 Wire.beginTransmission(slaveAddress);
511 for (byte i = 2; i < argc; i += 2) {
512 data = argv[i] + (argv[i + 1] << 7);
515 Wire.endTransmission();
516 delayMicroseconds(70);
520 // a slave register is specified
521 slaveRegister = argv[2] + (argv[3] << 7);
522 data = argv[4] + (argv[5] << 7); // bytes to read
525 // a slave register is NOT specified
526 slaveRegister = I2C_REGISTER_NOT_SPECIFIED;
527 data = argv[2] + (argv[3] << 7); // bytes to read
529 readAndReportData(slaveAddress, (int)slaveRegister, data, stopTX);
531 case I2C_READ_CONTINUOUSLY:
532 if ((queryIndex + 1) >= I2C_MAX_QUERIES) {
533 // too many queries, just ignore
534 Firmata.sendString("too many queries");
538 // a slave register is specified
539 slaveRegister = argv[2] + (argv[3] << 7);
540 data = argv[4] + (argv[5] << 7); // bytes to read
543 // a slave register is NOT specified
544 slaveRegister = (int)I2C_REGISTER_NOT_SPECIFIED;
545 data = argv[2] + (argv[3] << 7); // bytes to read
548 query[queryIndex].addr = slaveAddress;
549 query[queryIndex].reg = slaveRegister;
550 query[queryIndex].bytes = data;
551 query[queryIndex].stopTX = stopTX;
553 case I2C_STOP_READING:
554 byte queryIndexToSkip;
555 // if read continuous mode is enabled for only 1 i2c device, disable
556 // read continuous reporting for that device
557 if (queryIndex <= 0) {
560 queryIndexToSkip = 0;
561 // if read continuous mode is enabled for multiple devices,
562 // determine which device to stop reading and remove it's data from
563 // the array, shifiting other array data to fill the space
564 for (byte i = 0; i < queryIndex + 1; i++) {
565 if (query[i].addr == slaveAddress) {
566 queryIndexToSkip = i;
571 for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) {
572 if (i < I2C_MAX_QUERIES) {
573 query[i].addr = query[i + 1].addr;
574 query[i].reg = query[i + 1].reg;
575 query[i].bytes = query[i + 1].bytes;
576 query[i].stopTX = query[i + 1].stopTX;
587 delayTime = (argv[0] + (argv[1] << 7));
589 if (argc > 1 && delayTime > 0) {
590 i2cReadDelayTime = delayTime;
600 // these vars are here for clarity, they'll optimized away by the compiler
602 int minPulse = argv[1] + (argv[2] << 7);
603 int maxPulse = argv[3] + (argv[4] << 7);
605 if (IS_PIN_DIGITAL(pin)) {
606 if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
609 attachServo(pin, minPulse, maxPulse);
610 setPinModeCallback(pin, PIN_MODE_SERVO);
614 case SAMPLING_INTERVAL:
616 samplingInterval = argv[0] + (argv[1] << 7);
617 if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
618 samplingInterval = MINIMUM_SAMPLING_INTERVAL;
621 //Firmata.sendString("Not enough data");
624 case EXTENDED_ANALOG:
627 if (argc > 2) val |= (argv[2] << 7);
628 if (argc > 3) val |= (argv[3] << 14);
629 analogWriteCallback(argv[0], val);
632 case CAPABILITY_QUERY:
633 Firmata.write(START_SYSEX);
634 Firmata.write(CAPABILITY_RESPONSE);
635 for (byte pin = 0; pin < TOTAL_PINS; pin++) {
636 if (IS_PIN_DIGITAL(pin)) {
637 Firmata.write((byte)INPUT);
639 Firmata.write((byte)PIN_MODE_PULLUP);
641 Firmata.write((byte)OUTPUT);
644 if (IS_PIN_ANALOG(pin)) {
645 Firmata.write(PIN_MODE_ANALOG);
646 Firmata.write(10); // 10 = 10-bit resolution
648 if (IS_PIN_PWM(pin)) {
649 Firmata.write(PIN_MODE_PWM);
650 Firmata.write(DEFAULT_PWM_RESOLUTION);
652 if (IS_PIN_DIGITAL(pin)) {
653 Firmata.write(PIN_MODE_SERVO);
656 if (IS_PIN_I2C(pin)) {
657 Firmata.write(PIN_MODE_I2C);
658 Firmata.write(1); // TODO: could assign a number to map to SCL or SDA
660 #ifdef FIRMATA_SERIAL_FEATURE
661 serialFeature.handleCapability(pin);
665 Firmata.write(END_SYSEX);
667 case PIN_STATE_QUERY:
670 Firmata.write(START_SYSEX);
671 Firmata.write(PIN_STATE_RESPONSE);
673 if (pin < TOTAL_PINS) {
674 Firmata.write(Firmata.getPinMode(pin));
675 Firmata.write((byte)Firmata.getPinState(pin) & 0x7F);
676 if (Firmata.getPinState(pin) & 0xFF80) Firmata.write((byte)(Firmata.getPinState(pin) >> 7) & 0x7F);
677 if (Firmata.getPinState(pin) & 0xC000) Firmata.write((byte)(Firmata.getPinState(pin) >> 14) & 0x7F);
679 Firmata.write(END_SYSEX);
682 case ANALOG_MAPPING_QUERY:
683 Firmata.write(START_SYSEX);
684 Firmata.write(ANALOG_MAPPING_RESPONSE);
685 for (byte pin = 0; pin < TOTAL_PINS; pin++) {
686 Firmata.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
688 Firmata.write(END_SYSEX);
692 #ifdef FIRMATA_SERIAL_FEATURE
693 serialFeature.handleSysex(command, argc, argv);
699 /*==============================================================================
701 *============================================================================*/
703 void systemResetCallback()
707 // initialize a defalt state
708 // TODO: option to load config from EEPROM instead of default
710 #ifdef FIRMATA_SERIAL_FEATURE
711 serialFeature.reset();
718 for (byte i = 0; i < TOTAL_PORTS; i++) {
719 reportPINs[i] = false; // by default, reporting off
720 portConfigInputs[i] = 0; // until activated
724 for (byte i = 0; i < TOTAL_PINS; i++) {
725 // pins with analog capability default to analog input
726 // otherwise, pins default to digital output
727 if (IS_PIN_ANALOG(i)) {
728 // turns off pullup, configures everything
729 setPinModeCallback(i, PIN_MODE_ANALOG);
730 } else if (IS_PIN_DIGITAL(i)) {
731 // sets the output to 0, configures portConfigInputs
732 setPinModeCallback(i, OUTPUT);
735 servoPinMap[i] = 255;
737 // by default, do not report any analog inputs
738 analogInputsToReport = 0;
740 detachedServoCount = 0;
743 /* send digital inputs to set the initial state on the host computer,
744 * since once in the loop(), this firmware will only send on change */
746 TODO: this can never execute, since no pins default to digital input
747 but it will be needed when/if we support EEPROM stored config
748 for (byte i=0; i < TOTAL_PORTS; i++) {
749 outputPort(i, readPort(i, portConfigInputs[i]), true);
757 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
759 Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
760 Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
761 Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
762 Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
763 Firmata.attach(SET_PIN_MODE, setPinModeCallback);
764 Firmata.attach(SET_DIGITAL_PIN_VALUE, setPinValueCallback);
765 Firmata.attach(START_SYSEX, sysexCallback);
766 Firmata.attach(SYSTEM_RESET, systemResetCallback);
768 // to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega,
769 // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
770 // Serial1.begin(57600);
771 // Firmata.begin(Serial1);
772 // However do not do this if you are using SERIAL_MESSAGE
774 Firmata.begin(57600);
776 ; // wait for serial port to connect. Needed for ATmega32u4-based boards and Arduino 101
779 systemResetCallback(); // reset to default config
782 /*==============================================================================
784 *============================================================================*/
789 /* DIGITALREAD - as fast as possible, check for changes and output them to the
790 * FTDI buffer using Serial.print() */
791 checkDigitalInputs();
793 /* STREAMREAD - processing incoming messagse as soon as possible, while still
794 * checking digital inputs. */
795 while (Firmata.available())
796 Firmata.processInput();
798 // TODO - ensure that Stream buffer doesn't go over 60 bytes
800 currentMillis = millis();
801 if (currentMillis - previousMillis > samplingInterval) {
802 previousMillis += samplingInterval;
803 /* ANALOGREAD - do all analogReads() at the configured sampling interval */
804 for (pin = 0; pin < TOTAL_PINS; pin++) {
805 if (IS_PIN_ANALOG(pin) && Firmata.getPinMode(pin) == PIN_MODE_ANALOG) {
806 analogPin = PIN_TO_ANALOG(pin);
807 if (analogInputsToReport & (1 << analogPin)) {
808 Firmata.sendAnalog(analogPin, analogRead(analogPin));
812 // report i2c data for all device with read continuous mode enabled
813 if (queryIndex > -1) {
814 for (byte i = 0; i < queryIndex + 1; i++) {
815 readAndReportData(query[i].addr, query[i].reg, query[i].bytes, query[i].stopTX);
820 #ifdef FIRMATA_SERIAL_FEATURE
821 serialFeature.update();