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

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