I am trying to make a program that switches 3 pins in a way pictured in attachment.
What I have done already is setting a new hardware timer at a start of each pulse for the next pulse. Everything works fine with longer pulses, but there some jitter with pulses under 1 microsecond. I will attach my program later.
I wanted to ask if there is a way to use few timers instead of one, and preset them before period starts or any other suggestions are welcome.
ISR(TIMER2_OVF_vect) {
/* Reload the timer */
TCNT2 = tcnt2;
TCCR2B = tccrb2;
switch (bo) {
case 0:
sbi(PORTB, 3);//pin11
cbi(PORTB, 2); //pin10
cbi(PORTD, 3);//pin3
break;
case 1:
cbi(PORTB, 3);//pin11
sbi(PORTD, 3); //pin3
cbi(PORTB, 2); //pin10
break;
case 2:
sbi(PORTB, 2);//pin10
cbi(PORTD, 3);//pin3
cbi(PORTB, 3);//pin11
bo = -1;
i++;
if (i == imax2) {
s = s + 1;
i = 0;
if (s == 7)
{
s = 1;
}
switch (s) {
case 1:
sbi(PORTD, 4);//pin4
cbi(PORTB, 1);
break;
case 2:
sbi(PORTD, 5);//pin5
cbi(PORTD, 4);
break;
case 3:
sbi(PORTD, 6);//pin6
cbi(PORTD, 5);
break;
case 4:
sbi(PORTD, 7);//pin7
cbi(PORTD, 6);
break;
case 5:
sbi(PORTB, 0);//pin8
cbi(PORTD, 7);
break;
case 6:
sbi(PORTB, 1);//pin9
cbi(PORTB, 0);
break;
}
}
break;
}
bo = bo + 1;
if (taisr[i] == 256 and bo == 0) {
bo = bo + 1;
}
if (tbisr[i] == 256 and bo == 1) {
bo = bo + 1;
}
if (bo == 0) {
tcnt2 = taisr[i];
tccrb2 = tar[i];
}
else if (bo == 1) {
tcnt2 = tbisr[i];
tccrb2 = tbr[i];
}
else
{
tcnt2 = t0isr[i];
tccrb2 = t0r[i];
}
}
I have an arrays with calculated prescalers and overflows which I set at the start of every pulse. Shortest pulse is 0.5 us long and I guess arduino Uno does not keep up with calculations. Any suggestions on optimizing code are welcome.
vilius09:
So this is how I now do this task:
...........
Any suggestions on optimizing code are welcome.
Glad to hear it is working.
Without a detailed english explanation of what all the registers are being used for it would take me far too long to figure out what your program does.
vilius09:
Everything works fine with longer pulses, but there some jitter with pulses under 1 microsecond.
The Arduino UNO can only do 16 instruction cycles per microsecond. I suspect your ISR executes more than 16 instruction cycles so it can't complete in time to interrupt within a microsecond.
There may be a way to use Timer1 to generate two of the pulses using the OCR pins and some external logic hardware to generate the third pulse. The diagram doesn't specify any pulse length ranges or desired precision so it's hard to determine if your goal is possible.
That is not nearly enough for me. I would like to see a narrative that talks me through the entire program. This section does X when Y happens and this section does M when N happens etc.
Writing the narrative might also help you to spot a problem.
I don't think an interrupt can be called and returned within 0.5us, maybe not even a NAKED one.
0.5us is just 8 clock cycles. Your task is achievable on a UNO with careful management of instructions around that 0.5us pulse but if you just want a simple timers and interrupts solution you'll need a faster MCU.
It appears that one of the three signals is high at all times so you only need to generate two and use an NOR gate for the third. Timer1 might be able to generate two of the pulses using PWM. To get 100 uS cycle time you will need 10 kHz PWM.
To get 10 kHz PWM you divide 16 MHz by 10 kHz to get a TOP value of 1600 (give or take one, you have to look up the formula in the datasheet). That gets you 1600 steps of PWM for 1/16th microsecond to 100 microseconds in 16ths of a microsecond. Set the two Output Compare Registers where you want them and use some logic gates to get the three signals you want.