converting a sketch to Timer1

We are trying to convert this code to something based on Timer1

int ADC0=0; int ADC1=0; int valueADC0; int valueADC1; int pulsehigh; int pulselow; int pulsepin=13;

void setup() { pinMode(pulsepin,OUTPUT); }

void loop() { valueADC0=analogRead(ADC0); valueADC1=analogRead(ADC1); pulsehigh=valueADC0/10; pulselow=valueADC1*10; digitalWrite(pulsepin, HIGH); delayMicroseconds(pulsehigh); digitalWrite(pulsepin, LOW); delayMicroseconds(pulselow); }

The ADC0 and ADC1 control the ON/OFF time (thus independent of frequency) and frequence will eventually be calculated and written to serial or a display. Most important is that a pulse time period wil remain a ficed value (in opposite to PWM where pulse period is a percantage of the frequency, when you change the frequency then the pulseperiod changes along)

Now the current sketch is not stable (time glitches) and the max speed is still very slow so while lookin for more speed Timer1 seems to be the way to go.

Now we don't have a clue where to start with Timer1 If possible we like to avoid library includes and keep the whole sketch in one file. And above all stay with the basics and keep things as simple as possible so that we actually learn something and can eventually teach others what we have learned.

Now i'm not sure if i'm complete enough in my first post on this forum to get things started.

So i'll add a few questions

What are the basics of Timer one? Where do they go in the script?

I have read the TimerOne.h Library (and TimerOne.cpp) looks nice, but it doesn't really teach the timer function. Or atleast I get overwhelmed by the code. And i can't find a tutorial that breaks Timer1 down into clear language. And the AVR datasheet doesn't help us either.

Yes this is really the fist time we looked deeper then the basic Arduino commands.

How do we learn the right skills to get started with Timer Interrupts, so that we learn something that we can use for many years to come.

I hope our old brains are up to the task.

What i figured out so far is: - pin 9 and 10 are controlled by timer one - for highet resolution we need to use setting 0x01, division 1, and that gives 31250 Frequency

31250 Hz, not faster? I have read that timer one should be capable to give out 2MHz frequency is this correct? BTW i'm using a AtMega328P (ArduinoNano)

pin 9 = OC1A pin 10 = OC1B

I found this document: it mentions frequwnties of 16MHz and 32MHz in Non-PWM mode on Attiny devices http://www.atmel.com/Images/doc2542.pdf

It is starting to look like this is WAY over my head, though I hope i'm still going to get some result.

To make things more basic lets skip the ADC inputs and lets say i want to make a pulse from 20us (pulsehigh = 20MicroSeconds) followed by a pause of 600ms (pulselow = 600MilliSeconds)

What do i do to set Timer1 in a fast mode? 0x01 right? How do i set pin 10 HIGH for 20us and then LOW for 600ms?

Can it be as straightforward as this?

Am i reading the right documents for what i want to build or am i looking in the wrong corner? I read and read but for some reason i don't seem to come across a spark that wakes-up the right braincels

now i need some sleep i guess...

I'm still not 100% sure of what i'm doing.

have been reading this: http://www.avrbeginners.net/architecture/timers/timers.html http://www.mythic-beasts.com/~markt/ATmega-timers.html And several atmega datasheets

TCNT1 Should count up and down for the most stable timing. but how? what mode is that?

Do I need to use the CTC mode or Output Compare Register OCR1 A or B What mode is best suited? 0 Normal 0xFFFF 4 CTC OCR1A 12 CTC ICR1

these seem to be the 3 opions i have

initialise an output set output HIGH, count X number of clockpulses (equal to 20ns) set an output LOW, count x number of clock pulses (equal to 600ms)

Would be nice if someone could correct my mistakes, for all i know i could be 100% wrong.

Eventually a crude, but working, example could do the trick of giving me the insight that i need.

...Feels like going offroad with a tourbike / barefoot in the desert.

more digging, and this is what i figured out so far:

#define PulsePin 13
int timer1_counter;

void setup() 
{ 
  pinMode(PulsePin, OUTPUT);
  cli();         // disable global interrupts 
  TCCR1A = 0;    // set TCCR1A register to 0
  TCCR1B = 0;    // set TCCR1B register to 0
  TCCR1B |= (1 << CS10); // Run timer at clockspeed
//TCNT1 = timer1_counter;   // preload timer

//TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
//interrupts();             // enable all interrupts


} 

