2016-04-26 13 views
0

Ich versuche eine Gitarre mit dem Mbed LPC Mikrocontroller zu stimmen. Unten finden Sie einen Link für ein Beispiel des Projekts. https://developer.mbed.org/users/adurand/notebook/guitar-tuner/Mbed Guitar Tuner Code Probleme?

Allerdings habe ich einige Probleme damit. Erstens simuliere ich die Gitarreneingabe mit einem beliebigen Wellenformgenerator bei der erforderlichen Frequenz jeder Saite. Die Verstärkerschaltung ist gleich aufgebaut. Ich habe auch den Code geändert, um das Mbed LCD anstelle des Nokia zu verwenden. Ich habe ein Oszilloskop verwendet, um zu bestätigen, dass die Ausgabe, die in AnalogueIn p20 des Mbed geht, verstärkt wird und mit der richtigen Frequenz. Hier habe ich Probleme. Hier

ist der Code (mit Kredit zu Andrew Durand):

#include "mbed.h" 
#include "adc.h" 
#include "C12832.h" 
#include <math.h> 
#define PI 3.1415 
#define SAMPLE_RATE 24000 

InterruptIn button1(p12); 
C12832 lcd(p5, p7, p6, p8, p11); 
DigitalOut myled1(LED1); 
DigitalOut myled2(LED2); 
DigitalOut myled3(LED3); 

//LCD and Other Random Variables 
int string_select = 0; 
float high, high1, in_tune, in_tune1, in_tune2, in_tune3, 
low, low1, note, low_mod, high_mod; 
char* key; 
int Counter = 0; 
int Buffer[6000]; 

float goertzelFilter(int samples[], float freq, int N) { 
    float s_prev = 0.0; 
    float s_prev2 = 0.0; 
    float coeff,normalizedfreq,power,s; 
    int i; 
    normalizedfreq = freq/SAMPLE_RATE; 
    coeff = 2*cos(2*PI*normalizedfreq); 
    for (i=0; i<N; i++) { 
     s = samples[i] + coeff * s_prev - s_prev2; 
     s_prev2 = s_prev; 
     s_prev = s; 
    } 
    power = s_prev2*s_prev2+s_prev*s_prev-coeff*s_prev*s_prev2; 
    return power; 
} 

ADC adc(SAMPLE_RATE, 1); 

void sample_audio(int chan, uint32_t value) { 
    Buffer[Counter] = adc.read(p20); 
    Counter += 1; 
} 

void button1_pressed() { 
    string_select++; 
    if (string_select > 5) string_select = 0; 
} 

