arduino_firmata 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,655 @@
1
+ /*
2
+ * Firmata is a generic protocol for communicating with microcontrollers
3
+ * from software on a host computer. It is intended to work with
4
+ * any host computer software package.
5
+ *
6
+ * To download a host software package, please clink on the following link
7
+ * to open the download page in your default browser.
8
+ *
9
+ * http://firmata.org/wiki/Download
10
+ */
11
+
12
+ /*
13
+ Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
14
+ Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
15
+ Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
16
+ Copyright (C) 2009-2011 Jeff Hoefs. All rights reserved.
17
+ Copyright (C) 2013 Sho Hashimoto. All rights reserved.
18
+
19
+ This library is free software; you can redistribute it and/or
20
+ modify it under the terms of the GNU Lesser General Public
21
+ License as published by the Free Software Foundation; either
22
+ version 2.1 of the License, or (at your option) any later version.
23
+
24
+ See file LICENSE.txt for further informations on licensing terms.
25
+
26
+ formatted using the GNU C formatting and indenting
27
+ */
28
+
29
+ /*
30
+ * TODO: use Program Control to load stored profiles from EEPROM
31
+ */
32
+
33
+ #include <Servo.h>
34
+ #include <Wire.h>
35
+ #include <Firmata.h>
36
+
37
+ // move the following defines to Firmata.h?
38
+ #define I2C_WRITE B00000000
39
+ #define I2C_READ B00001000
40
+ #define I2C_READ_CONTINUOUSLY B00010000
41
+ #define I2C_STOP_READING B00011000
42
+ #define I2C_READ_WRITE_MODE_MASK B00011000
43
+ #define I2C_10BIT_ADDRESS_MODE_MASK B00100000
44
+
45
+ #define MAX_QUERIES 8
46
+ #define MINIMUM_SAMPLING_INTERVAL 10
47
+
48
+ #define REGISTER_NOT_SPECIFIED -1
49
+
50
+ /*==============================================================================
51
+ * GLOBAL VARIABLES
52
+ *============================================================================*/
53
+
54
+ /* analog inputs */
55
+ int analogInputsToReport = 0; // bitwise array to store pin reporting
56
+
57
+ /* digital input ports */
58
+ byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence
59
+ byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent
60
+
61
+ /* pins configuration */
62
+ byte pinConfig[TOTAL_PINS]; // configuration of every pin
63
+ byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
64
+ int pinState[TOTAL_PINS]; // any value that has been written
65
+
66
+ /* timer variables */
67
+ unsigned long currentMillis; // store the current value from millis()
68
+ unsigned long previousMillis; // for comparison with currentMillis
69
+ int samplingInterval = 19; // how often to run the main loop (in ms)
70
+
71
+ /* i2c data */
72
+ struct i2c_device_info {
73
+ byte addr;
74
+ byte reg;
75
+ byte bytes;
76
+ };
77
+
78
+ /* for i2c read continuous more */
79
+ i2c_device_info query[MAX_QUERIES];
80
+
81
+ byte i2cRxData[32];
82
+ boolean isI2CEnabled = false;
83
+ signed char queryIndex = -1;
84
+ unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom()
85
+
86
+ Servo servos[MAX_SERVOS];
87
+ /*==============================================================================
88
+ * FUNCTIONS
89
+ *============================================================================*/
90
+
91
+ void readAndReportData(byte address, int theRegister, byte numBytes) {
92
+ // allow I2C requests that don't require a register read
93
+ // for example, some devices using an interrupt pin to signify new data available
94
+ // do not always require the register read so upon interrupt you call Wire.requestFrom()
95
+ if (theRegister != REGISTER_NOT_SPECIFIED) {
96
+ Wire.beginTransmission(address);
97
+ #if ARDUINO >= 100
98
+ Wire.write((byte)theRegister);
99
+ #else
100
+ Wire.send((byte)theRegister);
101
+ #endif
102
+ Wire.endTransmission();
103
+ delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck
104
+ } else {
105
+ theRegister = 0; // fill the register with a dummy value
106
+ }
107
+
108
+ Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom
109
+
110
+ // check to be sure correct number of bytes were returned by slave
111
+ if(numBytes == Wire.available()) {
112
+ i2cRxData[0] = address;
113
+ i2cRxData[1] = theRegister;
114
+ for (int i = 0; i < numBytes; i++) {
115
+ #if ARDUINO >= 100
116
+ i2cRxData[2 + i] = Wire.read();
117
+ #else
118
+ i2cRxData[2 + i] = Wire.receive();
119
+ #endif
120
+ }
121
+ }
122
+ else {
123
+ if(numBytes > Wire.available()) {
124
+ Firmata.sendString("I2C Read Error: Too many bytes received");
125
+ } else {
126
+ Firmata.sendString("I2C Read Error: Too few bytes received");
127
+ }
128
+ }
129
+
130
+ // send slave address, register and received bytes
131
+ Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
132
+ }
133
+
134
+ void outputPort(byte portNumber, byte portValue, byte forceSend)
135
+ {
136
+ // pins not configured as INPUT are cleared to zeros
137
+ portValue = portValue & portConfigInputs[portNumber];
138
+ // only send if the value is different than previously sent
139
+ if(forceSend || previousPINs[portNumber] != portValue) {
140
+ Firmata.sendDigitalPort(portNumber, portValue);
141
+ previousPINs[portNumber] = portValue;
142
+ }
143
+ }
144
+
145
+ /* -----------------------------------------------------------------------------
146
+ * check all the active digital inputs for change of state, then add any events
147
+ * to the Serial output queue using Serial.print() */
148
+ void checkDigitalInputs(void)
149
+ {
150
+ /* Using non-looping code allows constants to be given to readPort().
151
+ * The compiler will apply substantial optimizations if the inputs
152
+ * to readPort() are compile-time constants. */
153
+ if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
154
+ if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
155
+ if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
156
+ if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
157
+ if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
158
+ if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
159
+ if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
160
+ if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
161
+ if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
162
+ if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
163
+ if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
164
+ if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
165
+ if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
166
+ if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
167
+ if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
168
+ if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
169
+ }
170
+
171
+ // -----------------------------------------------------------------------------
172
+ /* sets the pin mode to the correct state and sets the relevant bits in the
173
+ * two bit-arrays that track Digital I/O and PWM status
174
+ */
175
+ void setPinModeCallback(byte pin, int mode)
176
+ {
177
+ if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
178
+ // disable i2c so pins can be used for other functions
179
+ // the following if statements should reconfigure the pins properly
180
+ disableI2CPins();
181
+ }
182
+ if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) {
183
+ servos[PIN_TO_SERVO(pin)].detach();
184
+ }
185
+ if (IS_PIN_ANALOG(pin)) {
186
+ reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
187
+ }
188
+ if (IS_PIN_DIGITAL(pin)) {
189
+ if (mode == INPUT) {
190
+ portConfigInputs[pin/8] |= (1 << (pin & 7));
191
+ } else {
192
+ portConfigInputs[pin/8] &= ~(1 << (pin & 7));
193
+ }
194
+ }
195
+ pinState[pin] = 0;
196
+ switch(mode) {
197
+ case ANALOG:
198
+ if (IS_PIN_ANALOG(pin)) {
199
+ if (IS_PIN_DIGITAL(pin)) {
200
+ pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
201
+ digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
202
+ }
203
+ pinConfig[pin] = ANALOG;
204
+ }
205
+ break;
206
+ case INPUT:
207
+ if (IS_PIN_DIGITAL(pin)) {
208
+ pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
209
+ digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
210
+ pinConfig[pin] = INPUT;
211
+ }
212
+ break;
213
+ case OUTPUT:
214
+ if (IS_PIN_DIGITAL(pin)) {
215
+ digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
216
+ pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
217
+ pinConfig[pin] = OUTPUT;
218
+ }
219
+ break;
220
+ case PWM:
221
+ if (IS_PIN_PWM(pin)) {
222
+ pinMode(PIN_TO_PWM(pin), OUTPUT);
223
+ analogWrite(PIN_TO_PWM(pin), 0);
224
+ pinConfig[pin] = PWM;
225
+ }
226
+ break;
227
+ case SERVO:
228
+ if (IS_PIN_SERVO(pin)) {
229
+ pinConfig[pin] = SERVO;
230
+ if (!servos[PIN_TO_SERVO(pin)].attached()) {
231
+ servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
232
+ }
233
+ }
234
+ break;
235
+ case I2C:
236
+ if (IS_PIN_I2C(pin)) {
237
+ // mark the pin as i2c
238
+ // the user must call I2C_CONFIG to enable I2C for a device
239
+ pinConfig[pin] = I2C;
240
+ }
241
+ break;
242
+ default:
243
+ Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
244
+ }
245
+ // TODO: save status to EEPROM here, if changed
246
+ }
247
+
248
+ void analogWriteCallback(byte pin, int value)
249
+ {
250
+ if (pin < TOTAL_PINS) {
251
+ switch(pinConfig[pin]) {
252
+ case SERVO:
253
+ if (IS_PIN_SERVO(pin))
254
+ servos[PIN_TO_SERVO(pin)].write(value);
255
+ pinState[pin] = value;
256
+ break;
257
+ case PWM:
258
+ if (IS_PIN_PWM(pin))
259
+ analogWrite(PIN_TO_PWM(pin), value);
260
+ pinState[pin] = value;
261
+ break;
262
+ }
263
+ }
264
+ }
265
+
266
+ void digitalWriteCallback(byte port, int value)
267
+ {
268
+ byte pin, lastPin, mask=1, pinWriteMask=0;
269
+
270
+ if (port < TOTAL_PORTS) {
271
+ // create a mask of the pins on this port that are writable.
272
+ lastPin = port*8+8;
273
+ if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
274
+ for (pin=port*8; pin < lastPin; pin++) {
275
+ // do not disturb non-digital pins (eg, Rx & Tx)
276
+ if (IS_PIN_DIGITAL(pin)) {
277
+ // only write to OUTPUT and INPUT (enables pullup)
278
+ // do not touch pins in PWM, ANALOG, SERVO or other modes
279
+ if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
280
+ pinWriteMask |= mask;
281
+ pinState[pin] = ((byte)value & mask) ? 1 : 0;
282
+ }
283
+ }
284
+ mask = mask << 1;
285
+ }
286
+ writePort(port, (byte)value, pinWriteMask);
287
+ }
288
+ }
289
+
290
+
291
+ // -----------------------------------------------------------------------------
292
+ /* sets bits in a bit array (int) to toggle the reporting of the analogIns
293
+ */
294
+ //void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
295
+ //}
296
+ void reportAnalogCallback(byte analogPin, int value)
297
+ {
298
+ if (analogPin < TOTAL_ANALOG_PINS) {
299
+ if(value == 0) {
300
+ analogInputsToReport = analogInputsToReport &~ (1 << analogPin);
301
+ } else {
302
+ analogInputsToReport = analogInputsToReport | (1 << analogPin);
303
+ }
304
+ }
305
+ // TODO: save status to EEPROM here, if changed
306
+ }
307
+
308
+ void reportDigitalCallback(byte port, int value)
309
+ {
310
+ if (port < TOTAL_PORTS) {
311
+ reportPINs[port] = (byte)value;
312
+ }
313
+ // do not disable analog reporting on these 8 pins, to allow some
314
+ // pins used for digital, others analog. Instead, allow both types
315
+ // of reporting to be enabled, but check if the pin is configured
316
+ // as analog when sampling the analog inputs. Likewise, while
317
+ // scanning digital pins, portConfigInputs will mask off values from any
318
+ // pins configured as analog
319
+ }
320
+
321
+ /*==============================================================================
322
+ * SYSEX-BASED commands
323
+ *============================================================================*/
324
+
325
+ void sysexCallback(byte command, byte argc, byte *argv)
326
+ {
327
+ byte mode;
328
+ byte slaveAddress;
329
+ byte slaveRegister;
330
+ byte data;
331
+ unsigned int delayTime;
332
+
333
+ switch(command) {
334
+ case 0x01: // LED Blink Command
335
+ if(argc < 3) break;
336
+ byte blink_pin;
337
+ byte blink_count;
338
+ blink_pin = argv[0];
339
+ blink_count = argv[1];
340
+ delayTime = argv[2] * 100;
341
+
342
+ pinMode(blink_pin, OUTPUT);
343
+ byte i;
344
+ for(i = 0; i < blink_count; i++){
345
+ digitalWrite(blink_pin, true);
346
+ delay(delayTime);
347
+ digitalWrite(blink_pin, false);
348
+ delay(delayTime);
349
+ }
350
+ Firmata.sendSysex(command, argc, argv); // callback
351
+ break;
352
+ case I2C_REQUEST:
353
+ mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
354
+ if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
355
+ Firmata.sendString("10-bit addressing mode is not yet supported");
356
+ return;
357
+ }
358
+ else {
359
+ slaveAddress = argv[0];
360
+ }
361
+
362
+ switch(mode) {
363
+ case I2C_WRITE:
364
+ Wire.beginTransmission(slaveAddress);
365
+ for (byte i = 2; i < argc; i += 2) {
366
+ data = argv[i] + (argv[i + 1] << 7);
367
+ #if ARDUINO >= 100
368
+ Wire.write(data);
369
+ #else
370
+ Wire.send(data);
371
+ #endif
372
+ }
373
+ Wire.endTransmission();
374
+ delayMicroseconds(70);
375
+ break;
376
+ case I2C_READ:
377
+ if (argc == 6) {
378
+ // a slave register is specified
379
+ slaveRegister = argv[2] + (argv[3] << 7);
380
+ data = argv[4] + (argv[5] << 7); // bytes to read
381
+ readAndReportData(slaveAddress, (int)slaveRegister, data);
382
+ }
383
+ else {
384
+ // a slave register is NOT specified
385
+ data = argv[2] + (argv[3] << 7); // bytes to read
386
+ readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);
387
+ }
388
+ break;
389
+ case I2C_READ_CONTINUOUSLY:
390
+ if ((queryIndex + 1) >= MAX_QUERIES) {
391
+ // too many queries, just ignore
392
+ Firmata.sendString("too many queries");
393
+ break;
394
+ }
395
+ queryIndex++;
396
+ query[queryIndex].addr = slaveAddress;
397
+ query[queryIndex].reg = argv[2] + (argv[3] << 7);
398
+ query[queryIndex].bytes = argv[4] + (argv[5] << 7);
399
+ break;
400
+ case I2C_STOP_READING:
401
+ byte queryIndexToSkip;
402
+ // if read continuous mode is enabled for only 1 i2c device, disable
403
+ // read continuous reporting for that device
404
+ if (queryIndex <= 0) {
405
+ queryIndex = -1;
406
+ } else {
407
+ // if read continuous mode is enabled for multiple devices,
408
+ // determine which device to stop reading and remove it's data from
409
+ // the array, shifiting other array data to fill the space
410
+ for (byte i = 0; i < queryIndex + 1; i++) {
411
+ if (query[i].addr = slaveAddress) {
412
+ queryIndexToSkip = i;
413
+ break;
414
+ }
415
+ }
416
+
417
+ for (byte i = queryIndexToSkip; i<queryIndex + 1; i++) {
418
+ if (i < MAX_QUERIES) {
419
+ query[i].addr = query[i+1].addr;
420
+ query[i].reg = query[i+1].addr;
421
+ query[i].bytes = query[i+1].bytes;
422
+ }
423
+ }
424
+ queryIndex--;
425
+ }
426
+ break;
427
+ default:
428
+ break;
429
+ }
430
+ break;
431
+ case I2C_CONFIG:
432
+ delayTime = (argv[0] + (argv[1] << 7));
433
+
434
+ if(delayTime > 0) {
435
+ i2cReadDelayTime = delayTime;
436
+ }
437
+
438
+ if (!isI2CEnabled) {
439
+ enableI2CPins();
440
+ }
441
+
442
+ break;
443
+ case SERVO_CONFIG:
444
+ if(argc > 4) {
445
+ // these vars are here for clarity, they'll optimized away by the compiler
446
+ byte pin = argv[0];
447
+ int minPulse = argv[1] + (argv[2] << 7);
448
+ int maxPulse = argv[3] + (argv[4] << 7);
449
+
450
+ if (IS_PIN_SERVO(pin)) {
451
+ if (servos[PIN_TO_SERVO(pin)].attached())
452
+ servos[PIN_TO_SERVO(pin)].detach();
453
+ servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
454
+ setPinModeCallback(pin, SERVO);
455
+ }
456
+ }
457
+ break;
458
+ case SAMPLING_INTERVAL:
459
+ if (argc > 1) {
460
+ samplingInterval = argv[0] + (argv[1] << 7);
461
+ if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
462
+ samplingInterval = MINIMUM_SAMPLING_INTERVAL;
463
+ }
464
+ } else {
465
+ //Firmata.sendString("Not enough data");
466
+ }
467
+ break;
468
+ case EXTENDED_ANALOG:
469
+ if (argc > 1) {
470
+ int val = argv[1];
471
+ if (argc > 2) val |= (argv[2] << 7);
472
+ if (argc > 3) val |= (argv[3] << 14);
473
+ analogWriteCallback(argv[0], val);
474
+ }
475
+ break;
476
+ case CAPABILITY_QUERY:
477
+ Serial.write(START_SYSEX);
478
+ Serial.write(CAPABILITY_RESPONSE);
479
+ for (byte pin=0; pin < TOTAL_PINS; pin++) {
480
+ if (IS_PIN_DIGITAL(pin)) {
481
+ Serial.write((byte)INPUT);
482
+ Serial.write(1);
483
+ Serial.write((byte)OUTPUT);
484
+ Serial.write(1);
485
+ }
486
+ if (IS_PIN_ANALOG(pin)) {
487
+ Serial.write(ANALOG);
488
+ Serial.write(10);
489
+ }
490
+ if (IS_PIN_PWM(pin)) {
491
+ Serial.write(PWM);
492
+ Serial.write(8);
493
+ }
494
+ if (IS_PIN_SERVO(pin)) {
495
+ Serial.write(SERVO);
496
+ Serial.write(14);
497
+ }
498
+ if (IS_PIN_I2C(pin)) {
499
+ Serial.write(I2C);
500
+ Serial.write(1); // to do: determine appropriate value
501
+ }
502
+ Serial.write(127);
503
+ }
504
+ Serial.write(END_SYSEX);
505
+ break;
506
+ case PIN_STATE_QUERY:
507
+ if (argc > 0) {
508
+ byte pin=argv[0];
509
+ Serial.write(START_SYSEX);
510
+ Serial.write(PIN_STATE_RESPONSE);
511
+ Serial.write(pin);
512
+ if (pin < TOTAL_PINS) {
513
+ Serial.write((byte)pinConfig[pin]);
514
+ Serial.write((byte)pinState[pin] & 0x7F);
515
+ if (pinState[pin] & 0xFF80) Serial.write((byte)(pinState[pin] >> 7) & 0x7F);
516
+ if (pinState[pin] & 0xC000) Serial.write((byte)(pinState[pin] >> 14) & 0x7F);
517
+ }
518
+ Serial.write(END_SYSEX);
519
+ }
520
+ break;
521
+ case ANALOG_MAPPING_QUERY:
522
+ Serial.write(START_SYSEX);
523
+ Serial.write(ANALOG_MAPPING_RESPONSE);
524
+ for (byte pin=0; pin < TOTAL_PINS; pin++) {
525
+ Serial.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
526
+ }
527
+ Serial.write(END_SYSEX);
528
+ break;
529
+ }
530
+ }
531
+
532
+ void enableI2CPins()
533
+ {
534
+ byte i;
535
+ // is there a faster way to do this? would probaby require importing
536
+ // Arduino.h to get SCL and SDA pins
537
+ for (i=0; i < TOTAL_PINS; i++) {
538
+ if(IS_PIN_I2C(i)) {
539
+ // mark pins as i2c so they are ignore in non i2c data requests
540
+ setPinModeCallback(i, I2C);
541
+ }
542
+ }
543
+
544
+ isI2CEnabled = true;
545
+
546
+ // is there enough time before the first I2C request to call this here?
547
+ Wire.begin();
548
+ }
549
+
550
+ /* disable the i2c pins so they can be used for other functions */
551
+ void disableI2CPins() {
552
+ isI2CEnabled = false;
553
+ // disable read continuous mode for all devices
554
+ queryIndex = -1;
555
+ // uncomment the following if or when the end() method is added to Wire library
556
+ // Wire.end();
557
+ }
558
+
559
+ /*==============================================================================
560
+ * SETUP()
561
+ *============================================================================*/
562
+
563
+ void systemResetCallback()
564
+ {
565
+ // initialize a defalt state
566
+ // TODO: option to load config from EEPROM instead of default
567
+ if (isI2CEnabled) {
568
+ disableI2CPins();
569
+ }
570
+ for (byte i=0; i < TOTAL_PORTS; i++) {
571
+ reportPINs[i] = false; // by default, reporting off
572
+ portConfigInputs[i] = 0; // until activated
573
+ previousPINs[i] = 0;
574
+ }
575
+ // pins with analog capability default to analog input
576
+ // otherwise, pins default to digital output
577
+ for (byte i=0; i < TOTAL_PINS; i++) {
578
+ if (IS_PIN_ANALOG(i)) {
579
+ // turns off pullup, configures everything
580
+ setPinModeCallback(i, ANALOG);
581
+ } else {
582
+ // sets the output to 0, configures portConfigInputs
583
+ setPinModeCallback(i, OUTPUT);
584
+ }
585
+ }
586
+ // by default, do not report any analog inputs
587
+ analogInputsToReport = 0;
588
+
589
+ /* send digital inputs to set the initial state on the host computer,
590
+ * since once in the loop(), this firmware will only send on change */
591
+ /*
592
+ TODO: this can never execute, since no pins default to digital input
593
+ but it will be needed when/if we support EEPROM stored config
594
+ for (byte i=0; i < TOTAL_PORTS; i++) {
595
+ outputPort(i, readPort(i, portConfigInputs[i]), true);
596
+ }
597
+ */
598
+ }
599
+
600
+ void setup()
601
+ {
602
+ Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
603
+
604
+ Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
605
+ Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
606
+ Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
607
+ Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
608
+ Firmata.attach(SET_PIN_MODE, setPinModeCallback);
609
+ Firmata.attach(START_SYSEX, sysexCallback);
610
+ Firmata.attach(SYSTEM_RESET, systemResetCallback);
611
+
612
+ Firmata.begin(57600);
613
+ systemResetCallback(); // reset to default config
614
+ }
615
+
616
+ /*==============================================================================
617
+ * LOOP()
618
+ *============================================================================*/
619
+ void loop()
620
+ {
621
+ byte pin, analogPin;
622
+
623
+ /* DIGITALREAD - as fast as possible, check for changes and output them to the
624
+ * FTDI buffer using Serial.print() */
625
+ checkDigitalInputs();
626
+
627
+ /* SERIALREAD - processing incoming messagse as soon as possible, while still
628
+ * checking digital inputs. */
629
+ while(Firmata.available())
630
+ Firmata.processInput();
631
+
632
+ /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
633
+ * 60 bytes. use a timer to sending an event character every 4 ms to
634
+ * trigger the buffer to dump. */
635
+
636
+ currentMillis = millis();
637
+ if (currentMillis - previousMillis > samplingInterval) {
638
+ previousMillis += samplingInterval;
639
+ /* ANALOGREAD - do all analogReads() at the configured sampling interval */
640
+ for(pin=0; pin<TOTAL_PINS; pin++) {
641
+ if (IS_PIN_ANALOG(pin) && pinConfig[pin] == ANALOG) {
642
+ analogPin = PIN_TO_ANALOG(pin);
643
+ if (analogInputsToReport & (1 << analogPin)) {
644
+ Firmata.sendAnalog(analogPin, analogRead(analogPin));
645
+ }
646
+ }
647
+ }
648
+ // report i2c data for all device with read continuous mode enabled
649
+ if (queryIndex > -1) {
650
+ for (byte i = 0; i < queryIndex + 1; i++) {
651
+ readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
652
+ }
653
+ }
654
+ }
655
+ }