void loop()
{ 

}

Please, someone comment a bit if i’m at least heading in the right direction or not.

Sadly, there is no substitute for reading the atmega data sheet, timer section. It is very poorly organized and confusingly written, but it is definitive and accurate once you understand it! It does take some work to puzzle out. You absolutely need to know what all the bits mean in the various timer control registers in order to program the timer effectively.

Perhaps the best way to practice is to study someone else's timer initialization code, and make sure that you understand the reason for every bit they set. Lately, I've been working on modifying Peter Knight's "talkie" software speech synthesizer routines (see http://elek101.blogspot.com/2012/12/arduino-talking-clock.html) for a non-Arduino board using a 20 MHz crystal, and finding it to be a useful refresher and challenge. The routines use both Timer1 and Timer2 for different purposes.

For your problem (very short time high pulse and relatively long time low pulse) you can use Timer1 in fast pwm mode, but you can't get the exact timings that you suggest as examples. The smallest possible on-time:off-time ratio is 1:65535, then follow 2:65534, 3:65533, etc.

Maybe something here will help: http://www.gammon.com.au/forum/?id=11504

For the record, I think that this line

OCR2A = 124; // count up to 125 (zero relative!!!!)

in the above link should contain 125. But given the inaccuracy of the typical 16 MHz crystal used, it may be hard to tell the difference.

@ jremington:

Thank you, it makes me feel a lot better to know that i'm not the only one that becomes confused by atmels datasheets. Using a 20MHz crystal makes a lot of sense to stay sane, unfortunately the Arduino Nano 3 crystal is not very hackfriendly, so for now i skip this hack, If i get my head around this then i might buy and hack an UNO to do this. would be great if i can get this little pulse generator running!

The Talkie sketch: This is using regulair PWM (with a Pulse width that changes along when you change the frequency) and that's the exact thing what i try to overcome with my sketch. I'm only just become aware of the counter and i think i now first need to try to get my head around setting up and using a counter. Maybe i'm still suffering of timer blindness, the talkie script seems to be way over my head. I just can't see what is happening there. Though i also seem to have learned something from it, though i can't just piont my finger on what it is.

I do see what you say about OCR2A = 125; hehe 16MHz doesn't make it any easier to learn about timer1

@LarryD

Yes that link is giving me more insight, thank you. Now i wonder if it is possible to use 2 timers. Timer0 that counts the cycle time (frequency) then resets both timers Timer1 that count the microseconds for the pulse (the most important part for me)

It's still daunting though, considered that i'm very new to writing code.

I have experimented a bit with the examples and for some reason i don't get the same results as him. Tomorrow i'll try again. Looks like what he does with : Timer 0, mode 2 (CTC mode) is what i want to accomplish but then with timer1. So I should be able to get somekind of result.. This could take a few days... I hope i'll get my head around this.

I'm now thinking of making this for an Attiny + 20Mhz crystal, but i better first figure out how to get a first result at 16Mhz

Is Nick Gammon also on this forum? It might be nice if he extended his tutorial a bit deeper into counters.

Guy's thanks a lot! I already feel 2 bits smarter, now i need 6 more and then i can feel a byte smarter. :-)

Is Nick Gammon also on this forum?

Yes he is. You may want to look at his site in some length. http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

It might be nice if he extended his tutorial a bit deeper into counters.

Come on Nick, you have nothing to do ;)

Here is how the Talkie sketch sets up TIMER2 for PWM, which makes the actual sounds, and TIMER1 as an 8000 Hz clock.

TIMER2 initialization:

        TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
        TCCR2B = _BV(CS20);
        TIMSK2 = 0;

Explanation:

TCCR2A: -WGM21+WGM20 = 3, so we select fast PWM mode. The counter will count from BOTTOM (0) to TOP (255) and then overflow to 0, so the frequency is 16 MHz/256 = 62500 Hz -COM2B1 = 1, so in fast PWM mode, we have the timer set OC2B (PIN 3) when BOTTOM is reached (0) and clear OC2B (PIN 3) when counter reaches the value of output compare register OCR2B. The counter continues up to 255 and resets to 0.

