Sorry to resurrect an old(ish) thread but what is the best way to stop and start this timer? I am using it for ultrasonic distance measurement so I need to send out a short ping and then listen for the echo. The ping needs to be short - is it best to just set the pin to input from output or do I need to stop the PWM, if so how?
Apologies for reviving this thread again, but I am now trying to use a similar bit of code to generate a 1kHz signal, however it is fine down to about 8kHz but it won't go below that. I suspect that it is due to the fast PWM but I have read the datasheet and I haven't got a clue how to stop using the Fast PWM.
PWM uses a timer that if you change PWM speed will affect some other operations.
OTOH if you use a timer to drive a very short interrupt, the effect will be less to none.
Worst case, your square wave edge will be off a few usecs but that is the case with PWM.
Best case, you make it work both ways just to see which is more accurate.
I'm still not clear on what you are suggesting? Suppose in the main loop I want to do a Serial.print would this not affect the timing of the timer interrupt? Would the Serial.print complete or would it be interrupted by the timer?
Are you using the arrival of serial data sent from Arduino to time anything? I hope not!
You do a print command and what happens? This is as much as I can piece together, there are others on the board that can take it right down to the code and the metal:
With UNO there is the 328P that you program and the 8U2 to get to USB. Your text goes to the 8U2 via the serial RX pin at maximum 115200 bits per second (including start and stop bits) until that buffer is full when Serial fills its own buffer on the 328P. The 8U2 may empty faster than it can fill, or the PC may be busy now and then in which case hello Serial buffer. If you print long strings then you have more chance to find out and have serial output hang your sketch up, likely a fraction of a millisecond.
So let's suppose that we manage to not overload serial. Our timer interrupt will always run and flip the state of our output pin on time. Our ISR will not print. It may set a flag that the sketch can use to eventually print (do you plan on printing once every millisecond? then eventually is right then instead) but serial i/o should be down near the lowest priority of your sketch.
IMO the high priority is getting that square wave. And I would do it the same way at 50 kHz.
Of course if I'm wrong about any of this I would like to know soonest!
No I'm not triggering on serial data. More the other way round, generate the square wave, wait for a response and then record the time between signal and response. It's useful to be able to Serial.print after the start of the square wave to provide feed back that things are running.
No I'm not triggering on serial data. More the other way round, generate the square wave, wait for a response and then record the time between signal and response. It's useful to be able to Serial.print after the start of the square wave to provide feed back that things are running.
How exact does the square wave and time between signal and response have to be? Will the response happen in less than or 900 ms? Micros has a 4 usec accuracy. With a tight while loop you can beat that but only by blocking which if it can be done between critical events is okay. Timing for ultrasonic range sensors is done that way.
Something to get a good handle on is what the speed of the OS-free processor really means. I find that many people seem to feel it's 1000 times or more slower than it is. Yeah, "feel" because they either don't work the numbers or have trouble relating to them. It's nothing personal, my taste in fashion would get me life in prison if some people had their way. We all have different strengths.
sirch:
I'm still not clear on what you are suggesting? Suppose in the main loop I want to do a Serial.print would this not affect the timing of the timer interrupt? Would the Serial.print complete or would it be interrupted by the timer?
Serial output is done by interrupts. Once one interrupts starts the next one has to wait for it to finish.
Looking into the USART0 section of the 328P I see that interrupts are not required for 2-wire serial I/O... it just makes a load of sense to use them as the Arduino Serial class does.
It's -possible- to get around but I think way more work than for example using an external clock source to generate the square waves, or not generating the square waves all the time or tolerating a rising or falling wave edge not being within a few usecs of 1 ms from the last one.
IF the critical part is wave edge to return AND return will be soon (I am guessing less than 1 ms?) THEN you could turn interrupts off, generate the wave edge and use a timing loop instead of a timer to watch for the return then turn interrupts back on. (I wonder if pulseIn does that?) That would make Serial wait for the return timing with no chance of the reverse.
Please keep in mind that changing the PWM frequency changes the Atmega's timers and disrupts the normal operation of many functions that rely on time (delay(), millis(), Servo library).
I was thinking it'd disrupt micros() as well but even if it does he can use a timing loop for return time so my reason not to is probably less than moot.