source: rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/StandardFirmataWiFi/StandardFirmataWiFi.ino@ 224

Last change on this file since 224 was 224, checked in by ertl-honda, 8 years ago

1.7.10のファイルに更新

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