TCCR2B: -CS20=1, so we increment the timer at the system clock rate (16 MHz).

Elsewhere in the code, the actual pulse width is set with the line

OCR2B=nextPWM;

TIMSK2: = 0, so no interrupt is generated.

TIMER1 is initialized to generate interrupts at 8000 Hz:

        TCCR1A = 0;
        TCCR1B = _BV(WGM12) | _BV(CS10);
        TCNT1 = 0;
        OCR1A = F_CPU / FS;
        TIMSK1 = _BV(OCIE1A);

Explanation: TCCR1A = 0, so no pins are toggled by timer activity TCCR1B: -WGM12 = 1, so we select CTC mode, or Clear Timer on Compare match. -CS10 = 1, so no prescaling. Timer increments at 16 MHz.

TCNT1 = 0; make sure that the timer starts from 0 the first time through.

OCR1A = 16 MHz/8000; TIMER1 counts from 0 to OCR1A and then resets to 0, thus dividing 16MHz down to 8000 Hz

TIMSK1: -OCIE1A = 1, enable interrupt to trigger when TIMER1 count reaches OCR1A

Hope that helps!

@ LarryD : woops I didn't realize Nick decorated this place! And is the guru here... :D sorry for asking

@ jremington : yes now i see, and what i read at Nick's tutorial slowly begins to fall at it's place Thanks a lot to explain the Talkie! And now i see that this is almost 100% what i need.

Still this is at the edge of what my brain can take right now.

void setup() {

int Pulse=20; //still need to figure out how long 20 is
//control this with an ADC or something
  
  
//init T2 @ 62500Hz
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); //WGM21 + wgm20 = 3 (fastPWMmode)
TCCR2B = _BV(CS20); // 8bit so 16MHz/256
TIMSK2 = 0;

OCR2B=Pulse;

//init T1 and generate 2000Hz 

#define FS 8000
TCCR1A = 0;
TCCR1B = _BV(WGM12) | _BV(CS10); //prescaler 1
TCNT1 = 0;
OCR1A = F_CPU / FS; //16Mhz/8000 = 2000
TIMSK1 = _BV(OCIE1A); //enables interrupt to trigger at OCR1A
//thus on pin D9 is the pulse (pin15 on the chip)




}




void loop() {
}

i only have a bare nano v3 at hand and no oscilloscope so i have no way to see if this already works so far, but i already feel a byte of progress.

will check this and get back with my findings....

If you want to mimic the behavior of the software shown in your first post, you will have to use TIMER1 to do PWM in CTC mode 12, with one increment per microsecond (possible on an 8 MHz arduino), and set up the registers so that ICR1 = sum of the two ADC readings and OCR1A = first ADC reading. From the atmega328 data sheet:

16.9.2 Clear Timer on Compare Match (CTC) Mode In Clear Timer on Compare or CTC mode (WGM13:0 = 4 or 12), the OCR1A or ICR1 Register are used to manipulate the counter resolution. In CTC mode the counter is cleared to zero when the counter value (TCNT1) matches either the OCR1A (WGM13:0 = 4) or the ICR1 (WGM13:0 = 12). The OCR1A or ICR1 define the top value for the counter, hence also its resolution. This mode allows greater control of the compare match output frequency. It also simplifies the operation of counting external events. The timing diagram for the CTC mode is shown in Figure 16-6. The counter value (TCNT1) increases until a compare match occurs with either OCR1A or ICR1, and then counter (TCNT1) is cleared.

Today i have been digging around in the above sketch, for some reason i can't find why i don't get ANY pulses

There have been some people distracting me BIG time so probably i'm overlooking the obvious error.

Now let's move on to put everything in place and i'm sure i will find the blindspot. I forgot how to set the timer interrupt to a output pin, and i can't seem to find the answer right now. All i remember is that pin 9 and 10 are output pins of timer1 and that i need to set this somehow

I'm chaotic today and making a mess

At the time of writing i'm asking myself if i actually need to use timer2? Since everything is linked to the 16MHz As you can see I'm confused by OCR2B and ICR1. This all is a bit over my head tonight.

I really need to get some sleep and i'll post the sketch 'as is' with all the silly mistakes included

