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.
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.
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.