Hi there,
Since I read this article on High-Low-Tech, I've been trying to get my ATTiny45-20PU to play a piece by Bach.
So far, it's working quite well. The only problem is that the IC can't take more than nine bars of notes - I guess, this fills the capacity of the RAM.
Therefore, I wanted to save the scores to the flash memory to save RAM. For reasons unknown, this didn't seem to work out.
This works w/o any problems:
/**************************
Plays Wohltemperiertes Clavier Prelude 1 by J.S.Bach (BWV 846)
on Pin 0
Programmed for an ATTiny45
2012, Niklaus Messerli
***************************/
int periods[] = {19250,18169,17149,16186,15278,14421,13611,12847,12126,11446,10803,10197,9625,9084,8574,8093,7639,7210,6805,6423,6063,5723,5401,5098,4812} ;
int song[] = {3,7,10,15,19,10,15,19,3,5,12,17,20,12,17,20,2,5,10,17,20,10,17,20,3,7,10,15,19,10,15,19,3,7,12,19,24,12,19,24,3,5,9,12,17,9,12,17,2,5,10,17,22,10,17,22,2,3,7,10,14,7,10,14,0,3,7,10,14,7,10,14} ;
unsigned long time;
unsigned long time2;
unsigned long timeTone;
boolean on; // speaker high/low?
boolean repeat; // each half bar is repeated in bwv 846, saving space
int notecounter;
int barcounter;
int currentNote;
void setup() {
pinMode(0, OUTPUT); // speaker
time = 0;
time2 = 0;
timeTone = 0;
on = 0;
repeat = 0;
notecounter = 0;
barcounter = 0;
currentNote = 16168;
}
void loop() {
time2 = micros(); // only call micros() once probably saves resources. i guess...
if(time2 - timeTone > 2000000){ // about 0.5s per 16th-note
time = time2;
timeTone = time2;
notecounter++;
if(!(notecounter % 8)){ // one half-bar is reached
if(repeat){ // one full bar
barcounter++;
repeat = 0;
} else repeat = 1;
notecounter = 0;
}
currentNote = periods[song[notecounter+barcounter*8]];
}
if(time2 - time > currentNote){
time = time2;
on = 1 - on;
digitalWrite(0, on ? HIGH : LOW);
}
}
Whereas this just produces random beeping:
/**************************
Plays Wohltemperiertes Clavier Prelude 1 by J.S.Bach (BWV 846)
on Pin 0
Programmed for an ATTiny45
2012, Niklaus Messerli
***************************/
#import <avr/pgmspace.h>
int periods[] = {19250,18169,17149,16186,15278,14421,13611,12847,12126,11446,10803,10197,9625,9084,8574,8093,7639,7210,6805,6423,6063,5723,5401,5098,4812} ;
const int song[] PROGMEM = {3,7,10,15,19,10,15,19,3,5,12,17,20,12,17,20,2,5,10,17,20,10,17,20,3,7,10,15,19,10,15,19,3,7,12,19,24,12,19,24,3,5,9,12,17,9,12,17,2,5,10,17,22,10,17,22,2,3,7,10,14,7,10,14,0,3,7,10,14,7,10,14} ;
...etc.
Is there a difference between reading from RAM and reading from Flash?
Or is pgmspace.h filling Flash itself?
Or am I just too stupid to realize the obvious?
Thanks in advance for any help!
nik
bach_ram.mp3 (295 KB)
bach_flash.mp3 (225 KB)