A program to automatically tune a guitar. Written by Justin Reidhead and Steven Swenson

Dependencies:   FFT FrequencyFinder Motor NewTextLCD PinDetect mbed strings

Revision:
1:4a82a5178506
Parent:
0:d8909ac31fbf
Child:
2:9c0a83c5ded5
--- a/main.cpp	Sun Apr 15 00:20:28 2012 +0000
+++ b/main.cpp	Sun Apr 15 00:20:48 2012 +0000
@@ -1,92 +1,320 @@
-#include "mbed.h"
-
-//Button interrupts
-InterruptIn start_stop_b(p5);
-InterruptIn pitch_b(p6);
-InterruptIn string_b(p7);
-InterruptIn mode_b(p8);
-
-//
+//#include "mbed.h"
+//#include "Motor.h"
+//#include "FrequencyFinder.h"
+//#include "NewTextLCD.h"
+//#include "PinDetect.h"
+#include "strings.h"
+#include <iostream>
+#include <stdio.h>
+#include <vector>
 
-//AnalogIn
-AnalogIn guitar(p20);
+using namespace std;
+//***************************************************
+//***************Globals*****************************
+//PinDetect string_but(p11);
+//PinDetect pitch_but(p12);
+//PinDetect start_but(p13);
+//PinDetect mode_but(p14);
 
-//Motor Controller outputs
-PwmOut step(p26);
-DigitalOut direction(p27);
-DigitalOut motor_enable(p28);
+//DigitalOut led1(LED1);
+//DigitalOut led2(LED2);
 
-//Local File pointer
-LocalFileSystem local("local");
+//TextLCD lcd(p21,p22,p23,p24,p25,p26);
+//Motor motor(p26,p22,p21);//enable, direction, step
+//FrequencyFinder guitar(p20);//input
 
-//Global Variables
-bool begin=false;
-
+int selected_string;
+//int selected_pitch;
+bool current_mode;
+bool start_tuning;
+bool up, down;
 
-//Functions
-void device_init(){
-return;}
+vector<strings> strings_array;
 
-void start(){
-begin=true;
-return;}
+//***************************************************
+//*****************constants*************************
+const bool tuning_mode=false;
+const bool winding_mode=true;
 
-void stop(){
-return;}
-
-void pitch(){
-return;}
+//***************************************************
+//******************prototypes***********************
+void device_init();
 
-void string(){
-return;}
-
-void mode(){
-return;}
-
-
+void string_sel();
+void pitch_sel();
+void start();
+void stop();
+void mode();
+void do_nothing();
+void wind_up();
+void wind_down();
 
