Audio signal freezes every few seconds using Timer0 and Timer1

I am trying to make an arpeggiator guitar with membrane potentiometers, but the signal freezes every few notes. The signal freezes only while switching between notes, and the frozen signal is either 5V or 0V. The arpeggiation continues while the signal is frozen, the notes are simply skipped.

For example, if I have notes A, B, C, and D that arpeggiate like so:
A B C D A B C D A B C D
The signal will only output something like:
A _ _ _ A B ‾ ‾ ‾ ‾ C D

I am currently using an Arduino Micro with Timer 0 running at 100,000 Hz and Timer 1 running at 10 Hz.

I have tried:

  • Changing power supplies
  • Running with no load (only an oscilloscope)
  • Changing the output pin
  • Changing period[] to constant values instead of calculating them from potentiometers
  • Removing all IO pins except for the output
  • Removing all modes except for the simplest one - legato
  • Clearing loop()
  • Removing Timer1 entirely and using _delay_ms() to change the 'string' in loop()

I am at a loss at what to do. Here is the condensed code (that still has the issue):

void setup() {
  // put your setup code here, to run once:
  pinMode(11,OUTPUT);

  cli();
  // Timer 0: 100,000 Hz
  TCCR0B = (1 << CS01); // /8
  TCCR0A = (1 << WGM01);
  OCR0A = 19; // 16000000/(8*100000) - 1 = 19
  TIMSK0 = (1 << OCIE0A);

  // Timer 1: 10 Hz
  // TCCR1B = (1 << CS11) | (1 << CS10);
  // TCCR1B |= (1 << WGM12);
  // TCCR1A = 0x00;
  // OCR1A = 24999;
  // TIMSK1 |= (1 << OCIE1A);

  sei();
}

int period[4] = {271, 203, 362, 113};

int t = 0;
int current_string = 0;
int m = 0;

ISR(TIMER0_COMPA_vect) {
  t++;
  if (t==period[current_string]) {
    m = !m;
    t=0;
  }
  PORTB = (m << 7) | (PORTB & 0b01111111);
}

// ISR(TIMER1_COMPA_vect) {
//   if (current_string == 3) {
//     current_string = 0;
//   } else {
//     current_string++;
//   }
// }

void loop() {
  if (current_string == 3) {
    current_string = 0;
  } else {
    current_string++;
  }
  _delay_ms(100);
}

Ok, I figured it out. Turns out, when the period changes to a number less than the current value of t, t keeps incrementing until it reaches 0xFFFF and overflows, while the state of the signal does not change. This caused the freezes. Of course, the fix is very simple: On the line

  if (t==period[current_string]) {

I just needed to change == to >=. This worked perfectly. I'll leave this here if anyone else encounters this very specific problem.

It's always a simple fix. Cheers.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.