Slight modifications to original for different LCD and mbed pin outs
Fork of GT_Tuner by
main.cpp@2:0b7bf57470c4, 2016-12-16 (annotated)
- Committer:
- mptapton
- Date:
- Fri Dec 16 10:15:01 2016 +0000
- Revision:
- 2:0b7bf57470c4
- Parent:
- 1:ae7d0cf78b3e
Original code modified for a different LCD and mbed pin out. Additional output to LCD for real time input signal value
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mptapton | 2:0b7bf57470c4 | 1 | ////////////////////////////////////////// |
adurand | 0:490e67fb09c2 | 2 | // // |
adurand | 0:490e67fb09c2 | 3 | // Guitar Tuner via Goertzel's Algorithm // |
adurand | 0:490e67fb09c2 | 4 | // Created by: Andrew Durand // |
adurand | 0:490e67fb09c2 | 5 | // // |
adurand | 0:490e67fb09c2 | 6 | ////////////////////////////////////////// |
mptapton | 2:0b7bf57470c4 | 7 | #include "TextLCD.h" |
adurand | 0:490e67fb09c2 | 8 | #include "mbed.h" |
adurand | 0:490e67fb09c2 | 9 | #include "adc.h" |
mptapton | 2:0b7bf57470c4 | 10 | //#include "NokiaLCD.h" |
adurand | 1:ae7d0cf78b3e | 11 | #include <math.h> |
adurand | 0:490e67fb09c2 | 12 | #define PI 3.1415 |
adurand | 0:490e67fb09c2 | 13 | #define SAMPLE_RATE 24000 |
adurand | 0:490e67fb09c2 | 14 | |
adurand | 0:490e67fb09c2 | 15 | DigitalOut led_low(LED1); |
adurand | 0:490e67fb09c2 | 16 | DigitalOut led_ok(LED2); |
adurand | 0:490e67fb09c2 | 17 | DigitalOut led_high(LED4); |
mptapton | 2:0b7bf57470c4 | 18 | InterruptIn button1(p6); //mosi |
adurand | 0:490e67fb09c2 | 19 | |
adurand | 0:490e67fb09c2 | 20 | //LCD and Other Random Variables |
mptapton | 2:0b7bf57470c4 | 21 | //NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type |
mptapton | 2:0b7bf57470c4 | 22 | |
mptapton | 2:0b7bf57470c4 | 23 | /* This code uses libraries created for 4-bit LCD's based on the HD44780. This |
mptapton | 2:0b7bf57470c4 | 24 | program was designed for a similar product (Winstar's WH1602B 2x16 LC) working |
mptapton | 2:0b7bf57470c4 | 25 | into an Mbed LPC1768. |
mptapton | 2:0b7bf57470c4 | 26 | LCD pins: Pin 1(VSS) to Mbed Gnd, Pin 2(VDD) to Mbed VOUT, Pin 3(Vo- contrast) |
mptapton | 2:0b7bf57470c4 | 27 | to Mbed Gnd, Pin 5(R/W) to Mbed Gnd, Pin 15(A)to Mbed VOUT, Pin 16(B) to |
mptapton | 2:0b7bf57470c4 | 28 | MBed Gnd, Pins 4(RS),20(E) and the 4 data bits (DB4 [11] through to DB7 [14]) |
mptapton | 2:0b7bf57470c4 | 29 | go to the Mbed pins described below: */ |
mptapton | 2:0b7bf57470c4 | 30 | |
mptapton | 2:0b7bf57470c4 | 31 | TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d4-d7 |
mptapton | 2:0b7bf57470c4 | 32 | |
adurand | 0:490e67fb09c2 | 33 | int string_select = 0; |
adurand | 1:ae7d0cf78b3e | 34 | float high, high1, in_tune, in_tune1, in_tune2, in_tune3, |
adurand | 1:ae7d0cf78b3e | 35 | low, low1, note, low_mod, high_mod; |
adurand | 0:490e67fb09c2 | 36 | char* key; |
adurand | 0:490e67fb09c2 | 37 | int Counter = 0; |
adurand | 0:490e67fb09c2 | 38 | int Buffer[6000]; |
adurand | 0:490e67fb09c2 | 39 | |
adurand | 0:490e67fb09c2 | 40 | float goertzelFilter(int samples[], float freq, int N) { |
adurand | 0:490e67fb09c2 | 41 | float s_prev = 0.0; |
adurand | 0:490e67fb09c2 | 42 | float s_prev2 = 0.0; |
mptapton | 2:0b7bf57470c4 | 43 | float coeff,normalizedfreq,power,s; //k was defined here but nolonger needed |
adurand | 0:490e67fb09c2 | 44 | int i; |
adurand | 0:490e67fb09c2 | 45 | normalizedfreq = freq / SAMPLE_RATE; |
adurand | 0:490e67fb09c2 | 46 | coeff = 2*cos(2*PI*normalizedfreq); |
adurand | 0:490e67fb09c2 | 47 | for (i=0; i<N; i++) { |
adurand | 0:490e67fb09c2 | 48 | s = samples[i] + coeff * s_prev - s_prev2; |
adurand | 0:490e67fb09c2 | 49 | s_prev2 = s_prev; |
adurand | 0:490e67fb09c2 | 50 | s_prev = s; |
adurand | 0:490e67fb09c2 | 51 | } |
adurand | 0:490e67fb09c2 | 52 | power = s_prev2*s_prev2+s_prev*s_prev-coeff*s_prev*s_prev2; |
adurand | 0:490e67fb09c2 | 53 | return power; |
adurand | 0:490e67fb09c2 | 54 | } |
adurand | 0:490e67fb09c2 | 55 | |
adurand | 0:490e67fb09c2 | 56 | ADC adc(SAMPLE_RATE, 1); |
adurand | 0:490e67fb09c2 | 57 | |
adurand | 0:490e67fb09c2 | 58 | void sample_audio(int chan, uint32_t value) { |
adurand | 0:490e67fb09c2 | 59 | Buffer[Counter] = adc.read(p20); |
adurand | 0:490e67fb09c2 | 60 | Counter += 1; |
adurand | 0:490e67fb09c2 | 61 | } |
adurand | 0:490e67fb09c2 | 62 | |
adurand | 0:490e67fb09c2 | 63 | void button1_pressed() { |
adurand | 0:490e67fb09c2 | 64 | string_select++; |
adurand | 0:490e67fb09c2 | 65 | if (string_select > 5) string_select = 0; |
adurand | 0:490e67fb09c2 | 66 | } |
adurand | 0:490e67fb09c2 | 67 | |
adurand | 0:490e67fb09c2 | 68 | int main() { |
adurand | 0:490e67fb09c2 | 69 | //Interupt for Switching Strings |
adurand | 0:490e67fb09c2 | 70 | button1.mode(PullDown); |
adurand | 0:490e67fb09c2 | 71 | button1.rise(&button1_pressed); |
adurand | 0:490e67fb09c2 | 72 | |
adurand | 0:490e67fb09c2 | 73 | //Setup LCD |
mptapton | 2:0b7bf57470c4 | 74 | // lcd.background(0xF0000F); |
adurand | 0:490e67fb09c2 | 75 | lcd.cls(); |
adurand | 0:490e67fb09c2 | 76 | |
adurand | 0:490e67fb09c2 | 77 | while (1) { |
adurand | 0:490e67fb09c2 | 78 | |
adurand | 0:490e67fb09c2 | 79 | switch (string_select) { |
adurand | 0:490e67fb09c2 | 80 | case 0: |
adurand | 0:490e67fb09c2 | 81 | note = 82; |
adurand | 0:490e67fb09c2 | 82 | key= "E2"; |
adurand | 0:490e67fb09c2 | 83 | break; |
adurand | 0:490e67fb09c2 | 84 | case 1: |
adurand | 0:490e67fb09c2 | 85 | note = 110; |
adurand | 0:490e67fb09c2 | 86 | key= "A2"; |
adurand | 0:490e67fb09c2 | 87 | break; |
adurand | 0:490e67fb09c2 | 88 | case 2: |
adurand | 0:490e67fb09c2 | 89 | note = 147; |
adurand | 0:490e67fb09c2 | 90 | key= "D3"; |
adurand | 0:490e67fb09c2 | 91 | break; |
adurand | 0:490e67fb09c2 | 92 | case 3: |
adurand | 0:490e67fb09c2 | 93 | note = 196; |
adurand | 0:490e67fb09c2 | 94 | key= "G3"; |
adurand | 0:490e67fb09c2 | 95 | break; |
adurand | 0:490e67fb09c2 | 96 | case 4: |
adurand | 0:490e67fb09c2 | 97 | note = 247; |
adurand | 0:490e67fb09c2 | 98 | key= "B3"; |
adurand | 0:490e67fb09c2 | 99 | break; |
adurand | 0:490e67fb09c2 | 100 | case 5: |
adurand | 0:490e67fb09c2 | 101 | note = 330; |
adurand | 0:490e67fb09c2 | 102 | key= "E4"; |
adurand | 0:490e67fb09c2 | 103 | break; |
adurand | 0:490e67fb09c2 | 104 | } |
adurand | 0:490e67fb09c2 | 105 | |
adurand | 0:490e67fb09c2 | 106 | //Prepare for burst mode on all ADC pins and set up interrupt handler (using ADC library from Simon Blandford |
adurand | 0:490e67fb09c2 | 107 | adc.append(sample_audio); |
adurand | 0:490e67fb09c2 | 108 | adc.startmode(0,0); |
adurand | 0:490e67fb09c2 | 109 | adc.burst(1); |
adurand | 0:490e67fb09c2 | 110 | adc.setup(p20,1); |
adurand | 0:490e67fb09c2 | 111 | |
adurand | 0:490e67fb09c2 | 112 | //start the interrupt and wait for about 4096 samples |
adurand | 0:490e67fb09c2 | 113 | adc.interrupt_state(p20,1); |
adurand | 0:490e67fb09c2 | 114 | wait(.2); |
adurand | 0:490e67fb09c2 | 115 | |
adurand | 0:490e67fb09c2 | 116 | //Finsh up - Unset pin 20 |
adurand | 0:490e67fb09c2 | 117 | adc.interrupt_state(p20,0); |
adurand | 0:490e67fb09c2 | 118 | adc.setup(p20,0); |
adurand | 0:490e67fb09c2 | 119 | int actual_rate = adc.actual_sample_rate(); |
adurand | 0:490e67fb09c2 | 120 | |
adurand | 0:490e67fb09c2 | 121 | //for debugging tell the terminal sample rate and how many samples we took |
adurand | 0:490e67fb09c2 | 122 | printf("Requested max sample rate is %u, actual max sample rate is %u.\n", |
adurand | 0:490e67fb09c2 | 123 | SAMPLE_RATE, actual_rate); |
adurand | 0:490e67fb09c2 | 124 | printf("We did %i samples\n",Counter); |
adurand | 0:490e67fb09c2 | 125 | |
adurand | 1:ae7d0cf78b3e | 126 | high = 0; |
adurand | 1:ae7d0cf78b3e | 127 | low = 0; |
adurand | 1:ae7d0cf78b3e | 128 | for (int i=3; i<46; i+=3) { |
adurand | 1:ae7d0cf78b3e | 129 | high1 = goertzelFilter(Buffer, (note + i ), Counter); |
adurand | 1:ae7d0cf78b3e | 130 | if (high1 > high) high=high1; |
adurand | 1:ae7d0cf78b3e | 131 | } |
adurand | 1:ae7d0cf78b3e | 132 | for (int i=3; i<46; i+=3) { |
adurand | 1:ae7d0cf78b3e | 133 | low1 = goertzelFilter(Buffer, (note - i ), Counter); |
adurand | 1:ae7d0cf78b3e | 134 | if (low1 > low) low=low1; |
adurand | 1:ae7d0cf78b3e | 135 | } |
adurand | 1:ae7d0cf78b3e | 136 | in_tune1 = goertzelFilter(Buffer, (note+1), Counter); |
adurand | 0:490e67fb09c2 | 137 | in_tune2 = goertzelFilter(Buffer, note, Counter); |
adurand | 1:ae7d0cf78b3e | 138 | in_tune3 = goertzelFilter(Buffer, (note-1), Counter); |
adurand | 1:ae7d0cf78b3e | 139 | |
adurand | 1:ae7d0cf78b3e | 140 | if ((in_tune1 > in_tune2) && (in_tune1 > in_tune3)) in_tune = in_tune1; |
adurand | 1:ae7d0cf78b3e | 141 | else if ((in_tune2 > in_tune1) && (in_tune2 > in_tune3)) in_tune = in_tune2; |
adurand | 1:ae7d0cf78b3e | 142 | else in_tune = in_tune3; |
adurand | 1:ae7d0cf78b3e | 143 | // printf("high = %.2f, low = %.2f, in_tune = %.2f", high, low, in_tune); |
adurand | 1:ae7d0cf78b3e | 144 | // high_mod = high/in_tune; |
adurand | 1:ae7d0cf78b3e | 145 | // low_mod = low/in_tune; |
adurand | 1:ae7d0cf78b3e | 146 | // if ((high_mod > .8)&&(low_mod > .8)) { |
adurand | 1:ae7d0cf78b3e | 147 | // led_high = 0; |
adurand | 1:ae7d0cf78b3e | 148 | // led_ok = 0; |
adurand | 1:ae7d0cf78b3e | 149 | // led_low = 0; |
adurand | 1:ae7d0cf78b3e | 150 | // } |
adurand | 0:490e67fb09c2 | 151 | if ((in_tune > high) && (in_tune > low)) { |
adurand | 0:490e67fb09c2 | 152 | led_high = 0; |
adurand | 0:490e67fb09c2 | 153 | led_ok = 1; |
adurand | 0:490e67fb09c2 | 154 | led_low = 0; |
adurand | 0:490e67fb09c2 | 155 | } else if (high > in_tune) { |
adurand | 0:490e67fb09c2 | 156 | led_high = 1; |
adurand | 0:490e67fb09c2 | 157 | led_ok = 0; |
adurand | 0:490e67fb09c2 | 158 | led_low = 0; |
adurand | 0:490e67fb09c2 | 159 | } else if (low > in_tune) { |
adurand | 0:490e67fb09c2 | 160 | led_high = 0; |
adurand | 0:490e67fb09c2 | 161 | led_ok = 0; |
adurand | 0:490e67fb09c2 | 162 | led_low = 1; |
adurand | 0:490e67fb09c2 | 163 | } else { |
adurand | 0:490e67fb09c2 | 164 | led_high = 0; |
adurand | 0:490e67fb09c2 | 165 | led_ok = 0; |
adurand | 0:490e67fb09c2 | 166 | led_low = 0; |
adurand | 0:490e67fb09c2 | 167 | } |
adurand | 1:ae7d0cf78b3e | 168 | |
adurand | 0:490e67fb09c2 | 169 | // Display on the LCD |
mptapton | 2:0b7bf57470c4 | 170 | // lcd.locate(0,1); |
mptapton | 2:0b7bf57470c4 | 171 | // lcd.printf("Guitar Tuner"); |
mptapton | 2:0b7bf57470c4 | 172 | // lcd.locate(0,3); |
mptapton | 2:0b7bf57470c4 | 173 | // lcd.printf("Tuning String: %i", (6-string_select)); |
mptapton | 2:0b7bf57470c4 | 174 | int pintwenty = adc.read(p20); //read pin 20 |
adurand | 0:490e67fb09c2 | 175 | lcd.locate(0,1); |
mptapton | 2:0b7bf57470c4 | 176 | lcd.printf("%s %iHz %d\n",key, (int) note, pintwenty); |
mptapton | 2:0b7bf57470c4 | 177 | // lcd.locate(0,2); |
mptapton | 2:0b7bf57470c4 | 178 | if (led_ok) lcd.printf("Ok "); |
mptapton | 2:0b7bf57470c4 | 179 | else if (led_low) lcd.printf("Low "); |
mptapton | 2:0b7bf57470c4 | 180 | else if (led_high) lcd.printf("High"); |
adurand | 1:ae7d0cf78b3e | 181 | else lcd.printf("~~~~~~~~"); |
adurand | 0:490e67fb09c2 | 182 | |
adurand | 0:490e67fb09c2 | 183 | Counter = 0; |
adurand | 0:490e67fb09c2 | 184 | |
adurand | 0:490e67fb09c2 | 185 | } |
adurand | 0:490e67fb09c2 | 186 | |
adurand | 0:490e67fb09c2 | 187 | |
mptapton | 2:0b7bf57470c4 | 188 | |
adurand | 0:490e67fb09c2 | 189 | } |