I want to generate two synchronized pulse trains from Arduino Uno using Timer 1.
It will generate 4000 PWM pulses (having 50% duty cycle, ON time = OFF time = 700 microseconds) on Pin 9 continuously. Once the count of output pulses at pin 9 reaches 4000, Arduino will generate 2 millisecond positive pulse at some pin (other than pin 9, for example 10, 13 etc.) to indicate count 4000 crossing and then remains OFF for 5.598 seconds.
Both pin 9 and this other pin will provide output in synchronized manner.
I have tried but unable to code, Can anyone help about this?
That is a great picture of what you desire, but where is the code that you have tried? If you want to hire somebody to write the code for you, that is a different forum (Gigs and Collaborations).
You can use the GTCCR (General Timer Counter Control Register) to synchronize two timers. Use one to generate the 700-microsecond toggle and another to generate the 2mS pulse every 5.6 seconds.
How closely synchronized do the lead edges of the two pulses need to be?
On the same clock cycle of the processor? Within 1 microsecond?
Within 8 microseconds?
What is the tolerance of your application for offset?
// Sorry for delay in sending you the code, Please find attached,
// The code may look childish to the experts like you, hope you won't mind that,
// Sorry once again for the misunderstanding, i caused
#define PWMOP 9 #define OS 13
void setup()
{
// put your setup code here, to run once:
pinMode(PWMOP, OUTPUT);
pinMode(OS, OUTPUT);
}
Looks like to synchronize Timer2 and Timer1 you set
GTCCR = _BV(TSM) | _BV(PSRASY) | _BV(PSRSYNC);
That freezes the prescale counter at 0 and stops Timer0, Timer1, and Timer2. Note: PSRASY is for Timer2 and PSRSYNC is for both Timer0 and Timer1 which share a prescale counter.
Then you set TCNT1 and TCNT2 to zero and un-freeze the timers:
Don't do this often because every time you do you delay the Timer0 interrupt by an average of 32 clock ticks (2 microseconds). That will cause micros() and millis() to run slow.
You can get 700 uS pulses from Timer2 using a prescale of 64 and a TOP of 174. Use WGM 2 (CTC with TOP in OCR2A) and COM2B0 = 1 to toggle the OC2B pin on compare match.
Unfortunately, you can't get a 5.6 second timer in hardware. The Timer1 prescale only goes up to 1024 so you can't count any slower than 15625 Hz. The maximum interval is 65536 ticks so 4.194... seconds max. You could run the processor with a prescale on the system clock. That would mess up millis(), micros(), and Serial, but it might allow you to get the pulses you want. You would have to adjust the Timer2 values for the slower system clock.
Let's try a system clock prescale of 8. That would give you a 2 MHz system clock instead of 16 MHz. You could then switch the Timer2 prescale to 8 and keep the TOP=174.
With a 2 MHz clock you would need a prescale greater than 170 to keep a 5.6 second counter below 65536 counts. The next higher prescale is 256. That gives 7812.5 clocks per second. 43750 clocks per 5.6-second cycle. Unfortunately, that makes your 2 mS pulse 15.625 clock ticks. Closest would be 16 clock ticks or 0.002048 seconds. Is that close enough?
I'm sure some other people might be wondering - what do you need it for?
Yes, please explain why you need something which happens every 5.6 seconds ( or when a count of 700 microsecond square waves = 4000) needs to have a lead edge synchronized to one clock cycle.
@anon57585045 and @cattledog:
It is a hobby project of controlling servo motor using shaft encoders, under development by me. Hence, to make the encoder output correct, i require zero error margin.
If Uno cannot be this much accurate, probably i may have to shift towards FPGA based design (Altera / Xilinx) but before that, i would like to try my hands on Arduino Uno to see, how close i can reach to the target?
@Johnwasser
Dear Sir, Thank you for correcting me.
Yes, my original plan was to generate 700uS pulses from Timer 1 and 2ms pulses from Timer 2. But with your kind explanation, i could understand the error in my estimation. Following your guidelines, i am changing my code to generate 700uS from Timer2 and 2ms from Timer 1. Also, 0.002048 seconds (or 2.04 mS) is fine for my application.
Apart from this project, i have a query which arose while reading your explanation. If 4.194 seconds is the max duration for Arduino Timer 1, can it not generate the pulses having cycle time greater than 4.194 seconds (for example 6 seconds or 8 seconds) ?
Correct. It cannot, on a 16 MHz system clock, generate a cycle time greater than 4.194 seconds. That is why you have to use a slower system clock to get the 5.6 second cycle you want.
What about a Timer1 pulse length of 1.4 ms or 2.8 ms?
If that is acceptable, I think you could drive the external clock source on Timer1 with an edge of the pulse from Timer2 and turn a hardware output on at 4000 ticks and off at 4001 or 4002.
How far does a servo motor armature move in one microsecond?
I think you really are making this very difficult by not allowing the latency of a timer interrupt (which is less than 2 microseconds) in your code.