A program to automatically tune a guitar. Written by Justin Reidhead and Steven Swenson
Dependencies: FFT FrequencyFinder Motor NewTextLCD PinDetect mbed strings
main.cpp
- Committer:
- melangeaddict
- Date:
- 2012-04-15
- Revision:
- 2:9c0a83c5ded5
- Parent:
- 1:4a82a5178506
- Child:
- 3:c672e782f19b
File content as of revision 2:9c0a83c5ded5:
#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> using namespace std; //*************************************************** //***************Globals***************************** PinDetect string_but(p11); PinDetect pitch_but(p12); PinDetect start_but(p13); PinDetect mode_but(p14); DigitalOut led1(LED1); DigitalOut led2(LED2); TextLCD lcd(p23,p24,p25,p26,p27,p28); Motor motor(p20,p21,p22);//enable, direction, step FrequencyFinder guitar(p19);//input int selected_string; bool current_mode; bool start_tuning; bool up, down; vector<strings> strings_array; //*************************************************** //*****************constants************************* const bool tuning_mode=false; const bool winding_mode=true; //*************************************************** //******************prototypes*********************** void device_init(); 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() { lcd.cls(); lcd.printf("Perfect\n Pitch"); wait(.5); device_init(); int state=0,next_state=0; //float old_freq=0; float new_freq=0; float desired_freq=0; strings *temp=&strings_array[0]; while (1) { state=next_state; switch (state) { //------------------------------------ case 0://Stay here till the user selects the string and pitch if (start_tuning==true) { next_state=1; } else { next_state=0; } 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=guitar.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()); } //*************************************************** 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=0, freq_down=0; 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 the two frequencies! while (!done) { freq=guitar.find_frequency(); if (check_threshold(freq)) { freq_up=freq; done=true; } } motor.motor_turn(down,25);//TODO: Adjust the number of steps here done=false; while (!done) { freq=guitar.find_frequency(); if (check_threshold(freq)) { 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; }