diff --git a/MavLink_FrSkySPort/MavLink_FrSkySPort.ino b/MavLink_FrSkySPort/MavLink_FrSkySPort.ino index cb56a5eb9d3d2fc7857c38ef45893a3dadf25d0c..4f8ad542ccb9090cf8fe7a503737e3dd55e9ff08 100644 --- a/MavLink_FrSkySPort/MavLink_FrSkySPort.ino +++ b/MavLink_FrSkySPort/MavLink_FrSkySPort.ino @@ -45,8 +45,34 @@ APM2.5 Mavlink to FrSky X8R SPort interface using Teensy 3.1 http://www.pjrc.co */ #include <GCS_MAVLink.h> +#include <Tone.h> #include "FrSkySPort.h" //////////////////////////////// +Tone tone1; + +#define isdigit(n) (n >= '0' && n <= '9') + +#define OCTAVE_OFFSET 0 + +int notes[] = { 0, + +NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4, +NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, +NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, +NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7 +}; + +//****************************************SONGS***************************************************************** + + +char *song_armed = "MissionImp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d"; +char *song_disarmed = "smbdeath:d=4,o=5,b=90:32c6,32c6,32c6,8p,16b,16f6,16p,16f6,16f.6,16e.6,16d6,16c6,16p,16e,16p,16c"; + +char *song = "Gadget:d=16,o=5,b=50:32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,32d#,32f,32f#,32g#,a#,d#6,4d6,32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,8d#"; + +//****************************************SONGS***************************************************************** +uint8_t song_played = 0; +/////////////////////////////////////////////////////////////////////// #define _MavLinkSerial Serial1 #define START 1 @@ -117,11 +143,15 @@ void setup() { FrSkySPort_Init(); _MavLinkSerial.begin(57600); + //debugSerial.begin(57600); MavLink_Connected = 0; MavLink_Connected_timer=millis(); hb_timer = millis(); hb_count = 0; + + tone1.begin(11); + play_rtttl(song_disarmed); pinMode(led,OUTPUT); pinMode(12,OUTPUT); @@ -162,10 +192,21 @@ void loop() { _MavLink_receive(); // Check MavLink communication FrSkySPort_Process(); // Check FrSky S.Port communication - - adc2 =analogRead(0)/4; // Read ananog value from A0 (Pin 14). ( Will be A2 value on FrSky LCD) + if(song_played == 0 ){ + if(ap_base_mode){ // If ARMED + play_rtttl(song_armed); + song_played = 1; + } + } + if(!ap_base_mode ){ // Not If ARMED + if(song_played == 1){ + play_rtttl(song_disarmed); + song_played = 0; + } + } + adc2 =analogRead(0)/4; // Read ananog value from A0 (Pin 14). ( Will be A2 value on FrSky LCD) } diff --git a/ProminiTONE.jpg b/ProminiTONE.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7c5876185b083d2e9a2cc69661f6016bb84a9b4e Binary files /dev/null and b/ProminiTONE.jpg differ diff --git a/libraries/Tone/Tone.cpp b/libraries/Tone/Tone.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d780cbf71e7bb9bf8fbc2ff1f196ddb2e4003596 --- /dev/null +++ b/libraries/Tone/Tone.cpp @@ -0,0 +1,786 @@ +/* $Id: Tone.cpp 119 2010-07-17 18:56:36Z bhagman@roguerobotics.com $ + + A Tone Generator Library + + Written by Brett Hagman + http://www.roguerobotics.com/ + bhagman@roguerobotics.com + + This library is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + Amended by Lam Kwok Leong + for compatibility with ATmegaA32U4 boards (e.g. Leonardo) and Arduino IDE 1.00 onwards + Used Timer3 instead of Timer2 for such boards + kwok_leong1985@hotmail.com + 2013-08-08 2:20am +8GMT + +*************************************************/ + +#include <avr/interrupt.h> +#include <avr/pgmspace.h> +#if ARDUINO >= 100 + #include <Arduino.h> +#else + #include <WProgram.h> +#endif +#include <pins_arduino.h> +#include "Tone.h" + +#if defined(__AVR_ATmega32U4__) + volatile int32_t timer0_toggle_count; + volatile uint8_t *timer0_pin_port; + volatile uint8_t timer0_pin_mask; + volatile int32_t timer1_toggle_count; + volatile uint8_t *timer1_pin_port; + volatile uint8_t timer1_pin_mask; + volatile int32_t timer3_toggle_count; + volatile uint8_t *timer3_pin_port; + volatile uint8_t timer3_pin_mask; + + #define AVAILABLE_TONE_PINS 3 + const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3, 1, 0 }; + uint8_t Tone::_tone_pin_count = 0; + + void Tone::begin(uint8_t tonePin) + { + if (_tone_pin_count < AVAILABLE_TONE_PINS) + { + _pin = tonePin; + _timer = pgm_read_byte(tone_pin_to_timer_PGM + _tone_pin_count); + _tone_pin_count++; + switch (_timer) + { + case 0: + // 8 bit timer + TCCR0A = 0; + TCCR0B = 0; + bitWrite(TCCR0A, WGM01, 1); + bitWrite(TCCR0B, CS00, 1); + timer0_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer0_pin_mask = digitalPinToBitMask(_pin); + break; + case 1: + // 16 bit timer + TCCR1A = 0; + TCCR1B = 0; + bitWrite(TCCR1B, WGM12, 1); + bitWrite(TCCR1B, CS10, 1); + timer1_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer1_pin_mask = digitalPinToBitMask(_pin); + break; + case 3: + // 16 bit timer + TCCR3A = 0; + TCCR3B = 0; + bitWrite(TCCR3B, WGM32, 1); + bitWrite(TCCR3B, CS30, 1); + timer3_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer3_pin_mask = digitalPinToBitMask(_pin); + break; + } + } + else + { + // disabled + _timer = -1; + } + } + + void Tone::play(uint16_t frequency, uint32_t duration) + { + uint8_t prescalarbits = 0b001; + int32_t toggle_count = 0; + uint32_t ocr = 0; + + if (_timer >= 0) + { + pinMode(_pin, OUTPUT); + + // if we are using an 8 bit timer, scan through prescalars to find the best fit + if (_timer == 0 || _timer == 2) + { + ocr = F_CPU / frequency / 2 - 1; + prescalarbits = 0b001; // ck/1: same for both timers + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 8 - 1; + prescalarbits = 0b010; // ck/8: same for both timers + + if (_timer == 2 && ocr > 255) + { + ocr = F_CPU / frequency / 2 / 32 - 1; + prescalarbits = 0b011; + } + + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 64 - 1; + prescalarbits = _timer == 0 ? 0b011 : 0b100; + + if (_timer == 2 && ocr > 255) + { + ocr = F_CPU / frequency / 2 / 128 - 1; + prescalarbits = 0b101; + } + + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 256 - 1; + prescalarbits = _timer == 0 ? 0b100 : 0b110; + if (ocr > 255) + { + // can't do any better than /1024 + ocr = F_CPU / frequency / 2 / 1024 - 1; + prescalarbits = _timer == 0 ? 0b101 : 0b111; + } + } + } + } + if (_timer == 0) + TCCR0B = (TCCR0B & 0b11111000) | prescalarbits; + } + else + + { + // two choices for the 16 bit timers: ck/1 or ck/64 + ocr = F_CPU / frequency / 2 - 1; + + prescalarbits = 0b001; + if (ocr > 0xffff) + { + ocr = F_CPU / frequency / 2 / 64 - 1; + prescalarbits = 0b011; + } + + if (_timer == 1) + TCCR1B = (TCCR1B & 0b11111000) | prescalarbits; + else if (_timer == 3) + TCCR3B = (TCCR3B & 0b11111000) | prescalarbits; + } + + + // Calculate the toggle count + if (duration > 0) + { + toggle_count = 2 * frequency * duration / 1000; + } + else + { + toggle_count = -1; + } + + // Set the OCR for the given timer, + // set the toggle count, + // then turn on the interrupts + switch (_timer) + { + case 0: + OCR0A = ocr; + timer0_toggle_count = toggle_count; + bitWrite(TIMSK0, OCIE0A, 1); + break; + case 1: + OCR1A = ocr; + timer1_toggle_count = toggle_count; + bitWrite(TIMSK1, OCIE1A, 1); + break; + case 3: + OCR3A = ocr; + timer3_toggle_count = toggle_count; + bitWrite(TIMSK3, OCIE3A, 1); + break; + } + } + } + + + void Tone::stop() + { + switch (_timer) + { + case 0: + TIMSK0 &= ~(1 << OCIE0A); + break; + case 1: + TIMSK1 &= ~(1 << OCIE1A); + break; + case 3: + TIMSK3 &= ~(1 << OCIE3A); + break; + } + + digitalWrite(_pin, 0); + } + + + bool Tone::isPlaying(void) + { + bool returnvalue = false; + + switch (_timer) + { + case 0: + returnvalue = (TIMSK0 & (1 << OCIE0A)); + break; + case 1: + returnvalue = (TIMSK1 & (1 << OCIE1A)); + break; + case 3: + returnvalue = (TIMSK3 & (1 << OCIE3A)); + break; + + } + return returnvalue; + } + + + ISR(TIMER0_COMPA_vect) + { + if (timer0_toggle_count != 0) + { + // toggle the pin + *timer0_pin_port ^= timer0_pin_mask; + + if (timer0_toggle_count > 0) + timer0_toggle_count--; + } + else + { + TIMSK0 &= ~(1 << OCIE0A); // disable the interrupt + *timer0_pin_port &= ~(timer0_pin_mask); // keep pin low after stop + } + } + + ISR(TIMER1_COMPA_vect) + { + if (timer1_toggle_count != 0) + { + // toggle the pin + *timer1_pin_port ^= timer1_pin_mask; + + if (timer1_toggle_count > 0) + timer1_toggle_count--; + } + else + { + TIMSK1 &= ~(1 << OCIE1A); // disable the interrupt + *timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop + } + } + + ISR(TIMER3_COMPA_vect) + { + if (timer3_toggle_count != 0) + { + // toggle the pin + *timer3_pin_port ^= timer3_pin_mask; + + if (timer3_toggle_count > 0) + timer3_toggle_count--; + } + else + { + TIMSK3 &= ~(1 << OCIE3A); // disable the interrupt + *timer3_pin_port &= ~(timer3_pin_mask); // keep pin low after stop + } + } +#elif !defined(__AVR_ATmega32U4__) + + #if defined(__AVR_ATmega8__) + #define TCCR2A TCCR2 + #define TCCR2B TCCR2 + #define COM2A1 COM21 + #define COM2A0 COM20 + #define OCR2A OCR2 + #define TIMSK2 TIMSK + #define OCIE2A OCIE2 + #define TIMER2_COMPA_vect TIMER2_COMP_vect + #define TIMSK1 TIMSK + #endif + + // timerx_toggle_count: + // > 0 - duration specified + // = 0 - stopped + // < 0 - infinitely (until stop() method called, or new play() called) + + #if !defined(__AVR_ATmega8__) + volatile int32_t timer0_toggle_count; + volatile uint8_t *timer0_pin_port; + volatile uint8_t timer0_pin_mask; + #endif + + volatile int32_t timer1_toggle_count; + volatile uint8_t *timer1_pin_port; + volatile uint8_t timer1_pin_mask; + volatile int32_t timer2_toggle_count; + volatile uint8_t *timer2_pin_port; + volatile uint8_t timer2_pin_mask; + + #if defined(__AVR_ATmega1280__) + volatile int32_t timer3_toggle_count; + volatile uint8_t *timer3_pin_port; + volatile uint8_t timer3_pin_mask; + volatile int32_t timer4_toggle_count; + volatile uint8_t *timer4_pin_port; + volatile uint8_t timer4_pin_mask; + volatile int32_t timer5_toggle_count; + volatile uint8_t *timer5_pin_port; + volatile uint8_t timer5_pin_mask; + #endif + + + #if defined(__AVR_ATmega1280__) + + #define AVAILABLE_TONE_PINS 6 + + // Leave timers 1, and zero to last. + const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2, 3, 4, 5, 1, 0 }; + + #elif defined(__AVR_ATmega8__) + + #define AVAILABLE_TONE_PINS 2 + + const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2, 1 }; + + #else + + #define AVAILABLE_TONE_PINS 3 + + // Leave timer 0 to last. + const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2, 1, 0 }; + + #endif + + + + // Initialize our pin count + + uint8_t Tone::_tone_pin_count = 0; + + + void Tone::begin(uint8_t tonePin) + { + if (_tone_pin_count < AVAILABLE_TONE_PINS) + { + _pin = tonePin; + _timer = pgm_read_byte(tone_pin_to_timer_PGM + _tone_pin_count); + _tone_pin_count++; + + // Set timer specific stuff + // All timers in CTC mode + // 8 bit timers will require changing prescalar values, + // whereas 16 bit timers are set to either ck/1 or ck/64 prescalar + switch (_timer) + { + #if !defined(__AVR_ATmega8__) + case 0: + // 8 bit timer + TCCR0A = 0; + TCCR0B = 0; + bitWrite(TCCR0A, WGM01, 1); + bitWrite(TCCR0B, CS00, 1); + timer0_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer0_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + + case 1: + // 16 bit timer + TCCR1A = 0; + TCCR1B = 0; + bitWrite(TCCR1B, WGM12, 1); + bitWrite(TCCR1B, CS10, 1); + timer1_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer1_pin_mask = digitalPinToBitMask(_pin); + break; + case 2: + // 8 bit timer + TCCR2A = 0; + TCCR2B = 0; + bitWrite(TCCR2A, WGM21, 1); + bitWrite(TCCR2B, CS20, 1); + timer2_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer2_pin_mask = digitalPinToBitMask(_pin); + break; + + #if defined(__AVR_ATmega1280__) + case 3: + // 16 bit timer + TCCR3A = 0; + TCCR3B = 0; + bitWrite(TCCR3B, WGM32, 1); + bitWrite(TCCR3B, CS30, 1); + timer3_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer3_pin_mask = digitalPinToBitMask(_pin); + break; + case 4: + // 16 bit timer + TCCR4A = 0; + TCCR4B = 0; + bitWrite(TCCR4B, WGM42, 1); + bitWrite(TCCR4B, CS40, 1); + timer4_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer4_pin_mask = digitalPinToBitMask(_pin); + break; + case 5: + // 16 bit timer + TCCR5A = 0; + TCCR5B = 0; + bitWrite(TCCR5B, WGM52, 1); + bitWrite(TCCR5B, CS50, 1); + timer5_pin_port = portOutputRegister(digitalPinToPort(_pin)); + timer5_pin_mask = digitalPinToBitMask(_pin); + break; + #endif + } + } + else + { + // disabled + _timer = -1; + } + } + + + + // frequency (in hertz) and duration (in milliseconds). + + void Tone::play(uint16_t frequency, uint32_t duration) + { + uint8_t prescalarbits = 0b001; + int32_t toggle_count = 0; + uint32_t ocr = 0; + + if (_timer >= 0) + { + // Set the pinMode as OUTPUT + pinMode(_pin, OUTPUT); + + // if we are using an 8 bit timer, scan through prescalars to find the best fit + if (_timer == 0 || _timer == 2) + { + ocr = F_CPU / frequency / 2 - 1; + prescalarbits = 0b001; // ck/1: same for both timers + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 8 - 1; + prescalarbits = 0b010; // ck/8: same for both timers + + if (_timer == 2 && ocr > 255) + { + ocr = F_CPU / frequency / 2 / 32 - 1; + prescalarbits = 0b011; + } + + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 64 - 1; + prescalarbits = _timer == 0 ? 0b011 : 0b100; + + if (_timer == 2 && ocr > 255) + { + ocr = F_CPU / frequency / 2 / 128 - 1; + prescalarbits = 0b101; + } + + if (ocr > 255) + { + ocr = F_CPU / frequency / 2 / 256 - 1; + prescalarbits = _timer == 0 ? 0b100 : 0b110; + if (ocr > 255) + { + // can't do any better than /1024 + ocr = F_CPU / frequency / 2 / 1024 - 1; + prescalarbits = _timer == 0 ? 0b101 : 0b111; + } + } + } + } + + #if !defined(__AVR_ATmega8__) + if (_timer == 0) + TCCR0B = (TCCR0B & 0b11111000) | prescalarbits; + else + #endif + TCCR2B = (TCCR2B & 0b11111000) | prescalarbits; + } + else + { + // two choices for the 16 bit timers: ck/1 or ck/64 + ocr = F_CPU / frequency / 2 - 1; + + prescalarbits = 0b001; + if (ocr > 0xffff) + { + ocr = F_CPU / frequency / 2 / 64 - 1; + prescalarbits = 0b011; + } + + if (_timer == 1) + TCCR1B = (TCCR1B & 0b11111000) | prescalarbits; + #if defined(__AVR_ATmega1280__) + else if (_timer == 3) + TCCR3B = (TCCR3B & 0b11111000) | prescalarbits; + else if (_timer == 4) + TCCR4B = (TCCR4B & 0b11111000) | prescalarbits; + else if (_timer == 5) + TCCR5B = (TCCR5B & 0b11111000) | prescalarbits; + #endif + + } + + + // Calculate the toggle count + if (duration > 0) + { + toggle_count = 2 * frequency * duration / 1000; + } + else + { + toggle_count = -1; + } + + // Set the OCR for the given timer, + // set the toggle count, + // then turn on the interrupts + switch (_timer) + { + + #if !defined(__AVR_ATmega8__) + case 0: + OCR0A = ocr; + timer0_toggle_count = toggle_count; + bitWrite(TIMSK0, OCIE0A, 1); + break; + #endif + + case 1: + OCR1A = ocr; + timer1_toggle_count = toggle_count; + bitWrite(TIMSK1, OCIE1A, 1); + break; + case 2: + OCR2A = ocr; + timer2_toggle_count = toggle_count; + bitWrite(TIMSK2, OCIE2A, 1); + break; + + #if defined(__AVR_ATmega1280__) + case 3: + OCR3A = ocr; + timer3_toggle_count = toggle_count; + bitWrite(TIMSK3, OCIE3A, 1); + break; + case 4: + OCR4A = ocr; + timer4_toggle_count = toggle_count; + bitWrite(TIMSK4, OCIE4A, 1); + break; + case 5: + OCR5A = ocr; + timer5_toggle_count = toggle_count; + bitWrite(TIMSK5, OCIE5A, 1); + break; + #endif + + } + } + } + + + void Tone::stop() + { + switch (_timer) + { + #if !defined(__AVR_ATmega8__) + case 0: + TIMSK0 &= ~(1 << OCIE0A); + break; + #endif + case 1: + TIMSK1 &= ~(1 << OCIE1A); + break; + case 2: + TIMSK2 &= ~(1 << OCIE2A); + break; + + #if defined(__AVR_ATmega1280__) + case 3: + TIMSK3 &= ~(1 << OCIE3A); + break; + case 4: + TIMSK4 &= ~(1 << OCIE4A); + break; + case 5: + TIMSK5 &= ~(1 << OCIE5A); + break; + #endif + } + + digitalWrite(_pin, 0); + } + + + bool Tone::isPlaying(void) + { + bool returnvalue = false; + + switch (_timer) + { + #if !defined(__AVR_ATmega8__) + case 0: + returnvalue = (TIMSK0 & (1 << OCIE0A)); + break; + #endif + + case 1: + returnvalue = (TIMSK1 & (1 << OCIE1A)); + break; + case 2: + returnvalue = (TIMSK2 & (1 << OCIE2A)); + break; + + #if defined(__AVR_ATmega1280__) + case 3: + returnvalue = (TIMSK3 & (1 << OCIE3A)); + break; + case 4: + returnvalue = (TIMSK4 & (1 << OCIE4A)); + break; + case 5: + returnvalue = (TIMSK5 & (1 << OCIE5A)); + break; + #endif + + } + return returnvalue; + } + + + #if !defined(__AVR_ATmega8__) + ISR(TIMER0_COMPA_vect) + { + if (timer0_toggle_count != 0) + { + // toggle the pin + *timer0_pin_port ^= timer0_pin_mask; + + if (timer0_toggle_count > 0) + timer0_toggle_count--; + } + else + { + TIMSK0 &= ~(1 << OCIE0A); // disable the interrupt + *timer0_pin_port &= ~(timer0_pin_mask); // keep pin low after stop + } + } + #endif + + + ISR(TIMER1_COMPA_vect) + { + if (timer1_toggle_count != 0) + { + // toggle the pin + *timer1_pin_port ^= timer1_pin_mask; + + if (timer1_toggle_count > 0) + timer1_toggle_count--; + } + else + { + TIMSK1 &= ~(1 << OCIE1A); // disable the interrupt + *timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop + } + } + + + ISR(TIMER2_COMPA_vect) + { + int32_t temp_toggle_count = timer2_toggle_count; + + if (temp_toggle_count != 0) + { + // toggle the pin + *timer2_pin_port ^= timer2_pin_mask; + + if (temp_toggle_count > 0) + temp_toggle_count--; + } + else + { + TIMSK2 &= ~(1 << OCIE2A); // disable the interrupt + *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop + } + + timer2_toggle_count = temp_toggle_count; + } + + + + #if defined(__AVR_ATmega1280__) + + ISR(TIMER3_COMPA_vect) + { + if (timer3_toggle_count != 0) + { + // toggle the pin + *timer3_pin_port ^= timer3_pin_mask; + + if (timer3_toggle_count > 0) + timer3_toggle_count--; + } + else + { + TIMSK3 &= ~(1 << OCIE3A); // disable the interrupt + *timer3_pin_port &= ~(timer3_pin_mask); // keep pin low after stop + } + } + + ISR(TIMER4_COMPA_vect) + { + if (timer4_toggle_count != 0) + { + // toggle the pin + *timer4_pin_port ^= timer4_pin_mask; + + if (timer4_toggle_count > 0) + timer4_toggle_count--; + } + else + { + TIMSK4 &= ~(1 << OCIE4A); // disable the interrupt + *timer4_pin_port &= ~(timer4_pin_mask); // keep pin low after stop + } + } + + ISR(TIMER5_COMPA_vect) + { + if (timer5_toggle_count != 0) + { + // toggle the pin + *timer5_pin_port ^= timer5_pin_mask; + + if (timer5_toggle_count > 0) + timer5_toggle_count--; + } + else + { + TIMSK5 &= ~(1 << OCIE5A); // disable the interrupt + *timer5_pin_port &= ~(timer5_pin_mask); // keep pin low after stop + } + } + + #endif +#endif diff --git a/libraries/Tone/Tone.h b/libraries/Tone/Tone.h new file mode 100644 index 0000000000000000000000000000000000000000..be6ca1c2461514d612f29f6b38eaf1cf521435e8 --- /dev/null +++ b/libraries/Tone/Tone.h @@ -0,0 +1,142 @@ +/* $Id: Tone.h 113 2010-06-16 20:16:29Z bhagman@roguerobotics.com $ + + A Tone Generator Library + + Written by Brett Hagman + http://www.roguerobotics.com/ + bhagman@roguerobotics.com + + This library is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +*************************************************/ + +#ifndef _Tone_h +#define _Tone_h + +#include <stdint.h> + +/************************************************* +* Public Constants +*************************************************/ + +#define NOTE_B0 31 +#define NOTE_C1 33 +#define NOTE_CS1 35 +#define NOTE_D1 37 +#define NOTE_DS1 39 +#define NOTE_E1 41 +#define NOTE_F1 44 +#define NOTE_FS1 46 +#define NOTE_G1 49 +#define NOTE_GS1 52 +#define NOTE_A1 55 +#define NOTE_AS1 58 +#define NOTE_B1 62 +#define NOTE_C2 65 +#define NOTE_CS2 69 +#define NOTE_D2 73 +#define NOTE_DS2 78 +#define NOTE_E2 82 +#define NOTE_F2 87 +#define NOTE_FS2 93 +#define NOTE_G2 98 +#define NOTE_GS2 104 +#define NOTE_A2 110 +#define NOTE_AS2 117 +#define NOTE_B2 123 +#define NOTE_C3 131 +#define NOTE_CS3 139 +#define NOTE_D3 147 +#define NOTE_DS3 156 +#define NOTE_E3 165 +#define NOTE_F3 175 +#define NOTE_FS3 185 +#define NOTE_G3 196 +#define NOTE_GS3 208 +#define NOTE_A3 220 +#define NOTE_AS3 233 +#define NOTE_B3 247 +#define NOTE_C4 262 +#define NOTE_CS4 277 +#define NOTE_D4 294 +#define NOTE_DS4 311 +#define NOTE_E4 330 +#define NOTE_F4 349 +#define NOTE_FS4 370 +#define NOTE_G4 392 +#define NOTE_GS4 415 +#define NOTE_A4 440 +#define NOTE_AS4 466 +#define NOTE_B4 494 +#define NOTE_C5 523 +#define NOTE_CS5 554 +#define NOTE_D5 587 +#define NOTE_DS5 622 +#define NOTE_E5 659 +#define NOTE_F5 698 +#define NOTE_FS5 740 +#define NOTE_G5 784 +#define NOTE_GS5 831 +#define NOTE_A5 880 +#define NOTE_AS5 932 +#define NOTE_B5 988 +#define NOTE_C6 1047 +#define NOTE_CS6 1109 +#define NOTE_D6 1175 +#define NOTE_DS6 1245 +#define NOTE_E6 1319 +#define NOTE_F6 1397 +#define NOTE_FS6 1480 +#define NOTE_G6 1568 +#define NOTE_GS6 1661 +#define NOTE_A6 1760 +#define NOTE_AS6 1865 +#define NOTE_B6 1976 +#define NOTE_C7 2093 +#define NOTE_CS7 2217 +#define NOTE_D7 2349 +#define NOTE_DS7 2489 +#define NOTE_E7 2637 +#define NOTE_F7 2794 +#define NOTE_FS7 2960 +#define NOTE_G7 3136 +#define NOTE_GS7 3322 +#define NOTE_A7 3520 +#define NOTE_AS7 3729 +#define NOTE_B7 3951 +#define NOTE_C8 4186 +#define NOTE_CS8 4435 +#define NOTE_D8 4699 +#define NOTE_DS8 4978 + + +/************************************************* +* Definitions +*************************************************/ + +class Tone +{ + public: + void begin(uint8_t tonePin); + bool isPlaying(); + void play(uint16_t frequency, uint32_t duration = 0); + void stop(); + + private: + static uint8_t _tone_pin_count; + uint8_t _pin; + int8_t _timer; +}; + +#endif diff --git a/libraries/Tone/changelog.txt b/libraries/Tone/changelog.txt new file mode 100644 index 0000000000000000000000000000000000000000..927575500d14482c6c20c696f8fcc4a1980cf8d8 --- /dev/null +++ b/libraries/Tone/changelog.txt @@ -0,0 +1,17 @@ +$Id: changelog.txt 120 2010-07-17 19:01:15Z bhagman@roguerobotics.com $ + +Tone Library + +Version Modified By Date Comments +------- ----------- -------- -------- +0001 B Hagman 09/08/02 Initial coding +0002 B Hagman 09/08/18 Fixed: Multiple pins. +0003 B Hagman 09/08/18 Fixed: Moved initialization from constructor to + begin(). +0004 B Hagman 09/09/26 Fixed: Problems with ATmega8. +0005 B Hagman 09/11/23 Fixed: Scanned prescalars for best fit on 8 bit + timers + 09/11/25 Fixed: Pin toggle method to XOR. + 09/11/25 Fixed: timer0 from being excluded. +0006 B Hagman 10/03/21 Fixed: License updates, minor fixes. + B Hagman 10/07/17 Fixed: (more) problems with ATmega8 (thanks to Pete62) diff --git a/libraries/Tone/examples/DTMFTest/DTMFTest.pde b/libraries/Tone/examples/DTMFTest/DTMFTest.pde new file mode 100644 index 0000000000000000000000000000000000000000..92ac9ff46bb38cbc7a79ceac935d242e5b64b484 --- /dev/null +++ b/libraries/Tone/examples/DTMFTest/DTMFTest.pde @@ -0,0 +1,46 @@ +// DTMF (Dual Tone Multiple Frequency) Demonstration + +// http://en.wikipedia.org/wiki/Dual-tone_multi-frequency + +// To mix the output of the signals to output to a small speaker (i.e. 8 Ohms or higher), +// simply use 1K Ohm resistors from each output pin and tie them together at the speaker. +// Don't forget to connect the other side of the speaker to ground! + +#include <Tone.h> + +Tone freq1; +Tone freq2; + +const int DTMF_freq1[] = { 1336, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477 }; +const int DTMF_freq2[] = { 941, 697, 697, 697, 770, 770, 770, 852, 852, 852 }; + +void setup() +{ + Serial.begin(9600); + freq1.begin(11); + freq2.begin(12); +} + +void playDTMF(uint8_t number, long duration) +{ + freq1.play(DTMF_freq1[number], duration); + freq2.play(DTMF_freq2[number], duration); +} + + +void loop() +{ + int i; + uint8_t phone_number[] = { 8, 6, 7, 5, 3, 0 ,9 }; + + for(i = 0; i < sizeof(phone_number); i ++) + { + Serial.print(phone_number[i], 10); + Serial.print(' '); + playDTMF(phone_number[i], 500); + delay(600); + } + + Serial.println(); + delay(4000); +} diff --git a/libraries/Tone/examples/RTTTL/RTTTL.pde b/libraries/Tone/examples/RTTTL/RTTTL.pde new file mode 100644 index 0000000000000000000000000000000000000000..175e2035987b801a44ec506ae7aff53f3072ce58 --- /dev/null +++ b/libraries/Tone/examples/RTTTL/RTTTL.pde @@ -0,0 +1,222 @@ +// A fun sketch to demonstrate the use of the Tone library. + +// To mix the output of the signals to output to a small speaker (i.e. 8 Ohms or higher), +// simply use 1K Ohm resistors from each output pin and tie them together at the speaker. +// Don't forget to connect the other side of the speaker to ground! + +// You can get more RTTTL (RingTone Text Transfer Language) songs from +// http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation + +#include <Tone.h> + +Tone tone1; + +#define OCTAVE_OFFSET 0 + +int notes[] = { 0, +NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4, +NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, +NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, +NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7 +}; + +//char *song = "The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6"; +//char *song = "Indiana:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6"; +//char *song = "TakeOnMe:d=4,o=4,b=160:8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5,8f#5,8e5,8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5"; +//char *song = "Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6"; +//char *song = "Muppets:d=4,o=5,b=250:c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,8a,8p,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,8e,8p,8e,g,2p,c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,a,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,d,8d,c"; +//char *song = "Xfiles:d=4,o=5,b=125:e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,g6,f#6,e6,d6,e6,2b.,1p,g6,f#6,e6,d6,f#6,2b.,1p,e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,e6,2b."; +//char *song = "Looney:d=4,o=5,b=140:32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f"; +//char *song = "20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b"; +//char *song = "Bond:d=4,o=5,b=80:32p,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d#6,16d#6,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d6,16c#6,16c#7,c.7,16g#6,16f#6,g#.6"; +//char *song = "MASH:d=8,o=5,b=140:4a,4g,f#,g,p,f#,p,g,p,f#,p,2e.,p,f#,e,4f#,e,f#,p,e,p,4d.,p,f#,4e,d,e,p,d,p,e,p,d,p,2c#.,p,d,c#,4d,c#,d,p,e,p,4f#,p,a,p,4b,a,b,p,a,p,b,p,2a.,4p,a,b,a,4b,a,b,p,2a.,a,4f#,a,b,p,d6,p,4e.6,d6,b,p,a,p,2b"; +//char *song = "StarWars:d=4,o=5,b=45:32p,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#.6,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#6"; +//char *song = "GoodBad:d=4,o=5,b=56:32p,32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,d#,32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,c#6,32a#,32d#6,32a#,32d#6,8a#.,16f#.,32f.,32d#.,c#,32a#,32d#6,32a#,32d#6,8a#.,16g#.,d#"; +//char *song = "TopGun:d=4,o=4,b=31:32p,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,16f,d#,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,g#"; +//char *song = "A-Team:d=8,o=5,b=125:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#"; +//char *song = "Flinstones:d=4,o=5,b=40:32p,16f6,16a#,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,d6,16f6,16a#.,16a#6,32g6,16f6,16a#.,32f6,32f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,a#,16a6,16d.6,16a#6,32a6,32a6,32g6,32f#6,32a6,8g6,16g6,16c.6,32a6,32a6,32g6,32g6,32f6,32e6,32g6,8f6,16f6,16a#.,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#6,16c7,8a#.6"; +//char *song = "Jeopardy:d=4,o=6,b=125:c,f,c,f5,c,f,2c,c,f,c,f,a.,8g,8f,8e,8d,8c#,c,f,c,f5,c,f,2c,f.,8d,c,a#5,a5,g5,f5,p,d#,g#,d#,g#5,d#,g#,2d#,d#,g#,d#,g#,c.7,8a#,8g#,8g,8f,8e,d#,g#,d#,g#5,d#,g#,2d#,g#.,8f,d#,c#,c,p,a#5,p,g#.5,d#,g#"; +//char *song = "Gadget:d=16,o=5,b=50:32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,32d#,32f,32f#,32g#,a#,d#6,4d6,32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,8d#"; +//char *song = "Smurfs:d=32,o=5,b=200:4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8f#,p,8a#,p,4g#,4p,g#,p,a#,p,b,p,c6,p,4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8b,p,8f,p,4f#"; +//char *song = "MahnaMahna:d=16,o=6,b=125:c#,c.,b5,8a#.5,8f.,4g#,a#,g.,4d#,8p,c#,c.,b5,8a#.5,8f.,g#.,8a#.,4g,8p,c#,c.,b5,8a#.5,8f.,4g#,f,g.,8d#.,f,g.,8d#.,f,8g,8d#.,f,8g,d#,8c,a#5,8d#.,8d#.,4d#,8d#."; +//char *song = "LeisureSuit:d=16,o=6,b=56:f.5,f#.5,g.5,g#5,32a#5,f5,g#.5,a#.5,32f5,g#5,32a#5,g#5,8c#.,a#5,32c#,a5,a#.5,c#.,32a5,a#5,32c#,d#,8e,c#.,f.,f.,f.,f.,f,32e,d#,8d,a#.5,e,32f,e,32f,c#,d#.,c#"; +char *song = "MissionImp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d"; + +void setup(void) +{ + Serial.begin(9600); + tone1.begin(13); +} + +#define isdigit(n) (n >= '0' && n <= '9') + +void play_rtttl(char *p) +{ + // Absolutely no error checking in here + + byte default_dur = 4; + byte default_oct = 6; + int bpm = 63; + int num; + long wholenote; + long duration; + byte note; + byte scale; + + // format: d=N,o=N,b=NNN: + // find the start (skip name, etc) + + while(*p != ':') p++; // ignore name + p++; // skip ':' + + // get default duration + if(*p == 'd') + { + p++; p++; // skip "d=" + num = 0; + while(isdigit(*p)) + { + num = (num * 10) + (*p++ - '0'); + } + if(num > 0) default_dur = num; + p++; // skip comma + } + + Serial.print("ddur: "); Serial.println(default_dur, 10); + + // get default octave + if(*p == 'o') + { + p++; p++; // skip "o=" + num = *p++ - '0'; + if(num >= 3 && num <=7) default_oct = num; + p++; // skip comma + } + + Serial.print("doct: "); Serial.println(default_oct, 10); + + // get BPM + if(*p == 'b') + { + p++; p++; // skip "b=" + num = 0; + while(isdigit(*p)) + { + num = (num * 10) + (*p++ - '0'); + } + bpm = num; + p++; // skip colon + } + + Serial.print("bpm: "); Serial.println(bpm, 10); + + // BPM usually expresses the number of quarter notes per minute + wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds) + + Serial.print("wn: "); Serial.println(wholenote, 10); + + + // now begin note loop + while(*p) + { + // first, get note duration, if available + num = 0; + while(isdigit(*p)) + { + num = (num * 10) + (*p++ - '0'); + } + + if(num) duration = wholenote / num; + else duration = wholenote / default_dur; // we will need to check if we are a dotted note after + + // now get the note + note = 0; + + switch(*p) + { + case 'c': + note = 1; + break; + case 'd': + note = 3; + break; + case 'e': + note = 5; + break; + case 'f': + note = 6; + break; + case 'g': + note = 8; + break; + case 'a': + note = 10; + break; + case 'b': + note = 12; + break; + case 'p': + default: + note = 0; + } + p++; + + // now, get optional '#' sharp + if(*p == '#') + { + note++; + p++; + } + + // now, get optional '.' dotted note + if(*p == '.') + { + duration += duration/2; + p++; + } + + // now, get scale + if(isdigit(*p)) + { + scale = *p - '0'; + p++; + } + else + { + scale = default_oct; + } + + scale += OCTAVE_OFFSET; + + if(*p == ',') + p++; // skip comma for next note (or we may be at the end) + + // now play the note + + if(note) + { + Serial.print("Playing: "); + Serial.print(scale, 10); Serial.print(' '); + Serial.print(note, 10); Serial.print(" ("); + Serial.print(notes[(scale - 4) * 12 + note], 10); + Serial.print(") "); + Serial.println(duration, 10); + tone1.play(notes[(scale - 4) * 12 + note]); + delay(duration); + tone1.stop(); + } + else + { + Serial.print("Pausing: "); + Serial.println(duration, 10); + delay(duration); + } + } +} + +void loop(void) +{ + play_rtttl(song); + Serial.println("Done."); + while(1); +} diff --git a/libraries/Tone/examples/ToneTest/ToneTest.pde b/libraries/Tone/examples/ToneTest/ToneTest.pde new file mode 100644 index 0000000000000000000000000000000000000000..dd174098a949a86a3240dad8f2673baebe0105f1 --- /dev/null +++ b/libraries/Tone/examples/ToneTest/ToneTest.pde @@ -0,0 +1,67 @@ +// Duelling Tones - Simultaneous tone generation. +// To mix the output of the signals to output to a small speaker (i.e. 8 Ohms or higher), +// simply use 1K Ohm resistors from each output pin and tie them together at the speaker. +// Don't forget to connect the other side of the speaker to ground! + +// This example plays notes 'a' through 'g' sent over the Serial Monitor. +// 's' stops the current playing tone. Use uppercase letters for the second. + +#include <Tone.h> + +int notes[] = { NOTE_A3, + NOTE_B3, + NOTE_C4, + NOTE_D4, + NOTE_E4, + NOTE_F4, + NOTE_G4 }; + +// You can declare the tones as an array +Tone notePlayer[2]; + +void setup(void) +{ + Serial.begin(9600); + notePlayer[0].begin(11); + notePlayer[1].begin(12); +} + +void loop(void) +{ + char c; + + if(Serial.available()) + { + c = Serial.read(); + + switch(c) + { + case 'a'...'g': + notePlayer[0].play(notes[c - 'a']); + Serial.println(notes[c - 'a']); + break; + case 's': + notePlayer[0].stop(); + break; + + case 'A'...'G': + notePlayer[1].play(notes[c - 'A']); + Serial.println(notes[c - 'A']); + break; + case 'S': + notePlayer[1].stop(); + break; + + default: + notePlayer[1].stop(); + notePlayer[0].play(NOTE_B2); + delay(300); + notePlayer[0].stop(); + delay(100); + notePlayer[1].play(NOTE_B2); + delay(300); + notePlayer[1].stop(); + break; + } + } +} diff --git a/libraries/Tone/keywords.txt b/libraries/Tone/keywords.txt new file mode 100644 index 0000000000000000000000000000000000000000..f1b23b2184e3116da3071f0eb640dfde227d7a1e --- /dev/null +++ b/libraries/Tone/keywords.txt @@ -0,0 +1,112 @@ +####################################### +# Syntax Coloring Map For Tone +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Tone KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +play KEYWORD2 +stop KEYWORD2 +begin KEYWORD2 +isPlaying KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +NOTE_B0 LITERAL1 +NOTE_C1 LITERAL1 +NOTE_CS1 LITERAL1 +NOTE_D1 LITERAL1 +NOTE_DS1 LITERAL1 +NOTE_E1 LITERAL1 +NOTE_F1 LITERAL1 +NOTE_FS1 LITERAL1 +NOTE_G1 LITERAL1 +NOTE_GS1 LITERAL1 +NOTE_A1 LITERAL1 +NOTE_AS1 LITERAL1 +NOTE_B1 LITERAL1 +NOTE_C2 LITERAL1 +NOTE_CS2 LITERAL1 +NOTE_D2 LITERAL1 +NOTE_DS2 LITERAL1 +NOTE_E2 LITERAL1 +NOTE_F2 LITERAL1 +NOTE_FS2 LITERAL1 +NOTE_G2 LITERAL1 +NOTE_GS2 LITERAL1 +NOTE_A2 LITERAL1 +NOTE_AS2 LITERAL1 +NOTE_B2 LITERAL1 +NOTE_C3 LITERAL1 +NOTE_CS3 LITERAL1 +NOTE_D3 LITERAL1 +NOTE_DS3 LITERAL1 +NOTE_E3 LITERAL1 +NOTE_F3 LITERAL1 +NOTE_FS3 LITERAL1 +NOTE_G3 LITERAL1 +NOTE_GS3 LITERAL1 +NOTE_A3 LITERAL1 +NOTE_AS3 LITERAL1 +NOTE_B3 LITERAL1 +NOTE_C4 LITERAL1 +NOTE_CS4 LITERAL1 +NOTE_D4 LITERAL1 +NOTE_DS4 LITERAL1 +NOTE_E4 LITERAL1 +NOTE_F4 LITERAL1 +NOTE_FS4 LITERAL1 +NOTE_G4 LITERAL1 +NOTE_GS4 LITERAL1 +NOTE_A4 LITERAL1 +NOTE_AS4 LITERAL1 +NOTE_B4 LITERAL1 +NOTE_C5 LITERAL1 +NOTE_CS5 LITERAL1 +NOTE_D5 LITERAL1 +NOTE_DS5 LITERAL1 +NOTE_E5 LITERAL1 +NOTE_F5 LITERAL1 +NOTE_FS5 LITERAL1 +NOTE_G5 LITERAL1 +NOTE_GS5 LITERAL1 +NOTE_A5 LITERAL1 +NOTE_AS5 LITERAL1 +NOTE_B5 LITERAL1 +NOTE_C6 LITERAL1 +NOTE_CS6 LITERAL1 +NOTE_D6 LITERAL1 +NOTE_DS6 LITERAL1 +NOTE_E6 LITERAL1 +NOTE_F6 LITERAL1 +NOTE_FS6 LITERAL1 +NOTE_G6 LITERAL1 +NOTE_GS6 LITERAL1 +NOTE_A6 LITERAL1 +NOTE_AS6 LITERAL1 +NOTE_B6 LITERAL1 +NOTE_C7 LITERAL1 +NOTE_CS7 LITERAL1 +NOTE_D7 LITERAL1 +NOTE_DS7 LITERAL1 +NOTE_E7 LITERAL1 +NOTE_F7 LITERAL1 +NOTE_FS7 LITERAL1 +NOTE_G7 LITERAL1 +NOTE_GS7 LITERAL1 +NOTE_A7 LITERAL1 +NOTE_AS7 LITERAL1 +NOTE_B7 LITERAL1 +NOTE_C8 LITERAL1 +NOTE_CS8 LITERAL1 +NOTE_D8 LITERAL1 +NOTE_DS8 LITERAL1