1111 Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
1212 Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
1313 Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
14- Copyright (C) 2009-2015 Jeff Hoefs. All rights reserved.
14+ Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved.
1515
1616 This library is free software; you can redistribute it and/or
1717 modify it under the terms of the GNU Lesser General Public
2020
2121 See file LICENSE.txt for further informations on licensing terms.
2222
23- Last updated by Jeff Hoefs: December 26th, 2015
23+ Last updated by Jeff Hoefs: January 10th, 2016
2424*/
2525
2626#include < Servo.h>
4747 * GLOBAL VARIABLES
4848 *============================================================================*/
4949
50+ #ifdef FIRMATA_SERIAL_FEATURE
51+ SerialFirmata serialFeature;
52+ #endif
53+
5054/* analog inputs */
5155int analogInputsToReport = 0 ; // bitwise array to store pin reporting
5256
@@ -55,9 +59,7 @@ byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence
5559byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent
5660
5761/* pins configuration */
58- byte pinConfig[TOTAL_PINS]; // configuration of every pin
5962byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
60- int pinState[TOTAL_PINS]; // any value that has been written
6163
6264/* timer variables */
6365unsigned long currentMillis; // store the current value from millis()
@@ -89,6 +91,7 @@ byte servoCount = 0;
8991
9092boolean isResetting = false ;
9193
94+
9295/* utility functions */
9396void wireWrite (byte data)
9497{
@@ -230,10 +233,10 @@ void checkDigitalInputs(void)
230233 */
231234void setPinModeCallback (byte pin, int mode)
232235{
233- if (pinConfig[ pin] == PIN_MODE_IGNORE)
236+ if (Firmata. getPinMode ( pin) == PIN_MODE_IGNORE)
234237 return ;
235238
236- if (pinConfig[ pin] == PIN_MODE_I2C && isI2CEnabled && mode != PIN_MODE_I2C) {
239+ if (Firmata. getPinMode ( pin) == PIN_MODE_I2C && isI2CEnabled && mode != PIN_MODE_I2C) {
237240 // disable i2c so pins can be used for other functions
238241 // the following if statements should reconfigure the pins properly
239242 disableI2CPins ();
@@ -253,7 +256,7 @@ void setPinModeCallback(byte pin, int mode)
253256 portConfigInputs[pin / 8 ] &= ~(1 << (pin & 7 ));
254257 }
255258 }
256- pinState[ pin] = 0 ;
259+ Firmata. setPinState ( pin, 0 ) ;
257260 switch (mode) {
258261 case PIN_MODE_ANALOG:
259262 if (IS_PIN_ANALOG (pin)) {
@@ -264,7 +267,7 @@ void setPinModeCallback(byte pin, int mode)
264267 digitalWrite (PIN_TO_DIGITAL (pin), LOW); // disable internal pull-ups
265268#endif
266269 }
267- pinConfig[ pin] = PIN_MODE_ANALOG;
270+ Firmata. setPinMode ( pin, PIN_MODE_ANALOG) ;
268271 }
269272 break ;
270273 case INPUT:
@@ -274,33 +277,33 @@ void setPinModeCallback(byte pin, int mode)
274277 // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6
275278 digitalWrite (PIN_TO_DIGITAL (pin), LOW); // disable internal pull-ups
276279#endif
277- pinConfig[ pin] = INPUT;
280+ Firmata. setPinMode ( pin, INPUT) ;
278281 }
279282 break ;
280283 case PIN_MODE_PULLUP:
281284 if (IS_PIN_DIGITAL (pin)) {
282285 pinMode (PIN_TO_DIGITAL (pin), INPUT_PULLUP);
283- pinConfig[ pin] = PIN_MODE_PULLUP;
284- pinState[ pin] = 1 ;
286+ Firmata. setPinMode ( pin, PIN_MODE_PULLUP) ;
287+ Firmata. setPinState ( pin, 1 ) ;
285288 }
286289 break ;
287290 case OUTPUT:
288291 if (IS_PIN_DIGITAL (pin)) {
289292 digitalWrite (PIN_TO_DIGITAL (pin), LOW); // disable PWM
290293 pinMode (PIN_TO_DIGITAL (pin), OUTPUT);
291- pinConfig[ pin] = OUTPUT;
294+ Firmata. setPinMode ( pin, OUTPUT) ;
292295 }
293296 break ;
294297 case PIN_MODE_PWM:
295298 if (IS_PIN_PWM (pin)) {
296299 pinMode (PIN_TO_PWM (pin), OUTPUT);
297300 analogWrite (PIN_TO_PWM (pin), 0 );
298- pinConfig[ pin] = PIN_MODE_PWM;
301+ Firmata. setPinMode ( pin, PIN_MODE_PWM) ;
299302 }
300303 break ;
301304 case PIN_MODE_SERVO:
302305 if (IS_PIN_DIGITAL (pin)) {
303- pinConfig[ pin] = PIN_MODE_SERVO;
306+ Firmata. setPinMode ( pin, PIN_MODE_SERVO) ;
304307 if (servoPinMap[pin] == 255 || !servos[servoPinMap[pin]].attached ()) {
305308 // pass -1 for min and max pulse values to use default values set
306309 // by Servo library
@@ -312,9 +315,14 @@ void setPinModeCallback(byte pin, int mode)
312315 if (IS_PIN_I2C (pin)) {
313316 // mark the pin as i2c
314317 // the user must call I2C_CONFIG to enable I2C for a device
315- pinConfig[ pin] = PIN_MODE_I2C;
318+ Firmata. setPinMode ( pin, PIN_MODE_I2C) ;
316319 }
317320 break ;
321+ case PIN_MODE_SERIAL:
322+ #ifdef FIRMATA_SERIAL_FEATURE
323+ serialFeature.handlePinMode (pin, PIN_MODE_SERIAL);
324+ #endif
325+ break ;
318326 default :
319327 Firmata.sendString (" Unknown pin mode" ); // TODO: put error msgs in EEPROM
320328 }
@@ -330,8 +338,8 @@ void setPinModeCallback(byte pin, int mode)
330338void setPinValueCallback (byte pin, int value)
331339{
332340 if (pin < TOTAL_PINS && IS_PIN_DIGITAL (pin)) {
333- if (pinConfig[ pin] == OUTPUT) {
334- pinState[ pin] = value;
341+ if (Firmata. getPinMode ( pin) == OUTPUT) {
342+ Firmata. setPinState ( pin, value) ;
335343 digitalWrite (PIN_TO_DIGITAL (pin), value);
336344 }
337345 }
@@ -340,16 +348,16 @@ void setPinValueCallback(byte pin, int value)
340348void analogWriteCallback (byte pin, int value)
341349{
342350 if (pin < TOTAL_PINS) {
343- switch (pinConfig[ pin] ) {
351+ switch (Firmata. getPinMode ( pin) ) {
344352 case PIN_MODE_SERVO:
345353 if (IS_PIN_DIGITAL (pin))
346354 servos[servoPinMap[pin]].write (value);
347- pinState[ pin] = value;
355+ Firmata. setPinState ( pin, value) ;
348356 break ;
349357 case PIN_MODE_PWM:
350358 if (IS_PIN_PWM (pin))
351359 analogWrite (PIN_TO_PWM (pin), value);
352- pinState[ pin] = value;
360+ Firmata. setPinState ( pin, value) ;
353361 break ;
354362 }
355363 }
@@ -367,11 +375,11 @@ void digitalWriteCallback(byte port, int value)
367375 // do not disturb non-digital pins (eg, Rx & Tx)
368376 if (IS_PIN_DIGITAL (pin)) {
369377 // do not touch pins in PWM, ANALOG, SERVO or other modes
370- if (pinConfig[ pin] == OUTPUT || pinConfig[ pin] == INPUT) {
378+ if (Firmata. getPinMode ( pin) == OUTPUT || Firmata. getPinMode ( pin) == INPUT) {
371379 pinValue = ((byte)value & mask) ? 1 : 0 ;
372- if (pinConfig[ pin] == OUTPUT) {
380+ if (Firmata. getPinMode ( pin) == OUTPUT) {
373381 pinWriteMask |= mask;
374- } else if (pinConfig[ pin] == INPUT && pinValue == 1 && pinState[ pin] != 1 ) {
382+ } else if (Firmata. getPinMode ( pin) == INPUT && pinValue == 1 && Firmata. getPinState ( pin) != 1 ) {
375383 // only handle INPUT here for backwards compatibility
376384#if ARDUINO > 100
377385 pinMode (pin, INPUT_PULLUP);
@@ -380,7 +388,7 @@ void digitalWriteCallback(byte port, int value)
380388 pinWriteMask |= mask;
381389#endif
382390 }
383- pinState[ pin] = pinValue;
391+ Firmata. setPinState ( pin, pinValue) ;
384392 }
385393 }
386394 mask = mask << 1 ;
@@ -617,6 +625,9 @@ void sysexCallback(byte command, byte argc, byte *argv)
617625 Firmata.write (PIN_MODE_I2C);
618626 Firmata.write (1 ); // TODO: could assign a number to map to SCL or SDA
619627 }
628+ #ifdef FIRMATA_SERIAL_FEATURE
629+ serialFeature.handleCapability (pin);
630+ #endif
620631 Firmata.write (127 );
621632 }
622633 Firmata.write (END_SYSEX);
@@ -628,10 +639,10 @@ void sysexCallback(byte command, byte argc, byte *argv)
628639 Firmata.write (PIN_STATE_RESPONSE);
629640 Firmata.write (pin);
630641 if (pin < TOTAL_PINS) {
631- Firmata.write ((byte)pinConfig[ pin] );
632- Firmata.write ((byte)pinState[ pin] & 0x7F );
633- if (pinState[ pin] & 0xFF80 ) Firmata.write ((byte)(pinState[ pin] >> 7 ) & 0x7F );
634- if (pinState[ pin] & 0xC000 ) Firmata.write ((byte)(pinState[ pin] >> 14 ) & 0x7F );
642+ Firmata.write (Firmata. getPinMode ( pin) );
643+ Firmata.write ((byte)Firmata. getPinState ( pin) & 0x7F );
644+ if (Firmata. getPinState ( pin) & 0xFF80 ) Firmata.write ((byte)(Firmata. getPinState ( pin) >> 7 ) & 0x7F );
645+ if (Firmata. getPinState ( pin) & 0xC000 ) Firmata.write ((byte)(Firmata. getPinState ( pin) >> 14 ) & 0x7F );
635646 }
636647 Firmata.write (END_SYSEX);
637648 }
@@ -644,6 +655,12 @@ void sysexCallback(byte command, byte argc, byte *argv)
644655 }
645656 Firmata.write (END_SYSEX);
646657 break ;
658+
659+ case SERIAL_MESSAGE:
660+ #ifdef FIRMATA_SERIAL_FEATURE
661+ serialFeature.handleSysex (command, argc, argv);
662+ #endif
663+ break ;
647664 }
648665}
649666
@@ -682,6 +699,10 @@ void systemResetCallback()
682699 // initialize a defalt state
683700 // TODO: option to load config from EEPROM instead of default
684701
702+ #ifdef FIRMATA_SERIAL_FEATURE
703+ serialFeature.reset ();
704+ #endif
705+
685706 if (isI2CEnabled) {
686707 disableI2CPins ();
687708 }
@@ -740,12 +761,13 @@ void setup()
740761 // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
741762 // Serial1.begin(57600);
742763 // Firmata.begin(Serial1);
743- // then comment out or remove lines 701 - 704 below
764+ // However do not do this if you are using SERIAL_MESSAGE
744765
745766 Firmata.begin (57600 );
746767 while (!Serial) {
747768 ; // wait for serial port to connect. Needed for ATmega32u4-based boards and Arduino 101
748769 }
770+
749771 systemResetCallback (); // reset to default config
750772}
751773
@@ -772,7 +794,7 @@ void loop()
772794 previousMillis += samplingInterval;
773795 /* ANALOGREAD - do all analogReads() at the configured sampling interval */
774796 for (pin = 0 ; pin < TOTAL_PINS; pin++) {
775- if (IS_PIN_ANALOG (pin) && pinConfig[ pin] == PIN_MODE_ANALOG) {
797+ if (IS_PIN_ANALOG (pin) && Firmata. getPinMode ( pin) == PIN_MODE_ANALOG) {
776798 analogPin = PIN_TO_ANALOG (pin);
777799 if (analogInputsToReport & (1 << analogPin)) {
778800 Firmata.sendAnalog (analogPin, analogRead (analogPin));
@@ -786,4 +808,8 @@ void loop()
786808 }
787809 }
788810 }
811+
812+ #ifdef FIRMATA_SERIAL_FEATURE
813+ serialFeature.update ();
814+ #endif
789815}
0 commit comments