These questions are now on my mind: Do i really need timer2? What is the right way to generate the frequency? OCR2B or ICR1? Am i missing the point of ICR1? (Should i set ICR1=0;) How do i define the output pin? (should i use 9 or 10 or can i also output at pin 13 to visualise it trough the LED though then i should make LONG pulses so that the LED actually enough time to be on so that my eye can see it. I'm not always near a oscilloscope that's why this thought entered my mind)

3 questions to many, they keep the chaos alive.

Thank you jremington for actually making me think, I actually feel that i'm learning something. Tomorrow i'll also try to re-read the timer page on Nick Gammon's site that LarryD pointed me to and hope i can spark a few braincells back to life.

int ADC0=0;
int ADC1=0;
int valueADC0;
int valueADC1;
int frequency=0;
int pulsehigh=0;

//int pulsepin=13;  //some way to give the pulses a pin to live at


void setup() {
  
//init T2 @ 62500Hz
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); //WGM21 + wgm20 = 3 (fastPWMmode)
TCCR2B = _BV(CS20); // 8bit so 16MHz/256
TIMSK2 = 0;
OCR2B=frequency;

//init T1 and generate pulse 

#define FS 8000
TCCR1A = 0;
TCCR1B = _BV(WGM12) | _BV(CS10); //prescaler 1
ICR1 = valueADC0+valueADC1; //frequency
TCNT1 = pulsehigh;
OCR1A = F_CPU; //16Mhz
TIMSK1 = _BV(OCIE1A); //enables interrupt to trigger at OCR1A
//thus on pin D9 is the pulse (pin15 on the chip)

pinMode (9, OUTPUT); 

}


void loop() {
  
  valueADC0=analogRead(ADC0);
  valueADC1=analogRead(ADC1);
  frequency=valueADC0+valueADC1;
  pulsehigh=valueADC0;  
  
}

Since Timer2 is an 8-bit timer, it cannot accommodate values larger than 255. Again, if you want to mimic the behavior of the program described in your first post, which encodes 10-bit values from the ADC into pulse times, you will need to use 16 bit Timer1.

Hm ok, i'll clean up and try to figure out how to get a higher frequency

I stripped out the ADC stuff and set a fixed pulse and frequency for now. Is this still possible with a Arduino One / Nano? Since it only has one 16bit timer...

I really appreciate your help i hope i'm not making you pull out your hair with this move? Or is it better to stay with the original sketch to keep you sane?

Lets see if i start to understand timer / counter.

First i set all outputs to zero / initialise Timer1 set prescaler to 1 (16MHz) TCCR1A = 0; TCCR1B = _BV(WGM12) | _BV(CS10);

i set pulse output high then i start counting for the time that pulsehigh must be HIGH TCNT1 = pulsehigh;

when count reaches 20000 then pulsehigh sould go LOW

keep counting until frequency value is reached. (Can the 328 count that far?) OCR1A = F_CPU;

then reset.

TIMSK1 = _BV(OCIE1A); now i forgot what TIMSK does... Is this the output pulse? (then this is wrong...at this spot)

Is it possible to do that in this way?

I'm making a mistake here though i don't see how. Where is my A-HA moment????

Several mistakes, the first and most important of which is that you are not reading the timer1 section of the data sheet.

OCR1A = number to which the timer counts before it resets the OUTPUT and/or triggers an interrupt. F_CPU is 16000000. Is this what you want?

TIMSK1 = interrupt flags. Are you intending to use interrupts?

Got your point, chapter 16 is still a bit over my head it seems.

I am reading it, but the brain isn't processing the data. I read, i think i understand but when i experiment then i start to mess things up.

Tonight i will re-try to understand what the datasheet is telling me. It's most likely that i'm missing some basics about the coding lingo to fully grasp it. My english is pretty good i guess, but my level in coding is still in the early stages.

All i know about timer1 is what is written in this topic.

I'll first spend some extra time in chapter 16 of the datasheet/book My friend is also new at this so we confuse ourselves with our own mistakes. And chaotic creative minds are also at play. It is hard to focus and even harder to figure out on what we should focus. (so thanks for pointing us to the datasheet)

When trying to figure out how to program a timer on the AVR, I always start at the "Register Description" section of the data sheet for the particular timer of interest. That gives you a table of what control bits are in each timer register, followed by a brief description, then you can backtrack through the rest of the material to get the details if you need them. For Timer1 in the atmega328, that would be section 16.11.

