How speed up timers Arduino-UNO or Due (for 1...10 usec. pulse generation)

Hi All,

I want to generate pulses in the (10^-6) micro-sec. range. At the moment I'm running the ATmega328p (UNO/Rev.3) 8 bits timer at a clock of 16MHz (no divison used). To get some more resolution I need more clock speed.

Is that possible with the Arduino Due? The datasheet says that the core is running on 84MHz (max.), however the cristals mounted on the Arduino Due board are much lower 32.768kHz and 12 MHz ...? This is lower than for the UNO.

Can someone help me how I can speed up my timers?

Thanks! Rtra

Modern high speed processors derive their internal clocks from a crystal oscillator and a PLL, here the 12MHz crystal is multiplied by 7.

You could use an ATTiny861 (or ATTIny85). They run at 16MHz from a crystal but then have an internal 4xPLL which allows one of their timer modules to run at 64MHz. That would give you 4x the resolution of the ATMega328 without having to rewrite your code too much.

What code are you using to generate the pulse? digitalWrite() is inefficient. Search for fast digital io examples. The Due is fast enough if used properly, even the UNO can generate a digital switch in 125 nanosec.

I have used the fast DigitIO library here: http://forum.arduino.cc/index.php?topic=117356.0 https://code.google.com/p/rtoslibs/downloads/list DigitalIO20130221.zip

The basic idea is to manipulate the registers directly. See here for example: http://www.fiz-ix.com/2013/02/direct-control-of-arduino-uno-digital-inputoutput-pins-using-port-registers/

I have generated sub micro pulses even with an UNO with fast digital.

[quote author=joe mcd link=topic=196933.msg1453496#msg1453496 date=1383492194] What code are you using to generate the pulse? digitalWrite() is inefficient. Search for fast digital io examples. The Due is fast enough if used properly, even the UNO can generate a digital switch in 125 nanosec. [/quote] He's using the timers which is the correct approach.

I'm running the ATmega328p (UNO/Rev.3) 8 bits timer

He's using the timers which is the correct approach.

But, he didn't post any code to back up that assertion, which isn't the correct approach.

MarkT: Modern high speed processors derive their internal clocks from a crystal oscillator and a PLL, here the 12MHz crystal is multiplied by 7.

Thank ypu for the information. I have read (parts of) the datasheet of the SAM3X8E (uC of the Arduino Due), however it is unclear to me whether this high speed clock input can be used for Timer Counters (TC's).

the arduino analogWrite pwm uses 490hz freq,or about 2ms period. If you want to do 1us period on the UNO, you must access the timer registers directly.

first, use a smaller divider, like 8, which gives you 0.125us per timer count, this gives you 8 counts to get your period of 1 us.

if you use mode 11, phase correct PWM mode, all you need to do is set OCR register to 4, then you will get your 1us pulse at 50% duty cycle. the divider and mode are set in timer registers TCCRnA and TCCRnB

If you want a duty cycle other than 50%, then you must use mode 10, use ICR register to set your top (value 4), then the OCR register to control your duty cycle.

everything you need to know is in the timer/counter chapter in the atmega datasheet.

correction to my above note. it only applies to atmega2560. atmega328 does not go beyond mode 7. I have not used the due.

[quote author=Tom Carpenter link=topic=196933.msg1453435#msg1453435 date=1383488840] You could use an ATTiny861 (or ATTIny85). They run at 16MHz from a crystal but then have an internal 4xPLL which allows one of their timer modules to run at 64MHz. That would give you 4x the resolution of the ATMega328 without having to rewrite your code too much. [/quote]

Hello Tom, thanks for your answer. This is where I'm looking for. Is there an (Arduino or other standard) board that use the ATTinny that you mentioned above? I cannot find it at the Arduino website. Rewriting the code is (probably;-) faster than designing a new AVR-PCB-board myself.

Regards, Rtrab

There isn’t, but there is software support for it. This core supports the ATTiny861 among others

The Attiny’s are very simple to use, all you need is a 16MHz crystal, 2 caps and the ATTiny861 chip. A pullup resistor on the reset pin is also a good idea. Its breadboard friendly and you can use another Arduino board as a programmer (ArduinoISP sketch).

I have attached a circuit diagram for a basic setup. This should be very easy to build up on a small piece of veroboard or protoboard. You could even build it on a proto-shield for an Arduino which would allow you to directly connect the programming pins to the Arduino shield pins.

The MISO pin, along with PB3 are also your two high speed PWM output pins which can run up to 64MHz and are generated by a 16bit timer. MOSI and SCLK pins can also be used to output the same PWM signals but inverted.

MOSI, MISO, SCLK and RESET are your programming pins which simply connect to another Arduino board when you need to program.

Attiny861.png

a correction to my correction. The UNO can do modes 10 and 11 as well on the 16 bit tmer register.

do you need a shorter period (higher frequency) or a higher resolution? the default arduino library analogWrite pwm is 8 bit resolution at 490hz.

you can do 16 bit pwm resolution but at 122hz, or 2 bit pwm resolution at 2.6mhz on the 16bit timer registers see pages 128-129 of Atmega328 datasheet

it is just a few lines of code to do it.

try this on MEGA to get 0.5us 50% duty cycle pulse (2mhz) for UNO, change PB5 to PB1

void setup() {
DDRB |= _BV(PB5);
TCCR1A=0;
TCCR1B=0;
TCCR1A |= _BV(WGM11);
TCCR1B |= _BV(WGM13)|_BV(CS10);
OCR1A = 2;
ICR1=4;
TCCR1A |= _BV(COM1A1);
}

void loop() {

}

PWM output is on Digital pin 9 for UNO, and pin11 for MEGA

this is the waveform

You you want a really high frequency, you can make the arduino timer use an external clock instead of the arduino 16mhz clock.

I think this is the simplest solution to what you need.

doughboy: You you want a really high frequency, you can make the arduino timer use an external clock instead of the arduino 16mhz clock.

That wont work at all. The external clock input pins for the timers must be run at F_CPU/2 or slower which means the maximum you could have is 8MHz on one of the external timer input pins.

It looks to me as same topic, http://forum.arduino.cc//index.php?topic=196815.new#new

[quote author=Tom Carpenter link=topic=196933.msg1454068#msg1454068 date=1383518121]

doughboy: You you want a really high frequency, you can make the arduino timer use an external clock instead of the arduino 16mhz clock.

That wont work at all. The external clock input pins for the timers must be run at F_CPU/2 or slower which means the maximum you could have is 8MHz on one of the external timer input pins. [/quote]

thanks for the correction. it seems the purpose of using external clock is for counting external events, not for waveform generation. So the highest freq waveform you can get out of arduino is 2.666mhz pulse. I think the OP only asks for 1us pulse, so using the sample program I provided (which give 0.5us pulse) is more than sufficient, no need to make this more complicated with external circuits.

rtrab: Hi All,

I want to generate pulses in the (10^-6) micro-sec. range.

What range? Every few microseconds? The Uno can do that easily. Running at 16 MHz it can output a 4 MHz signal.

For example:

const byte CLOCKOUT = 9;

void setup ()
  {
  pinMode (CLOCKOUT, OUTPUT);
  
  // set up Timer 1
  TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC, no prescaling
  OCR1A =  1;       // output every second cycle
 }  // end of setup

void loop () {}

That produces a 4 MHz signal (pulses every 125 nS).