507 lines
10 KiB
C++
507 lines
10 KiB
C++
/*
|
||
Name: Babito2Anniversary.ino
|
||
Created: 01/01/2021 15:36:29
|
||
Author: Lorenzo Dellac<61>
|
||
*/
|
||
|
||
#include <Servo.h>
|
||
#include <EEPROM.h>
|
||
|
||
const unsigned long baudRate = 115200;
|
||
const unsigned long baudRates[] =
|
||
{
|
||
300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 31250, 38400, 57600, 115200
|
||
};
|
||
|
||
const int buzzerPin = 3;
|
||
const int servoPin = 5;
|
||
const int buttonPin = 7;
|
||
const int switchPin = 9;
|
||
const int led1Pin = 10;
|
||
const int led2Pin = 6;
|
||
|
||
const int pause = 0;
|
||
const int gL = 196;
|
||
const int gSL = 207;
|
||
const int aL = 220;
|
||
const int aSL = 233;
|
||
const int bL = 247;
|
||
const int c = 261;
|
||
const int d = 294;
|
||
const int dS = 311;
|
||
const int e = 329;
|
||
const int f = 349;
|
||
const int g = 391;
|
||
const int gS = 415;
|
||
const int a = 440;
|
||
const int aS = 455;
|
||
const int b = 494;
|
||
const int cH = 523;
|
||
const int cSH = 554;
|
||
const int dH = 587;
|
||
const int dSH = 622;
|
||
const int eH = 659;
|
||
const int fH = 698;
|
||
const int fSH = 740;
|
||
const int gH = 784;
|
||
const int gSH = 830;
|
||
const int aH = 880;
|
||
|
||
const int alpiniNotes[] =
|
||
{
|
||
c,g,e,e,c,g,e,e,e,d,e,f,d,pause,
|
||
d,e,f,f,f,g,a,a,a,g,f,e,pause,g,g,e,pause,
|
||
|
||
c,g,e,e,c,g,e,e,e,d,e,f,d,pause,
|
||
d,e,f,f,f,g,a,a,a,g,f,e,pause,g,g,e,pause,
|
||
|
||
e,f,g,a,a,pause,cH,b,a,g,g,pause,e,f,g,a,a,cH,cH,b,a,g,g,pause,
|
||
e,f,g,a,a,pause,cH,b,a,g,g,pause,e,f,g,a,a,b,b,cH,pause,
|
||
|
||
pause
|
||
};
|
||
const int alpiniDurations[] =
|
||
{
|
||
500,500,250,250,250,250,250,125,125,250,250,500,500,1000,
|
||
500,500,250,250,250,250,250,125,125,250,250,500,50,375,125,500,750,
|
||
|
||
500,500,250,250,250,250,250,125,125,250,250,500,500,1000,
|
||
500,500,250,250,250,250,250,125,125,250,250,500,50,375,125,500,750,
|
||
|
||
250,250,250,500,500,250,250,250,250,500,500,250,250,250,250,500,500,375,125,250,250,500,500,250,
|
||
250,250,250,500,500,250,250,250,250,500,500,250,250,250,250,500,500,500,500,1000,1000,
|
||
|
||
10000
|
||
};
|
||
int alpiniMusicSize = 0;
|
||
|
||
const int jingleBellsNotes[] =
|
||
{
|
||
e,e,e,e,e,e,e,g,c,d,e,pause,
|
||
|
||
f,f,f,f,f,e,e,e,e,e,d,d,e,d,pause,g,pause,
|
||
|
||
e,e,e,e,e,e,e,g,c,d,e,pause,
|
||
|
||
f,f,f,f,f,e,e,e,e,g,g,f,d,c,pause,
|
||
|
||
gL,gL,gL,e,d,c,gL,pause,
|
||
gL,gL,gL,e,d,c,aL,pause,
|
||
aL,aL,aL,f,e,d,bL,pause,
|
||
g,g,g,g,f,d,e,pause,
|
||
|
||
gL,gL,gL,e,d,c,gL,pause,
|
||
gL,gL,gL,e,d,c,aL,pause,
|
||
aL,aL,aL,f,e,d,g,g,g,
|
||
g,a,g,f,d,c,pause,
|
||
|
||
pause
|
||
};
|
||
|
||
const int jingleBellsDurations[] =
|
||
{
|
||
250,250,500,250,250,500,250,250,375,125,500,500,
|
||
|
||
250,250,375,125,250,250,250,125,125,250,250,250,250,400,100,400,100,
|
||
|
||
250,250,500,250,250,500,250,250,375,125,500,500,
|
||
|
||
250,250,375,125,250,250,250,125,125,250,250,250,250,500,250,
|
||
|
||
125,125,250,250,250,250,500,250,
|
||
125,125,250,250,250,250,500,250,
|
||
125,125,250,250,250,250,500,250,
|
||
125,125,250,250,250,250,500,250,
|
||
|
||
125,125,250,250,250,250,500,250,
|
||
125,125,250,250,250,250,500,250,
|
||
125,125,250,250,250,250,250,250,250,
|
||
250,250,250,250,250,500,250,
|
||
|
||
10000
|
||
};
|
||
int jingleBellsMusicSize = 0;
|
||
|
||
const int windowsShutdownNotes[] =
|
||
{
|
||
pause,gS,dS,gSL,aSL,pause
|
||
};
|
||
|
||
const int windowsShutdownDurations[] =
|
||
{
|
||
1000,250,250,250,500,100
|
||
};
|
||
int windowsShutdownMusicSize = 0;
|
||
|
||
int musicPosition = 0;
|
||
|
||
int currentSong = 0;
|
||
|
||
unsigned long currentMillis;
|
||
unsigned long lastMillisNote = 0;
|
||
unsigned long lastMillisServo = 0;
|
||
unsigned long lastButtonPress = 0;
|
||
unsigned long lastSwitchUpdate = 0;
|
||
unsigned long lastEEPROMWrite = 0;
|
||
|
||
const int buttonPressDelay = 500;
|
||
const int switchUpdateDelay = 200;
|
||
const int eepromWriteDelay = 1000;
|
||
|
||
bool isLeftLed = false;
|
||
|
||
bool isSwitchOn = false;
|
||
|
||
bool poweredUp = false;
|
||
|
||
Servo servo;
|
||
int servoAngle = 90;
|
||
const int eepromAngleAddress = 0;
|
||
|
||
|
||
void setup() {
|
||
|
||
sendSerials();
|
||
|
||
Serial.end();
|
||
Serial.begin(baudRate);
|
||
Serial.println("Serial Ready");
|
||
|
||
pinMode(buzzerPin, OUTPUT);
|
||
pinMode(servoPin, OUTPUT);
|
||
pinMode(buttonPin, INPUT);
|
||
pinMode(switchPin, INPUT);
|
||
pinMode(led1Pin, OUTPUT);
|
||
pinMode(led2Pin, OUTPUT);
|
||
|
||
servo.write(EEPROM.read(eepromAngleAddress));
|
||
servo.attach(servoPin);
|
||
|
||
currentMillis = millis();
|
||
lastMillisNote = millis();
|
||
|
||
alpiniMusicSize = (sizeof(alpiniNotes) / sizeof(alpiniNotes[0]));
|
||
jingleBellsMusicSize = (sizeof(jingleBellsNotes) / sizeof(jingleBellsNotes[0]));
|
||
windowsShutdownMusicSize = (sizeof(windowsShutdownNotes) / sizeof(windowsShutdownNotes[0]));
|
||
|
||
|
||
checkAndResetAngle(1.0f);
|
||
|
||
}
|
||
|
||
void loop() {
|
||
|
||
if (isSwitchOn)
|
||
{
|
||
openLid(0.7f);
|
||
}
|
||
else
|
||
{
|
||
closeLid(0.7f);
|
||
}
|
||
|
||
if (poweredUp)
|
||
{
|
||
if (currentSong == 0)
|
||
{
|
||
playMusicAlpini(0.7f);
|
||
}
|
||
|
||
if (currentSong == 1)
|
||
{
|
||
playMusicJingleBells(1.0f);
|
||
}
|
||
|
||
if (currentSong == 404)
|
||
{
|
||
playShutdownSong(1.0f);
|
||
}
|
||
}
|
||
|
||
checkButton();
|
||
checkSwitch();
|
||
|
||
updateEEPROM();
|
||
|
||
currentMillis = millis();
|
||
|
||
}
|
||
|
||
void updateEEPROM()
|
||
{
|
||
if (currentMillis >= lastEEPROMWrite + eepromWriteDelay)
|
||
{
|
||
|
||
Serial.println("Updating EEPROM...");
|
||
lastEEPROMWrite = millis();
|
||
|
||
int currentAngle = servo.read();
|
||
int savedAngle = EEPROM.read(eepromAngleAddress);
|
||
|
||
if (currentAngle != savedAngle)
|
||
{
|
||
Serial.print("Written Angle: ");
|
||
Serial.println(currentAngle);
|
||
EEPROM.update(eepromAngleAddress, currentAngle);
|
||
}
|
||
}
|
||
}
|
||
|
||
void checkButton()
|
||
{
|
||
if (digitalRead(buttonPin) == HIGH && isSwitchOn)
|
||
{
|
||
|
||
if (currentMillis >= lastButtonPress + buttonPressDelay)
|
||
{
|
||
lastButtonPress = millis();
|
||
|
||
if (currentSong < 2) {
|
||
currentSong++;
|
||
noTone(buzzerPin);
|
||
}
|
||
else {
|
||
currentSong = 0;
|
||
}
|
||
|
||
musicPosition = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
void checkSwitch()
|
||
{
|
||
|
||
if (currentMillis >= lastSwitchUpdate + switchUpdateDelay)
|
||
{
|
||
|
||
if (digitalRead(switchPin) == HIGH)
|
||
{
|
||
if (!isSwitchOn)
|
||
{
|
||
isSwitchOn = true;
|
||
currentSong = 0;
|
||
musicPosition = 0;
|
||
Serial.println("Switch On");
|
||
|
||
if (!poweredUp)
|
||
{
|
||
poweredUp = true;
|
||
digitalWrite(led1Pin, HIGH);
|
||
digitalWrite(led2Pin, HIGH);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (isSwitchOn)
|
||
{
|
||
isSwitchOn = false;
|
||
currentSong = 404;
|
||
musicPosition = 0;
|
||
Serial.println("Switch Off");
|
||
}
|
||
}
|
||
|
||
lastSwitchUpdate = millis();
|
||
}
|
||
|
||
}
|
||
|
||
void openLid(float speed)
|
||
{
|
||
if (currentMillis >= lastMillisServo + (100.0 * 1/speed))
|
||
{
|
||
if (servoAngle >= 0)
|
||
{
|
||
servoAngle--;
|
||
}
|
||
|
||
if (servoAngle > 0)
|
||
{
|
||
servo.write(servoAngle);
|
||
}
|
||
else
|
||
{
|
||
//servo.detach();
|
||
}
|
||
|
||
lastMillisServo = millis();
|
||
}
|
||
}
|
||
|
||
void closeLid(float speed)
|
||
{
|
||
|
||
if (currentMillis >= lastMillisServo + (100.0 * 1 / speed))
|
||
{
|
||
|
||
if (servoAngle <= 90)
|
||
{
|
||
servoAngle++;
|
||
}
|
||
|
||
if (servoAngle < 90)
|
||
{
|
||
servo.write(servoAngle);
|
||
}
|
||
|
||
lastMillisServo = millis();
|
||
}
|
||
}
|
||
|
||
void checkAndResetAngle(float speed)
|
||
{
|
||
Serial.print("Checking Angle... ");
|
||
|
||
int angle = servo.read();
|
||
|
||
Serial.println(angle);
|
||
|
||
if (angle < 90)
|
||
{
|
||
for (int currentAngle = angle; currentAngle <= 90; currentAngle++)
|
||
{
|
||
Serial.println(currentAngle);
|
||
servo.write(currentAngle);
|
||
delay(100.0 * 1 / speed);
|
||
|
||
|
||
currentMillis = millis();
|
||
updateEEPROM();
|
||
}
|
||
} else if (angle > 90)
|
||
{
|
||
for (int currentAngle = angle; currentAngle >= 90; currentAngle--)
|
||
{
|
||
Serial.print("B: ");
|
||
Serial.println(currentAngle);
|
||
servo.write(currentAngle);
|
||
delay(100.0 * 1 / speed);
|
||
|
||
|
||
currentMillis = millis();
|
||
updateEEPROM();
|
||
}
|
||
}
|
||
|
||
Serial.println("Angle Fixed!");
|
||
}
|
||
|
||
void playMusicAlpini(float speed)
|
||
{
|
||
if (currentMillis >= lastMillisNote + alpiniDurations[musicPosition - 1] * 1 / speed)
|
||
{
|
||
noTone(buzzerPin);
|
||
|
||
if (!(alpiniNotes[musicPosition] == pause))
|
||
{
|
||
switchLed();
|
||
tone(buzzerPin, alpiniNotes[musicPosition], (alpiniDurations[musicPosition] * 1 / speed) - 10);
|
||
}
|
||
|
||
|
||
if (musicPosition < alpiniMusicSize)
|
||
{
|
||
musicPosition++;
|
||
}
|
||
else
|
||
{
|
||
musicPosition = 0;
|
||
}
|
||
|
||
lastMillisNote = millis();
|
||
}
|
||
}
|
||
|
||
void playMusicJingleBells(float speed)
|
||
{
|
||
|
||
if (currentMillis >= lastMillisNote + jingleBellsDurations[musicPosition - 1] * 1 / speed)
|
||
{
|
||
noTone(buzzerPin);
|
||
|
||
if (!(jingleBellsNotes[musicPosition] == pause))
|
||
{
|
||
switchLed();
|
||
tone(buzzerPin, jingleBellsNotes[musicPosition], (jingleBellsDurations[musicPosition] * 1 / speed) - 10);
|
||
}
|
||
|
||
|
||
if (musicPosition < jingleBellsMusicSize)
|
||
{
|
||
musicPosition++;
|
||
}
|
||
else
|
||
{
|
||
musicPosition = 0;
|
||
}
|
||
|
||
lastMillisNote = millis();
|
||
}
|
||
}
|
||
|
||
void playShutdownSong(float speed)
|
||
{
|
||
|
||
if (currentMillis >= lastMillisNote + windowsShutdownDurations[musicPosition - 1] * 1 / speed)
|
||
{
|
||
noTone(buzzerPin);
|
||
|
||
if (!(windowsShutdownNotes[musicPosition] == pause))
|
||
{
|
||
switchLed();
|
||
tone(buzzerPin, windowsShutdownNotes[musicPosition], (windowsShutdownDurations[musicPosition] * 1 / speed) - 10);
|
||
}
|
||
|
||
|
||
if (musicPosition < windowsShutdownMusicSize)
|
||
{
|
||
musicPosition++;
|
||
}
|
||
else
|
||
{
|
||
musicPosition = 0;
|
||
currentSong = 405;
|
||
noTone(buzzerPin);
|
||
digitalWrite(led1Pin, LOW);
|
||
digitalWrite(led2Pin, LOW);
|
||
}
|
||
|
||
lastMillisNote = millis();
|
||
}
|
||
}
|
||
|
||
void switchLed() {
|
||
if (isLeftLed)
|
||
{
|
||
digitalWrite(led1Pin, LOW);
|
||
digitalWrite(led2Pin, HIGH);
|
||
}
|
||
else
|
||
{
|
||
digitalWrite(led2Pin, LOW);
|
||
digitalWrite(led1Pin, HIGH);
|
||
}
|
||
|
||
isLeftLed = !isLeftLed;
|
||
}
|
||
|
||
void sendSerials()
|
||
{
|
||
int baudRatesArraySize = sizeof(baudRates) / sizeof(baudRates[0]);
|
||
|
||
for (int i = 0; i < baudRatesArraySize; i++)
|
||
{
|
||
unsigned long currentBaudRate = baudRates[i];
|
||
|
||
Serial.end();
|
||
Serial.begin(currentBaudRate);
|
||
Serial.println();
|
||
Serial.println();
|
||
Serial.print("Set baud rate to ");
|
||
Serial.println(baudRate);
|
||
Serial.println();
|
||
Serial.end();
|
||
}
|
||
} |