/* Based on * freqout(freq, t) // freq in hz, t in ms * Paul Badger 2007 * a simple tone generation function * generates square waves of arbitrary frequency and duration * program also includes a top-octave lookup table & transposition function */ #define outpin 2 // audio out to speaker or amp //#define DEBUG #ifdef DEBUG #define DEBUG_PRINT(x) Serial.print(x) #define DEBUG_PRINTLN(x) Serial.println(x) #else #define DEBUG_PRINT(x) #define DEBUG_PRINTLN(x) #endif #define switchpowerpin 10 #define switchpin1 11 #define switchpin2 12 #define switchpin3 13 #define NUM_SEGS 7 #include // requires an Atmega168 chip #include int sevenSegpin[] = { 3, 4, 5, 6, 7, 8, 9}; int ptime; int k, x, dur, freq, t; int i, j; int CLENGTH = 500; // Crochett length - vary me to speed up or slow down the tune. float ps; // variable for pow pitchShift routine float noteval; // required for recording switch states for debouncing. long debounce = 200; long time1 = LOW; long time2 = LOW; long time3 = LOW; boolean reading1 = LOW; boolean reading2 = LOW; boolean reading3 = LOW; boolean previous1 = LOW; boolean previous2 = LOW; boolean previous3 = LOW; int state = 1; // note values for two octave scale // divide them by powers of two to generate other octaves float R = 0; float A = 14080; float AS = 14917.2; float B = 15804.3; float C = 16744; float CS = 17739.7; float D = 18794.5; float DS = 19912.1; float E = 21096.2; float F = 22350.6; float FS = 23679.6; float G = 25087.7; float GS = 26579.5; float A2 = 28160; float A2S = 29834.5; float B2 = 31608.5; float C2 = 33488.1; float C2S = 35479.4; float D2 = 37589.1; float D2S = 39824.3; float E2 = 42192.3; float F2 = 44701.2; float F2S = 47359.3; float G2 = 50175.4; float G2S = 53159; float A3 = 56320; // Happy Birthday tune float tune1[] = { C, C, D, C, F, E, C, C, D, C, G, F, C, C, C2, A2, F, E, D, A2S, A2S, A2, F, G, F}; float length1[] = { 0.75, 0.25, 1, 1, 1, 2, 0.75, 0.25, 1, 1, 1, 2, 0.75, 0.25, 1, 1, 1, 1, 3, 0.75, 0.25, 1, 1, 1, 3}; // The first Noel float tune2[] = { F, E, D, E, F, G, A2, B2, C2S, D2, C2S, B2, A2, B2, C2S, D2, C2S, B2, A2, B2, C2S, D2, A2, G, FS}; float length2[] = { 0.5, 0.5, 1.5, 0.5, 0.5, 0.5, 2.0, 0.5, 0.5, 1.0, 1.0, 1.0, 2.0, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0}; // Jingle Bells float tune3[] = { B2, B2, B2, B2, B2, B2, B2, D2, G, A2, B2, R, C2, C2, C2, C2, C2, B2, B2, B2, B2, B2, A2, A2, G, A2, D2,};// B2, B2, B2, B2, B2, B2, B2, D2, G, A2, B2, R, C2, C2, C2, C2, C2, B2, B2, B2, B2, D2, D2, C2, A2, G}; float length3[] = { 0.5, 0.5, 1, 0.5, 0.5, 1, 0.5, 0.5, 0.75, 0.25, 1, 1, 0.5, 0.5, 0.75, 0.25, 0.5, 0.5, 0.5, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5, 1, 1, };//0.5, 0.5, 1, 0.5, 0.5, 1, 0.5, 0.5, 0.75, 0.25, 1, 1, 0.5, 0.5, 0.75, 0.25, 0.5, 0.5, 0.5, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5, 1.5}; // Happy Birthday words (in ROM) prog_char string_0[] PROGMEM = "Ha"; prog_char string_1[] PROGMEM = "ppy"; prog_char string_2[] PROGMEM = " Birth"; prog_char string_3[] PROGMEM = "day"; prog_char string_4[] PROGMEM = " to"; prog_char string_5[] PROGMEM = " you\r\n"; prog_char string_6[] PROGMEM = "Ha"; prog_char string_7[] PROGMEM = "ppy"; prog_char string_8[] PROGMEM = " Birth"; prog_char string_9[] PROGMEM = "day"; prog_char string_10[] PROGMEM = " to"; prog_char string_11[] PROGMEM = " you\r\n"; prog_char string_12[] PROGMEM = "Ha"; prog_char string_13[] PROGMEM = "ppy"; prog_char string_14[] PROGMEM = " Birth"; prog_char string_15[] PROGMEM = "day"; prog_char string_16[] PROGMEM = " dear"; prog_char string_17[] PROGMEM = " Rich"; prog_char string_18[] PROGMEM = "ard\r\n"; prog_char string_19[] PROGMEM = "Ha"; prog_char string_20[] PROGMEM = "ppy"; prog_char string_21[] PROGMEM = " Birth"; prog_char string_22[] PROGMEM = "day"; prog_char string_23[] PROGMEM = " to"; prog_char string_24[] PROGMEM = " you!\r\n\r\n"; PGM_P PROGMEM string_table[] = { string_0, string_1, string_2, string_3, string_4, string_5, string_6, string_7, string_8, string_9, string_10, string_11, string_12, string_13, string_14, string_15, string_16, string_17, string_18, string_19, string_20, string_21, string_22, string_23, string_24, }; void freqout(int freq, int t) // freq in hz, t in ms { DEBUG_PRINTLN("Entered freqout"); DEBUG_PRINT("noteval="); DEBUG_PRINTLN(freq); DEBUG_PRINT("dur="); DEBUG_PRINTLN(t); if (freq != 0) { int hperiod; //calculate 1/2 period in us long cycles, i; pinMode(outpin, OUTPUT); // turn on output pin hperiod = (500000 / freq) - 7; // subtract 7 us to make up for digitalWrite overhead cycles = ((long)freq * (long)t) / 1000; // calculate cycles DEBUG_PRINT(freq); DEBUG_PRINT((char)9); // ascii 9 is tab - you have to coerce it to a char to work DEBUG_PRINT(hperiod); DEBUG_PRINT((char)9); DEBUG_PRINTLN(cycles); for (i=0; i<= cycles; i++){ // play note for t ms digitalWrite(outpin, HIGH); delayMicroseconds(hperiod); digitalWrite(outpin, LOW); delayMicroseconds(hperiod - 1); // - 1 to make up for digitaWrite overhead } pinMode(outpin, INPUT); // shut off pin to avoid noise from other operations } else { DEBUG_PRINTLN("detected rest"); delay(t); } } void playtune(int t){ switch(t){ case 1: { char word[15]; int arraylen = sizeof(tune1) / sizeof(float) -1 ; for(int x= 0; x<=arraylen; x++){ strcpy_P(word, (char*)pgm_read_word(&(string_table[x]))); Serial.print(word); noteval = (tune1[x] / 64); dur = (length1[x] * CLENGTH); freqout((int)noteval, dur); delay(10); }; break; }; case 2: { int arraylen = sizeof(tune2) / sizeof(float) -1 ; for(int x= 0; x<=arraylen; x++){ noteval = (tune2[x] / 64); dur = (length2[x] * CLENGTH); freqout((int)noteval, dur); delay(10); }; break; }; case 3: { int arraylen = sizeof(tune3) / sizeof(float) -1 ; for(int x= 0; x<=arraylen; x++){ noteval = (tune3[x] / 64); dur = (length3[x] * CLENGTH); freqout((int)noteval, dur); delay(10); }; }; } // end switch } void sevenSegout(byte data){ int i=0; byte mask = B00000001; DEBUG_PRINT("in sevenSegout. data="); DEBUG_PRINT(data); DEBUG_PRINT(", mask="); DEBUG_PRINTLN(mask); for(int i=0;i