]> AND Private Git Repository - Cipher_code.git/blob - Arduino/libraries/Firmata/examples/StandardFirmataEthernet/StandardFirmataEthernet.ino
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
arduino
[Cipher_code.git] / Arduino / libraries / Firmata / examples / StandardFirmataEthernet / StandardFirmataEthernet.ino
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 click on the following link
7   to open the list of Firmata client libraries in your default browser.
8
9   https://github.com/firmata/arduino#firmata-client-libraries
10
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-2017 Jeff Hoefs.  All rights reserved.
15
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.
20
21   See file LICENSE.txt for further informations on licensing terms.
22
23   Last updated August 17th, 2017
24 */
25
26 /*
27   README
28
29   StandardFirmataEthernet is a TCP client/server implementation. You will need a Firmata client library
30   with a network transport that can act as a TCP server or client in order to establish a connection between
31   StandardFirmataEthernet and the Firmata client application.
32
33   To use StandardFirmataEthernet you will need to have one of the following
34   boards or shields:
35
36   - Arduino Ethernet shield (or clone)
37   - Arduino Ethernet board (or clone)
38   - Arduino Yun
39
40   Follow the instructions in the ethernetConfig.h file (ethernetConfig.h tab in Arduino IDE) to
41   configure your particular hardware.
42
43   NOTE: If you are using an Arduino Ethernet shield you cannot use the following pins on
44   the following boards. Firmata will ignore any requests to use these pins:
45
46   - Arduino Uno or other ATMega328 boards: (D4, D10, D11, D12, D13)
47   - Arduino Mega: (D4, D10, D50, D51, D52, D53)
48   - Arduino Leonardo: (D4, D10)
49   - Arduino Due: (D4, D10)
50   - Arduino Zero: (D4, D10)
51
52   If you are using an ArduinoEthernet board, the following pins cannot be used (same as Uno):
53   - D4, D10, D11, D12, D13
54 */
55
56 #include <Servo.h>
57 #include <Wire.h>
58 #include <Firmata.h>
59
60 /*
61  * Uncomment the #define SERIAL_DEBUG line below to receive serial output messages relating to your
62  * connection that may help in the event of connection issues. If defined, some boards may not begin
63  * executing this sketch until the Serial console is opened.
64  */
65 //#define SERIAL_DEBUG
66 #include "utility/firmataDebug.h"
67
68 // follow the instructions in ethernetConfig.h to configure your particular hardware
69 #include "ethernetConfig.h"
70 #include "utility/EthernetClientStream.h"
71 #include "utility/EthernetServerStream.h"
72
73 /*
74  * Uncomment the following include to enable interfacing with Serial devices via hardware or
75  * software serial.
76  *
77  * DO NOT uncomment if you are running StandardFirmataEthernet on an Arduino Leonardo,
78  * Arduino Micro or other ATMega32u4-based board or you will not have enough Flash and RAM
79  * remaining to reliably run Firmata. Arduino Yun is okay because it doesn't import the Ethernet
80  * libraries.
81  */
82 // In order to use software serial, you will need to compile this sketch with
83 // Arduino IDE v1.6.6 or higher. Hardware serial should work back to Arduino 1.0.
84 //#include "utility/SerialFirmata.h"
85
86 #define I2C_WRITE                   B00000000
87 #define I2C_READ                    B00001000
88 #define I2C_READ_CONTINUOUSLY       B00010000
89 #define I2C_STOP_READING            B00011000
90 #define I2C_READ_WRITE_MODE_MASK    B00011000
91 #define I2C_10BIT_ADDRESS_MODE_MASK B00100000
92 #define I2C_END_TX_MASK             B01000000
93 #define I2C_STOP_TX                 1
94 #define I2C_RESTART_TX              0
95 #define I2C_MAX_QUERIES             8
96 #define I2C_REGISTER_NOT_SPECIFIED  -1
97
98 // the minimum interval for sampling analog input
99 #define MINIMUM_SAMPLING_INTERVAL   1
100
101 /*==============================================================================
102  * GLOBAL VARIABLES
103  *============================================================================*/
104
105 #if defined remote_ip && !defined remote_host
106 #ifdef local_ip
107 EthernetClientStream stream(client, local_ip, remote_ip, NULL, network_port);
108 #else
109 EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), remote_ip, NULL, network_port);
110 #endif
111 #endif
112
113 #if !defined remote_ip && defined remote_host
114 #ifdef local_ip
115 EthernetClientStream stream(client, local_ip, IPAddress(0, 0, 0, 0), remote_host, network_port );
116 #else
117 EthernetClientStream stream(client, IPAddress(0, 0, 0, 0), IPAddress(0, 0, 0, 0), remote_host, network_port);
118 #endif
119 #endif
120
121 #if !defined remote_ip && !defined remote_host
122 #ifdef local_ip
123 EthernetServerStream stream(local_ip, network_port);
124 #else
125 EthernetServerStream stream(IPAddress(0, 0, 0, 0), network_port);
126 #endif
127 #endif
128
129 #ifdef FIRMATA_SERIAL_FEATURE
130 SerialFirmata serialFeature;
131 #endif
132
133 /* analog inputs */
134 int analogInputsToReport = 0;      // bitwise array to store pin reporting
135
136 /* digital input ports */
137 byte reportPINs[TOTAL_PORTS];       // 1 = report this port, 0 = silence
138 byte previousPINs[TOTAL_PORTS];     // previous 8 bits sent
139
140 /* pins configuration */
141 byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
142
143 /* timer variables */
144 unsigned long currentMillis;        // store the current value from millis()
145 unsigned long previousMillis;       // for comparison with currentMillis
146 unsigned int samplingInterval = 19; // how often to sample analog inputs (in ms)
147
148 /* i2c data */
149 struct i2c_device_info {
150   byte addr;
151   int reg;
152   byte bytes;
153   byte stopTX;
154 };
155
156 /* for i2c read continuous mode */
157 i2c_device_info query[I2C_MAX_QUERIES];
158
159 byte i2cRxData[64];
160 boolean isI2CEnabled = false;
161 signed char queryIndex = -1;
162 // default delay time between i2c read request and Wire.requestFrom()
163 unsigned int i2cReadDelayTime = 0;
164
165 Servo servos[MAX_SERVOS];
166 byte servoPinMap[TOTAL_PINS];
167 byte detachedServos[MAX_SERVOS];
168 byte detachedServoCount = 0;
169 byte servoCount = 0;
170
171 boolean isResetting = false;
172
173 // Forward declare a few functions to avoid compiler errors with older versions
174 // of the Arduino IDE.
175 void setPinModeCallback(byte, int);
176 void reportAnalogCallback(byte analogPin, int value);
177 void sysexCallback(byte, byte, byte*);
178
179 /* utility functions */
180 void wireWrite(byte data)
181 {
182 #if ARDUINO >= 100
183   Wire.write((byte)data);
184 #else
185   Wire.send(data);
186 #endif
187 }
188
189 byte wireRead(void)
190 {
191 #if ARDUINO >= 100
192   return Wire.read();
193 #else
194   return Wire.receive();
195 #endif
196 }
197
198 /*==============================================================================
199  * FUNCTIONS
200  *============================================================================*/
201
202 void attachServo(byte pin, int minPulse, int maxPulse)
203 {
204   if (servoCount < MAX_SERVOS) {
205     // reuse indexes of detached servos until all have been reallocated
206     if (detachedServoCount > 0) {
207       servoPinMap[pin] = detachedServos[detachedServoCount - 1];
208       if (detachedServoCount > 0) detachedServoCount--;
209     } else {
210       servoPinMap[pin] = servoCount;
211       servoCount++;
212     }
213     if (minPulse > 0 && maxPulse > 0) {
214       servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
215     } else {
216       servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin));
217     }
218   } else {
219     Firmata.sendString("Max servos attached");
220   }
221 }
222
223 void detachServo(byte pin)
224 {
225   servos[servoPinMap[pin]].detach();
226   // if we're detaching the last servo, decrement the count
227   // otherwise store the index of the detached servo
228   if (servoPinMap[pin] == servoCount && servoCount > 0) {
229     servoCount--;
230   } else if (servoCount > 0) {
231     // keep track of detached servos because we want to reuse their indexes
232     // before incrementing the count of attached servos
233     detachedServoCount++;
234     detachedServos[detachedServoCount - 1] = servoPinMap[pin];
235   }
236
237   servoPinMap[pin] = 255;
238 }
239
240 void enableI2CPins()
241 {
242   byte i;
243   // is there a faster way to do this? would probaby require importing
244   // Arduino.h to get SCL and SDA pins
245   for (i = 0; i < TOTAL_PINS; i++) {
246     if (IS_PIN_I2C(i)) {
247       // mark pins as i2c so they are ignore in non i2c data requests
248       setPinModeCallback(i, PIN_MODE_I2C);
249     }
250   }
251
252   isI2CEnabled = true;
253
254   Wire.begin();
255 }
256
257 /* disable the i2c pins so they can be used for other functions */
258 void disableI2CPins() {
259   isI2CEnabled = false;
260   // disable read continuous mode for all devices
261   queryIndex = -1;
262 }
263
264 void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX) {
265   // allow I2C requests that don't require a register read
266   // for example, some devices using an interrupt pin to signify new data available
267   // do not always require the register read so upon interrupt you call Wire.requestFrom()
268   if (theRegister != I2C_REGISTER_NOT_SPECIFIED) {
269     Wire.beginTransmission(address);
270     wireWrite((byte)theRegister);
271     Wire.endTransmission(stopTX); // default = true
272     // do not set a value of 0
273     if (i2cReadDelayTime > 0) {
274       // delay is necessary for some devices such as WiiNunchuck
275       delayMicroseconds(i2cReadDelayTime);
276     }
277   } else {
278     theRegister = 0;  // fill the register with a dummy value
279   }
280
281   Wire.requestFrom(address, numBytes);  // all bytes are returned in requestFrom
282
283   // check to be sure correct number of bytes were returned by slave
284   if (numBytes < Wire.available()) {
285     Firmata.sendString("I2C: Too many bytes received");
286   } else if (numBytes > Wire.available()) {
287     Firmata.sendString("I2C: Too few bytes received");
288   }
289
290   i2cRxData[0] = address;
291   i2cRxData[1] = theRegister;
292
293   for (int i = 0; i < numBytes && Wire.available(); i++) {
294     i2cRxData[2 + i] = wireRead();
295   }
296
297   // send slave address, register and received bytes
298   Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
299 }
300
301 void outputPort(byte portNumber, byte portValue, byte forceSend)
302 {
303   // pins not configured as INPUT are cleared to zeros
304   portValue = portValue & portConfigInputs[portNumber];
305   // only send if the value is different than previously sent
306   if (forceSend || previousPINs[portNumber] != portValue) {
307     Firmata.sendDigitalPort(portNumber, portValue);
308     previousPINs[portNumber] = portValue;
309   }
310 }
311
312 /* -----------------------------------------------------------------------------
313  * check all the active digital inputs for change of state, then add any events
314  * to the Stream output queue using Stream.write() */
315 void checkDigitalInputs(void)
316 {
317   /* Using non-looping code allows constants to be given to readPort().
318    * The compiler will apply substantial optimizations if the inputs
319    * to readPort() are compile-time constants. */
320   if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
321   if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
322   if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
323   if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
324   if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
325   if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
326   if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
327   if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
328   if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
329   if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
330   if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
331   if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
332   if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
333   if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
334   if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
335   if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
336 }
337
338 // -----------------------------------------------------------------------------
339 /* sets the pin mode to the correct state and sets the relevant bits in the
340  * two bit-arrays that track Digital I/O and PWM status
341  */
342 void setPinModeCallback(byte pin, int mode)
343 {
344   if (Firmata.getPinMode(pin) == PIN_MODE_IGNORE)
345     return;
346
347   if (Firmata.getPinMode(pin) == PIN_MODE_I2C && isI2CEnabled && mode != PIN_MODE_I2C) {
348     // disable i2c so pins can be used for other functions
349     // the following if statements should reconfigure the pins properly
350     disableI2CPins();
351   }
352   if (IS_PIN_DIGITAL(pin) && mode != PIN_MODE_SERVO) {
353     if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
354       detachServo(pin);
355     }
356   }
357   if (IS_PIN_ANALOG(pin)) {
358     // turn on/off reporting
359     reportAnalogCallback(PIN_TO_ANALOG(pin), mode == PIN_MODE_ANALOG ? 1 : 0);
360   }
361   if (IS_PIN_DIGITAL(pin)) {
362     if (mode == INPUT || mode == PIN_MODE_PULLUP) {
363       portConfigInputs[pin / 8] |= (1 << (pin & 7));
364     } else {
365       portConfigInputs[pin / 8] &= ~(1 << (pin & 7));
366     }
367   }
368   Firmata.setPinState(pin, 0);
369   switch (mode) {
370     case PIN_MODE_ANALOG:
371       if (IS_PIN_ANALOG(pin)) {
372         if (IS_PIN_DIGITAL(pin)) {
373           pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
374 #if ARDUINO <= 100
375           // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6
376           digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
377 #endif
378         }
379         Firmata.setPinMode(pin, PIN_MODE_ANALOG);
380       }
381       break;
382     case INPUT:
383       if (IS_PIN_DIGITAL(pin)) {
384         pinMode(PIN_TO_DIGITAL(pin), INPUT);    // disable output driver
385 #if ARDUINO <= 100
386         // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6
387         digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
388 #endif
389         Firmata.setPinMode(pin, INPUT);
390       }
391       break;
392     case PIN_MODE_PULLUP:
393       if (IS_PIN_DIGITAL(pin)) {
394         pinMode(PIN_TO_DIGITAL(pin), INPUT_PULLUP);
395         Firmata.setPinMode(pin, PIN_MODE_PULLUP);
396         Firmata.setPinState(pin, 1);
397       }
398       break;
399     case OUTPUT:
400       if (IS_PIN_DIGITAL(pin)) {
401         if (Firmata.getPinMode(pin) == PIN_MODE_PWM) {
402           // Disable PWM if pin mode was previously set to PWM.
403           digitalWrite(PIN_TO_DIGITAL(pin), LOW);
404         }
405         pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
406         Firmata.setPinMode(pin, OUTPUT);
407       }
408       break;
409     case PIN_MODE_PWM:
410       if (IS_PIN_PWM(pin)) {
411         pinMode(PIN_TO_PWM(pin), OUTPUT);
412         analogWrite(PIN_TO_PWM(pin), 0);
413         Firmata.setPinMode(pin, PIN_MODE_PWM);
414       }
415       break;
416     case PIN_MODE_SERVO:
417       if (IS_PIN_DIGITAL(pin)) {
418         Firmata.setPinMode(pin, PIN_MODE_SERVO);
419         if (servoPinMap[pin] == 255 || !servos[servoPinMap[pin]].attached()) {
420           // pass -1 for min and max pulse values to use default values set
421           // by Servo library
422           attachServo(pin, -1, -1);
423         }
424       }
425       break;
426     case PIN_MODE_I2C:
427       if (IS_PIN_I2C(pin)) {
428         // mark the pin as i2c
429         // the user must call I2C_CONFIG to enable I2C for a device
430         Firmata.setPinMode(pin, PIN_MODE_I2C);
431       }
432       break;
433     case PIN_MODE_SERIAL:
434 #ifdef FIRMATA_SERIAL_FEATURE
435       serialFeature.handlePinMode(pin, PIN_MODE_SERIAL);
436 #endif
437       break;
438     default:
439       Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
440   }
441   // TODO: save status to EEPROM here, if changed
442 }
443
444 /*
445  * Sets the value of an individual pin. Useful if you want to set a pin value but
446  * are not tracking the digital port state.
447  * Can only be used on pins configured as OUTPUT.
448  * Cannot be used to enable pull-ups on Digital INPUT pins.
449  */
450 void setPinValueCallback(byte pin, int value)
451 {
452   if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) {
453     if (Firmata.getPinMode(pin) == OUTPUT) {
454       Firmata.setPinState(pin, value);
455       digitalWrite(PIN_TO_DIGITAL(pin), value);
456     }
457   }
458 }
459
460 void analogWriteCallback(byte pin, int value)
461 {
462   if (pin < TOTAL_PINS) {
463     switch (Firmata.getPinMode(pin)) {
464       case PIN_MODE_SERVO:
465         if (IS_PIN_DIGITAL(pin))
466           servos[servoPinMap[pin]].write(value);
467         Firmata.setPinState(pin, value);
468         break;
469       case PIN_MODE_PWM:
470         if (IS_PIN_PWM(pin))
471           analogWrite(PIN_TO_PWM(pin), value);
472         Firmata.setPinState(pin, value);
473         break;
474     }
475   }
476 }
477
478 void digitalWriteCallback(byte port, int value)
479 {
480   byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0;
481
482   if (port < TOTAL_PORTS) {
483     // create a mask of the pins on this port that are writable.
484     lastPin = port * 8 + 8;
485     if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
486     for (pin = port * 8; pin < lastPin; pin++) {
487       // do not disturb non-digital pins (eg, Rx & Tx)
488       if (IS_PIN_DIGITAL(pin)) {
489         // do not touch pins in PWM, ANALOG, SERVO or other modes
490         if (Firmata.getPinMode(pin) == OUTPUT || Firmata.getPinMode(pin) == INPUT) {
491           pinValue = ((byte)value & mask) ? 1 : 0;
492           if (Firmata.getPinMode(pin) == OUTPUT) {
493             pinWriteMask |= mask;
494           } else if (Firmata.getPinMode(pin) == INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) {
495             // only handle INPUT here for backwards compatibility
496 #if ARDUINO > 100
497             pinMode(pin, INPUT_PULLUP);
498 #else
499             // only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier
500             pinWriteMask |= mask;
501 #endif
502           }
503           Firmata.setPinState(pin, pinValue);
504         }
505       }
506       mask = mask << 1;
507     }
508     writePort(port, (byte)value, pinWriteMask);
509   }
510 }
511
512
513 // -----------------------------------------------------------------------------
514 /* sets bits in a bit array (int) to toggle the reporting of the analogIns
515  */
516 //void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
517 //}
518 void reportAnalogCallback(byte analogPin, int value)
519 {
520   if (analogPin < TOTAL_ANALOG_PINS) {
521     if (value == 0) {
522       analogInputsToReport = analogInputsToReport & ~ (1 << analogPin);
523     } else {
524       analogInputsToReport = analogInputsToReport | (1 << analogPin);
525       // prevent during system reset or all analog pin values will be reported
526       // which may report noise for unconnected analog pins
527       if (!isResetting) {
528         // Send pin value immediately. This is helpful when connected via
529         // ethernet, wi-fi or bluetooth so pin states can be known upon
530         // reconnecting.
531         Firmata.sendAnalog(analogPin, analogRead(analogPin));
532       }
533     }
534   }
535   // TODO: save status to EEPROM here, if changed
536 }
537
538 void reportDigitalCallback(byte port, int value)
539 {
540   if (port < TOTAL_PORTS) {
541     reportPINs[port] = (byte)value;
542     // Send port value immediately. This is helpful when connected via
543     // ethernet, wi-fi or bluetooth so pin states can be known upon
544     // reconnecting.
545     if (value) outputPort(port, readPort(port, portConfigInputs[port]), true);
546   }
547   // do not disable analog reporting on these 8 pins, to allow some
548   // pins used for digital, others analog.  Instead, allow both types
549   // of reporting to be enabled, but check if the pin is configured
550   // as analog when sampling the analog inputs.  Likewise, while
551   // scanning digital pins, portConfigInputs will mask off values from any
552   // pins configured as analog
553 }
554
555 /*==============================================================================
556  * SYSEX-BASED commands
557  *============================================================================*/
558
559 void sysexCallback(byte command, byte argc, byte *argv)
560 {
561   byte mode;
562   byte stopTX;
563   byte slaveAddress;
564   byte data;
565   int slaveRegister;
566   unsigned int delayTime;
567
568   switch (command) {
569     case I2C_REQUEST:
570       mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
571       if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
572         Firmata.sendString("10-bit addressing not supported");
573         return;
574       }
575       else {
576         slaveAddress = argv[0];
577       }
578
579       // need to invert the logic here since 0 will be default for client
580       // libraries that have not updated to add support for restart tx
581       if (argv[1] & I2C_END_TX_MASK) {
582         stopTX = I2C_RESTART_TX;
583       }
584       else {
585         stopTX = I2C_STOP_TX; // default
586       }
587
588       switch (mode) {
589         case I2C_WRITE:
590           Wire.beginTransmission(slaveAddress);
591           for (byte i = 2; i < argc; i += 2) {
592             data = argv[i] + (argv[i + 1] << 7);
593             wireWrite(data);
594           }
595           Wire.endTransmission();
596           delayMicroseconds(70);
597           break;
598         case I2C_READ:
599           if (argc == 6) {
600             // a slave register is specified
601             slaveRegister = argv[2] + (argv[3] << 7);
602             data = argv[4] + (argv[5] << 7);  // bytes to read
603           }
604           else {
605             // a slave register is NOT specified
606             slaveRegister = I2C_REGISTER_NOT_SPECIFIED;
607             data = argv[2] + (argv[3] << 7);  // bytes to read
608           }
609           readAndReportData(slaveAddress, (int)slaveRegister, data, stopTX);
610           break;
611         case I2C_READ_CONTINUOUSLY:
612           if ((queryIndex + 1) >= I2C_MAX_QUERIES) {
613             // too many queries, just ignore
614             Firmata.sendString("too many queries");
615             break;
616           }
617           if (argc == 6) {
618             // a slave register is specified
619             slaveRegister = argv[2] + (argv[3] << 7);
620             data = argv[4] + (argv[5] << 7);  // bytes to read
621           }
622           else {
623             // a slave register is NOT specified
624             slaveRegister = (int)I2C_REGISTER_NOT_SPECIFIED;
625             data = argv[2] + (argv[3] << 7);  // bytes to read
626           }
627           queryIndex++;
628           query[queryIndex].addr = slaveAddress;
629           query[queryIndex].reg = slaveRegister;
630           query[queryIndex].bytes = data;
631           query[queryIndex].stopTX = stopTX;
632           break;
633         case I2C_STOP_READING:
634           byte queryIndexToSkip;
635           // if read continuous mode is enabled for only 1 i2c device, disable
636           // read continuous reporting for that device
637           if (queryIndex <= 0) {
638             queryIndex = -1;
639           } else {
640             queryIndexToSkip = 0;
641             // if read continuous mode is enabled for multiple devices,
642             // determine which device to stop reading and remove it's data from
643             // the array, shifiting other array data to fill the space
644             for (byte i = 0; i < queryIndex + 1; i++) {
645               if (query[i].addr == slaveAddress) {
646                 queryIndexToSkip = i;
647                 break;
648               }
649             }
650
651             for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) {
652               if (i < I2C_MAX_QUERIES) {
653                 query[i].addr = query[i + 1].addr;
654                 query[i].reg = query[i + 1].reg;
655                 query[i].bytes = query[i + 1].bytes;
656                 query[i].stopTX = query[i + 1].stopTX;
657               }
658             }
659             queryIndex--;
660           }
661           break;
662         default:
663           break;
664       }
665       break;
666     case I2C_CONFIG:
667       delayTime = (argv[0] + (argv[1] << 7));
668
669       if (argc > 1 && delayTime > 0) {
670         i2cReadDelayTime = delayTime;
671       }
672
673       if (!isI2CEnabled) {
674         enableI2CPins();
675       }
676
677       break;
678     case SERVO_CONFIG:
679       if (argc > 4) {
680         // these vars are here for clarity, they'll optimized away by the compiler
681         byte pin = argv[0];
682         int minPulse = argv[1] + (argv[2] << 7);
683         int maxPulse = argv[3] + (argv[4] << 7);
684
685         if (IS_PIN_DIGITAL(pin)) {
686           if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) {
687             detachServo(pin);
688           }
689           attachServo(pin, minPulse, maxPulse);
690           setPinModeCallback(pin, PIN_MODE_SERVO);
691         }
692       }
693       break;
694     case SAMPLING_INTERVAL:
695       if (argc > 1) {
696         samplingInterval = argv[0] + (argv[1] << 7);
697         if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
698           samplingInterval = MINIMUM_SAMPLING_INTERVAL;
699         }
700       } else {
701         //Firmata.sendString("Not enough data");
702       }
703       break;
704     case EXTENDED_ANALOG:
705       if (argc > 1) {
706         int val = argv[1];
707         if (argc > 2) val |= (argv[2] << 7);
708         if (argc > 3) val |= (argv[3] << 14);
709         analogWriteCallback(argv[0], val);
710       }
711       break;
712     case CAPABILITY_QUERY:
713       Firmata.write(START_SYSEX);
714       Firmata.write(CAPABILITY_RESPONSE);
715       for (byte pin = 0; pin < TOTAL_PINS; pin++) {
716         if (IS_PIN_DIGITAL(pin)) {
717           Firmata.write((byte)INPUT);
718           Firmata.write(1);
719           Firmata.write((byte)PIN_MODE_PULLUP);
720           Firmata.write(1);
721           Firmata.write((byte)OUTPUT);
722           Firmata.write(1);
723         }
724         if (IS_PIN_ANALOG(pin)) {
725           Firmata.write(PIN_MODE_ANALOG);
726           Firmata.write(10); // 10 = 10-bit resolution
727         }
728         if (IS_PIN_PWM(pin)) {
729           Firmata.write(PIN_MODE_PWM);
730           Firmata.write(DEFAULT_PWM_RESOLUTION);
731         }
732         if (IS_PIN_DIGITAL(pin)) {
733           Firmata.write(PIN_MODE_SERVO);
734           Firmata.write(14);
735         }
736         if (IS_PIN_I2C(pin)) {
737           Firmata.write(PIN_MODE_I2C);
738           Firmata.write(1);  // TODO: could assign a number to map to SCL or SDA
739         }
740 #ifdef FIRMATA_SERIAL_FEATURE
741         serialFeature.handleCapability(pin);
742 #endif
743         Firmata.write(127);
744       }
745       Firmata.write(END_SYSEX);
746       break;
747     case PIN_STATE_QUERY:
748       if (argc > 0) {
749         byte pin = argv[0];
750         Firmata.write(START_SYSEX);
751         Firmata.write(PIN_STATE_RESPONSE);
752         Firmata.write(pin);
753         if (pin < TOTAL_PINS) {
754           Firmata.write(Firmata.getPinMode(pin));
755           Firmata.write((byte)Firmata.getPinState(pin) & 0x7F);
756           if (Firmata.getPinState(pin) & 0xFF80) Firmata.write((byte)(Firmata.getPinState(pin) >> 7) & 0x7F);
757           if (Firmata.getPinState(pin) & 0xC000) Firmata.write((byte)(Firmata.getPinState(pin) >> 14) & 0x7F);
758         }
759         Firmata.write(END_SYSEX);
760       }
761       break;
762     case ANALOG_MAPPING_QUERY:
763       Firmata.write(START_SYSEX);
764       Firmata.write(ANALOG_MAPPING_RESPONSE);
765       for (byte pin = 0; pin < TOTAL_PINS; pin++) {
766         Firmata.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
767       }
768       Firmata.write(END_SYSEX);
769       break;
770
771     case SERIAL_MESSAGE:
772 #ifdef FIRMATA_SERIAL_FEATURE
773       serialFeature.handleSysex(command, argc, argv);
774 #endif
775       break;
776   }
777 }
778
779 /*==============================================================================
780  * SETUP()
781  *============================================================================*/
782
783 void systemResetCallback()
784 {
785   isResetting = true;
786
787   // initialize a defalt state
788   // TODO: option to load config from EEPROM instead of default
789
790 #ifdef FIRMATA_SERIAL_FEATURE
791   serialFeature.reset();
792 #endif
793
794   if (isI2CEnabled) {
795     disableI2CPins();
796   }
797
798   for (byte i = 0; i < TOTAL_PORTS; i++) {
799     reportPINs[i] = false;    // by default, reporting off
800     portConfigInputs[i] = 0;  // until activated
801     previousPINs[i] = 0;
802   }
803
804   for (byte i = 0; i < TOTAL_PINS; i++) {
805     // pins with analog capability default to analog input
806     // otherwise, pins default to digital output
807     if (IS_PIN_ANALOG(i)) {
808       // turns off pullup, configures everything
809       setPinModeCallback(i, PIN_MODE_ANALOG);
810     } else if (IS_PIN_DIGITAL(i)) {
811       // sets the output to 0, configures portConfigInputs
812       setPinModeCallback(i, OUTPUT);
813     }
814
815     servoPinMap[i] = 255;
816   }
817   // by default, do not report any analog inputs
818   analogInputsToReport = 0;
819
820   detachedServoCount = 0;
821   servoCount = 0;
822
823   /* send digital inputs to set the initial state on the host computer,
824    * since once in the loop(), this firmware will only send on change */
825   /*
826   TODO: this can never execute, since no pins default to digital input
827         but it will be needed when/if we support EEPROM stored config
828   for (byte i=0; i < TOTAL_PORTS; i++) {
829     outputPort(i, readPort(i, portConfigInputs[i]), true);
830   }
831   */
832   isResetting = false;
833 }
834
835 void printEthernetStatus()
836 {
837   DEBUG_PRINT("Local IP Address: ");
838   IPAddress ip = Ethernet.localIP();
839   DEBUG_PRINTLN(ip);
840 #ifdef remote_ip
841   DEBUG_PRINT("Connecting to server at: ");
842   DEBUG_PRINTLN(remote_ip);
843 #endif
844 }
845
846 /*
847  * StandardFirmataEthernet communicates with Ethernet shields over SPI. Therefore all
848  * SPI pins must be set to IGNORE. Otherwise Firmata would break SPI communication.
849  * Additional pins may also need to be ignored depending on the particular board or
850  * shield in use.
851  */
852 void ignorePins()
853 {
854 #ifdef IS_IGNORE_PIN
855   for (byte i = 0; i < TOTAL_PINS; i++) {
856     if (IS_IGNORE_PIN(i)) {
857       Firmata.setPinMode(i, PIN_MODE_IGNORE);
858     }
859   }
860 #endif
861
862 #ifdef WIZ5100_ETHERNET
863   // Arduino Ethernet and Arduino EthernetShield have SD SS wired to D4
864   pinMode(PIN_TO_DIGITAL(4), OUTPUT);    // switch off SD card bypassing Firmata
865   digitalWrite(PIN_TO_DIGITAL(4), HIGH); // SS is active low;
866
867 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
868   pinMode(PIN_TO_DIGITAL(53), OUTPUT); // configure hardware SS as output on MEGA
869 #endif
870
871 #endif // WIZ5100_ETHERNET
872 }
873
874 void initTransport()
875 {
876 #ifdef YUN_ETHERNET
877   Bridge.begin();
878 #else
879 #ifdef local_ip
880   Ethernet.begin((uint8_t *)mac, local_ip); //start ethernet
881 #else
882   DEBUG_PRINTLN("Local IP will be requested from DHCP...");
883   //start ethernet using dhcp
884   if (Ethernet.begin((uint8_t *)mac) == 0) {
885     DEBUG_PRINTLN("Failed to configure Ethernet using DHCP");
886   }
887 #endif
888 #endif
889   printEthernetStatus();
890 }
891
892 void initFirmata()
893 {
894   Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
895   Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
896   Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
897   Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
898   Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
899   Firmata.attach(SET_PIN_MODE, setPinModeCallback);
900   Firmata.attach(SET_DIGITAL_PIN_VALUE, setPinValueCallback);
901   Firmata.attach(START_SYSEX, sysexCallback);
902   Firmata.attach(SYSTEM_RESET, systemResetCallback);
903
904   ignorePins();
905
906   // start up Network Firmata:
907   Firmata.begin(stream);
908   systemResetCallback();  // Initialize default configuration
909 }
910
911 void setup()
912 {
913   DEBUG_BEGIN(9600);
914
915   initTransport();
916
917   initFirmata();
918 }
919
920 /*==============================================================================
921  * LOOP()
922  *============================================================================*/
923 void loop()
924 {
925   byte pin, analogPin;
926
927   /* DIGITALREAD - as fast as possible, check for changes and output them to the
928    * Stream buffer using Stream.write()  */
929   checkDigitalInputs();
930
931   /* STREAMREAD - processing incoming messagse as soon as possible, while still
932    * checking digital inputs.  */
933   while (Firmata.available())
934     Firmata.processInput();
935
936   // TODO - ensure that Stream buffer doesn't go over 60 bytes
937
938   currentMillis = millis();
939   if (currentMillis - previousMillis > samplingInterval) {
940     previousMillis += samplingInterval;
941     /* ANALOGREAD - do all analogReads() at the configured sampling interval */
942     for (pin = 0; pin < TOTAL_PINS; pin++) {
943       if (IS_PIN_ANALOG(pin) && Firmata.getPinMode(pin) == PIN_MODE_ANALOG) {
944         analogPin = PIN_TO_ANALOG(pin);
945         if (analogInputsToReport & (1 << analogPin)) {
946           Firmata.sendAnalog(analogPin, analogRead(analogPin));
947         }
948       }
949     }
950     // report i2c data for all device with read continuous mode enabled
951     if (queryIndex > -1) {
952       for (byte i = 0; i < queryIndex + 1; i++) {
953         readAndReportData(query[i].addr, query[i].reg, query[i].bytes, query[i].stopTX);
954       }
955     }
956   }
957
958 #ifdef FIRMATA_SERIAL_FEATURE
959   serialFeature.update();
960 #endif
961
962 #if !defined local_ip && !defined YUN_ETHERNET
963   // only necessary when using DHCP, ensures local IP is updated appropriately if it changes
964   if (Ethernet.maintain()) {
965     stream.maintain(Ethernet.localIP());
966   }
967 #endif
968
969 }