the code continued here
case 3:
digitalWrite(led_e4, LOW); // sets the proper LED on, all else off
digitalWrite(led_b3, LOW);
digitalWrite(led_g3, HIGH);
digitalWrite(led_d3, LOW);
digitalWrite(led_a2, LOW);
digitalWrite(led_e2, LOW);
a = 0.0730;
b = 0.8541;
threshold = 130;
upper_bound = 50;
lower_bound = 15;
avg_upper = 29;
in_tune = 27; // This is the “in tune” average of cross counts for the string.
avg_lower = 26;
timer_divide = 500;
divide_by = 4;
break;
case 4:
digitalWrite(led_e4, LOW); // sets the proper LED on, all else off
digitalWrite(led_b3, HIGH);
digitalWrite(led_g3, LOW);
digitalWrite(led_d3, LOW);
digitalWrite(led_a2, LOW);
digitalWrite(led_e2, LOW);
a = 0.1270;
b = 0.7459;
threshold = 140;
upper_bound = 50;
lower_bound = 15;
avg_upper = 35;
in_tune = 34; // This is the “in tune” average of cross counts for the string.
avg_lower = 33;
timer_divide = 500;
divide_by = 4;
break;
case 5:
digitalWrite(led_e4, HIGH); // sets the proper LED on, all else off
digitalWrite(led_b3, LOW);
digitalWrite(led_g3, LOW);
digitalWrite(led_d3, LOW);
digitalWrite(led_a2, LOW);
digitalWrite(led_e2, LOW);
a = 0.1648;
b = 0.6705;
threshold = 150;
upper_bound = 60;
lower_bound = 20;
avg_upper = 47;
in_tune = 45; // This is the “in tune” average of cross counts for the string.
avg_lower = 43;
timer_divide = 500;
divide_by = 4;
break;
}
check_crossings();
// After the string input has been idle for a while, we take the average of a number of cross counts that were in bound.
if (idle_timer == 10000)
{
Serial.println("AVG AVG LOOK HERE AVG AVG");
average_val = avg_cross / divide_by;
Serial.println(average_val);
// If else statements for tuner lights
if ((average_val < avg_lower) && (average_val > 0))
{
// Turn off all string display lights to conserve power
digitalWrite(led_e4, LOW);
digitalWrite(led_b3, LOW);
digitalWrite(led_g3, LOW);
digitalWrite(led_d3, LOW);
digitalWrite(led_a2, LOW);
digitalWrite(led_e2, LOW);
// Sets the proper tuning LED on, all else off
digitalWrite(led_high, LOW);
digitalWrite(led_ok, LOW);
digitalWrite(led_low, HIGH);
pitch_diff = in_tune - average_val;
Serial.print("Pitch Difference Low: ");
Serial.println(pitch_diff);
// If the tuning is off by a questionably high amount, count it as an error in reading and do not turn the peg.
// Otherwise tune the peg for a period of time. This time depends on how far off the read average is.
if (pitch_diff < 20)
for(long i = 0; i < pitch_diff * 36000; i++)
{
digitalWrite(servoPin, HIGH); // start the pulse
delayMicroseconds(15); // pulse width
digitalWrite(servoPin, LOW); // stop the pulse
}
}
// Don't turn the peg if the guitar is in tune.
else if ((average_val >= avg_lower && average_val <= avg_upper) || (average_val == 0))
{
// Sets the proper tuning LED on, all else off
digitalWrite(led_high, LOW);
digitalWrite(led_ok, HIGH);
digitalWrite(led_low, LOW);
}
else if (average_val > avg_upper)
{
// Turn off all string display lights to conserve power
digitalWrite(led_e4, LOW);
digitalWrite(led_b3, LOW);
digitalWrite(led_g3, LOW);
digitalWrite(led_d3, LOW);
digitalWrite(led_a2, LOW);
digitalWrite(led_e2, LOW);
// Sets the proper tuning LED on, all else off
digitalWrite(led_high, HIGH);
digitalWrite(led_ok, LOW);
digitalWrite(led_low, LOW);
pitch_diff = average_val - in_tune;
Serial.print("Pitch Difference High: ");
Serial.println(pitch_diff);
// If the tuning is off by a questionably high amount, count it as an error in reading and do not turn the peg.
// Otherwise tune the peg for a period of time. This time depends on how far off the read average is.
if (pitch_diff < 20)
for(long i = 0; i < pitch_diff * 270000; i++)
{
digitalWrite(servoPin, HIGH); // start the pulse
delayMicroseconds(2); // pulse width
digitalWrite(servoPin, LOW); // stop the pulse
}
}
// Reset all variables used for pitch detection
cross_count = 0;
avg_cross = 0;
avg_counter = 0;
}
// We take the average of cross counts after the first value in bound. We dismiss the first value since it is usually inaccurate
// for finding a good average.
if (timer % timer_divide == 0){
if (cross_count > lower_bound && cross_count < upper_bound) {
if (avg_counter >= 1 && avg_counter < (divide_by + 1)) {
avg_cross = avg_cross + cross_count;
Serial.print("Runnin Avg cross sum: ");
Serial.println(avg_cross);
}
avg_counter++;
}
Serial.print("cross_count: ");
Serial.println(cross_count);
cross_count = 0;
}
}
void check_crossings()
{
lastx = x;
lasty = y;
x = analogRead(analogPin); // Read the input pin
y = a * x + a * lastx + b * lasty; // Apply Butterworth filter to eliminate high frequencies
// If the string crosses it's set threshold, add it to the count. If there are no crossings, the idle timer will begin to run.
if (lasty > threshold and y < threshold)
{
cross_count++;
idle_timer = 0;
}
}