int main() { 
    //Interupt for Switching Strings 
    button1.mode(PullDown); 
    button1.rise(&button1_pressed); 

    while (1) { 

     switch (string_select) { 
      case 0: 
       note = 82; 
       key= "E2"; 
       break; 
      case 1: 
       note = 110; 
       key= "A2"; 
       break; 
      case 2: 
       note = 147; 
       key= "D3"; 
       break; 
      case 3: 
       note = 196; 
       key= "G3"; 
       break; 
      case 4: 
       note = 247; 
       key= "B3"; 
       break; 
      case 5: 
       note = 330; 
       key= "E4"; 
       break; 
     } 

     //Prepare for burst mode on all ADC pins and set up interrupt handler (using ADC library from Simon Blandford 
     adc.append(sample_audio); 
     adc.startmode(0,0); 
     adc.burst(1); 
     adc.setup(p20,1); 

     //start the interrupt and wait for about 4096 samples 
     adc.interrupt_state(p20,1); 
     wait(.2); 

     //Finsh up - Unset pin 20 
     adc.interrupt_state(p20,0); 
     adc.setup(p20,0); 
     int actual_rate = adc.actual_sample_rate(); 

     //for debugging tell the terminal sample rate and how many samples we took 
     printf("Requested max sample rate is %u, actual max sample rate is %u.\n", 
       SAMPLE_RATE, actual_rate); 
     printf("We did %i samples\n",Counter); 

high = 0; 
low = 0; 
for (int i=3; i<46; i+=3) { 
    high1 = goertzelFilter(Buffer, (note + i), Counter); 
    if (high1 > high) high=high1; 
} 
for (int i=3; i<46; i+=3) { 
    low1 = goertzelFilter(Buffer, (note - i), Counter); 
    if (low1 > low) low=low1; 
} 
     in_tune1 = goertzelFilter(Buffer, (note+1), Counter); 
     in_tune2 = goertzelFilter(Buffer, note, Counter); 
     in_tune3 = goertzelFilter(Buffer, (note-1), Counter); 

     if ((in_tune1 > in_tune2) && (in_tune1 > in_tune3)) in_tune = in_tune1; 
     else if ((in_tune2 > in_tune1) && (in_tune2 > in_tune3)) in_tune = in_tune2; 
     else in_tune = in_tune3; 
     printf("high = %.2f, low = %.2f, in_tune = %.2f", high, low, in_tune); 
     high_mod = high/in_tune; 
     low_mod = low/in_tune; 
     if ((high_mod > .8)&&(low_mod > .8)) { 
      myled1 = 0; 
      myled2 = 0; 
      myled3 = 0; 
     } 
       if ((high_mod < .8)&&(low_mod > .8)) { 
      myled1 = 0; 
      myled2 = 0; 
      myled3 = 0; 
     } 
     if ((high > in_tune) && (low < in_tune)) {   //Guitar string is at correct frequency 
      myled1 = 0; 
      myled2 = 1; 
      myled3 = 0; 

     } else if (high > in_tune) {      // String is higher than the desired frequency 
      myled1 = 1; 
      myled2 = 0; 
      myled3 = 0; 

     } else if (low < in_tune){      // String is below that of the desired frequency 
      myled1 = 0; 
      myled2 = 0; 
      myled3 = 1; 

     } else {          // Else no input, display squiggles 
      myled1 = 0; 
      myled2 = 0; 
      myled3 = 0; 
     } 

     // Display on the LCD 
     lcd.cls(); 
     lcd.locate(0,0); 
     lcd.printf("Tuning String: %i", (6-string_select)); 
     lcd.locate(0,11); 
     lcd.printf("%s at %i Hz",key, (int) note); 
     lcd.locate(0,23); 
     if (myled2) lcd.printf("In Tune!");    // if myled2 is on, guitar is in tune 
     else if (myled3) lcd.printf("Too Low ");   // if myled3 is on, guitar is lower than desired tone 
     else if (myled1) lcd.printf("Too High");   // if myled1 is on, guitar is higher than desired tone 
     else lcd.printf("No Input Detected");      // corresponds to led case 4 - no guitar input present 

     Counter = 0; 

    } 



} 

Nun, wenn ich das Programm zu kompilieren, um den Druck Nachrichten. Die LEDs wechseln jedoch zwischen "Too high", "Too low" und den Squiggles. Ich werde der Erste sein, der zugibt, dass ich nicht der beste Coder bin, etwas, an dem ich im Sommer wirklich arbeiten werde. Es könnte ein sehr signifikantes Problem mit dem Code geben oder es könnte etwas relativ Einfaches sein. Alle Eingaben werden geschätzt.

Hinweis: Ich habe die Entprellschaltung auf dem Steckbrett nicht angeschlossen - sie ist mit dem Nokia LCD verbunden, das ich nicht benutzt habe. Ich kann die gewünschte Saite zwischen 1-6 mit dem Joystick auf der mbed-Anwendungsplatine ändern. Ist das in Ordnung? Oder ist die Entprellschaltung von zentraler Bedeutung? Danke nochmal.

Antwort

1

Die Schleife, die low findet, ist (fast) die gleiche wie die Schleife, die high in diesem Code findet:

high = 0; 
low = 0; 
for (int i=3; i<46; i+=3) { 
    high1 = goertzelFilter(Buffer, (note + i), Counter); 
    if (high1 > high) high=high1; 
} 
for (int i=3; i<46; i+=3) { 
    low1 = goertzelFilter(Buffer, (note - i), Counter); 
    if (low1 > low) low=low1; 
} 

Ich schlage vor, die low Teil wie dieses

low = FLT_MAX; 
for (int i=3; i<46; i+=3) { 
    low1 = goertzelFilter(Buffer, (note - i), Counter); 
    if (low1 < low) low=low1; 
} 

sein sollte .. Obwohl ich bei der beabsichtigten Verwendung von low irrtümlich sein könnte.

+0

Wie würde ich FLT_MAX definieren? – jvnlendm

+0

'#include ' und BTW Ich sehe, Sie verwenden 'printf' so # #include ' auch. –

+0

... oder setzen Sie 'niedrig' auf einen anderen, unausweichlich hohen Wert. –