So sieht jetzt der fertige Sketch aus
#define piezoPin A5
char melodie[]="1a8,2d4,6c4,PP4,1a8,2d4,6c4,PP4,PP4,6e8,8d4,8d4,PP4,6d8,6d8,6d8,8g4,6c4,PP8,5f8,7d4,7d4,PP4,7d8,PP4,5e8,4g4,4d4,4f4,4aa,0ba";
#define BPM 120
#define SECONDS_PER_MINUTE 60
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11, 5, 4, 3, 2);
int x = 0;
int y=0;
long previousMillis =0;
byte A[8] =
{
B00111,
B01111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111
};
byte B[8] =
{
B11111,
B11111,
B11111,
B00000,
B00000,
B00000,
B00000,
B00000
};
byte C[8] =
{
B00111,
B01111,
B11111,
B00000,
B00000,
B11111,
B11111,
B11111
};
byte D[8] =
{
B11111,
B11111,
B11111,
B11111,
B00000,
B00000,
B11111,
B00000
};
int getNotenDauer(int beatsPerMinute, char notendauer){
long factor;
switch (notendauer)
{
case '0': factor=1024;break; // ganze Note
case '1': factor=1536;break; // ganze Note punktiert
case '2': factor=512;break; // halbe Note
case '3': factor=768;break; // halbe Note punktiert
case '4': factor=256;break; // viertel Note
case '5': factor=384;break; // viertel Note punktiet
case '6': factor=128;break; // achtel Note
case '7': factor=192;break; // achtel Note punktiert
case '8': factor=64;break; // sechzehntel Note
case '9': factor=96;break; // sechzehntel Note punktiert
case 'a': factor=32;break; // 32stel Note
case 'b': factor=48;break; // 32stel Note punktiert
default: {Serial.print("Error Tondauer ");Serial.println(notendauer);}
}
return (4*factor*SECONDS_PER_MINUTE/beatsPerMinute);
}
int getTonHoehe(char oktave, char note)
{
int tonhoehe;
switch (note)
{
case 'c': tonhoehe=330;break;
case 'd': tonhoehe=349;break;
case 'e': tonhoehe=370;break;
case 'f': tonhoehe=392;break;
case 'g': tonhoehe=415;break;
case 'a': tonhoehe=440;break;
case 'h': tonhoehe=466;break;
}
switch (oktave)
{
case '1': break;
case '2': tonhoehe*=2;break;
case '3': tonhoehe*=4;break;
case '4': tonhoehe*=8;break;
case '5': tonhoehe*=16;break;
case '6': tonhoehe*=32;break;
}
return(tonhoehe);
}
void task_tone(){
static int notencounter;
static boolean note_an;
static long nextnote, nextpause;
if (millis()>nextnote)
{
if (!note_an)
{
if (melodie[notencounter]!='P')
{
tone (piezoPin,getTonHoehe(melodie[notencounter], melodie[notencounter+1]));
}
else
{
noTone(piezoPin);
}
nextpause=millis()+getNotenDauer(BPM,melodie[notencounter+2]);
note_an=true;
}
}
if (millis()>nextpause)
{
if (note_an)
{
noTone(piezoPin);
notencounter+=4; // notencounter weiter
if (notencounter>=strlen(melodie))
{
notencounter=0; // melodie zuende, notencounter reset
nextnote=millis()+1000;
}
else nextnote=millis()+300; // Feste Pause von 100 ms zwischen den Noten
note_an=false; // spielen der Note is abgeschaltet
}
}
}
void task_Muster1(){
static long interval=50;
static long startmillis=0;
lcd.createChar(1,A);
lcd.setCursor(x,0);
lcd.write(1);
x=x+0;
lcd.createChar(2,B);
lcd.setCursor(x,0);
lcd.write(2);
lcd.createChar(3,C);
lcd.setCursor(x,1);
lcd.write(3);
x=x+1;
lcd.createChar(4,D);
lcd.setCursor(x, y);
lcd.write(4);
x=x+2;
y=y+1;
startmillis=millis();
if (millis()-previousMillis>interval);
}
void setup() {
lcd.begin(0, 2);
}
void loop() {
task_Muster1();
task_tone();
}