Closed manhabc closed 1 year ago
Please paste the full output code of the tool, including the deep link back to the preconfigured tool.
Absolutely, here is my code with the link back to config website.
void setup(){ / https://dbuezas.github.io/arduino-web-timers/#mcu=LGT8F328P&timer=3&timerMode=Normal&clockPrescalerOrSource=8&FCPU_UI=8Mhz&interruptA=on&OCR3A=20000 / noInterrupts(); TCCR3B = 1 << CS31; TIMSK3 = 1 << OCIE3A; OCR3A = 20000; interrupts(); }
ISR(TIMER3_vect) { if (TIFR3 & (1 << OCF3A)) { TIFR3 = 1 << OCF3A; digitalWrite(D9,LOW); }
void loop(){ digitalWrite(D9, HIGH); }
}
void loop(){
digitalWrite(D9, HIGH);
}
This code snippet set continuously D9 to high. It is no coincidence that the pulse is short.
void loop(){ digitalWrite(D9, HIGH); }
This code snippet set continuously D9 to high. It is no coincidence that the pulse is short.
But I do see D9 pul down for abt 0.25mS, monitoring on my oscilloscope.
But I do see D9 pul down for abt 0.25mS, monitoring on my oscilloscope.
Yes, that time when the interrupt set this output low, then the digitalWrite() inside the loop() sets back to high.
But I do see D9 pul down for abt 0.25mS, monitoring on my oscilloscope.
Yes, that time when the interrupt set this output low, then the digitalWrite() inside the loop() sets back to high.
But what I concern is the timing, with 0cr3a = 20000 it should be almost 20mS but I got only 0.5mS. I Change value but it is the same.
Time for D9 go L is only 25uS not 0.25mS (my bad on converting)
The timer3 controls only the interrupt, which sets the output low. But the digitalWrite(D9, HIGH) inside the loop() not controlled by any Timer, so the output will going to high as soon as could.
To expand on what @LaZsolt said, those 25uS are the time between an interrupt and the next time the loop runs, which can be anything depending on what else you have in the loop or what other interrupts do. So not what you want.
Here's a potential solution for what you want to achieve: If you want to generate a pwm in a pin which is not an output of the timer, (D9 in your case), you could use the interrupts of two outputs. One to write the pin HIGH and the other to write it LOW.
Like this but add digitalWrite(D9, HIGH)
and digitalWrite(D9, LOW)
inside each of the if
statements of the interrupt.
Closing the issue as it is a question, but feel free to continue the discussion below :)
Maybe you misunderstand my concern, since English is not my mother language. Im not asking why the 25uS D9 pul low , (I did it for marking purpose only). I’m asking about the time from x1 to x2, 8mhz sys clk , prescale 1:8 which is 1uS for 1 count. Then with ocr3a change from 0-65535 the time from x1 to x2 is not change, it’s stable at 0.5mS. That is my problem now. If you are not going with me, I will try to make another example for more details
Okay. Try this code:
The same as previous, I also reset TCNT3 each time it reach Ocr3a but no different. Am I got the fake one? Timer1 and 2 are exactly as in my setting
Oh, I see. You mean that timers 1 and 2 work as you expect but timer 3 doesn't?
Mmm I think you found a bug in the app. Nothing sets the TCCR3A register
Mmm I think you found a bug in the app. Nothing sets the TCCR3A register
I think in this example WGM30 ad WGM31 bits are 0, that's why your app not generating code to set TCRR3A register. (In this timer 3 configuration all bits of TCCR3A register are 0.)
Oh, I see. You mean that timers 1 and 2 work as you expect but timer 3 doesn't?
Yes, It drive me crazy till I narrow down my code to timer3 set up
@ LaZsoft I think so but how to manually turn on all the bits?
If you could use D6 Arduino pin instead of D9 here is an idea. In this setup the timer generate the short pulses without use of any interrupt. ICR3 sets the lengt of time between pulses and OCR3A must be less than ICR3.
void setup(){
/* https://dbuezas.github.io/arduino-web-timers/#mcu=LGT8F328P&timer=3&CompareOutputModeA=clear-on-match%2C+set-at-max&FCPU_UI=8Mhz&clockPrescalerOrSource=8&topValue=ICR3&ICR3=20000&OCR3A=19950&OCnA_OutputPort=AC0P%28D6%29 */
noInterrupts();
TCCR3A =
1 << COM3A1;
TCCR3B =
1 << WGM33 |
1 << CS31;
PMX0 =
1 << WCE;
PMX1 =
1 << C3AC;
OCR3A = 19950;
ICR3 = 20000;
interrupts();
}
(In the case of using Timer 3 compare B output the pulses came out on D2 Arduino pin.)
I think in this example WGM30 ad WGM31 bits are 0, that's why your app not generating code to set TCRR3A register. (In this timer 3 configuration all bits of TCCR3A register are 0.)
But is that correct? the other timers look very different
If you could use D6 Arduino pin instead of D9 here is an idea. In this setup the timer generate the short pulses without use of any interrupt. ICR3 sets the lengt of time between pulses and OCR3A must be less than ICR3.
void setup(){ /* https://dbuezas.github.io/arduino-web-timers/#mcu=LGT8F328P&timer=3&CompareOutputModeA=clear-on-match%2C+set-at-max&FCPU_UI=8Mhz&clockPrescalerOrSource=8&topValue=ICR3&ICR3=20000&OCR3A=19950&OCnA_OutputPort=AC0P%28D6%29 */ noInterrupts(); TCCR3A = 1 << COM3A1; TCCR3B = 1 << WGM33 | 1 << CS31; PMX0 = 1 << WCE; PMX1 = 1 << C3AC; OCR3A = 19950; ICR3 = 20000; interrupts(); }
(In the case of using Timer 3 compare B output the pulses came out on D2 Arduino pin.)
I’m using timer3 to create a pulse from 1-100mS, just when buttons was pressed, it will make D9 H for setting time (1-100mS) then it’s done I’m thinking of using timer0 but it’s affecting the millis function. I will try this way t = millis D9 H While ( millis - t < timeset*1000)
D9 L
it might not accurate but hope it works well. Many thanks and I really appreciate your help
But is that correct? the other timers look very different
Yes, looks different, because WGM bits are in one register. Timer 3 WGM bits are in two different registers.
Then I guess the question remains, why @manhabc is getting the wrong period
Remains a mystery.
Remains a mystery.
So how can I check the version of IC? Maybe they reduce some func to lower the price?
I made a test, but the behaviour is really strange.
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
noInterrupts();
TCCR3B =
1 << CS31;
TIMSK3 =
1 << OCIE3A;
OCR3A = 20000;
interrupts();
}
ISR(TIMER3_vect) {
if (TIFR3 & (1 << OCF3A)) {
TIFR3 = 1 << OCF3A;
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));
}
}
void loop(){
OCR3A = 20000;
delay(5000);
OCR3A = 15000;
delay(5000);
OCR3A = 10000;
delay(5000);
OCR3A = 5000;
delay(5000);
}
The Timer 3 behaviour not as what we expect according arduino-web-timers. I'll keep testing.
I started the Timer 3 test with the setup above. Then in arduino-web-timer I turned off the normal mode, and after this I turned on the ICR3 box. I get this result:
The Timer 3 behaviour not as what we expect according arduino-web-timers. I'll keep testing.
I think the settings TCCR3B = 1 << CS31; TIMSK3 = 1 << OCIE3A;
not the normal mode.
I'll keep testing.
Okay. I think I found the reason: If the compare output not enabled, the timer behavior is not that then you expected. So @dbuezas, if no behaviour selected on Timer 3 any compare outputs there in no predictable behaviour. Not even interrupt.
@manhabc
Here is the code for you:
Does not need include lgt328p.h, interrupt.h, io.h
void setup(){
pinMode(D9,OUTPUT);
noInterrupts();
TCCR3A =
1 << COM3A0;
TCCR3B =
1 << WGM32 |
1 << CS31;
TIMSK3 =
1 << OCIE3A;
PMX0 =
1 << WCE;
PMX1 =
1 << C3AC; // Set compare output to D2 arduino pin (LQFP32 package)
OCR3A = 20000; // You can control the time between low pulses
interrupts();
}
ISR(TIMER3_vect) {
if (TIFR3 & (1 << OCF3A)) {
TIFR3 = 1 << OCF3A;
digitalWrite(D9, LOW);
}
}
void loop(){
digitalWrite(D9, HIGH);
}
You are unable to use D2 arduino pin as general IO. https://dbuezas.github.io/arduino-web-timers/#mcu=LGT8F328P&timer=3&clockPrescalerOrSource=8&FCPU_UI=8Mhz&interruptA=on&OCR3A=20000&CompareOutputModeA=toggle&topValue=OCR3A&OCnA_OutputPort=AC0P%28D6%29
if no behaviour selected on Timer 3 any compare outputs there in no predictable behaviour
Oh wow. This is specific to Timer 3, right? Maybe one could use Output C, the F3 pin is not even exposed in the QFP32 and SSOP20 packages.
Maybe one could use Output C
Yes, good idea. The modified and tested source:
//Does not need include lgt328p.h, interrupt.h, io.h
void setup(){
pinMode(D9,OUTPUT);
noInterrupts();
TCCR3A =
1 << COM3C0;
TCCR3B =
1 << WGM32 |
1 << CS31;
TIMSK3 =
1 << OCIE3C;
OCR3A = 20000; // You can control the time between low pulses
OCR3C = 1; // Compare C interrupt at 1
interrupts();
}
ISR(TIMER3_vect) {
if (TIFR3 & (1 << OCF3C)) {
TIFR3 = 1 << OCF3C;
digitalWrite(D9, LOW);
}
}
void loop(){
digitalWrite(D9, HIGH);
}
This is specific to Timer 3, right? I mean, Timer0 for example is more than happy running keeping track of millis without any output. I could add a constraint that forbids that all outputs are disconnected if an interrupt is used on Timer3
I tried to search in the databook a mention about this behavior, but nothing found. @manhabc wrote that when tested Timer 1 and 2 they do what he want, but Timer 3 not. I made a test on Timer 3 which ended up to turn out this behavior.
So add a constraint that forbids using Timer 3 interrupts if no output connected.
So, no interrupts on an output if if is disconnected. I assume this happens independently on each channel.
Btw @manhabc you could also use the overflow and capture interrupts.
So, no interrupts on an output if if is disconnected. I assume this happens independently on each channel.
When I tested the interrupts there was interrupts, but the behaviour was not as what we expected. The interrupt behaviour became good after I turned on an output (eg. toggle).
These are now fixed:
Note: you need to clear the cache to get the latest version. In Chrome, cmd+shift+r
in Mac, ctrl+f5
in Windows and Linux.
I can't test on an LGT at the moment, but another alternative is to use ICR3 as top value and use the interrupt on input capture (it triggers on match too) or/and the overflow interrupt. See here for the example.
Thank you so much! I will test and tell you later.
One more comment on web timer, could you please add option to change the values of OCRXA or ICR …. Using mouse to slide the bar from 0-65535 for exact value is the most painful things in my life. I have to create an excel file for reference
As a workaround, you can enter/modify the value directly in the URL. No mouse sliding required.
Here you can see I set OCR1A to 64999 https://dbuezas.github.io/arduino-web-timers/#mcu=ATMEGA328P&timer=1&timerMode=PCPWM&topValue=OCR1A&OCR1A=64999
As a workaround, you can enter/modify the value directly in the URL. No mouse sliding required.
Here you can see I set OCR1A to 64999 https://dbuezas.github.io/arduino-web-timers/#mcu=ATMEGA328P&timer=1&timerMode=PCPWM&topValue=OCR1A&OCR1A=64999
Ah ha, it’s ok now. Thanks!
I can't test on an LGT at the moment, but another alternative is to use ICR3 as top value and use the interrupt on input capture (it triggers on match too) or/and the overflow interrupt.
I did the test with OCR3A and Interrupt on Timer overflow at TOP. In this case not need to enable any compare outputs. Working. :)
// Timer 3 OCR3A interrupt on overflow test
void setup() {
pinMode(LED_BUILTIN,OUTPUT);
digitalWrite(LED_BUILTIN,HIGH);
delay(3000); // Wait 3 seconds after reset for reprogramming
noInterrupts();
TCCR3A =
1 << WGM31 |
1 << WGM30;
TCCR3B =
1 << WGM33 |
1 << WGM32 |
1 << CS32;
TIMSK3 =
1 << TOIE3;
OCR3A = 20000;
interrupts();
} // end setup()
ISR(TIMER3_vect) {
if (TIFR3 & (1 << TOV3)) {
TIFR3 = 1 << TOV3;
digitalToggle(LED_BUILTIN);
}
} // end Timer3 ISR
void loop() {
delay(5000);
noInterrupts();
OCR3A = 10000;
interrupts();
delay(5000);
noInterrupts();
OCR3A = 5000;
interrupts();
delay(5000);
noInterrupts();
OCR3A = 20000;
interrupts();
} // end loop()
@manhabc you can now edit the values with the keyboard too
Hello it's me again with new issues in using timer3, I'm doing project and Timer1, Timer2 already used, so I'm using the Web timer edit to setup. But the output of the timer3 is supper weird, with the value OCR3A = 20000, what I saw on my oscilloscope is the D9 go LOW every 0.5mS (with my calculation, it should be 20mS). More interesting, when I changed to 0-65535, I got the same results. I also tried to use 8MHz or 16MHz, internal or 8MHz external (my project use 8mhz external) system clk, it's the same
Do you have any idea what is going on with my setup? Many thanks!
ps: I edited for being more clearly. So sorry for my English
Here is the code I check with timer3
`