I received a few ATtiny13's in the mail the other day, and got going on my melody player (which is what i wanted them for) and of course memory is tiny, and i want to store as big a melody as possible. So far i got to this
#include "notes.h"
#define PIEZOPIN 4
#define BPM 100
#define QUART 60000/BPM
#define EIGHTH QUART/2
#define THREIGHTH EIGHTH*3
#define SIXTEENTH QUART/4
#define THRSIX SIXTEENTH*3
#define HALF QUART*2
void setup() {
pinMode(PIEZOPIN,OUTPUT);
}
void loop() {
buzz(0,EIGHTH);
buzz(0,THRSIX);
buzz(0,SIXTEENTH);
buzz(3,QUART);
buzz(3,QUART);
buzz(4,QUART);
buzz(4,QUART);
buzz(7,THREIGHTH);
buzz(5,EIGHTH);
buzz(3,THRSIX);
buzz(3,SIXTEENTH);
buzz(5,THRSIX);
buzz(3,SIXTEENTH);
buzz(1,QUART);
buzz(6,QUART);
buzz(6,QUART);
buzz(4,THRSIX);
buzz(2,SIXTEENTH);
buzz(3,HALF);
wait(QUART);
buzz(3,THRSIX);
buzz(4,SIXTEENTH);
buzz(5,QUART);
buzz(5,QUART);
buzz(5,QUART);
buzz(6,THRSIX);
buzz(5,SIXTEENTH);
}
void buzz(uint8_t note, uint16_t notelength) {
//const uint16_t notelength[]={HALF,THREIGHTH,QUART,THRSIX,EIGHTH,SIXTEENTH};
const uint16_t period[]={M64,M66,M68,M69,M71,M73,M74,M76};
uint16_t ms=millis();
notelength=notelength/8;
while (((uint16_t) millis()-ms)<notelength*7) {
uint16_t halfperiod=period[note]/2;
digitalWrite(PIEZOPIN,HIGH);
wait(halfperiod);
digitalWrite(PIEZOPIN,LOW);
wait(period[note]-halfperiod);
}
delay(notelength);
}
void wait(uint32_t us) {
for(uint32_t mics=0; mics<us; mics++) delayMicroseconds(1);
}
and for notes.h just using the intervals in us
#define M21 36360
#define M22 34320
#define M23 32400
#define M24 30580
#define M25 28860
#define M26 27240
#define M27 25710
#define M28 24270
#define M29 22910
#define M30 21620
#define M31 20410
#define M32 19260
#define M33 18180
#define M34 17160
#define M35 16200
#define M36 15290
#define M37 14290
#define M38 13620
#define M39 12860
#define M40 12130
#define M41 11450
#define M42 10810
#define M43 10200
#define M44 9631
#define M45 9091
#define M46 8581
#define M47 8099
#define M48 7645
#define M49 7216
#define M50 6811
#define M51 6428
#define M52 6068
#define M53 5727
#define M54 5405
#define M55 5102
#define M56 4816
#define M57 4545
#define M58 4290
#define M59 4050
#define M60 3822
#define M61 3608
#define M62 3405
#define M63 3214
#define M64 3034
#define M65 2863
#define M66 2703
#define M67 2551
#define M68 2408
#define M69 2273
#define M70 2145
#define M71 2025
#define M72 1910
#define M73 1804
#define M74 1703
#define M75 1607
#define M76 1517
#define M77 1432
#define M78 1351
#define M79 1276
#define M80 1204
#define M81 1136
#define M82 1073
#define M83 1012
#define M84 956
#define M85 902
#define M86 851
#define M87 803
#define M88 758
#define M89 716
#define M90 676
#define M91 638
#define M92 602
#define M93 568
#define M94 536
#define M95 506
#define M96 478
now of course i am trying to reduce the size of memory being used, and the main inefficiency i see now is that i am doing calls to 'buzz' which costs me 3 bytes every note (just for the call, op-code+address) which i could also do from a loop just retrieving the 3 note related bytes on each pass (which could actually be 2 bytes, if i compact the 5-bit note and a 11-bit length into a 16-bit value) but how to do this, i am sure i've seen it pass by somewhere.