Timer 1 with overflow interrupt using arduino genuino uno board

Hi please can someone tell me how to generate a 500Hz and a 250Hz signal with timer 1 overflow interrupt ?

What have you tried?

Post the program that represents your best attempt and tell us what happens when you run it.

What is the purpose of this Timer interrupt?

...R

H iam using Arduino genuino uno board and I am trying to generate 500Hz and 250 Hz signals using timer1 overflow interrupt. i am having problems with how to preload the TCNT1 register in order to generate the appropriate signal. Can anyone please help me with this issue ?

Cross post from here : http://forum.arduino.cc/index.php?topic=560374

Reported to mods

This is the program. : i am trying to program a servo motor to rotate from 0 to 180 degrees but it is not rotating a full 180 degrees.

#define ledPin 13
int const potPin = A0;
float pulse=1;
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;

TCNT1 = 25536; // preload timer
TCCR1B = 0x01;
TIMSK1 = 0x01; // enable timer overflow interrupt
interrupts(); // enable all interrupts
}

ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{
pulse=(analogRead(potPin)*23.4375);
TCNT1 = 25536+pulse; // preload timer
digitalWrite(ledPin, digitalRead(ledPin) ^ 1);

}

void loop()
{
Serial.println(TCNT1);

Serial.print("pulse: ");
Serial.println(pulse);
}

0 to 180 degrees but it is not rotating a full 180 degrees

How much is it moving?

Threads merged.

Don't read the potentiometer inside the ISR. analogRead() is slow so read it in loop() and save the value into a variable that can be used by the ISR. Also do all the maths outside the ISR so that all that is needed inside the ISR is

TCNT1 = newValue;            // preload timer
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1);

...R

i arranged the program now i did the analog read function and the necessary math inside the loop body. However the servo is still rotating only about 90 degrees

jamefarrcar:
i arranged the program now i did the analog read function and the necessary math inside the loop body. However the servo is still rotating only about 90 degrees

You need to post the latest version of your program in your next Reply so we can see exactly what you did.

...R

This is the latest program so far : Still not getting a full 180 degrees rotation. I am getting only about 90 degrees.

#define ledPin 13
int const potPin = A0;
float pulse=1;
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;

TCNT1 = 25536; // preload timer
TCCR1B = 0x01;
TIMSK1 = 0x01; // enable timer overflow interrupt
interrupts(); // enable all interrupts
}

ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{

TCNT1 = pulse; // preload timer
digitalWrite(ledPin, digitalRead(ledPin) ^ 1);

}

void loop()
{
pulse=25536+(analogRead(potPin)*19.53);
Serial.println(TCNT1);

Serial.print("pulse: ");
Serial.println(pulse);
}

Are you getting the value you expect for the variable "pulse"?

You should also save the analogRead() value to a variable so you can verify the calculation.

What servo are you using? I have some HobbyKing servos that need pulse widths from about 450µsecs to 2400µsecs - and I have verified the pulse widths with my oscilloscope.

I suggest you test your servos with the regular Servo library.

...R

I think I got it this time I made the servo go from 0us to 2000us instead of from 1000us to 2000us. I think that was the problem.The only problem now is that the servo is heating up a bit during normal operation.

jamefarrcar:
The only problem now is that the servo is heating up a bit during normal operation.

Maybe you are forcing it against its internal end-stops. Many servos cannot actually move through 180°

If you are pushing against the end-stops for any length of time you are likely to damage the servo.

...R

I tested your program using a Tower Pro - SG90 stepping-Servo Motor. The results are:

Servo makes a turn and then getting too hot and jitters at pot value = 0. Why should it be hot and jittering? This servo works very fine when fed 50 Hz PWM signal.

You are not using the Servo.h Library; insted, you are creating so called PWM at DPin-13 signal using TOV1 interrupt of TC1.

1. When pot value is 0, you are generating 2.5 ms HIGH and 2.5 ms LOW signal continuously at DPin-13. This is the signal which you have (probably) injected at the control pin of the servo motor. The frequency of this PWM signal is: 1/5 ms = 200 Hz. Can you inject such a high frequency signal at the control pin of a stepping-servo?

Overflow/roll-over time = (0x10000 - 25536)1/16000000 = 400001/16000000 = 0.0025 s = 2.5 ms
===> frequency of PWM = 1/(2*0.0025) = 200 Hz.

2. When pot value is max, you are generating 1.25 ms HIGH and 1.25 ms LOW signal continuously at DPin-13. This is the signal which you have (probably) injected at the control pin of the stepping-servo motor. The frequency of this PWM signal is: 1/0.0025 = 400 Hz. Can you inject such a high frequency signal at the control pin of a stepping-servo?

Overflow/roll-over time = (0x10000 - (25536+102319.53))1/16000000
= 20021
1/16000000 = 0.00125 s = 1.25 ms
===> frequency of PWM = 1/(2
0.00125) = 400 Hz. Can you inject such a high frequency signal at the control pin of a stepping-servo?

Recommendation: Use Servo.h Library or one of the TCs of ATmega328P MCU to create 50 Hz PWM signal.

Hi I finally managed to program a servo with arduino uno genuino board using timer1 overflow interrupt. To minimize high frequency I resetted the TCNT1 register to 0 when a logic low is detected on the corresponding pin. I did this by an if condition in the ISR routine. A simple if condition shouldn’t be a great deal inside the ISR no ? This is the program I made so far:

#define ledPin 9
int const potPin = A0;
float pulse=61536;
char stpin=0;
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
// initialize timer1
cli(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;

TCNT1 = 60536; // preload timer
TCCR1B = 0x02;
TIMSK1 = 0x01; // enable timer overflow interrupt
sei(); // enable all interrupts
}

ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{
if ((digitalRead(ledPin) ^ 1)==0)
{
TCNT1=0;

}

else
{

TCNT1 = pulse; // preload timer
}
digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
}

void loop()
{

pulse=60536+(analogRead(potPin)*3.8);

Serial.print("TCNT1: ");
Serial.print(TCNT1);
Serial.println();
Serial.print("pulse: ");
Serial.print(pulse);
Serial.println();
}

I greatly appreciate any feedback :slight_smile:

I have suggested to the Moderator to merge this with your other Thread on the same subject so we have all the info in one place.

...R

To make it easy for people to help you please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

…R