11/*
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
1110
12- /*
1311 Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
1412 Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
1513 Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
2321
2422 See file LICENSE.txt for further informations on licensing terms.
2523
26- formatted using the GNU C formatting and indenting
24+ Last updated by Jeff Hoefs: April 11, 2015
2725 */
2826
2927/*
30- * TODO: use Program Control to load stored profiles from EEPROM
31- */
28+ README
29+
30+ The Arduino Yun has both an Arduino (Atmega32u4) environment and a
31+ Linux (Linino) environment.
32+
33+ StandardFirmataYun enables Firmata running on the Arduino environment
34+ to communicate with a Firmata client application running on the Linux
35+ environment.
36+ */
3237
3338#include < Servo.h>
3439#include < Wire.h>
3540#include < Firmata.h>
3641
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
42+ #define I2C_WRITE B00000000
43+ #define I2C_READ B00001000
44+ #define I2C_READ_CONTINUOUSLY B00010000
45+ #define I2C_STOP_READING B00011000
46+ #define I2C_READ_WRITE_MODE_MASK B00011000
4347#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
48+ #define MAX_QUERIES 8
49+ #define REGISTER_NOT_SPECIFIED -1
4450
45- # define MAX_QUERIES 8
51+ // the minimum interval for sampling analog input
4652#define MINIMUM_SAMPLING_INTERVAL 10
4753
48- #define REGISTER_NOT_SPECIFIED -1
4954
5055/* ==============================================================================
5156 * GLOBAL VARIABLES
@@ -66,7 +71,7 @@ int pinState[TOTAL_PINS]; // any value that has been written
6671/* timer variables */
6772unsigned long currentMillis; // store the current value from millis()
6873unsigned long previousMillis; // for comparison with currentMillis
69- unsigned int samplingInterval = 19 ; // how often to run the main loop (in ms)
74+ unsigned int samplingInterval = 19 ; // how often to run the main loop (in ms)
7075
7176/* i2c data */
7277struct i2c_device_info {
@@ -78,19 +83,38 @@ struct i2c_device_info {
7883/* for i2c read continuous more */
7984i2c_device_info query[MAX_QUERIES];
8085
81- boolean isResetting = false ;
82-
8386byte i2cRxData[32 ];
8487boolean isI2CEnabled = false ;
8588signed char queryIndex = -1 ;
86- unsigned int i2cReadDelayTime = 0 ; // default delay time between i2c read request and Wire.requestFrom()
89+ // default delay time between i2c read request and Wire.requestFrom()
90+ unsigned int i2cReadDelayTime = 0 ;
8791
8892Servo servos[MAX_SERVOS];
8993byte servoPinMap[TOTAL_PINS];
9094byte detachedServos[MAX_SERVOS];
9195byte detachedServoCount = 0 ;
9296byte servoCount = 0 ;
9397
98+ boolean isResetting = false ;
99+
100+ /* utility functions */
101+ void wireWrite (byte data)
102+ {
103+ #if ARDUINO >= 100
104+ Wire.write ((byte)data);
105+ #else
106+ Wire.send (data);
107+ #endif
108+ }
109+
110+ byte wireRead (void )
111+ {
112+ #if ARDUINO >= 100
113+ return Wire.read ();
114+ #else
115+ return Wire.receive ();
116+ #endif
117+ }
94118
95119/* ==============================================================================
96120 * FUNCTIONS
@@ -103,19 +127,16 @@ void attachServo(byte pin, int minPulse, int maxPulse)
103127 if (detachedServoCount > 0 ) {
104128 servoPinMap[pin] = detachedServos[detachedServoCount - 1 ];
105129 if (detachedServoCount > 0 ) detachedServoCount--;
106- }
107- else {
130+ } else {
108131 servoPinMap[pin] = servoCount;
109132 servoCount++;
110133 }
111134 if (minPulse > 0 && maxPulse > 0 ) {
112135 servos[servoPinMap[pin]].attach (PIN_TO_DIGITAL (pin), minPulse, maxPulse);
113- }
114- else {
136+ } else {
115137 servos[servoPinMap[pin]].attach (PIN_TO_DIGITAL (pin));
116138 }
117- }
118- else {
139+ } else {
119140 Firmata.sendString (" Max servos attached" );
120141 }
121142}
@@ -127,8 +148,7 @@ void detachServo(byte pin)
127148 // otherwise store the index of the detached servo
128149 if (servoPinMap[pin] == servoCount && servoCount > 0 ) {
129150 servoCount--;
130- }
131- else if (servoCount > 0 ) {
151+ } else if (servoCount > 0 ) {
132152 // keep track of detached servos because we want to reuse their indexes
133153 // before incrementing the count of attached servos
134154 detachedServoCount++;
@@ -144,41 +164,31 @@ void readAndReportData(byte address, int theRegister, byte numBytes) {
144164 // do not always require the register read so upon interrupt you call Wire.requestFrom()
145165 if (theRegister != REGISTER_NOT_SPECIFIED) {
146166 Wire.beginTransmission (address);
147- #if ARDUINO >= 100
148- Wire.write ((byte)theRegister);
149- #else
150- Wire.send ((byte)theRegister);
151- #endif
167+ wireWrite ((byte)theRegister);
152168 Wire.endTransmission ();
153169 // do not set a value of 0
154170 if (i2cReadDelayTime > 0 ) {
155171 // delay is necessary for some devices such as WiiNunchuck
156172 delayMicroseconds (i2cReadDelayTime);
157173 }
158- }
159- else {
174+ } else {
160175 theRegister = 0 ; // fill the register with a dummy value
161176 }
162177
163178 Wire.requestFrom (address, numBytes); // all bytes are returned in requestFrom
164179
165180 // check to be sure correct number of bytes were returned by slave
166181 if (numBytes < Wire.available ()) {
167- Firmata.sendString (" I2C Read Error: Too many bytes received" );
168- }
169- else if (numBytes > Wire.available ()) {
170- Firmata.sendString (" I2C Read Error: Too few bytes received" );
182+ Firmata.sendString (" I2C: Too many bytes received" );
183+ } else if (numBytes > Wire.available ()) {
184+ Firmata.sendString (" I2C: Too few bytes received" );
171185 }
172186
173187 i2cRxData[0 ] = address;
174188 i2cRxData[1 ] = theRegister;
175189
176190 for (int i = 0 ; i < numBytes && Wire.available (); i++) {
177- #if ARDUINO >= 100
178- i2cRxData[2 + i] = Wire.read ();
179- #else
180- i2cRxData[2 + i] = Wire.receive ();
181- #endif
191+ i2cRxData[2 + i] = wireRead ();
182192 }
183193
184194 // send slave address, register and received bytes
@@ -228,6 +238,9 @@ void checkDigitalInputs(void)
228238 */
229239void setPinModeCallback (byte pin, int mode)
230240{
241+ if (pinConfig[pin] == IGNORE)
242+ return ;
243+
231244 if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
232245 // disable i2c so pins can be used for other functions
233246 // the following if statements should reconfigure the pins properly
@@ -244,8 +257,7 @@ void setPinModeCallback(byte pin, int mode)
244257 if (IS_PIN_DIGITAL (pin)) {
245258 if (mode == INPUT) {
246259 portConfigInputs[pin / 8 ] |= (1 << (pin & 7 ));
247- }
248- else {
260+ } else {
249261 portConfigInputs[pin / 8 ] &= ~(1 << (pin & 7 ));
250262 }
251263 }
@@ -254,15 +266,15 @@ void setPinModeCallback(byte pin, int mode)
254266 case ANALOG:
255267 if (IS_PIN_ANALOG (pin)) {
256268 if (IS_PIN_DIGITAL (pin)) {
257- pinMode (PIN_TO_DIGITAL (pin), INPUT); // disable output driver
269+ pinMode (PIN_TO_DIGITAL (pin), INPUT); // disable output driver
258270 digitalWrite (PIN_TO_DIGITAL (pin), LOW); // disable internal pull-ups
259271 }
260272 pinConfig[pin] = ANALOG;
261273 }
262274 break ;
263275 case INPUT:
264276 if (IS_PIN_DIGITAL (pin)) {
265- pinMode (PIN_TO_DIGITAL (pin), INPUT); // disable output driver
277+ pinMode (PIN_TO_DIGITAL (pin), INPUT); // disable output driver
266278 digitalWrite (PIN_TO_DIGITAL (pin), LOW); // disable internal pull-ups
267279 pinConfig[pin] = INPUT;
268280 }
@@ -417,11 +429,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
417429 Wire.beginTransmission (slaveAddress);
418430 for (byte i = 2 ; i < argc; i += 2 ) {
419431 data = argv[i] + (argv[i + 1 ] << 7 );
420- #if ARDUINO >= 100
421- Wire.write (data);
422- #else
423- Wire.send (data);
424- #endif
432+ wireWrite (data);
425433 }
426434 Wire.endTransmission ();
427435 delayMicroseconds (70 );
@@ -466,8 +474,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
466474 // read continuous reporting for that device
467475 if (queryIndex <= 0 ) {
468476 queryIndex = -1 ;
469- }
470- else {
477+ } else {
471478 // if read continuous mode is enabled for multiple devices,
472479 // determine which device to stop reading and remove it's data from
473480 // the array, shifiting other array data to fill the space
@@ -526,8 +533,7 @@ void sysexCallback(byte command, byte argc, byte *argv)
526533 if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
527534 samplingInterval = MINIMUM_SAMPLING_INTERVAL;
528535 }
529- }
530- else {
536+ } else {
531537 // Firmata.sendString("Not enough data");
532538 }
533539 break ;
@@ -551,19 +557,19 @@ void sysexCallback(byte command, byte argc, byte *argv)
551557 }
552558 if (IS_PIN_ANALOG (pin)) {
553559 Firmata.write (ANALOG);
554- Firmata.write (10 );
560+ Firmata.write (10 ); // 10 = 10-bit resolution
555561 }
556562 if (IS_PIN_PWM (pin)) {
557563 Firmata.write (PWM);
558- Firmata.write (8 );
564+ Firmata.write (8 ); // 8 = 8-bit resolution
559565 }
560566 if (IS_PIN_DIGITAL (pin)) {
561567 Firmata.write (SERVO);
562568 Firmata.write (14 );
563569 }
564570 if (IS_PIN_I2C (pin)) {
565571 Firmata.write (I2C);
566- Firmata.write (1 ); // to do: determine appropriate value
572+ Firmata.write (1 ); // TODO: could assign a number to map to SCL or SDA
567573 }
568574 Firmata.write (127 );
569575 }
@@ -609,7 +615,6 @@ void enableI2CPins()
609615
610616 isI2CEnabled = true ;
611617
612- // is there enough time before the first I2C request to call this here?
613618 Wire.begin ();
614619}
615620
@@ -627,14 +632,16 @@ void disableI2CPins() {
627632void systemResetCallback ()
628633{
629634 isResetting = true ;
635+
630636 // initialize a defalt state
631637 // TODO: option to load config from EEPROM instead of default
638+
632639 if (isI2CEnabled) {
633640 disableI2CPins ();
634641 }
635642
636643 for (byte i = 0 ; i < TOTAL_PORTS; i++) {
637- reportPINs[i] = false ; // by default, reporting off
644+ reportPINs[i] = false ; // by default, reporting off
638645 portConfigInputs[i] = 0 ; // until activated
639646 previousPINs[i] = 0 ;
640647 }
@@ -645,8 +652,7 @@ void systemResetCallback()
645652 if (IS_PIN_ANALOG (i)) {
646653 // turns off pullup, configures everything
647654 setPinModeCallback (i, ANALOG);
648- }
649- else {
655+ } else {
650656 // sets the output to 0, configures portConfigInputs
651657 setPinModeCallback (i, OUTPUT);
652658 }
@@ -663,11 +669,11 @@ void systemResetCallback()
663669 * since once in the loop(), this firmware will only send on change */
664670 /*
665671 TODO: this can never execute, since no pins default to digital input
666- but it will be needed when/if we support EEPROM stored config
667- for (byte i=0; i < TOTAL_PORTS; i++) {
668- outputPort(i, readPort(i, portConfigInputs[i]), true);
669- }
670- */
672+ but it will be needed when/if we support EEPROM stored config
673+ for (byte i=0; i < TOTAL_PORTS; i++) {
674+ outputPort(i, readPort(i, portConfigInputs[i]), true);
675+ }
676+ */
671677 isResetting = false ;
672678}
673679
@@ -710,14 +716,12 @@ void loop()
710716 * FTDI buffer using Serial.print() */
711717 checkDigitalInputs ();
712718
713- /* SERIALREAD - processing incoming messagse as soon as possible, while still
719+ /* STREAMREAD - processing incoming messagse as soon as possible, while still
714720 * checking digital inputs. */
715721 while (Firmata.available ())
716722 Firmata.processInput ();
717723
718- /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
719- * 60 bytes. use a timer to sending an event character every 4 ms to
720- * trigger the buffer to dump. */
724+ // TODO - ensure that Stream buffer doesn't go over 60 bytes
721725
722726 currentMillis = millis ();
723727 if (currentMillis - previousMillis > samplingInterval) {
@@ -739,4 +743,3 @@ void loop()
739743 }
740744 }
741745}
742-
0 commit comments