Skip to content

Instantly share code, notes, and snippets.

@edgar-bonet
Created August 26, 2016 15:00
Show Gist options
  • Save edgar-bonet/ec86ab7c65e7661b2f3dc4e3e053b0fb to your computer and use it in GitHub Desktop.
Save edgar-bonet/ec86ab7c65e7661b2f3dc4e3e053b0fb to your computer and use it in GitHub Desktop.
Pulse an LED at an adjustable frequency
/*
* 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)");
}
}
@predzZzZzZ
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment