I'm creating a test setup for the speed sample firmware.
In this post I'm reviewing the speed sensing approach and how the Arduino knows how fast the turntable is spinning.
Where should I measure the speed?
There are a number of options. The table has 5 parts where the speed can be measured.
- motor: should run at a constant speed all the time, regardless of the selected turntable speed
- belt: constant
- stepped pulley: constant
- idler: dependent on selected speed, moves up and down depending on speed too
- turntable platter: dependent on selected speed.
As it turns out, the easiest candidate is the stepped pulley. Its speed should be constant regardless of the selected platter speed, and it is easy to attach a sensor under it.
For a more detailed explanation of how the record player works, speed calculations and selection of the speed sensor, have a look at these posts:
The gist of all the above is that I'm going to measure the speed of that stepped pulley with an infrared sender - receiver pair.
A small piece of mirror glued to the underside of the pulley will reflect the IR beam once per rotation.
We'll get a nice digital signal from that sensor with the same frequency as the pulley speed.
More on that in a next post.
The only thing we have to remember for now that that pulley is going to spin at a few 10's of RPMs.
Simulating the Speed Sensor
We know that the sensor is going to give a signal with the frequency of the spinning pulley.
The signal will be high when the mirror is in front of the IR sensor, and low for the rest of the rotation. The width of the small mirror defines the duty cycle of our sensor output.
It's easy to simulate that signal with a signal generator with TTL output and variable duty cycle.
If we set that to a signal within the speed range of that pulley (I've selected 12.5 Hz in my test setup here), and play a bit with the duty cycle, we have a signal that is very similar to the sensor output.
We can change the functuon generator frequency to simulate that the turntable is slowing down or going too fast.
We can play with the duty cycle to test that our firmware will sample the frequency correctly in the real world, and find the minimum size of the mirror.
The Speed Sample Firmware
I've looked at several frequency measure examples for the Arduino.
I selected the first one that works together with my PWM solution for the motor driver (1958 Turntable from the Black Forest - 4: Motor control with Infineon Motor Shield and Arduino UNO).
It is avdweb Frequency / period counter for the Arduino.
You can use this library in polling mode (do a measurement when you need it) or in interrupt mode. I chose interrupt mode.
In interrupt mode, the frequency polling will happen in the interrupt handler when the sensor signal changes.
Whenever we need to know the speed, we can just look up the value that was collected in the interrupt.
There are only a few pins that can be used with interrupts. You can find more info on the attachInterrupt() help page.
The library is not hard to use. This is how you initialize it:
// includes for sensor #include <FreqPeriodCounter.h> // ... // variables and constant for sendor const byte iSensorPin = 3; const byte iSensoCounterInterrupt = 1; // = pin 3 FreqPeriodCounter sensorCounter(iSensorPin, micros);
The next step is to set up the interrupt mechanism. We have a handler that's called when the value on pin 3 changes.
We have to register that handler. And that's it. From that moment the frequency measurement is working.
void sensoCounterISR() { sensorCounter.poll(); } void sensorSetup() { attachInterrupt(iSensoCounterInterrupt, sensoCounterISR, CHANGE); }
We can get at the last measured frequency anytime. I've created this method for that:
long sensorPeriod() { return sensorCounter.period; }
I'm using the period because that's not a floating point. Frequency is 1/period, and that's a float.
For my use, I can work with both period and frequency. Both indicate how fast the table is spinning.
So I avoided the requirement to link in the floating point libraries by sticking with period.
That's all.
For testing purposes, I'm logging the period in the main loop of my firmware.
When I change the frequency of my function generator, the Arduino serial monitor has to display the correct period.
When I change the duty cycle on my function generator, the Arduino should ignore that and keep showing the correct period.
void setup(void) { Serial.begin(9600); sensorSetup(); // ... } void loop(void) { // ... long period = sensorPeriod(); Serial.println(period); delay(1000); }
The Results
In the photos and captures below, you can see the results.
The figures on the frequency counter, oscilloscope and Arduino serial monitor match within a reasonable margin.
Frequency counter | Oscilloscope | Arduino sampled values |
---|---|---|
Let's have a closer look at that oscilloscope capture:
This is an odd capture. The two signals don't have the same time base (one is 33 kHz, the second 15.5 Hz - and still both show stable and well-triggered on the scope).
This is called alternate trigger mode. It's used to show to signals that don't relate to each other in the time dimension.
I want to show the PWM signal of my motor control on the oscilloscope to validate that my sample firmware does not impact the motor drive firmware.
So any change of my frequency generator should leave the upper part of the scope unchanged.
Vise versa, if I change the PWM of the motor driver, the sample firmware should still measure the sensor signal correctly.
The alternate trigger technique is a good method to show this. You can see if altering one signal has impact on the other.
But don't try to relate the signals to each other. You have to see this display as 'split screen'. Upper and lower part have a different timeline and trigger point.
More on the subject of alternate triggers in this video:
In the next post, I'm going to build the sensor and do real world tests.
Top Comments