Hi all!
I am programming an alarm clock that I have made based on the Atmega16. I have added a Piezo buzzer, so I can make the alarm be a song instead of just a regular buzzer. I have barely added any notes for the song though, and things on the clock stop functioning. The dynamic memory is only at 70% though, so it isn't maxed out
.
Now, if I try to add a couple more notes, for example, the alarm set just flashes zeros, and you cant set it.
Any ideas on what's going on? And how I can finish the song?
Thanks in advance!
alarm.ino:
#include "Clock.hpp"
#include "music.h"
#include <avr/eeprom.h>
#define setbuttondelay 2000
int hour = 6;
int minute = 0;
int lastsecond = 0;
bool secondflash = false;
bool setalarm = false;
bool alarm = true;
String alarmtime = "";
unsigned long stmillis = 0;
unsigned long buttonmillis = 0;
bool flash = false;
unsigned long flashmillis = 0;
int flashon = 500;
int flashoff = 1200;
bool pm = false;
SevSeg sevseg;
dht DHT;
uRTCLib rtc(0x68);
Clock clock(&sevseg, &DHT, &rtc);
void setup(){
//to set the time, uncomment the lines below
//URTCLIB_WIRE.begin();
//rtc.set(0, 27, 7, 5, 8, 3, 23);
clock.begin();
hour = eeprom_read_byte((const uint8_t*)0);
minute = eeprom_read_byte((const uint8_t*)1);
alarm = eeprom_read_byte((const uint8_t*)2);
pm = eeprom_read_byte((const uint8_t*)3);
if (alarm){
clock.setalarm(1,hour,minute,0,rtc.day(),pm);
}
if (pm){
hour = hour+12;
}
}
void loop(){
if (setalarm){
ret:
handlesetalarm();
if (setalarm){goto ret;}
eeprom_update_byte((uint8_t*)0,hour);
eeprom_update_byte((uint8_t*)1,minute);
eeprom_update_byte((uint8_t*)2,alarm);
if (hour > 11){pm = true;}//afternoon is PM
if (hour == 24){pm = false;}//midnight would be AM
if (hour <= 11){pm = false;}//morning is AM
if (hour > 12){hour=hour-12;}//12 hour time
eeprom_update_byte((uint8_t*)3,pm);
clock.setalarm(1,hour,minute,0,rtc.day(),pm);
if (pm){
hour = hour+12;
}
playtone();
}
if (lastsecond != rtc.second()){
secondflash = !secondflash;
lastsecond = rtc.second();
}
if (secondflash){
clock.displayint(clock.gettime());
}
else {
int timee = 0;
if (rtc.hour() > 12){//convert to 12hr time
timee = rtc.hour() - 12;
}
else {
timee = rtc.hour();
}
String displaytime = "";
if (rtc.minute() < 10){
displaytime = String(timee) + "0" + String(rtc.minute());
}
else {
displaytime = String(timee) + String(rtc.minute());
}
clock.displayint(displaytime.toInt(),0);
}
clock.rgb(0,clock.potentiometer(),0);
if (digitalRead(Button1) == LOW){
stmillis = millis();
while (digitalRead(Button1) == LOW);
if (millis() - stmillis > setbuttondelay){
setalarm = true;
flashmillis = millis();
}
else {
setalarm = false;
}
}
if (digitalRead(Button2) == LOW){
unsigned long stmill = millis();
while(digitalRead(Button2) == LOW);
if (millis() - stmill > 3000){
alarm = !alarm;
if (alarm){
clock.setalarm(1,hour,minute,0,rtc.day(),pm);
playtone();
unsigned long curmil = millis();
while(millis() - curmil < 4000){
clock.displaychar("ON");
clock.refresh();
}
}
else {
clock.setalarm(1,hour,minute,0,rtc.day(),pm,false);
unsigned long curmil = millis();
while(millis() - curmil < 4000){
clock.displaychar("OFF");
clock.refresh();
}
}
}
}
clock.checkalarm();
if (buzzeralarm){
playmelody();
buzzeralarm = false;
}
clock.refresh();
}
void handlesetalarm(){
if (minute < 10){
alarmtime = String(hour) + "0" + String(minute);
}
else {
alarmtime = String(hour) + String(minute);
}
if (flash){
if (millis() - flashmillis > flashon){
flashmillis = millis();
flash = !flash;
}
}
else {
if (millis() - flashmillis > flashoff){
flashmillis = millis();
flash = !flash;
}
}
if (flash){
clock.displayclear();
}
else {
clock.displayint(alarmtime.toInt());
}
if (digitalRead(Button1) == LOW){
buttonmillis = millis();
while (digitalRead(Button1) == LOW);
if (millis() - buttonmillis > setbuttondelay){
setalarm = false;
}
else {
hour++;
if (hour > 24){
hour = 1;
}
}
clock.beep(50);
}
if (digitalRead(Button2) == LOW){
buttonmillis = millis();
while (digitalRead(Button2) == LOW){
if (millis() - buttonmillis > 200){
minute++;
goto ext;
}
}
ext:
minute++;
if (minute >= 60){
minute = 0;
}
clock.beep(50);
}
clock.refresh();
}
music.h:
#include "pitches.h"
int mel[] = {
NOTE_E4, NOTE_G4, NOTE_D4, NOTE_E4, NOTE_C4
};
int notedur[] = {
2, 4, 4, 4, 3
};
void playtone(float speed=0.8){
for (int thisNote = 0; thisNote < 5; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = (1000 / notedur[thisNote]) * speed;
tone(Buzzer, mel[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(Buzzer);
}
}
// change this to make the song slower or faster
int tempo = 100;
// notes of the moledy followed by the duration.
// a 4 means a quarter note, 8 an eighteenth , 16 sixteenth, so on
// !!negative numbers are used to represent dotted notes,
// so -4 means a dotted quarter note, that is, a quarter plus an eighteenth!!
int melody[] = {
// Cannon in D - Pachelbel
// Score available at https://musescore.com/user/4710311/scores/1975521
// C F
/*NOTE_FS4,2, NOTE_E4,2,
NOTE_D4,2, NOTE_CS4,2,
NOTE_B3,2, NOTE_A3,2,
NOTE_B3,2, NOTE_CS4,2,
NOTE_FS4,2, NOTE_E4,2,
NOTE_D4,2, NOTE_CS4,2,
NOTE_B3,2, NOTE_A3,2,
NOTE_B3,2, NOTE_CS4,2,
NOTE_D4,2, NOTE_CS4,2,
NOTE_B3,2, NOTE_A3,2,
NOTE_G3,2, NOTE_FS3,2,
NOTE_G3,2, NOTE_A3,2,*/
NOTE_A4,4, NOTE_FS4,8, NOTE_G4,8, NOTE_A4,4, NOTE_FS4,8, NOTE_G4,8,
NOTE_A4,8, NOTE_A3,8, NOTE_B3,8, NOTE_CS4,8, NOTE_D4,8, NOTE_E4,8, NOTE_FS4,8, NOTE_G4,8,
NOTE_FS4,4, NOTE_D4,8, NOTE_E4,8, NOTE_FS4,4, NOTE_FS4,8, NOTE_G4,8,
NOTE_A4,8, NOTE_B4,8, NOTE_A4,8, NOTE_G4,8, NOTE_A4,8, NOTE_FS4,8, NOTE_G4,8, NOTE_A4,8,
/*NOTE_G4,4, NOTE_B4,8, NOTE_A4,8, NOTE_G4,4, NOTE_FS4,8, NOTE_E4,8,
NOTE_FS4,8, NOTE_E4,8, NOTE_D4,8, NOTE_E4,8, NOTE_FS4,8, NOTE_G4,8, NOTE_A4,8, NOTE_B4,8,*/
/*NOTE_G4,4, NOTE_B4,8, NOTE_A4,8, NOTE_B4,4, NOTE_CS4,8, NOTE_D5,8,
NOTE_A3,8, NOTE_B3,8, NOTE_CS4,8, NOTE_D4,8, NOTE_E4,8, NOTE_FS4,8, NOTE_G4,8, NOTE_A4,8,
NOTE_A4,1, NOTE_A4,4, NOTE_B4,4, NOTE_A4,4, NOTE_G4,4,
NOTE_FS4,1, NOTE_FS4,4, NOTE_G4,4, NOTE_FS4,4, NOTE_E4,4, NOTE_D4,4, NOTE_C3,4, NOTE_B3,4, NOTE_C3,4, NOTE_A3,1,
NOTE_G3,2, NOTE_B3,2, NOTE_C3,1, NOTE_D4,-16, NOTE_D4,1,*/
/*NOTE_A4,4, NOTE_FS4,8, NOTE_G4,8, NOTE_A4,4,
NOTE_FS4,8, NOTE_G4,8, NOTE_A4,8, NOTE_A3,8, NOTE_B3,8, NOTE_CS4,8,
NOTE_D4,8, NOTE_E4,8, NOTE_FS4,8, NOTE_G4,8, NOTE_FS4,4, NOTE_D4,8, NOTE_E4,8,
NOTE_FS4,8, NOTE_CS4,8, NOTE_A3,8, NOTE_A3,8,*/
/*NOTE_CS4,4, NOTE_B3,4, NOTE_D4,8, NOTE_CS4,8, NOTE_B3,4,
NOTE_A3,8, NOTE_G3,8, NOTE_A3,4, NOTE_D3,8, NOTE_E3,8, NOTE_FS3,8, NOTE_G3,8,
NOTE_A3,8, NOTE_B3,4, NOTE_G3,4, NOTE_B3,8, NOTE_A3,8, NOTE_B3,4,
NOTE_CS4,8, NOTE_D4,8, NOTE_A3,8, NOTE_B3,8, NOTE_CS4,8, NOTE_D4,8, NOTE_E4,8,
NOTE_FS4,8, NOTE_G4,8, NOTE_A4,2,*/
};
// sizeof gives the number of bytes, each int value is composed of two bytes (16 bits)
// there are two values per note (pitch and duration), so for each note there are four bytes
int notes = sizeof(melody) / sizeof(melody[0]) / 2;
// this calculates the duration of a whole note in ms
int wholenote = (60000 * 4) / tempo;
int divider = 0, noteDuration = 0;
void playmelody(){
// iterate over the notes of the melody.
// Remember, the array is twice the number of notes (notes + durations)
for (int thisNote = 0; thisNote < notes * 2; thisNote = thisNote + 2) {
// calculates the duration of each note
divider = melody[thisNote + 1];
if (divider > 0) {
// regular note, just proceed
noteDuration = (wholenote) / divider;
} else if (divider < 0) {
// dotted notes are represented with negative durations!!
noteDuration = (wholenote) / abs(divider);
noteDuration *= 1.5; // increases the duration in half for dotted notes
}
// we only play the note for 90% of the duration, leaving 10% as a pause
tone(Buzzer, melody[thisNote], noteDuration * 0.9);
// Wait for the specief duration before playing the next note.
delay(noteDuration);
// stop the waveform generation before the next note.
noTone(Buzzer);
if (digitalRead(Button1) == LOW){
goto ex;
}
}
ex:
delay(1);
}
pitches.h:
#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 REST 0
Clock.hpp library can be found here:
Edit:
Here is the verbose output on space when uploading:
Sketch uses 14506 bytes (91%) of program storage space. Maximum is 15872 bytes.
Global variables use 718 bytes (70%) of dynamic memory, leaving 306 bytes for local variables. Maximum is 1024 bytes.