Last active
January 20, 2019 16:56
-
-
Save nicfv/cc14bebc90ee342be4aa041bd208880d to your computer and use it in GitHub Desktop.
BMES Make-A-Thon Jan 2019
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define ARD true // Set to true if Arduino, false if Trinket. | |
#define ANG 180 // Defines the angle of rotation for the servo motor. | |
#if ARD // Arduino Globals: | |
const int motorPin = 10; | |
const int LEDPin = 4; | |
const int soundPin = 9; | |
const int buttonPin = 2; | |
#include <Servo.h> // Include the Servo library. | |
Servo myServo; // Create a servo object. | |
#else // Trinket Globals: | |
const int motorPin = PB2; | |
const int LEDPin = PB0; | |
const int soundPin = PB1; | |
const int buttonPin = PB3; | |
#include <Adafruit_SoftServo.h> // Include the Adafruit Trinket Servo library. | |
Adafruit_SoftServo myServo; // Create an Adafruit Trinket servo object. | |
#endif | |
void setup() { | |
#if !ARD | |
OCR0A = 0xAF; // any number is OK | |
TIMSK |= _BV(OCIE0A); // Turn on the compare interrupt (below!) | |
#endif | |
pinMode(LEDPin, OUTPUT); | |
pinMode(soundPin, OUTPUT); | |
pinMode(buttonPin, INPUT); | |
myServo.attach(motorPin); // Attaches the servo on motorPin to the servo object. | |
digitalWrite(buttonPin, HIGH); | |
// Set the servo position. | |
myServo.write(0); | |
} | |
void loop() { | |
if(digitalRead(buttonPin) == LOW) { | |
// The button is pressed. | |
// Light up the LED. | |
digitalWrite(LEDPin, HIGH); | |
// Play the sound to start. | |
play("ee e ce g", 9, 100); | |
// Pause for a short time. | |
delay(1000); | |
// Set the servo position. | |
myServo.write(0); | |
delay(1000); | |
myServo.write(ANG); | |
delay(1000); | |
myServo.write(0); | |
delay(1000); | |
// Play the sound to indicate completeness. | |
play("bg", 2, 100); | |
// Turn off the LED. | |
digitalWrite(LEDPin, LOW); | |
} else if(digitalRead(buttonPin) == HIGH) { | |
// The button is not pressed. | |
} else { | |
// I'm not sure what the result is. | |
} | |
} | |
void play(char notes[], int len, int tempo) { | |
for (int i = 0; i < len; i++) // step through the song arrays | |
{ | |
if (notes[i] == ' ') // is this a rest? | |
{ | |
delay(tempo); // then pause for a moment | |
} | |
else // otherwise, play the note | |
{ | |
#if ARD // Arduino Sound: | |
tone(soundPin, frequency(notes[i]), tempo); | |
#else // Trinket Sound: | |
analogWrite(soundPin, frequency(notes[i])); | |
#endif | |
delay(tempo); // wait for tone to finish | |
} | |
delay(tempo/10); // brief pause between notes | |
} | |
#if !ARD | |
digitalWrite(soundPin, LOW); | |
#endif | |
} | |
int frequency(char note) | |
{ | |
// This function takes a note character (a-g), and returns the | |
// corresponding frequency in Hz for the tone() function. | |
const int numNotes = 8; // number of notes we're storing | |
// The following arrays hold the note characters and their | |
// corresponding frequencies. The last "C" note is uppercase | |
// to separate it from the first lowercase "c". If you want to | |
// add more notes, you'll need to use unique characters. | |
// For the "char" (character) type, we put single characters | |
// in single quotes. | |
char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' }; | |
int frequencies[] = {262, 294, 330, 349, 392, 440, 494, 523}; | |
// Now we'll search through the letters in the array, and if | |
// we find it, we'll return the frequency for that note. | |
for (int i = 0; i < numNotes; i++) // Step through the notes | |
{ | |
if (names[i] == note) // Is this the one? | |
{ | |
return(frequencies[i]); // Yes! Return the frequency | |
} | |
} | |
return(0); // We looked through everything and didn't find it, | |
// but we still need to return a value, so return 0. | |
} | |
#if !ARD | |
// We'll take advantage of the built in millis() timer that goes off | |
// to keep track of time, and refresh the servo every 20 milliseconds | |
// The SIGNAL(TIMER0_COMPA_vect) function is the interrupt that will be | |
// Called by the microcontroller every 2 milliseconds | |
volatile uint8_t counter = 0; | |
SIGNAL(TIMER0_COMPA_vect) { | |
// this gets called every 2 milliseconds | |
counter += 2; | |
// every 20 milliseconds, refresh the servos! | |
if (counter >= 20) { | |
counter = 0; | |
myServo.refresh(); | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment