DC motor control in TT

Hello,
I want to play again with DC motors as well on turntable, like the Maxon A-max 26 110189. Long time ago I did joined a group buy for a motor and a current mirror type of speed control, it worked, but also tried to implement Manfred Huber's speed controller. That time I gave up, but now I want to restart.
Do you know if that or similar circuit is available for DIY?
I know some people run the DC motor with only a straight stable voltage, but I would not like to keep adjusting it manually. I'm looking for projects which either put some feedback on the platter or filters on the motor current for commutation and measure that.
What DC motor control would you recommend for best result?
Thanks!
JG
 
Thanks,
I did participated in a group buy for a maxon motor + driver which worked this way, but did not like it. It still needed fine tuning time to time and was sensitive to ... everything. On the other hand, sound was excellent.
I do not mind to put a printed ring to the bottom of the sub platter and a sensor. The systemdek has place enough inside also.
Another way could be to filter on the commutation and measure period between, but that is not easy either.
The robust and easy looks to be the feedback from the platter or sub platter.
JG
 
I developed my own circuit and closed loop control, using a maxon motor. It was a lot of work but a fun project. Negative terminal resistance is good for accurate speed stability since it deals well with varying stylus drag. It also gives the motor more power during startup. Startup is very feeble with a flat voltage supply. You also need closed loop control otherwise speed drift is too high. I got obsessed with making speed as accurate as possible and got to around 0.02%. There is a snag to be aware of. The voltage and current is so low the motors can misbehave and become useless with speed varying badly. I bought 3 motors and one did this and was scrap, so its hit and miss in my experience. Maxon told me they use gold flake coating on brushes in turntable applications. Radikal has this. Unfortunately these motors are not available to buy for general public.

I can share details of my setup later in week if you like (away from home now).
 
  • Like
Reactions: Giordano
Eventually i also came to the conclusion that these types of dc motors are useless for TT design if precise pitch is desired. The sound is interesting and lively because of the constant speed fluctuations. Perhaps a precision servo will cure this, but the negative resistance drive certainly does not.
 
I developed my own circuit and closed loop control, using a maxon motor. It was a lot of work but a fun project. Negative terminal resistance is good for accurate speed stability since it deals well with varying stylus drag. It also gives the motor more power during startup. Startup is very feeble with a flat voltage supply. You also need closed loop control otherwise speed drift is too high. I got obsessed with making speed as accurate as possible and got to around 0.02%. There is a snag to be aware of. The voltage and current is so low the motors can misbehave and become useless with speed varying badly. I bought 3 motors and one did this and was scrap, so its hit and miss in my experience. Maxon told me they use gold flake coating on brushes in turntable applications. Radikal has this. Unfortunately these motors are not available to buy for general public.

I can share details of my setup later in week if you like (away from home now).
Hi, yes, please share details how You implemented. I am very curious.

Thanks
JG
 
I don't like any form of TT drive that requires a feedback loop (with the possible exception of slow adjustment systems like the Roadrunner)
My preference is for a synchronous motor driving the platter where the motor derives it's speed from a xtal generated signal.
My favourite motor is the 3 phase Papst 'Aussenlaufer', but these are getting hard to find in good condition, so an alternative is a 3 phase BLDC.
 
Hi ralphfcooke, than why do you write into this thread? : -) Just joking, I kind of agree. My main line motor is also Philips/Airpax/Premotec what is in the Rega and Systemdek (and several other). I went crazy with the driver for that, I use 2 dds generator and I adjust phase and amplitudes for minimal resonance. I also rewind some to different Voltages and found the 24V version is the optimal for me. With phase and amplitude fine tuning, on the 24V Airpax I can optimize so far that I needed a pickup glued to the motor with a weight on the needle to measure resonances because with the motor in my hands I could not feel any more.
BUT, I've heard so much good about DC motors (and I've used to have a Maxon 110189 with the current mirror kind of control, I gave it to a friend) that I feel I have to try again 🙂
I'm hunting for a 110189 also, but building control in the same time.
I also agree, the control has to have 2 phase. First to spin up and stabilize, than switch to a very slow control loop. That is what I want to play with.
 
Here is a snip of the circuit I have. Its controlled by Arduino and I have a PCB stacked onto a MEGA board. To explan some details J4 is DC in. J1 is connection to the motor. R1/R4 is set to match the terminal resistance of the motor. U8 is for Hall sensor. P3 is a momentary action switch. Im using U9 for LCD display and P1/P2 for LEDs for speed warnings. Voltage is controlled by a voltage DAC where im using both channels output A for course adjustment and B for fine adjustment. There is more than enough resolution to control speep very accurately.
Screenshot 2024-11-10 073920.png
 
And the Arduino program is copied here...



// This sketch for Arduino provides closed loop dc motor control for
// powering a hifi turntable.
//v7 adds long button press for 45rpm
//v8 develops MCP4822 with MEGA
//v9 shorter ISR
//v11 Optimised for Linn Radikal 1 motor
//v13 Adjust speed every 2 revs on instantaneuous speed

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include <MCP48xx.h>

MCP4822 dac(10);
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display

volatile int revolutions; // counter for Hall sensor
int buttonPushCounter; // counter for the number of button presses
float platterRPM;
float platterAverageRPM;
float speedError;
float motorVoltsCourse;
float motorVoltsFine;
float platterSetspeed;
float hours_run;
unsigned long start_run;
unsigned long timeold = 0;
unsigned long timenew;
unsigned long avtimeold;
unsigned long button_time;
unsigned long last_button_time;
unsigned long buttonStart;
unsigned long buttonStop;
const byte interruptPin = 3;
boolean hasRun = false;
boolean hasRun2 = false;
int buttonState = 0; // current state of the button
int lastbuttonState = 0; // previous state of the button

void setup()
{
Serial.begin(9600);
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
pinMode(5, OUTPUT); //for red LED
digitalWrite(5, HIGH);
pinMode(6, OUTPUT); //for green LED
//pinMode(7, OUTPUT);
pinMode(2, INPUT);
lcd.init();
lcd.backlight();
revolutions = 0;
buttonPushCounter = 0;
timeold = 0;

dac.init();
// The channels are turned off at startup so we need to turn the channel we need on
dac.turnOnChannelA();
dac.turnOnChannelB();
// Configure the channels in High gain
dac.setGainA(MCP4822::High);
dac.setGainB(MCP4822::High);

attachInterrupt(digitalPinToInterrupt(interruptPin), rpm1, FALLING);
}

void loop()
{
buttonState = digitalRead(2); //section measures switch state and time held down
if (buttonState == HIGH && lastbuttonState == LOW) {
buttonStart = millis(); }
if (buttonState == LOW && lastbuttonState == HIGH) {
buttonStop = millis();
button_time = buttonStop - buttonStart;
if (button_time < 1000) { //need to set run to 33rpm
platterSetspeed = 33.3333; //33.3333
motorVoltsCourse = 1806; //set this to give 33rpm
}
else if (button_time >= 1000) { //one second press to set run to 45rpm
platterSetspeed = 45.0; //45.000
motorVoltsCourse = 2502; //set this to give 45rpm
}
}
if (buttonState == LOW && lastbuttonState == HIGH && button_time > 100) { //bebounces switch
buttonPushCounter++;
// start_run = millis();
revolutions = 0;
}

lastbuttonState = buttonState;

if (buttonPushCounter == 0) {
motorVoltsCourse = 0;
motorVoltsFine = 0;
digitalWrite(5, LOW);
digitalWrite(6, LOW);
if (hasRun2 == false) {
DAC();
}
}

//else
if (buttonPushCounter == 1) {

if (revolutions <= 8 ) {
motorVoltsFine = 3500;
DAC();
}

if (hasRun == false) {
platterRPM = 60000000.0 / (timenew - timeold) ;
if ((revolutions % 3) == 0) {
platterAverageRPM = 180000000.0 / (timenew - avtimeold) ;
avtimeold = timenew;
}
if (revolutions >= 9 && revolutions <= 29 && revolutions % 2 == 0) {
speedError = platterSetspeed - platterRPM;
motorVoltsFine = 3600;
motorVoltsCourse += speedError * 50;
motorVoltsCourse = constrain(motorVoltsCourse, 1, 4000);
DAC();
}
if (revolutions >= 9) {
if (speedError > 0.1 || speedError < -0.1){
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
}
else if (speedError < 0.05 || speedError > -0.05){
digitalWrite(5, LOW);
digitalWrite(6, HIGH);
}
}

if (revolutions >= 30 && revolutions % 4 == 0) {
speedError = platterSetspeed - platterAverageRPM;
speedError = constrain(speedError, -0.1, 0.1);
motorVoltsFine += speedError * 2500; //5000 was a bit unstable
DAC();
if (motorVoltsFine > 3800 || motorVoltsFine < 3400) { //set range to not trip when cartridge dropped
noInterrupts();
revolutions = 8;
interrupts();
lcd.clear();
}
}
Serial.print(platterRPM, 4);
Serial.print(", ");
Serial.print(platterAverageRPM, 4);
Serial.print(", ");
Serial.print(motorVoltsFine);
Serial.print(", ");
Serial.print(motorVoltsCourse);
Serial.print(", ");
Serial.print(revolutions);
Serial.print(", ");
Serial.println();
hasRun = true;
}
}
else if (buttonPushCounter >= 2) {
buttonPushCounter = 0;
lcd.clear();
hasRun2 = false;
}


lcd.setCursor(0,0);
lcd.print(platterRPM,3);
lcd.setCursor(0,1);
lcd.print(platterAverageRPM,3);
lcd.setCursor(7,0);
lcd.print(revolutions);
lcd.setCursor(7,1);
lcd.print(buttonPushCounter);
lcd.setCursor(12,0);
lcd.print(motorVoltsCourse);
lcd.setCursor(12,1);
lcd.print(motorVoltsFine);
}

void rpm1() {
timeold = timenew;
timenew = micros();
revolutions++;
hasRun = false;
}

void DAC() {
dac.setVoltageA(motorVoltsCourse);
dac.setVoltageB(motorVoltsFine);
dac.updateDAC();
hasRun2 = true;
}
 
Last edited:
Thanks! What hall sensor you use and what you sense?
So far I was using a simple printed ring and glued on the bottom of the platter, but the hall sensor sounds good. May be more reliable. Do you put it on the platter or motor pulley?
Another interesting idea I saw before, using a normal 1/4 magnetic tape with a single tone recorded and a tape head to sense it.

JG
 
I put the hall sensor on the plinth and a single small magnet on the platter. I used a A3144. The mag tape option sounds interesting. I did find sensing once per rev works fine. Adding any more is problematic since they need to be accurately positioned relative to each other. I suppose adding several magnets could work by spacing them intentionally unevenly and then using the program to figure out which sensor its looking for next.
 
Hello deano1712,
very nice work.

Two questions about it:
1. Is the alignment of the two diodes (D1, D2) correct?
2. Is the thermal compensation via the resistors (R1, R4) necessary at all?
You are measuring the speed of the disk directly. All errors are compensated for there.
And the thermal changes take place very slowly.

Greetings
Thomas
 
Thomas
Yes sorry looks like the diodes go the other way. R1/R4 are not for thermal compensation it's for load compensation. It's possible to set it up to achieve a constant speed with variable load. This is useful to improving speed accuracy when stylus drag varies (which it does). However I believe the main benefit is during startup. Om my LP12 it gets up to speed within 8 revolutions. This is fast enough to be OK by the time you can move the tonearm and lower it. There is no need to wait. If the motor is supplied by an uncompensated voltage motor starts much more slowly and it's a matter of waiting or giving the platter a helping hand to get it going.

Regards
Mark
 
I put the hall sensor on the plinth and a single small magnet on the platter. I used a A3144. The mag tape option sounds interesting. I did find sensing once per rev works fine. Adding any more is problematic since they need to be accurately positioned relative to each other. I suppose adding several magnets could work by spacing them intentionally unevenly and then using the program to figure out which sensor its looking for next.
I suspect you should use optical sensing if you want more counts per revolution, moving lots of magnets near a cartridge could create pick up in the audio band... I worry that a single magnet per revolution will lead to step-wise changes in speed that could be audible. Traditional PID control wants as little latency as possible for good performance.
 
  • Like
