What do you need for this project:
- a 50 Hz stoboscope disk that you can print from the internet.
- and
- an Arduino UNO, a 330 Ohm resistor and an LED or
- a Hercules TMS570LS04 LaunchPad
The Theory
Stroboscopes are used in many disciplines to measure speed.
It's a series of dots that are spaced for a given frequency / speed (usually for rounds per minute, RPM).
They are put on the object you want to measure. That could be a motor axle. In my case it's the spinning platter of a turntable.
if you blink a light on them with a fixed frequency, the dots will appear standing still, if the speed is spot on.
If the speed is too slow or too fast, the dots will appear to be moving slow direction left or right.
The slower they appear to move, the closer you are to the desired frequency.
The way that it works is, that they are fooling our eyes. Let's use the turntable as an example.
When you switch on the turntable, with a strobe disk on it, the dots spin as fast as the turntable platter.
If you then use a stroboscope light and shine that on the strobe disk, our eyes will record the view when the strobe is on.
The dots are placed in such a way that, if the speed is correct, all the dots will be on an exact same place.
It will be another dot, but it's spot on the same location of a dot that was there on the previous blink.
Here you can see the effect of using my design on a turntable. You can see that the inner circle appears to be standing still.
That's because its dots are placed for 45 RPM, and for a 100 Hz strobe.
I'm strobing the LEDs on the LaunchPad in the photo at 100 Hz.
Why 100 Hz for a strobe disk that's made for 50 Hz?
These strobe disks, all originating from the turntable era, when we used light bulbs, are tuned for the mains frequency.
Where I live that's 50 Hz, other places its 60 Hz.
Let's assume 50 Hz in this explanation. That's the same frequency as used in this project, where ever you use it, anyway.
The 50 Hz mains is a sinusoidal signal. It goes to max/minimum twice fer cycle. And through 0 twice per cycle too.
That means that at 50 Hz, the light will be brightest 2 times per cycle, and dimmest 2 times too.
So it blinks 2 times per cycle. That means 100 blinks per second in a 50 Hz situation. That is a blink frequency of 100 Hz.
So we'll have to build something that blinks 100 Hz.
note: I used incandescent bulbs as an example, but the effect is not good on those.
The filament temperature is dampening the effect. It doesn't cool off 100 times per second.
It is noticeable though if you kind of squint your eye.
But in practice, on turntables they typically used small Neon bulbs. They keep up with the frequency. Not visible to the eye, but they do.
In the auto industry, where they use this technique too, they used Xenon lamps in the past. These days they use powerful white LEDs.
The LEDs that we use in the project here are fast too. So they are up to the job. But because they are faint, it works better in a darkened place.
Why Does my project use a 50 Hz Disk, even in the USA?
That's because I use a fixed frequency of 100 Hz, generated by a microcontroller timer.
That design will blink 100 * per second, wherever you are located. So you print the 50 Hz strobe disk.
If you have a 60 Hz strobe disk (maybe it came with the turntable), then change the project code to make the LED blink 120 times per second.
Precision?
Well, in the past they used the mains frequency to control the speed. That's never been ultra-stable over short periods.
So our designs here for the Arduino UNO and the LaunchPad, both are "good enough", both between 99.93 and 100.04 Hz.
I use hardware timers in both designs, so interrupts have no lasting effect.
In fact, the Arduino is a little bit bette than the Hercules in my design, because I connected a LED directly on the timer output pin.
Whatever happens with that controller, the tick will be ticking accurately.
For the Hercules, I've put 2 API calls in the timer handler (because I wanted to blink 2 LEDs at the same time to increase brightness).
Since those two calls use the main CPU, there's always a risk that an interrupt interferes within one cycle.
But it will not interfere in the long time, because each cycle is driven by the timer.
In practice, this can be ignored.
First Project: The Arduino UNO Design
This is very very simple. I tried to stay within the Project14 spirit.
It's in essence the well known Blinky. The version that uses the hardware timer instead of the delay() function.
Here's the sketch:
// Inspiration for the correct dividers: https://www.engineersgarage.com/knowledge_share/generating-variable-frequency-with-arduino/ // Engineers Garage #define PWM_OUTPUT 9 #define FREQ_DIV 10000 void setup() { pinMode(PWM_OUTPUT, OUTPUT);//Pwm pin as Output TCCR1A=_BV(COM1A1)|_BV(COM1B1);//Non-inverted Mode TCCR1B=_BV(WGM13)|_BV(CS11);//Prescalar 8 ICR1 = FREQ_DIV; OCR1A = int (FREQ_DIV/2); // duty cycle } void loop(){ // do nothing. // Delay as long as the delay allows. // https://www.arduino.cc/reference/en/language/variables/data-types/unsignedlong/ delay((2^32 - 1)); }
Pin 9 is used to power the LED. This is because Pin 9 on a UNO is connected to the output of TIMER1.
In the setup(), the pin is set to output, and then the timer is configured.
This sneaks a little bit of advanced controller development in Project14, but it's a good opportunity for yourself to have a look at those hardware timers.
What happens is that in line 10, the timer is configured in simple PWM mode.
In line 11, the 16 MHz I/O clock is divided by the prescaler to slow down the speed a first time.
Then, in line 12, I divide that clock again, by setting the timer's counter. The result is a 100 Hz signal.
Last, in line 13, the duty cycle is set to 50%.
From that moment on the pin 9 starts behaving as we want it. No further config or logic needed. It will do that until the Arduino is powered off.
As a consequence, the loop() does not have to do anything and there's no code needed there. phoenixcomm , you will not like this .
I just let it delay for the maximum time (max unsigned long), at each loop cycle.
Wiring for Arduino
Very simple. An LED with a 330 Ohm resistor between digital 9 and GND.
source: edited https://www.arduino.cc/en/Tutorial/blink
To use it, place the turntable in a location without bright lights. On a normal day, closing the curtains is good enough.
Print and cut out the strobe disk. Place it on the turntable.
Switch it on, and bring the led as close to the strobo disk as you can. I used a little breadboard and long wires.
If your turntable is spinning correctly, the corresponding circle on your strobe disk (or at least the part directly lit by the LED) appears to stand still.
If you have speed control on your turntable, you can now use that to correct the speed until the dots become stable.
Second Project: Hercules LaunchPad Design
I used this one first, before making the Aruino design, to test my own turntable. The LaunchPad comes with two bright white LEDs ad needs no additional components.
(the full code composer studio project with config and sources is attached to this blog)
The software is in essence the rtiBlinky example (real time clock) for that board. But in the interrupt of the RTC, I toggle the two LEDs.
I've doubled the speed here, compared to the Arduino example, because of that toggling.
To blink a led at 100 Hz, you have to toggle it at twice the speed (because one toggle lights it up, the next toggle dims it). That means 200 Hz, or 5 ms:
The interrupt for that RTI is enabled:
.. and the two pins with connected to the LEDS (GPIOA.2 and HET1.8) are defined as outputs:
The drivers for GIO, HET and RTI are set:
In the code, we enable the interrupts and init the modules:
int main(void) { rtiInit(); gioInit(); hetInit(); /* Enable RTI Compare 0 interrupt notification */ rtiEnableNotification(rtiNOTIFICATION_COMPARE0); /* Enable IRQ - Clear I flag in CPS register */ /* Note: This is us void rtiNotification(uint32 notification) { /* enter user code between the USER CODE BEGIN and USER CODE END. */ /* USER CODE BEGIN (9) */ /* Toggle HET pin 0 */ gioToggleBit(gioPORTA, 2); gioToggleBit(hetPORT1, 8); /* USER CODE END */ } ually done by the OS or in an svc dispatcher */ _enable_IRQ(); /* Start RTI Counter Block 0 */ rtiStartCounter(rtiCOUNTER_BLOCK0); /* Run forever */ while(1); return 0; }
In the RTI interrupt, the LEDs are toggled.
void rtiNotification(uint32 notification) { gioToggleBit(gioPORTA, 2); gioToggleBit(hetPORT1, 8); }
That's it. You cans see the effect on the photo in The Theory chapter.
A video will follow, but it needs to be darker for that, and it's not easy to film strobe efect with a camera. It does not behave like the human eye...
Top Comments