I did some scrutinizing of the data sheet, and I was wrong in an earlier post of this thread. If you want a timer to count to 125 in CTC mode and then reset, you set the ICRx register to 124. This is because the timer sets a flag when TCNTx = ICRx but does not reset to zero until the next timer cycle. So, the count is ..., 123, 124, 0, 1, ... for 125 counts in a complete timer cycle.

Hmmm,

What i don't see is : Can i count trough register A and trigger a pulse then shut it off after 1000 counts but keep counting and then reset the counter when it reaches 30000 Or do I need to : In Register A, Trigger a pulse, Count to 1000, then turn off the output, then move to register B count to 30000 and then reset Timer1 as a whole. Or still another way? and if both are possible what is the most simple approach? and why?

Also would it make sense to turn pause and pulse counts around? first count the pause 30000 counts, then set output high count until 31000 and reset timer1?

The reason i ask this is that there never should be an output HIGH for any time longer then the pulse (to prevent transistors from going up in smoke)

And what is the correct way to make OC1A and OC1B change state? How do i say ON and OFF. From the datasheet i can't really tell, and when I google for OC1A or B then i see several different ways but they yet don't make real sense since I lack some insight in the whole timer workings.

I have experimented with it but i still have to manage to get pulses. This is where i feel kinda stupid. But it's probably one of the other settings that i still ave to get right.

My thoughts go in curves and infinite loops. I think to hard about the things i already know and that keeps me from looking where i should be looking.

Al that said, you know what really would be a nice tool to have? An interactive tutorial web page, where you can play with the timer. Just to gain insight in the basics of the timer and also useful as a tutorial on reading the various diagrams.

The working of the mode is now clear CTC, however i'm still uncomfortable of how to ensure myself that i've set the parameters correct.

Right now i'm not at home so i only can dig trough the datasheet. I've tried to install a Arduino simulator on Ubuntu but unfortunately without success, then i could have done some more experiments.

I'm drifting off-topic... More tomorrow.

Took more time then expected to get back here. (my router failed)

I have done more reading and a few experiments so i think i'm slowly gaining knowledge and sort of made a fresh start

Turns out that i misunderstood the setting of the mode table. Probably because i was also reading to much about timer 0 and 2 and this drove my mind all over the place.

This seems to be the most straight forward way.

pinMode(9, OUTPUT); pinMode(10, OUTPUT);

TCCR1A = _BV(COM1A1) | _BV(COM1B1); // Toggle OC1A/OC1B on Compare Match TCCR1B = _BV(WGM12) | _BV(CS10); // CTC mode, Prescaler 1

OCR1A = 20000; OCR1B = 50;

How do i reason the HIGH and LOW state? 16.11.5 of the data sheet seems to be the key. Is it that pin9 always starts HIGH and thus 10 is then LOW until it toggles, so in this scenario pin 10 is my output? I'm asking this because i need to make sure the FET or Transistor has to be OFF by default.

This i also will try to figure out with the scope, i havn't been near a scope the past few days. Just to let you know i'm still on the case.

I also have this scenario in mind: (Though this doesn't feel complete yet)

pinMode(9, OUTPUT); pinMode(10, OUTPUT);

TCCR1A = _BV(COM1A0) | _BV(COM1B1); // on Compare Match Set OC1A/OC1B (HIGH) TCCR1B = _BV(WGM12) | _BV(CS10); // CTC mode, Prescaler 1

OCR1A = 20000; OCR1B = 50;

Is it safe to use it in this way and then replace the OCR1 values with variables generated by a analog read value?

in 16.11.4 the datasheet states: Modifying the counter (TCNT1) while the counter is running introduces a risk of missing a compare match between TCNT1 and one of the OCR1x Registers.

Do i also have this risk with OCR1? Can it be that i experienced this kind of behavior in my previous sketches? In other words, what happens if OCR1A value is changed to 1000 when the counter is somewhere at 9000 will the counter then count all the way up to the max value and then reset itself? (and thus glitch the signal) This can even be worse when OCR1B misses a toggle (and then becomes HIGH for a long period)

Or am i thinking to far about this?