Outputting multiple TTL pulses at 500Hz

Hi everyone,

I am new to the forum, I have done a fair bit of stuff with Arduino at a basic level a while back but have not done anything for a while (so probably forgot alot of what I knew).

I am wanting to make a system that will take an incoming ~500Hz square wave signal and at the rising edge of every pulse start a delay of 500us, then output a 50us pulse, wait 1ms and then output another 50us pulse then wait for the process to start over again. I want the system to react to the rising edge every time.

I have never used Arduino to do anything on such short time scales, or repeatedly I have only used 10s-100s of millisecond delays and timings, I just wanted to check that this is possible and what the best way to go about it was? Reading up on things I was thinking an interrupt would be the way to go but have no experience of using them in any of my previous projects, any advice anyone can offer would be greatly appreciated.

This will get you the timing:
reference/en/language/functions/time/micros/

Is that all the microprocessor must do, or will there be other tasks?

Thanks

Yes that's all the microprocessor needs to do, I just need the output pulses to be fairly clean and square.

Is the triggering best done with an interrupt?

The "micros()" function linked in post#2 has a resolution of 4 microseconds. This means that the timing of any signal based on it may jitter in absolute timing by about that amount.

Does it matter in your application if the pulse delay is 500 +/-4 uS, the pulse width is nominally 48-52 uS, and the delay to the second pulse 1000 +/- 4 uS?

If it does, there are timers on the Arduino that can be configured to higher resolution, but that's another level of complexity.

If the timing is not particularly critical and the Arduino has no other function, then simply polling the input and sequencing the output pulse with delays would be a very simple approach. Using an edge detection interrupt would induce less additional jitter than would polling with "digitalRead()".

The 4us jitter won't be a problem, so keeping things simple is best.

Edge detection would be my prefered option, but I have never used the interrupts before, I am assuming code like this is what I would need?

// Define variables
int Output = 13;              // Define output and trigger pin numbers
int Trigger = 8;
int pulseLength;              // Length of pulses
int delayOne;                 // Delay between trigger and first pulse
int delayTwo;                 // Delay between first pulse and second pulse
int triggered;                // A flag to determine whether the processor should do anything

void setup() {
  pinMode(Output, OUTPUT);      // Define modes of the pins
  attachInterrupt(digitalPinToInterrupt(Trigger), delaySequence, RISING); // Setup interrupt on rising edge of trigger pin to start 'delaySequence' routine

  digitalWrite(Output, LOW);    // Initialise the output to low
  triggered = 0;                // Set initial status to zero


  // Pulse parameters (in microseconds)
  pulseLength = 50;            // Pulse length
  delayOne = 500;              // Length of delayOne (between trigger and first pulse)
  delayTwo = 950;              // Length of delayTwo (between pulses)
}

void loop() {
  if (triggered == 1) {               // If interupt is triggered
    delayMicroseconds(delayOne);      // wait for delay one
    digitalWrite(Output, HIGH);       // then trigger an output pulse
    delayMicroseconds(pulseLength);   // wait for length of output pulse
    digitalWrite(Output, LOW);        // return to low status
    delayMicroseconds(delayTwo);      // wait for delay two
    digitalWrite(Output, HIGH);       // then trigger the second output pulse
    delayMicroseconds(pulseLength);   // wait for length of output pulse
    digitalWrite(Output, LOW);        // return to a low state
    triggered = 0;                    // return triggered indicator to zero and wait for next interrupt
  }
// if flag triggered = 0 the loop does nothing but wait for the interrupt...
}

void delaySequence() {              // Interrupt sequence (keep as simple as possible)
  triggered = 1;                    // When interrupted it turns the flag ered parameter triggered high
                                    // This means that the if loop in the main code runs
}

As I say I have never used interrupts before but I read that it is best to keep it simple so though this was best. Again I know that the delayMicroseconds isn't a particularly elegant way of doing things, but as the microcontroller doesn't have to do anything else it keeps things simple.

The code in post #4 looks good except the trigger flag should be declared volatile since its value is changed in the interrupt service routine.

What about millis() timing wrapped around tone(500);

MrMark:
The code in post #4 looks good except the trigger flag should be declared volatile since its value is changed in the interrupt service routine.

Thanks I will add that, I didn't know you needed to do that

lastchancename:
What about millis() timing wrapped around tone(500);

Would that produce the 500Hz signal from the arduino? I should say that the frequency isn't exactly 500Hz, (although it should be very close), my thinking was that triggering from every rising edge independently gives me consistency if/when the frequency of the trigger fluctuates a little.

exiled_red:
Would that produce the 500Hz signal from the arduino? I should say that the frequency isn't exactly 500Hz, (although it should be very close), my thinking was that triggering from every rising edge independently gives me consistency if/when the frequency of the trigger fluctuates a little.

If you're receiving 500Hz and you want to remain synchronized to it, just respond programmatically to that, don't try to generate 500Hz.