Digital Tachometer for record player (LCD display)

Hi,
Also make sure that the strip in the platen it is about 1/4 width. The way I found the use of the capacitor was that I was experiencing erratic reading and decided to scope the signal. As soon the probe was connected to the sensor output pin it started to give me good Rpm reading. The pulses were cleaned. So decided that the sensor may need a cap. These happened to me in few occasion while fixing some electronics circuits. The capacitance of the probe was fixing the problem like this one. There is a member that has the circuit running and he has to used the cap because the erratic reading. The Mouser sensor since it is TTL schmitt trigger output it will give you a clean square output with not noise. It is pricey but do a really good job.

If I do not remembered but my reading without the capacitor were about same as your are 45 Rpm.
 
Phase 1 complete! https://youtu.be/-SC0N19KkVo

It's ugly, but it works! The sensor is taped to the plinth in the motor cut-out. Reflective tape from my cheapo handheld laser tach is placed across the blacked-out underside of the platter. I wound up using the blue flat capacitor (the reddish ceramic one did nothing). Not sure the values of each, but they match this photo: https://electronics.stackexchange.com/questions/266031/identify-capacitors-in-arduino-starter-kit

Next up will be the serial communication with the Falcon. I did notice the following as a potentially cleaner connection between the two devices, but I think the pin connections for TX and RX are reversed from what I would need, so I'll go the uglier DIY route. :p

I also noticed that the screen only updates ever 2-3 revolutions rather than every revolution. I may well poke at the code a little to see if I can alter that. I'd rather have more frequent updates.

Cheers, folks! We're making headway!
 
I also noticed that the screen only updates ever 2-3 revolutions rather than every revolution. I may well poke at the code a little to see if I can alter that. I'd rather have more frequent updates.

I noticed that too in your code snippet. Your interrupt service routine (ISR) requires 3 executions to produce a result (3 revs); the first case statement (blank, with break statement only), does essentially nothing except consume one rev from what I can tell.

Tauro221's code requires 2 revs (two ISR executions), but this can be done on every interrupt: count=micros()-count. This computes the time between the last count and the current one in microseconds (with a resolution of 4µS).

You do not need to enable and disable the interrupt service routine every reading. Turn it on at setup() and leave it running. Set a flag in the ISR to indicate a reading is ready. Your main code loops continuously to check for the flag; if it is set, compute and display a reading, then clear the flag and continue looping. No need to delay at the end. When the platter starts moving, the first RPM reading will be extremely small as the time since the last trigger will be large. You can ignore (and display) this, or trap it by setting a FIRST flag and don't display the first reading (then clear the flag). Set FIRST again when the rotation time-out (5 sec) occurs.

You can also clean up the rpm calculation: RPM=60,000,000/count.
 
Last edited:
Hi,
Glad that you have your Rpm display running. I think you are the third one got it running using the cap. About the delay at the end of the Loop there is a delay of 2500 that you can make it smaller. I added it because for me was refreshing the display too fast. You may see also small delay in the display because I used 3 pulses from the platen. The first one it is to be in the interrupt routine to wait for the next 2 pulses to calculate the Rpm. Doing so it will give you a steady reading.
 
The code I used was primarily tauro0221's with some text cleanup and changes to the LCD driver. I didn't dig too much into the calculation logic since I just wanted to get it working. I did notice that "intp_flag = intp_flag + 1;" could probably be rewritten as "intp_flag++;", but again, I wanted to get to this functional point before I messed with anything else. I'll see if I can do some fine tuning before tackling the serial connection, since loading new sketches is a PITA once the RS232 shield is installed.
 
For anyone new to the thread, I think the cleanest result could LIKELY be had with the following (caveat: I have not tried these parts):

