Created
August 26, 2016 15:00
-
-
Save edgar-bonet/ec86ab7c65e7661b2f3dc4e3e053b0fb to your computer and use it in GitHub Desktop.
Pulse an LED at an adjustable frequency
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* stroboscope.ino: Pulse an LED at an adjustable frequency. | |
* | |
* This program strobes an LED at a frequency which is controlled by a | |
* potentiometer. The frequency is continuously displayed on the serial | |
* port. | |
* | |
* The potentiometer sets the frequency, on a logarithmic scale, from | |
* 15.26 to 1012 Hz (assuming a 16 MHz clock). The output is generated | |
* by Timer 1 in phase correct PWM mode with a /8 prescaler. This | |
* provides cycle-accurate timing with a 1 us resolution. | |
* | |
* This program is intended for an Arduino Uno and is likely to work, | |
* with only minor modifications, on any AVR microcontroller having a | |
* 16-bit timer. | |
* | |
* Circuit: | |
* - a potentiometer between GND and 5V | |
* - the pot's wiper connected to A0 | |
* - an LED + series resistor between digital 10 and GND | |
* | |
* Inspired by a similar program by Steve Krave: | |
* http://mehax.blogspot.fr/2011/02/arduino-stroboscope.html | |
* | |
* Copyright (c) 2016 Edgar Bonet Orozco. | |
* Released under the terms of the MIT license: | |
* https://opensource.org/licenses/MIT | |
*/ | |
const int pot_pin = A0; // potentiometer wiper pin | |
const uint16_t print_period = 200; // print every 200 ms | |
void setup() { | |
Serial.begin(9600); // serial port @ 9600/8N1 | |
DDRB |= _BV(PB2); // set PB2 = digital 10 as output | |
// Configure Timer 1. | |
TCCR1A = _BV(COM1B1) // non inverting PWM on OC1B = PB2 | |
| _BV(WGM10) // phase correct PWM, TOP = OCR1A | |
| _BV(WGM11); // ditto | |
TCCR1B = _BV(WGM13) // ditto | |
| _BV(CS11); // clock at F_CPU/8 | |
} | |
void loop() { | |
int reading = analogRead(pot_pin); | |
uint16_t period = 65535 * exp(-4.1e-3 * reading); // in us | |
uint16_t width = period / 64; // pulse width | |
OCR1A = period; | |
OCR1B = width; | |
uint16_t now = millis(); | |
static uint16_t last_print; | |
if (now - last_print >= print_period) { | |
last_print += print_period; | |
Serial.print(1e6 / period); | |
Serial.print(" Hz ("); | |
Serial.print(60e6 / period); | |
Serial.println(" rpm)"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello, I am trying to make a stroboscope ranging from 0-83.33 Hz (5000 RPM) using an encoder rather than a potentiometer. I stumbled upon your website/code as well as your comments on (http://mehax.blogspot.co.uk/2011/02/arduino-stroboscope.html) and I am a little confused. I am afraid of using the code on that website due to the random math performed for timing purposes and due to my desired accuracy. I was wondering if you could help me with mine or give me an insight of how accurate your strobe is? I've been working on this for 6 months now and I desperately need help for a senior design project. Any help would be appreciated.