Generation of synchronized pulse trains

Dear All,

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?

Thanking you,

Post your best effort, using code tags, and explain what goes wrong.

Forum members will be happy to help.

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.

That old name could be misleading.

True. It looks like it is now: Jobs and Paid Consultancy - Arduino Forum

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?

Hi @dev31
Is this what you need?
Is this deviation of values acceptable?

// 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);
}

void setupTimer1()
{
noInterrupts();
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;

// compare match register 16MHz / 1024 / 714.285 Hz
OCR1A = 22399; // (16000000/((22399+1)*1))
TCCR1B |= (1 << WGM12); // CTC Mode
TCCR1B |= (1 << CS10); // 1 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts();
}

ISR(TIMER1_COMPA_vect)
{
digitalWrite(OS, HIGH);
delayMicroseconds(2000);
digitalWrite(OS, LOW);
delay(5598);
}

void loop() {
// put your main code here, to run repeatedly:
}

Thank you very much Sir, for your kind guidance,
I found the description of GTCCR in the ATMEGA328 Datasheet and studying it.

unfortunately, there is no margin for error (zero tolerance) so they should be on the same clock cycle of the processor as shown in the image above.

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:

TCNT1 = 0;
TCNT2 = 0;
GTCCR = 0; // Resume counting at 0.0

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?

Just to voice what I'm sure some other people might be wondering - what do you need it for? Not to invade your privacy...

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.

You've got me intrigued.

Especially since the UNO CPU clock timing is not that accurate...

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

How far does a servo motor armature move in one microsecond? Let alone 1/16 of a microsecond?

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.