Mouser Part No. 828-OPB770TZ optical sensor: $11.31 ($6.32 + $4.99 Shipping)
LCD Button Shield (http://www.ebay.com/itm/LCD-Keypad-...o-Uno-Mega-2560-Blue-White-USA/182489965777): $11.64 ($8.95 + $2.69 shipping)
Arduino UNO clone board (Amazon): $10.99
ZJchao 9V 1A Power Adapter for Arduino (Amazon): $5.99
TOOGOO(R) 40 x 10 cm breadboard jumpers Plug Male to Male Jumper Wires Cables (Amazon): $2.13 & FREE Shipping

That's about $42 all in. You could go cheaper, but probably not necessary. The jumper wires would just be for connecting the Mouser sensor (which wouldn't require fiddling with capacitors) to the LCD Keypad shield (the one I have linked SHOULD provide headers for connection without the need to solder, most other LCD shields require soldering). I would be interested to see if someone could get this kit working together.
 
You could also use the RR sensor with Hall Effect IC. I posted this shared project before, but it is available from OshPark at this link: RoadRunner Sensor

The cost of the PCB is $5 for 3 pcs.

Q1 is the AH337 sensor IC SOT23 package. Digikey PN: AH337-WGCT-ND http://www.digikey.com/product-detail/en/diodes-incorporated/AH337-WG-7/AH337-WGCT-ND/2122985
D1 & D2 are 5V zeners SOT23 package Digikey PN: BZX84C5V1-FDICT-ND http://www.digikey.com/products/en?keywords=BZX84C5V1-FDICT-ND
R1 is a 1.0K 0805 resistor Digikey PN: P1.0KJCT-ND http://www.digikey.com/product-deta...ic-components/ERJ-2GEJ102X/P1.0KJCT-ND/146897
P1 is a 3.5mm RA socket Digikey PN: CP-3523SJCT-ND http://www.digikey.com/product-detail/en/cui-inc/SJ-3523-SMT-TR/CP-3523SJCT-ND/669704

Neodym magnets are available all over e-Bay. I used a 3/16" diameter, 1/32" thick magnet for the RR. The sensor only responds to one pole (flat side) of the magnet, so you need to manually test it before sticking it to the platter. I used 3/16" glue dots to stick the magnet to the platter (available at any school/office supply house).
 
Last edited:
Hi.
To Packgrog: "intp_flag = intp_flag + 1;" could probably be rewritten as "intp_flag++;",

Thank you for your advice. You can not teach an old dog new tricks. The old way to increment a variable was val = val + 1. Today there are some many ways to do programming that I can not keep with it. Tooooo old. I learn programming by self taught and still learning. Thank you
 
Hi.
To Packgrog: "intp_flag = intp_flag + 1;" could probably be rewritten as "intp_flag++;",

Thank you for your advice. You can not teach an old dog new tricks. The old way to increment a variable was val = val + 1. Today there are some many ways to do programming that I can not keep with it. Tooooo old. I learn programming by self taught and still learning. Thank you

Just for reference: https://en.wikipedia.org/wiki/Increment_and_decrement_operators
 
@Pyramid: Edge case questions...

Does the format of the data sent to the Falcon/Eagle need to be zero-padded (ie: 09.123)? In the event that > 99 is sent (ie: 101.23), how will it react? I can certainly put boundaries in for whether to even send serial data over (ie: between 10.0 and 60.0, but I want to be careful here in case it was not designed to handle glitches in the serial communication.
 
@Pyramid: Edge case questions...

Does the format of the data sent to the Falcon/Eagle need to be zero-padded (ie: 09.123)? In the event that > 99 is sent (ie: 101.23), how will it react? I can certainly put boundaries in for whether to even send serial data over (ie: between 10.0 and 60.0, but I want to be careful here in case it was not designed to handle glitches in the serial communication.

The string has to be 8 characters long; 2 numbers to the left of the decimal point, decimal point, 3 numbers to the right and terminated with [lf] [cr] ([char 10][char 13] in that order).

If the Falcon is in 33 RPM mode, the first digit has to be a 3 or it will be ignored; If 45 RPM mode, first digit has to be a 4. So even if you sent 101.23, _9.123 or 09.123, they would all be ignored. If you output 345.67 in 33 RPM mode, that will generate an erroneous correction and should be avoided (the Falcon assumes the 3rd char is the decimal point and 4th is numeric and it does not trap it if they aren't as the RR would never output that string). The RR limits its output from 27.466 RPM to 99.994 RPM.

Once the Falcon speed is 'synched' (decimal point stops blinking), any speed errors over ±0.025 will be ignored; once the platter speed is synched to 33.333 or 45.000, errors larger than a few thousandths usually indicate a record broom or some other external force is slowing the platter. If we applied correction, when the broom is removed, the speed would shoot through the roof and take a long time to settle back to normal. If we ignore large errors, the speed will return to near normal as soon as the broom is removed.
 
Hi,
I have a question. What about using an stepper motor like I did. The Arduino can sent PWM to drive the stepper motor to keep the Rpm of the platen. It will be easy to built.

Stepper motors have some of the highest cogging of any of the motor types. This is a result of their design which optimizes positioning by moving in discrete steps for each change of phase in the windings; the rotors have a toothed gear that provides maximum attraction to the windings to hold their position when not moving, but this is a source of extreme cogging. They are normally driven by square waves and require special drive components at higher speeds. They can be driven by sinewaves, but I've never done this; not sure of the pros and cons (or limitations) of that drive method. Sota uses a stepper motor on some of their higher end tables, but it is a strange choice; speed control is good, but cogging is terrible.

Not sure why you would want to do this; a 3 phase BLDC motor does a remarkably better job on just about all counts that matter.

The ATMega328 has 6 channels of PWM, so you could use it to generate sinewaves. Looking at the data sheet, it is quite a bit more complicated, just to set up vs the AT89C52RB2 that is used in the SG-4. Doing PWM with a timer and fixed sample rate is problematic as the frequency resolution is poor to begin with and the resolution changes with frequency. The SG-4 does DDS in software and is much better (much higher resolution and fixed with frequency but with a variable sample rate) but it requires extremely efficient code in the timer routine; I'm not sure if you could pull it off in C, but you could try. Assembly language would be a better choice, especially if you are going to vary the amplitude in the digital domain as the SG-4 does. You need to know exactly how many instruction cycles it takes to do the processing in the interrupt service routine, and I'm not sure if you can get that information from the Arduino IDE?

Doing this would not be trivial, it will be a major step up from what I'm seeing in your tachometer code; the SG-4 has ~1500 lines of code and doesn't accept feedback from the tach. The Falcon has over 3000 lines of code, both are done in 8051 assembly.
 
Last edited:
Well, more tweaks, and everything working EXCEPT sending data to the Falcon. I tried the black and red wired in both the RX and TX locations on my adapter, but no joy. The decimal point on the Falcon does not flash. So either something is wrong with the RS232 shield setup, or I misunderstood the settings necessary in the Arduino software. The TX LED on the shield does flash when sending a pulse, but it's not getting to the Falcon. :/

Anyway, here's the latest and greatest, totally functional as a plain tach at least. I renamed it Ostrich in honor of your bird theme. :p
 

Attachments

  • diyaudio_tach_3.txt
    1.9 KB · Views: 178
Hi,
I did replacing a Garrard motor with stepper motor. The stepper was keeping the Rpm right on. Now you need to have a ratio between the platen and the motor drive pulley to maintain the PWM frequency low. In one of the pictures showed the Rpm 33.3333 and there is not stepper whining noise. Now if you increase the frequency high then there is a high pitch whining noise coming from the stepper. I still have the components since dumped the turntable due to a very bad paint. If somebody dare to try it I am willing to let go free. You can install it outside if you use a belt.
 
Well, more tweaks, and everything working EXCEPT sending data to the Falcon. I tried the black and red wired in both the RX and TX locations on my adapter, but no joy. The decimal point on the Falcon does not flash. So either something is wrong with the RS232 shield setup, or I misunderstood the settings necessary in the Arduino software. The TX LED on the shield does flash when sending a pulse, but it's not getting to the Falcon. :/

Anyway, here's the latest and greatest, totally functional as a plain tach at least. I renamed it Ostrich in honor of your bird theme. :p

You have to make sure the string is terminated with [lf][cr] (not [cr][lf]). I wouldn't leave it to the println() function. Append chr(10)+chr(13) to the 6 char rpm reading and send it with the print() function.

dtostrf() converts a double to a string. RPM is a float type. It also returns a pointer to a string, not the string.
 
Last edited: