Timer 1 Problems

I’m trying to use my Arduino Uno as an interface with my synth, but I’m running into problems. The goal is for it to find the frequency from my guitar, check it against a table, generate a corresponding PWM (filtered to DC), and send a pin high to trigger the envelope. The filtered PWM will act as a voltage control element for the synth.

Here’s my code:

#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

#include <avr/interrupt.h>

Adafruit_7segment matrix = Adafruit_7segment();

// Note Array
static const int noteArray[] = {
  24270, 23991, 23715, 23443, 23174, 22908, 22645, 22384, 21873, 21622,
  21374, 21128, 20885, 20646, 20408, 20174, 19942, 19713, 19487, 19263,
  19042, 18823, 18607, 18393, 18182, 17973, 17767, 17562, 17361, 17161,
  16964, 16769, 16577, 16386, 16198, 16012, 15828, 15646, 15467, 15289,
  15113, 14940, 14768, 14599, 14431, 14265, 14101, 13939, 13779, 13621,
  13465, 13310, 13157, 13006, 12856, 12709, 12563, 12419, 12276, 12135,
  11996, 11858, 11722, 11587, 11454, 11322, 11192, 11064, 10937, 10811,
  10687, 10564, 10443, 10323, 10204, 10087, 9971, 9857, 9743, 9631,
  9521, 9411, 9303, 9197, 9091, 8986, 8883, 8781, 8680, 8581,
  8482, 8385, 8288, 8193, 8099, 8006, 7914, 7823, 7733, 7645,
  7557, 7470, 7384, 7299, 7215, 7133, 7051, 6970, 6890, 6810,
  6732, 6655, 6578, 6503, 6428, 6354, 6281, 6209, 6138, 6067,
  5998, 5929, 5861, 5793, 5727, 5661, 5596, 5532, 5468, 5405,
  5343, 5282, 5221, 5161, 5102, 5043, 4986, 4928, 4872, 4816,
  4760, 4706, 4652, 4598, 4545, 4493, 4442, 4391, 4340, 4290,
  4241, 4192, 4144, 4097, 4050, 4003, 3957, 3912, 3867, 3822,
  3778, 3735, 3692, 3650, 3608, 3566, 3525, 3485, 3445, 3405,
  3366, 3327, 3289, 3251, 3214, 3177, 3141, 3105, 3069, 3034
  };

volatile unsigned int period = 0; // Period of the signal in microseconds; read from 
                                  //    Timer 1

int difference;             // Stores difference between period and value in note
                            //    array. When difference > 0, the corresponding array
                            //    element # is the PWM value needed to generate that
                            //    note on the Werkstatt.
volatile int i = 0;         // Counts array elements

void setup() {
 
  ADCSRB |= (1 << ACME);    // (Disable) ACME = Analog Control Multiplexer Enable
                            // AIN1 is negative input
  
  ACSR |= (1 << ACIE) |     // (Enable) ACIE = Analog Comparator Interrupt Enable
          (1 << ACI) |      // Clears interrupt
          (1 << ACIS1) | (1 << ACIS0);  // ACIS = Analog Comparator Interrupt Select
                                        // ACIS[1:1] triggers interrupt on rising edge

  DIDR1 |= (1 << AIN1D) |   // Disable digital input for AIN1 (power saver)
           (1 << AIN0D);    // Disable digital input for AIN0

  TCCR1A |= 0x00;     // Clear Timer 1 control register--normal mode operation
  TCCR1B |= 0x00;     // Initialize Timer 1 control register B
  
  
  TCCR1B |= (0 << CS11);    // (Disable) 1/8 Prescaler select. This bit will be used
                            //    to start and stop the clock.

  TIMSK1 |= (1 << TOIE1);   // Timer 1 overflow interrupt enable. If Timer 1
                            //    overflows, then the signal has decayed below the
                            //    comparator threshold. This will close the gate.

  TIFR1 |= 0xFF;            // Clear interrupts

  TCNT1 |= 0x0000;          // Clear Timer 1 counter

  matrix.begin(0x70);       // Start I2C for 7-Segment
  Wire.setClock(400000L);   // Sets I2C clock to 400 kHz
  Serial.begin(115200);
  pinMode(13, OUTPUT);
  pinMode(2, OUTPUT);       // Configures Digital Pin 2 as OUTPUT. This is the
                            //    gate.

  sei();                    // Global Interrupt Enable
}

void loop() {
 
}

ISR (ANALOG_COMP_vect){
    
  if (TCCR1B & (1 << CS11)){
    period = TCNT1;           // Load value of Timer 1 into variable
    TCNT1 = 0;                // Reset Timer 1
    //Serial.println(period);
    //digitalWrite(13, HIGH);
    // Note Determination from Lookup Table
    for (i = 0; i < sizeof(noteArray); i++){
      difference = period - noteArray[i];
    
      if (difference >= 0){
        break;                  // Break the loop once note is found
      }
    }
    analogWrite(5, i);          // Output the PWM wave on Digital Pin 5
    //matrix.println(i);          // Write to the 7-Segment
    //matrix.writeDisplay();
    //Serial.println(i);      
  }
  if (TCCR1B & (0 << CS11)){
    //digitalWrite(2, HIGH);
    TCCR1B |= (1 << CS11);      // Start Timer 1
  }  
}

ISR (TIMER1_OVF_vect){
  TCCR1B |= (0 << CS11);            // Disable Timer 1
  TCNT1 = 0;                  // Reset Timer 1
  //digitalWrite(13, LOW);  
  period = 0;
}

AIN0 is getting an amplified, half-wave rectified signal from my guitar. The idea is to use Timer 1 to count the time between comparator interrupts, which should yield the period. Then, once the signal’s decayed below the comparator threshold, Timer 1 will overflow, and that ISR is used to turn off the pin and setup the system for the next note.

When tested individually, the guitar is generating interrupts as it should, and if given a predefined variable, the for loop finds the right note. The PWM works. The problem lies in getting the value from Timer 1 into a variable and the Timer 1 overflow.

When the system has functioned, I always received a ‘1’ when I printed the period variable to serial; when the system hasn’t functioned, I’ve gotten no output at all. My original idea was to trigger an input capture with the comparator, but that function doesn’t seem to be available if Timer 1 is in normal mode.
Using digitalWrite as a test, I also found that the program is never entering the overflow ISR. In the code, I’m trying to use the prescaler as a start/stop button. Could that be causing the issue?

Any help is much appreciated.

Timer 1 to count the time between comparator interrupts,

Wouldnt using interrupts be a better method of calculating durations? this has a 4-microsecond accuracy
This will display the current reading every 50 milliseconds but it will update the time every cycle.the
Like:

volatile unsigned long DurationTime;
volatile unsigned long XTime;
volatile unsigned long LastTime;

void XTimer( )
{
  XTime = micros();         // micros() return a uint32_t
  DurationTime = XTime - LastTime; // Calculate the change in time  
  LastTime = XTime; //store the time
}
void setup() {

  attachInterrupt(0, XTimer, RISING );// Set interrupt on pin 2 (interupt 0)
  Serial.begin(115200);
}

void loop() {

  static unsigned long SpamTimer;
  if ((millis() - SpamTimer) >= (50)) {
    SpamTimer = millis();
    Serial.println(DurationTime);
  }
}

Z