+void button_init();
+void setup_buttons();
+void output_menu();
+void motor_calibration();
+bool check_threshold(float);
+//*************************************************
+//*********************main************************
 int main() {
-    int state=0, next_state=0;
-
-
-    start_stop_b.rise(&start);//Assign what functions to call when
-    pitch_b.rise(&pitch);     //the interrupt occurs
-    string_b.rise(&string);
-    mode_b.rise(&mode);
+    //    lcd.cls();
+    //    lcd.printf("Perfect\n      Pitch");
+    
+    //    wait(.5);
     
     device_init();
-
-   
+    
+    int state=0,next_state=0;
+    float old_freq=0,new_freq=0;
+    float desired_freq;
+    strings *temp=&strings_array[0];
     while (1) {
+        
         state=next_state;
-        switch (state) {
-            case(0)://Waiting for user input
-            if(begin){
+        
+        switch(state){
+            //------------------------------------
+        case 0://Stay here till the user selects the string and pitch
+            if(start_tuning==true){
                 next_state=1;
             }
-            else
+            else{
                 next_state=0;
-                break;
-            case(1)://Take Sample
-                break;
-            case(2)://Take FFT
-                break;
-            case(3)://Analyze FFT for Peaks
-                break;
-            case(4)://Compare current freq with desired
-            //Determine Hz per step
-                break;
-            case(5)://Motor Direction Calibration
-                break;
-            case(6)://Step Up
-                break;
-            case(7)://Step Down
-                break;
-            default:
-                break;
+            }
+            
+            break;
+            //----------------------------------------
+        case 1://motor calibration state
+            motor_calibration();
+            next_state=2;
+            break;
+            //-----------------------------------------
+        case 2://begin the actual tuning
+            temp=&strings_array[selected_string];
+            desired_freq=temp->get_freq();
+            
+            next_state=3;
+            break;
+            //-----------------------------------------
+        case 3:
+            //new_freq=frequency.find_frequency();
+            if(check_threshold(new_freq)){
+                if((desired_freq-.5)<new_freq && (desired_freq+.5)>new_freq){//We are within .5Hz of the desired frequency
+                    //lcd.cls();
+                    //lcd.
+                    printf("String %d\ntuned",selected_string);
+                    //wait(.5);
+                    
+                    start_tuning=false;
+                    next_state=0;
+                }
+                else if((desired_freq-.5)>new_freq){
+                    //motor(up,# of steps);
+                    next_state=3;
+                }
+                else{
+                    //motor(down,# of steps);
+                    next_state=3;
+                }
+            }
+            else{
+                next_state=3;
+            }
+            
+            //TODO:Determine number of steps per frequency change
+            old_freq=new_freq;
+            break;
+            //-----------------------------------------
+        default:
+            break;
+        }
+        //wait_ms(5);
+        
+        if(start_tuning==false){//If the stop button is pressed, the state machine returns to user input
+            next_state=0;
+        }
+    }
+    
+    //   return 0;
+}
+
+//***************************************************
+//******************functions************************
+void output_menu() {
+    //    lcd.cls();
+    strings temp=strings_array[selected_string];
+    /*lcd.*/printf("Select String: %d\nSelect Pitch: %s",selected_string,temp.get_note().c_str());
+            fflush(stdout);
         }
 
+//***************************************************
+void button_init(){
+    //    string_but.mode( PullDown );
+    //    string_but.setSampleFrequency();
+    
+    //    pitch_but.mode( PullDown );
+    //    pitch_but.setSampleFrequency();
+    
+    //    start_but.mode( PullDown );
+    //    start_but.setSampleFrequency();
+    
+    //    mode_but.mode( PullDown );
+    //    mode_but.setSampleFrequency();
+}
+
+//***************************************************
+void setup_buttons() {
+    if(current_mode==tuning_mode){
+        //    string_but.attach_asserted(&string_sel);
+        //    pitch_but.attach_asserted(&pitch_sel);
+        //    start_but.attach_asserted(&start);
+        //    mode_but.attach_asserted(&mode);
+    }
+    else{
+        //    string_but.attach_asserted(&wind_up);
+        //    pitch_but.attach_asserted(&wind_down);
+        //    start_but.attach_asserted(&do_nothing);
+        //    mode_but.attach_asserted(&mode);
     }
 }
-
-
+//***************************************************
+void string_sel() {
+    selected_string++;
+    if (selected_string>6)
+        selected_string=1;
+    
+    output_menu();
+}
+//***************************************************
+void pitch_sel() {
+    strings *temp=&strings_array[selected_string];
+    temp->inc_index();
+    
+    output_menu();
+}
+//***************************************************
+void start() {
+    start_tuning=true;
+}
+//***************************************************
+void mode() {
+    if(current_mode==tuning_mode){
+        current_mode=winding_mode;
+        //lcd.cls();
+        /*lcd.*/printf("Winding Mode");
+                //wait(1);
+            }
+    else{
+        current_mode=tuning_mode;
+        //lcd.cls();
+        /*lcd.*/printf("Tuning Mode");
+                //wait(1);
+            }
+    setup_buttons();
+}
+//***************************************************
+void stop() {
+    start_tuning=false;
+}
+//***************************************************
+void do_nothing(){
+    return;
+}
+//***************************************************
+void wind_up(){
+    //motor.motor_turn(1,10);
+}
+//***************************************************
+void wind_down(){
+    //motor.motor_turn(0,10);
+}
+//***************************************************
+void device_init(){
+    strings string1(1);
+    strings string2(2);
+    strings string3(3);
+    strings string4(4);
+    strings string5(5);
+    strings string6(6);
+    strings_array.push_back(string1);
+    strings_array.push_back(string2);
+    strings_array.push_back(string3);
+    strings_array.push_back(string4);
+    strings_array.push_back(string5);
+    strings_array.push_back(string6);
+    
+    selected_string=1;
+    current_mode=tuning_mode;
+    start_tuning=false;
+    up=true;
+    down=false;
+    
+    button_init();
+    
+    output_menu();
+}
+//***************************************************
+void motor_calibration(){
+    //lcd.cls();
+    //lcd.
+    printf("Calibrate Motor");
+    
+    float freq=0, freq_up, freq_down;
+    // bool calibration_done=false;
+    bool done=false;
+    //lcd.cls();
+    /*lcd.*/
+    printf("Please pluck\nstring");
+    
+    //motor.motor_turn(up,25)//TODO: Adjust the number of steps here
+    //On second thought, we don't need to tune up and down for this, we can find the current frequency
+    //and then turn the peg for two frequencies!
+    while(!done){
+        //freq=frequency.find_frequency();
+        
+        if(freq>500){
+            printf("Please pluck\nstring again");
+            //wait(.5);
+            //lcd.cls();
+        }
+        else{
+            freq_up=freq;
+            done=true;
+        }
+    }
+    //motor.motor_turn(down,25)//TODO: Adjust the number of steps here
+    done=false;
+    while(!done){
+        //freq=frequency.find_frequency();
+        
+        if(freq>500){
+            printf("Please pluck\nstring again");
+            //wait(.5);
+            //lcd.cls();
+        }
+        else{
+            freq_down=freq;
+            done=true;
+        }
+    }
+    
+    if(freq_up<freq_down){
+        down=true;
+        up=false;
+    }
+    
+    //lcd.cls();
+    //lcd.
+    printf("Calibration Done");
+}
+//**********************************************
+bool check_threshold(float freq){
+    if(freq>500){
+        //lcd.cls();
+        //lcd.
+        printf("Pluck string \nagain");
+        return false;
+    }
+    else
+        return true;
+}