1
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
- */
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
+ https://github.com/firmata/arduino#firmata-client-libraries
11
10
12
- /*
13
11
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
14
12
Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
15
13
Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
16
- Copyright (C) 2009-2014 Jeff Hoefs. All rights reserved.
14
+ Copyright (C) 2009-2015 Jeff Hoefs. All rights reserved.
17
15
18
16
This library is free software; you can redistribute it and/or
19
17
modify it under the terms of the GNU Lesser General Public
22
20
23
21
See file LICENSE.txt for further informations on licensing terms.
24
22
25
- formatted using the GNU C formatting and indenting
23
+ Last updated by Jeff Hoefs: April 11, 2015
26
24
*/
27
25
28
- /*
29
- * TODO: use Program Control to load stored profiles from EEPROM
30
- */
31
-
32
26
#include < Servo.h>
33
27
#include < Wire.h>
34
28
#include < Firmata.h>
35
29
36
- // move the following defines to Firmata.h?
37
- #define I2C_WRITE B00000000
38
- #define I2C_READ B00001000
39
- #define I2C_READ_CONTINUOUSLY B00010000
40
- #define I2C_STOP_READING B00011000
41
- #define I2C_READ_WRITE_MODE_MASK B00011000
30
+ #define I2C_WRITE B00000000
31
+ #define I2C_READ B00001000
32
+ #define I2C_READ_CONTINUOUSLY B00010000
33
+ #define I2C_STOP_READING B00011000
34
+ #define I2C_READ_WRITE_MODE_MASK B00011000
42
35
#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
36
+ #define MAX_QUERIES 8
37
+ #define REGISTER_NOT_SPECIFIED -1
43
38
44
- # define MAX_QUERIES 8
39
+ // the minimum interval for sampling analog input
45
40
#define MINIMUM_SAMPLING_INTERVAL 10
46
41
47
- #define REGISTER_NOT_SPECIFIED -1
48
42
49
43
/* ==============================================================================
50
44
* GLOBAL VARIABLES
@@ -65,7 +59,7 @@ int pinState[TOTAL_PINS]; // any value that has been written
65
59
/* timer variables */
66
60
unsigned long currentMillis; // store the current value from millis()
67
61
unsigned long previousMillis; // for comparison with currentMillis
68
- unsigned int samplingInterval = 19 ; // how often to run the main loop (in ms)
62
+ unsigned int samplingInterval = 19 ; // how often to run the main loop (in ms)
69
63
70
64
/* i2c data */
71
65
struct i2c_device_info {
@@ -77,19 +71,38 @@ struct i2c_device_info {
77
71
/* for i2c read continuous more */
78
72
i2c_device_info query[MAX_QUERIES];
79
73
80
- boolean isResetting = false ;
81
-
82
74
byte i2cRxData[32 ];
83
75
boolean isI2CEnabled = false ;
84
76
signed char queryIndex = -1 ;
85
- unsigned int i2cReadDelayTime = 0 ; // default delay time between i2c read request and Wire.requestFrom()
77
+ // default delay time between i2c read request and Wire.requestFrom()
78
+ unsigned int i2cReadDelayTime = 0 ;
86
79
87
80
Servo servos[MAX_SERVOS];
88
81
byte servoPinMap[TOTAL_PINS];
89
82
byte detachedServos[MAX_SERVOS];
90
83
byte detachedServoCount = 0 ;
91
84
byte servoCount = 0 ;
92
85
86
+ boolean isResetting = false ;
87
+
88
+ /* utility functions */
89
+ void wireWrite (byte data)
90
+ {
91
+ #if ARDUINO >= 100
92
+ Wire.write ((byte)data);
93
+ #else
94
+ Wire.send (data);
95
+ #endif
96
+ }
97
+
98
+ byte wireRead (void )
99
+ {
100
+ #if ARDUINO >= 100
101
+ return Wire.read ();
102
+ #else
103
+ return Wire.receive ();
104
+ #endif
105
+ }
93
106
94
107
/* ==============================================================================
95
108
* FUNCTIONS
@@ -139,11 +152,7 @@ void readAndReportData(byte address, int theRegister, byte numBytes) {
139
152
// do not always require the register read so upon interrupt you call Wire.requestFrom()
140
153
if (theRegister != REGISTER_NOT_SPECIFIED) {
141
154
Wire.beginTransmission (address);
142
- #if ARDUINO >= 100
143
- Wire.write ((byte)theRegister);
144
- #else
145
- Wire.send ((byte)theRegister);
146
- #endif
155
+ wireWrite ((byte)theRegister);
147
156
Wire.endTransmission ();
148
157
// do not set a value of 0
149
158
if (i2cReadDelayTime > 0 ) {
@@ -158,20 +167,16 @@ void readAndReportData(byte address, int theRegister, byte numBytes) {
158
167
159
168
// check to be sure correct number of bytes were returned by slave
160
169
if (numBytes < Wire.available ()) {
161
- Firmata.sendString (" I2C Read Error : Too many bytes received" );
170
+ Firmata.sendString (" I2C: Too many bytes received" );
162
171
} else if (numBytes > Wire.available ()) {
163
- Firmata.sendString (" I2C Read Error : Too few bytes received" );
172
+ Firmata.sendString (" I2C: Too few bytes received" );
164
173
}
165
174
166
175
i2cRxData[0 ] = address;
167
176
i2cRxData[1 ] = theRegister;
168
177
169
178
for (int i = 0 ; i < numBytes && Wire.available (); i++) {
170
- #if ARDUINO >= 100
171
- i2cRxData[2 + i] = Wire.read ();
172
- #else
173
- i2cRxData[2 + i] = Wire.receive ();
174
- #endif
179
+ i2cRxData[2 + i] = wireRead ();
175
180
}
176
181
177
182
// send slave address, register and received bytes
@@ -221,6 +226,9 @@ void checkDigitalInputs(void)
221
226
*/
222
227
void setPinModeCallback (byte pin, int mode)
223
228
{
229
+ if (pinConfig[pin] == IGNORE)
230
+ return ;
231
+
224
232
if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
225
233
// disable i2c so pins can be used for other functions
226
234
// the following if statements should reconfigure the pins properly
@@ -246,15 +254,15 @@ void setPinModeCallback(byte pin, int mode)
246
254
case ANALOG:
247
255
if (IS_PIN_ANALOG (pin)) {
248
256
if (IS_PIN_DIGITAL (pin)) {
249
- pinMode (PIN_TO_DIGITAL (pin), INPUT); // disable output driver
257
+ pinMode (PIN_TO_DIGITAL (pin), INPUT); // disable output driver
250
258
digitalWrite (PIN_TO_DIGITAL (pin), LOW); // disable internal pull-ups
251
259
}
252
260
pinConfig[pin] = ANALOG;
253
261
}
254
262
break ;
255
263
case INPUT:
256
264
if (IS_PIN_DIGITAL (pin)) {
257
- pinMode (PIN_TO_DIGITAL (pin), INPUT); // disable output driver
265
+ pinMode (PIN_TO_DIGITAL (pin), INPUT); // disable output driver
258
266
digitalWrite (PIN_TO_DIGITAL (pin), LOW); // disable internal pull-ups
259
267
pinConfig[pin] = INPUT;
260
268
}
@@ -409,11 +417,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
409
417
Wire.beginTransmission (slaveAddress);
410
418
for (byte i = 2 ; i < argc; i += 2 ) {
411
419
data = argv[i] + (argv[i + 1 ] << 7 );
412
- #if ARDUINO >= 100
413
- Wire.write (data);
414
- #else
415
- Wire.send (data);
416
- #endif
420
+ wireWrite (data);
417
421
}
418
422
Wire.endTransmission ();
419
423
delayMicroseconds (70 );
@@ -541,19 +545,19 @@ void sysexCallback(byte command, byte argc, byte *argv)
541
545
}
542
546
if (IS_PIN_ANALOG (pin)) {
543
547
Firmata.write (ANALOG);
544
- Firmata.write (10 );
548
+ Firmata.write (10 ); // 10 = 10-bit resolution
545
549
}
546
550
if (IS_PIN_PWM (pin)) {
547
551
Firmata.write (PWM);
548
- Firmata.write (8 );
552
+ Firmata.write (8 ); // 8 = 8-bit resolution
549
553
}
550
554
if (IS_PIN_DIGITAL (pin)) {
551
555
Firmata.write (SERVO);
552
556
Firmata.write (14 );
553
557
}
554
558
if (IS_PIN_I2C (pin)) {
555
559
Firmata.write (I2C);
556
- Firmata.write (1 ); // to do: determine appropriate value
560
+ Firmata.write (1 ); // TODO: could assign a number to map to SCL or SDA
557
561
}
558
562
Firmata.write (127 );
559
563
}
@@ -599,7 +603,6 @@ void enableI2CPins()
599
603
600
604
isI2CEnabled = true ;
601
605
602
- // is there enough time before the first I2C request to call this here?
603
606
Wire.begin ();
604
607
}
605
608
@@ -617,14 +620,16 @@ void disableI2CPins() {
617
620
void systemResetCallback ()
618
621
{
619
622
isResetting = true ;
623
+
620
624
// initialize a defalt state
621
625
// TODO: option to load config from EEPROM instead of default
626
+
622
627
if (isI2CEnabled) {
623
628
disableI2CPins ();
624
629
}
625
630
626
631
for (byte i = 0 ; i < TOTAL_PORTS; i++) {
627
- reportPINs[i] = false ; // by default, reporting off
632
+ reportPINs[i] = false ; // by default, reporting off
628
633
portConfigInputs[i] = 0 ; // until activated
629
634
previousPINs[i] = 0 ;
630
635
}
@@ -687,14 +692,12 @@ void loop()
687
692
* FTDI buffer using Serial.print() */
688
693
checkDigitalInputs ();
689
694
690
- /* SERIALREAD - processing incoming messagse as soon as possible, while still
695
+ /* STREAMREAD - processing incoming messagse as soon as possible, while still
691
696
* checking digital inputs. */
692
697
while (Firmata.available ())
693
698
Firmata.processInput ();
694
699
695
- /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
696
- * 60 bytes. use a timer to sending an event character every 4 ms to
697
- * trigger the buffer to dump. */
700
+ // TODO - ensure that Stream buffer doesn't go over 60 bytes
698
701
699
702
currentMillis = millis ();
700
703
if (currentMillis - previousMillis > samplingInterval) {
0 commit comments