Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tone support to StandardFirmata. #204

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Firmata.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

// extended command set using sysex (0-127/0x00-0x7F)
/* 0x00-0x0F reserved for user-defined commands */
#define TONE_DATA 0x5F // send a tone or noTone command
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TONE_MESSAGE

#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
Expand Down Expand Up @@ -79,8 +80,9 @@
#define ONEWIRE 0x07 // pin configured for 1-wire
#define STEPPER 0x08 // pin configured for stepper motor
#define ENCODER 0x09 // pin configured for rotary encoders
#define TONE 0x0A // 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 12

extern "C" {
// callback function types
Expand Down
34 changes: 34 additions & 0 deletions examples/StandardFirmata/StandardFirmata.ino
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include <Wire.h>
#include <Firmata.h>

#define TONE_TONE 0x00
#define TONE_NO_TONE 0x01

#define I2C_WRITE B00000000
#define I2C_READ B00001000
#define I2C_READ_CONTINUOUSLY B00010000
Expand Down Expand Up @@ -229,6 +232,9 @@ void setPinModeCallback(byte pin, int mode)
if (pinConfig[pin] == IGNORE)
return;

if (pinConfig[pin] == TONE && mode != TONE) {
noTone(pin);
}
if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
// disable i2c so pins can be used for other functions
// the following if statements should reconfigure the pins properly
Expand Down Expand Up @@ -298,6 +304,13 @@ void setPinModeCallback(byte pin, int mode)
pinConfig[pin] = I2C;
}
break;
case TONE:
if (IS_PIN_DIGITAL(pin)) {
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
pinConfig[pin] = TONE;
}
break;
default:
Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
}
Expand Down Expand Up @@ -402,6 +415,23 @@ void sysexCallback(byte command, byte argc, byte *argv)
unsigned int delayTime;

switch (command) {
case TONE_DATA:
if (argc > 1) {
byte toneCommand = argv[0];
byte pin = argv[1];

if (toneCommand == TONE_TONE && argc > 5) {
unsigned int frequency = argv[2] + (argv[3] << 7);
// duration is currently limited to 16,383 ms
unsigned int duration = argv[4] + (argv[5] << 7);
setPinModeCallback(pin, TONE);
tone(pin, frequency, duration);
}
if (toneCommand == TONE_NO_TONE) {
noTone(pin);
}
}
break;
case I2C_REQUEST:
mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
Expand Down Expand Up @@ -555,6 +585,10 @@ void sysexCallback(byte command, byte argc, byte *argv)
Firmata.write(SERVO);
Firmata.write(14);
}
if (IS_PIN_DIGITAL(pin)) {
Firmata.write(TONE);
Firmata.write(14); // 14 bit frequency value
}
if (IS_PIN_I2C(pin)) {
Firmata.write(I2C);
Firmata.write(1); // TODO: could assign a number to map to SCL or SDA
Expand Down