diff --git a/examples/ConfigurableFirmata/ConfigurableFirmata.ino b/examples/ConfigurableFirmata/ConfigurableFirmata.ino index a41a598..697d911 100644 --- a/examples/ConfigurableFirmata/ConfigurableFirmata.ino +++ b/examples/ConfigurableFirmata/ConfigurableFirmata.ino @@ -22,7 +22,7 @@ See file LICENSE.txt for further informations on licensing terms. - Last updated by Jeff Hoefs: April 25, 2015 + Last updated by Jeff Hoefs: October 18, 2015 */ @@ -108,6 +108,9 @@ OneWireFirmata oneWire; #include StepperFirmata stepper; +#include +ToneFirmata toneFirmata; + #include FirmataExt firmataExt; @@ -238,6 +241,9 @@ void setup() #ifdef StepperFirmata_h firmataExt.addFeature(stepper); #endif +#ifdef ToneFirmata_h + firmataExt.addFeature(toneFirmata); +#endif #ifdef FirmataReporting_h firmataExt.addFeature(reporting); #endif diff --git a/src/ConfigurableFirmata.h b/src/ConfigurableFirmata.h index 95888b5..10387fa 100644 --- a/src/ConfigurableFirmata.h +++ b/src/ConfigurableFirmata.h @@ -10,6 +10,8 @@ version 2.1 of the License, or (at your option) any later version. See file LICENSE.txt for further informations on licensing terms. + + Last updated by Jeff Hoefs: October 18th, 2015 */ #ifndef Configurable_Firmata_h @@ -43,6 +45,7 @@ // extended command set using sysex (0-127/0x00-0x7F) /* 0x00-0x0F reserved for user-defined commands */ +#define TONE_MESSAGE 0x5F // control generation and playback of tones #define ENCODER_DATA 0x61 // reply with encoders current positions #define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq #define STRING_DATA 0x71 // a string message with 14-bits per char @@ -82,8 +85,10 @@ #define ONEWIRE 0x07 // pin configured for 1-wire #define STEPPER 0x08 // pin configured for stepper motor #define ENCODER 0x09 // pin configured for encoders +#define MODE_SERIAL 0x0A // pin configured for serial communication +#define MODE_TONE 0x0B // pin configured for tone function #define IGNORE 0x7F // pin configured to be ignored by digitalWrite and capabilityResponse -#define TOTAL_PIN_MODES 11 +#define TOTAL_PIN_MODES 13 extern "C" { // callback function types diff --git a/src/ToneFirmata.cpp b/src/ToneFirmata.cpp new file mode 100644 index 0000000..e16282f --- /dev/null +++ b/src/ToneFirmata.cpp @@ -0,0 +1,92 @@ +/* + ToneFirmata.cpp - Firmata library + Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. + Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved. + Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. + Copyright (C) 2013 Norbert Truchsess. All rights reserved. + Copyright (C) 2009-2015 Jeff Hoefs. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + See file LICENSE.txt for further informations on licensing terms. + + Last updated by Jeff Hoefs: October 18th, 2015 +*/ + +#include +#include "ToneFirmata.h" + +boolean ToneFirmata::handlePinMode(byte pin, int mode) +{ + if (mode == MODE_TONE) { + if (IS_PIN_DIGITAL(pin)) { + //digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM + //pinMode(PIN_TO_DIGITAL(pin), OUTPUT); + return true; + } + } + return false; +} + +void ToneFirmata::handleCapability(byte pin) +{ + if (IS_PIN_DIGITAL(pin)) { + Firmata.write(MODE_TONE); + Firmata.write(14); // 14 bit frequency value + } +} + +/*============================================================================== + * SYSEX-BASED commands + *============================================================================*/ + +// TO DO: make duration optional? +// if duration is option, then noTone would need to be called to end tone +boolean ToneFirmata::handleSysex(byte command, byte argc, byte *argv) +{ + byte toneCommand, pin; + int frequency, duration; + + if (command == TONE_MESSAGE) { + + toneCommand = argv[0]; + pin = argv[1]; + + if (Firmata.getPinMode(pin) != MODE_TONE) { + if (IS_PIN_DIGITAL(pin) && Firmata.getPinMode(pin) != IGNORE) { + Firmata.setPinMode(pin, MODE_TONE); + } + } + + if (toneCommand == TONE_PLAY) { + frequency = argv[2] + (argv[3] << 7); + // duration is currently limited to 16,383 ms + duration = argv[4] + (argv[5] << 7); + tone(pin, frequency, duration); + } + else if (toneCommand == TONE_STOP) { + noTone(pin); + } + return true; + + } + return false; +} + +/*============================================================================== + * SETUP() + *============================================================================*/ + +void ToneFirmata::reset() +{ + // currently reset is called after all pins have been reset to default so + // the following won't work until this is resolved (if necessary) + // for (int i=0; i < TOTAL_PINS; i++) { + // if (Firmata.getPinMode(i) == TONE) { + // noTone(i); + // } + // } +} diff --git a/src/ToneFirmata.h b/src/ToneFirmata.h new file mode 100644 index 0000000..817cbfc --- /dev/null +++ b/src/ToneFirmata.h @@ -0,0 +1,37 @@ +/* + ToneFirmata.h - Firmata library + Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. + Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved. + Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. + Copyright (C) 2013 Norbert Truchsess. All rights reserved. + Copyright (C) 2009-2015 Jeff Hoefs. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + See file LICENSE.txt for further informations on licensing terms. + + Last updated by Jeff Hoefs: October 18th, 2015 +*/ + +#ifndef ToneFirmata_h +#define ToneFirmata_h + +#include +#include "FirmataFeature.h" + +#define TONE_PLAY 0x00 +#define TONE_STOP 0x01 + +class ToneFirmata:public FirmataFeature +{ +public: + boolean handlePinMode(byte pin, int mode); + void handleCapability(byte pin); + boolean handleSysex(byte command, byte argc, byte *argv); + void reset(); +}; + +#endif