Hi,
I´m new to programming and trying to understand some functions. I have successfully "read" voltage to make a led blink at different speed according to voltage input on A0. Now i´m trying to do the same but using TimerOne instead of "delay" but i cant get it to work the way i want. Now the input value (get_voltage) to adjust the blinking is in the setup but i want it in the loop. Is that possible and what code shall i use? maybe "bool"?
If you are not especially interested in using the library you can probably achieve what you want by using millis() as illustrated in Several Things at a Time
People will find it easier to help you if you post your code using the code tags. You can do that by hitting the “Code” icon above the posting area. It is the first icon, with the symbol: </>
const unsigned int POT_READ=0;
const float SUPPLY_VOLTAGE=5.0;
const unsigned int BAUD_RATE=9600;
#include "TimerOne.h"
void setup() {
Serial.begin(BAUD_RATE);
pinMode(9, OUTPUT);
Timer1.initialize(get_voltage()*50000); // initialize timer1, and set a 1/2 second period
Timer1.pwm(9,512); // setup pwm on pin 9, 50% duty cycle
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
}
void callback()
{
digitalWrite(10, digitalRead(10) ^ 1);
}
void loop() {
Serial.print(get_voltage());
Serial.println(" Volt");
delay(1000);
}
const float get_voltage(){
const int out_voltage=analogRead(POT_READ);
const float voltage=out_voltage*SUPPLY_VOLTAGE/1024;
return (voltage);
}
To change the frequency within the loop add the following line
void loop() {
ICR1 = (get_voltage()*50000); //add this line
Serial.print(get_voltage());
Serial.println(" Volt");
delay(1000);
}
If you read the documentation (TimerOne.h) for the TimerOne library you will see how the frequency is set by Timer1.initialize().
DS21:
Hi,
I´m new to programming and trying to understand some functions. I have successfully “read” voltage to make a led blink at different speed according to voltage input on A0. Now i´m trying to do the same but using TimerOne instead of “delay” but i cant get it to work the way i want. Now the input value (get_voltage) to adjust the blinking is in the setup but i want it in the loop. Is that possible and what code shall i use? maybe “bool”?
You don’t need a timer library to do what you are doing. Try this:
#define DIV_1024 (_BV(CS12)|_BV(CS10))
#define LED_PIN 13 // any pin number you like
volatile uint8_t state = 0;
volatile uint16_t divider;
uint16_t analog;
uint16_t frequency;
ISR (TIMER1_COMPA_vect)
{
digitalWrite (LED_PIN, state ? HIGH : LOW);
state ? state = 0 : state = 1;
OCR1A = divider; // set divider (i.e. frequency)
}
void setup (void)
{
// setup pin as an output
pinMode (LED_PIN, OUTPUT);
// set timer 1 to Mode 4
TCCR1A = 0;
TCCR1B = _BV (WGM12);
// set clock prescaler to F_CPU/1024
TCCR1B |= DIV_1024;
// enable interrupt on OCR1A match
TIMSK1 = _BV (OCIE1A);
}
void loop (void)
{
analog = analogRead (A0); // any analog port you want
// map analog 0..1023 to 100...500 (whatever you want)
frequency = map (analog, 0, 1023, 100, 500);
// calculate divider needed
divider = ((F_CPU / 1024) / ((frequency * 2) + 1));
delay (500); // wait 1/2 sec between changes
}
This demo maps analog 0…1023 to 100…500 hertz, but you can change it to whatever you wish (as you can change which pin to use for the output signal and which pin as the analog input).
Note: We set the divider INSIDE the ISR to avoid confusing it by asynchronously setting it at random and “pulling the rug out from under it” if we set it inside the loop.
LarryD:
You can also just use the analogRead to adjust the duty cycle on pin 9
Not tested:
Timer1.setPwmDuty(9,analogRead(A0));
.
That would change the BRIGHTNESS of the LED depending on the analog reading, but not it's blink rate. I assumed the OP wanted a different blink rate.... maybe I'm wrong?