//Cinderalla MIDI tune
#include <avr/pgmspace.h> //notes and corresponding duration are stored in flash memory of the arduino
#include <Servo.h> //library for servo motor
Servo myservo; //
Servo baseServo; //
static const uint8_t tonePin = 4; //speaker pin
const int ledPin = LED_BUILTIN; //led pin
int ledState = LOW;
int pirLeft = 7; // pir motion sensor pins
int pirRight = 6 ;
unsigned long previousMillis = 0; const long interval = 1000;
unsigned long previousMillispir = 0; const long headsup = 1000;
//Notes definition : The duration is in the upper 8 bits, and the note is in the lower 8 bits.
// Octave 5 Note Codes
#define NOTE_C_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01010000)
#define NOTE_CS_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01010001)
#define NOTE_D_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01010010)
#define NOTE_DS_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01010011)
#define NOTE_E_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01010100)
#define NOTE_F_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01010101)
#define NOTE_FS_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01010110)
#define NOTE_G_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01010111)
#define NOTE_GS_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01011000)
#define NOTE_A_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01011001)
#define NOTE_AS_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01011010)
#define NOTE_B_5(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01011011)
// Octave 6 Note Codes
#define NOTE_C_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01100000)
#define NOTE_CS_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01100001)
#define NOTE_D_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01100010)
#define NOTE_DS_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01100011)
#define NOTE_E_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01100100)
#define NOTE_F_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01100101)
#define NOTE_FS_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01100110)
#define NOTE_G_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01100111)
#define NOTE_GS_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01101000)
#define NOTE_A_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01101001)
#define NOTE_AS_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01101010)
#define NOTE_B_6(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01101011)
// Octave 7 Note Codes
#define NOTE_C_7(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01110000)
#define NOTE_CS_7(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01110001)
#define NOTE_D_7(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01110010)
#define NOTE_DS_7(DURATION) ( (((uint16_t)DURATION)<<8) | 0b01110011)
#define NOTE_SILENT(DURATION) ((((uint16_t)DURATION)<<8) | 0b00001111)
#define NUMBER_OF_MELODIES 1
void setup()
{
myservo.attach(3); // rudder motion servo
baseServo.attach(5); // base motor (to be replaced with stepper)
pinMode(ledPin, OUTPUT);
pinMode(pirLeft, INPUT);
pinMode(pirRight, INPUT);
Serial.begin(9600);
uint8_t melodyToPlay = 0;
uint8_t tempoToPlay = 4; //how fast song is being played ( 1 being fastest and 127 being slowest)
playMelody(melodyToPlay, tempoToPlay); // Main funtion call
}
//----------------------------
void loop()
{
// If the tune needs to be continuoslys played in loop place main funtion in the loop.
}
// TWINKLE TWINKLE
static const uint16_t Melody0[] PROGMEM = {
NOTE_C_6( 89 ), NOTE_SILENT( 31 ), NOTE_C_6( 119 ), NOTE_G_6( 149 ),
NOTE_SILENT(91 ), NOTE_A_6( 89 ), NOTE_SILENT( 31), NOTE_A_6( 119 ),
NOTE_G_6( 209 ), NOTE_SILENT( 31 ), NOTE_F_6( 89 ), NOTE_SILENT( 31 ),
NOTE_F_6( 119 ), NOTE_E_6( 89 ), NOTE_SILENT(31 ), NOTE_E_6( 119 ),
NOTE_D_6( 89 ), NOTE_SILENT( 31 ), NOTE_D_6( 89 ), NOTE_SILENT( 31 ),
NOTE_C_6( 209 ), NOTE_SILENT( 31 ), NOTE_G_6( 89 ), NOTE_SILENT( 31 ),
NOTE_G_6( 89 ), NOTE_SILENT( 31 ), NOTE_F_6( 89 ), NOTE_SILENT( 31 ),
NOTE_F_6( 89 ), NOTE_SILENT( 31 ), NOTE_E_6( 89 ), NOTE_SILENT( 31 ),
NOTE_E_6( 89 ), NOTE_SILENT( 31 ), NOTE_D_6( 179 ), NOTE_SILENT( 61 ),
NOTE_G_6( 89 ), NOTE_SILENT( 31 ), NOTE_G_6( 89 ), NOTE_SILENT( 31 ),
NOTE_F_6( 59 ), NOTE_SILENT( 61 ), NOTE_F_6( 89 ), NOTE_SILENT( 31 ),
NOTE_E_6( 89 ), NOTE_SILENT( 31 ), NOTE_E_6( 59 ), NOTE_SILENT( 61 ),
NOTE_D_6( 179 ), NOTE_SILENT( 61 ), NOTE_C_6( 89 ), NOTE_SILENT( 31 ),
NOTE_C_6( 59 ), NOTE_SILENT( 61 ), NOTE_G_6( 89 ), NOTE_SILENT( 31 ),
NOTE_G_6( 89 ), NOTE_SILENT( 31 ), NOTE_A_6( 89 ), NOTE_SILENT( 31 ),
NOTE_A_6( 89 ), NOTE_SILENT( 31 ), NOTE_G_6( 179 ), NOTE_SILENT( 61 ),
NOTE_F_6( 89 ), NOTE_SILENT( 31 ), NOTE_F_6( 59 ), NOTE_SILENT( 61 ),
NOTE_E_6( 59 ), NOTE_SILENT( 61 ), NOTE_E_6( 59 ), NOTE_SILENT( 61 ),
NOTE_D_6( 89 ), NOTE_SILENT( 31 ), NOTE_D_6( 59 ), NOTE_SILENT( 61 ),
NOTE_C_6( 179 ),
};
static const uint16_t Melody0_Length = sizeof( Melody0 ) / sizeof(uint16_t);
//-----------------------------------------------------------------------------
void playMelody_Data(const uint16_t MelodyData[], const uint16_t MelodyLength, const uint8_t tempo)
{
uint16_t arrayIndex = 0; uint16_t logs[MelodyLength];
int i = 0; int left = 0; int right = 0;
static const uint16_t Freq8[] PROGMEM = { 4186 , 4435 , 4699 , 4978 , 5274 , 5588 , 5920 , 6272 , 6645 , 7040 , 7459 , 7902 }; // from frequency of c8 to B8 lower vlues like c6 calculated
for (uint16_t x = 0; x < MelodyLength; x++)
{
unsigned long currentMillis = millis();
int count = 0;
int left = digitalRead(pirLeft); //reading left pir sesnor
int right = digitalRead(pirRight); //reading right pir sesnor
uint16_t data = pgm_read_word((uint16_t *)& MelodyData[x]);
if ((data & 0xF) == 0xF)
{
noTone(tonePin);
}
else
{
uint16_t Freq = pgm_read_word(&Freq8[data & 0xF]) / ( 1 << (8 - (data >> 4 & 0xF)) ); // frequencies of played notes will be obtained
uint16_t Frequency[MelodyLength];
Frequency[arrayIndex] = Freq;
uint16_t logs[MelodyLength];
if (Freq > 1350)
{
logs[i] = 300 ;
myservo.writeMicroseconds(1000); //rotate servo in clockwise
Serial.println(count);
}
else
{
logs[i] = 100 ;
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
if (count == 1)
{
myservo.writeMicroseconds(1500);
Serial.println(count);
count = 0;
digitalWrite(LED_BUILTIN, HIGH);
}
else
{
myservo.writeMicroseconds(2000); //rotate servo in clockwise direction
Serial.print("gowd");Serial.println(count);
count++;
digitalWrite(LED_BUILTIN, LOW);
}
}
}
if (currentMillis - previousMillispir >= headsup)
{
previousMillispir = currentMillis;
if (left == 1) //check if left motion sensor detects the motion
{
left = 0;
baseServo.writeMicroseconds(2000);
}
else if (right == 1) //check if right motion sensor detects the motion
{
baseServo.writeMicroseconds(1000);
right = 0;
}
else //servo reset
{
baseServo.writeMicroseconds(1500);
}
}
arrayIndex++; i++;
tone(tonePin, Freq);
if (x == MelodyLength - 1)
{
Serial.println(" End of Playback");
}
}
int16_t Duration = data >> 8;
while (Duration--) delay(tempo);
}
noTone(4);
myservo.writeMicroseconds(1500);
//-----
}
//-----------------------------------
inline static void playMelody(uint8_t melodyNumber, uint8_t tempo)
{
switch (melodyNumber)
{
#if NUMBER_OF_MELODIES ==1
case 0: {
playMelody_Data(Melody0, Melody0_Length, tempo);
return;
}
#endif
}
}