Signal generation using Timer2 - random spikes clusters showing up - SOLVED

Hi,

I'm trying to stream 1's and 0's using pin 53 at 250KHz on a Mega2560. My goal is to take a character string, break the characters down to binary and stream out the bits. Every 4 microseconds a pulse with a duty cycle of 25% for a 1 and 0% for a zero will be generated. Right now I'm just trying to generate a 1 every 4 microseconds. I have it working but, I am seeing random cluster of spikes in the signal generated by the Arduino. I turned off Timer0, external interrupts and I still can't get rid of the random spikes. I am using a Kingst LA1010 logic analyzer to view the signal generated by the Arduino and the 250KHz reference signal the LA1010 is generating.

I did read Gannon's website on timers and interrupts, and I thought generating 250KHz using an ISR might be too aggressive, so I set the OCR2A to 128 and I still see the spikes. I tried two different Keystudio boards with the same results.

I am looking for suggestions/ideas as to why the spikes are occurring. Thanks!

Here is my code:

#define OFF   LOW
#define ON    HIGH
#define SIGNAL_PIN    53

void setup() {
  Serial.begin(500000);
  Serial.println("Trigger signal every 4 us, using timer");

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, OFF);

  pinMode(SIGNAL_PIN, OUTPUT);
  digitalWrite(SIGNAL_PIN, LOW);

  noInterrupts();

  // clear out external interrupts
  EICRA = 0;
  EICRB = 0;
  EIFR = 0;

  // turn off Timer0
  TCCR0A = 0;
  TCCR0B = 0;
  TIMSK0 = 0;
 
  // config Timer2 interrupt
  TCCR2A = 0;
  TCCR2B = 0;
  OCR2A = 0;
  OCR2B = 0;
  TCNT2 = 0;
  OCR2A = 63;             // generate interrupt every 64 cycles (zero relative)

  // need CTC mode
  TCCR2A |= (1 << WGM21);
  TCCR2B = 0b00000001;    // set to no prescaling, this will start count down
  
  // enable Timer2 interrupt compare
  TIMSK2 = (1 << OCIE2A);
  
  // enable general interrupts
  interrupts();
}

// create signal
ISR(TIMER2_COMPA_vect) {
  TCNT2 = 0;
  PORTB |= 1;
  asm("nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      "nop  \n"
      );

  PORTB &= 0;
}

void loop() {
}

Here is a screenshot of the spikes, they go away and then will reappear a bit later in the roughly the same number of spikes per cluster.

It's been a while and I was using the 328p, but they are handled very similarly across lots of machines.

I would think that even if it was an interrupt, I would expect slightly longer 'periods' in the output when you're going through the nop's.

Within the interrupt routine, I would think interrupts are disabled anyway... ? You don't want to be interrupted in the interrupt handler...

It would have to be executing code somewhere to tell it to toggle the pin. That doesn't seem logical it could occur within the interrupt.

Good luck

:smile_cat:

That is a very unusual, high bandwidth and unwieldy encoding scheme, unless there is an accompanying clock signal on a separate line. Are you committed to it?

After reading @jkwilborn response, it occurred to me that this might be a signal bounce issue and I realized that I did not ground the logic analyzer to Arudino board, I just connected the grounds and the noise went away! I'm new to hardware, thanks @jkwilborn!

Yeah, I'm trying to use the Arduino to read Apple II 5.25" floppies. The data timing from the drive is a pluse or no-pulse every 4 microseconds.

-Ven

1 Like

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