Reactions: Giordano
The platter responds quite slowly to speed corrections so if you try adjust more than once per rev I expect it could be unstable. I have found measuring every rev and making adjustments every one or two revs works well. THe speed trace below is my setup with the drive circuit shown which seems more than accurate enough for a turntable drive.
Screenshot 2024-11-23 064927.png
 
One means of increasingthe feedback loop accuracy is to attach an optical encoder onto the motor. Such an arrangement with a 500 PPR encoder provides several thousand readings per platter revolution. The large platter inertia will require that the electronics loop be filtered down to a significantly lower frequency. However, the error signal will still be proportioonal to the RPM error, I designed and built such a circuit as a replacement for a Papst motor. Space considerations forced me to mount the encoder directly on the motor chassis. However, Maxon does make motor/encoder combinations that would save you a lot of mechanical design and machining effort. I'm including a block diagram of the circuit as an attachment.

Jeff
 

Attachments

  • Optical_Encoder_Motor_Controller.JPG
    Optical_Encoder_Motor_Controller.JPG
    50.8 KB · Views: 72
I have to smile when I see that a basically very simple analog control loop has evolved into something into an Arduino system. If that is 50 years of progress...

Back in 1980 when I was a student I built my own turntable lacking the funds of buying the Philips 212 which I actually desired.

This circuit was published in the Dutch magazine Radio Bulletin in March 1976. The first part is the optical speed sensor and the V/F converter with its output at R7. The next part is the motor controller. The input of the controller R8 has to be connected to R7.

C3/R6 determine the V/F conversion constant. The circuit was designed for a DC motor at ca. 2800 rpm and 4 pulses/rev. V4 is the actual comparator, R9 sets the speed.

According to the article C5 was needed to get the control loop stable. The V/F has a (fairly large) time constant. A time constant in the feedback loop is a problem for stability. Hence C5 was added to compensate. I assume a heavy platter or a time constant in the motor control circuit which is large in comparison with the V/F also helps in stability.

If I had to redesign the circuit today I would do a proper control engineering analysis. However I knew this after I graduated in 1983. And in 1984 when I still believed in progress I purchased a CD player.

The light bulb / LDR can be replaced by a modern optical sensor, it does not have to be slow.

The DC motor driving circuit has to be adapted for the motor requirements and modern transistors. Although real audiophiles might advocate the use of the Germanium power transistors for better audio quality.

1732367152147.png


1732367269828.png


The complete edition of this magazine can be downloaded here: https://drive.google.com/file/d/1VkrB77BC2-MSPZvcAyNXbNBbVoF0t50e/view?usp=sharing But it might be of limited use because it is in Dutch. And it is a scanned so hard to copy & translate.

Since I object against posting links in this forum to sites where you have to register first, I attach the article. Although I am aware of the limited use due the language barrier.
 

Attachments

Last edited:
Hello,
I want to develop a (for me) new motor drive, with dc motor. For first, I want to make it work with DC motor, with PID startup and slow I maintaining.
Next, I will make it work with Papst async motors with controlling the frequency of the 3 phase drive.

Back to DC drive for now, at the moment I use no feedback, only manually control what the motor gets (yes, the speed is measured and on the oled, but it is not used yet in the routine). I would have 2 questions to those who use DC motor drive with the simple stabilized Voltage/Current source with no feedback (where the speed is adjusted with a multi turn trimmer).

1, when I find the Current/Voltage to maintain 33.33 RPM, if I stop the platter, it takes about 30s to reach 33 rpm again. Is that normal?

2, If I leave it turning for a day, it is drifting about 0,3-1 rpm away from 33,33. Is that normal? How do you handle that? You keep adjusting it?(The 0.5rpm drift is measureable with the strobo also, it is a very, very slow move of the bars.

1738412783910.png
Thanks!JG