Hello,
Like the title suggests, I'm trying to use Timer1's overflow on pin3. I am using an Arduino Ethernet. I want to get my output PWM at 200 Hz. I am going to use Fast PWM with ICR1 as my TOP. In other words, WGM13:0 = BV(1 1 1 0).
I looked at the atmel spec sheet and I can set the 16Mhz Arduino clock to a fast PWM at 8 MHz. I then found out that there are 40,000 8MHz in one 200 Hz pulse. This allows me a .125 usec resolution.
I then set my limits between 900 usec and 2100 usec. Using the resolution to determine the number of 8MHz pulses, I found that 900 usec is 7200 pulses and 2100 usec is 16800 pulses. In other words, the number of 8Mhz pulses = (desired PW)*8.
I am using TIMER1_OVF_vect as the interrupt to control the PW of the servo. Currently, it is set to 12000 for testing purposes but I have code which can change the pulse width for later versions. The current one is a simple if... else if loop, where if the counter is equal to the cut number of 8Mhz pulses (12000), go low, else if counter is equal to the period (40000), go high and set counter to 0.
Below is my code. I am a bit unsure on what I want for TIFR1 and TIMSK1 to be. However, I've noticed when I change the TIFR1 registry, that the Serial communication stops to the Arduino.
Can someone please help me with what is wrong with my code? To make the registry stuff easier, CS = 1, WGM = 14, TIMSK1 is unchanged and TIFR1 is unchanged.
//Code example for Arduino Uno by Ukeri
//Bart Borghuis and Zoomkat wrote the majority of the code that I used, I just changed it to what I needed.
//Zoomkat's "servo-test-22-dual-input"'s void loop() is my void loop() code
//This program drives a servo motor using timer1 interrupts at 200Hz.
//The Ethernet code is used to change the SS of SPI from 10 to 3 - Code from SurferTim - and test if servo can still
//be controlled on pin 10.
// Done for servo control
#include <avr/interrupt.h>
#include <Serial.h>
//storage variables
String readString;
volatile unsigned int pin3_PW=12000, pin3_diff=0, pin9_PW=12000, pin9_diff=0, period=40000, counter=0; // Tilt
// Initialize Ethernet stuff
void setup(){
//allows serial communication with the Arduino
Serial.begin(9600);
//set pins as outputs
pinMode(3, OUTPUT);
pinMode(9,OUTPUT);
Serial.println("pre registry output");
Serial.print("TCCR1A: ");
Serial.print(TCCR1A);
Serial.print(" TCCR1B: ");
Serial.print(TCCR1B);
Serial.print(" TCCR1C: ");
Serial.print(TCCR1C);
Serial.print(" TIMSK1: ");
Serial.print(TIMSK1);
Serial.print(" TIFR1: ");
Serial.println(TIFR1);
delay(500);
cli();//stop interrupts
//Initialize the registries for 8 MHz
ICR1 = 0x1;
TCCR1A = 0x2; // BV(0 0 0 0 0 0 1 0)
TCCR1B = 0x19; // BV(0 0 0 1 1 0 0 1)
TCCR1C = 0x0; // BV(0 0 0 0 0 0 0 0)
// TIFR1 = 0x1; // BV(0 0 0 0 0 0 0 1)
// TIMSK1 = 0x1; // BV(0 0 0 0 0 0 0 1)
TCNT1 = 0;//initialize counter value to 0
sei();//allow interrupts
counter=0;
Serial.println("servo registry control - Interrupt - custom 4MHz signal - Fast PWM mode"); // so I can keep track of what is loaded
Serial.print("TCCR1A: ");
Serial.print(TCCR1A);
Serial.print(" TCCR1B: ");
Serial.print(TCCR1B);
Serial.print(" TCCR1C: ");
Serial.print(TCCR1C);
Serial.print(" TIMSK1: ");
Serial.print(TIMSK1);
Serial.print(" TIFR1: ");
Serial.println(TIFR1);
}//end setup
void loop()
{
Write_serial_data(pin3_PW); // Writes to pin 10
}
void Write_serial_data(unsigned int PW)
{
while (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
delay(2); //slow looping to allow buffer to fill with next character
}
if (readString.length() >0)
{
Serial.println(readString); //so you can see the captured string
int n = readString.toInt(); //convert readString into a number
// determines if the input is within the range of the servo.
if(n >= 900 && n <=2100) // input is within the range of the servo
{
PW = n * 8; // takes input pulse width and converts it to a value for OCR1A
}
else if(n < 900) // input is too small
{
n=900;
PW = n * 8; // takes input pulse width and converts it to a value for OCR1A
}
else if(n > 2100) // input is too large
{
n = 2100;
PW = n * 8; // takes input pulse width and converts it to a value for OCR1A
}
readString=""; //empty for next input
}
// Serial.print("counter: ");
// Serial.println(counter);
}
ISR(TIMER1_OVF_vect)
{
counter++;
if(counter = pin3_PW)
{
digitalWrite(3, LOW);
}
else if(counter = period)
{
digitalWrite(3, HIGH);
counter = 0;
}
}
Thanks,
Matt