Everyone has some old vinyl records in a cellar or in a closet. I'm only 24 years old, and I had never listened one of it before building one. 
I read a lot about this old technology to achieve the right amount of knowledge to build a record Player on my own. It required a lot of time, almost two full weeks of tests during the COVID's lockdown. I used MATLAB to find the best geometry and angles. 

I have adopted the method of least squares to choose the right curve.


From the chart we can see that with the chosen geometry (arm length, cartridge angle and arm position) in the range of (50mm-150mm the vinyl dimension) the angle remains pretty close the 90°. 90 degrees means tangent, our purpose.

The main problems came with right choose of material for the arm and base.

I made a lot of tests and i preferred a carbon fiber arm and a sandwich of wood for the base.

A CNC platform were too expensive for me, so I took a brake's disk of a Nissan.
(9 euro two disks on amazon).
Due to the high moment of inertia they the speed is more constant and stable.

For the first attempt I used a Nema 17 stepper motor, it worked but it was too noisy and there were too many vibrations.
The new version adopted a dc motor with and integrated encoder... I can't give you the model because I found it in a broken Rumba robot.

So there is a closed loop control thanks the encoder and the dvr8833 dc driver.

I tried all the frequencies available for the PWM  for the Arduino Mega and  31 kHz is the best one (not audible).

I'm not full satisfied yet because the Arduino mega offer only 8 bit of PWM resolution.(Arduino due with 12 bit resolution maybe will be my next upgrade).

I tried three different kind of belts:

- A typical 3D printer's belt (GT2) very cheap, it would be perfect without the teeth

- A generic washing machine belt, very rigid but very hard to find it 
 in the right dimensions

- Round belt because I can choose its length and weld with a lighter and because it fits perfectly in the groove of the brake's disk.

At the end of the page you will find the download of the STL files.

I used three kind of bearings:

-608  if you find take without the cover to reduce the friction.

 buy something of good quality like the one for the skateboard...less friction means better sound quality and calibration. you will need two of this kind

-a 35x47 for the base of the tonearm

-a 6207 for the disk.

I repeat again, don't save up for the bearing or you will regret after. 

The tonearm adopt a simple weight anti_skating system, and you can calibrate with more or less bolts.

The counterweight is a small piece of plastic with holes for other bolts.The calibration is allowed due to a M8 bolt.

This is a quick sheet of the break's disk dimensions. It should belong to an old Nissan. Use what you want even with bigger diameter should be better. The only constraints is bout the 50mm of the diameter of the holes.

As base I used a wood sandwich. Three 18mm panel glued each other with a sheet of something that can dump the vibration between the layers.

Below there an image for the dimension I used, but do as you want because I have not a really good aesthetics taste. 



As mentioned in the introduction, I didn't want a complicate interface, so avoided a switch between different speeds (but it could be done very easily) and other strange features...its work it's just to spin the disk.

I used a simple Arduino Mega, or a simple Arduino Uno they have the same performance for this application. Maybe I will upgrade to an Arduino Due just for my perfection phobia and not a real problem. ( Maybe you have a much better listening capability for the small speed fluctuations.)

So you need:

- Arduino Mega, Uno or DUE as you want 

-DC driver with PWM capabilities, I uses a simple dvr8833.

-PSU in the range of (9-17)V depends on your motor. It will power up the motor and the Arduino. You will not need high power, 1A, 2A should be enough, but I recommend a PSU  with Ground that should be connected to the Amplifier Ground port. No ground and you will have  high noise in background. 

-Hall sensor


The encoder and the pwm control insure us that the motor's speed is in the right range. The disk is moved with the friction of the belt and I made that it very low to let the disk spin more interdependently from the motor(less speed variations). This low friction has a problem.. we don't know the exact rotation speed of the disk. Indeed the Hall sensor has this purpose , compensate the asynchronous transmission of the motion.    



const int AIN1 = 2;  //direction
const int AIN2 = 9;  //PWM control
const int STBY = 7;  //power on motor
const int HALL = 53; // Hall sensor
float K=1.0/50.0;   //simple constant for the closed loop control of the disk
float velocity_disk;
float delta_angolo=30; //angle between pulses of the encoder
int Pin = 4;     
int val = 0; 
long int t0;                  //orange=+5v blue=signal marrone=gnd
float count;
float velocity;
long int delta_t;
int pwm_value=180;
float target_velocity=941;                   //  This is the motor speed
float target_velocity_disk=33.33;      //   This is the rotational speed, put 45 if you listen 45 rpm vinyl
int numero_count=18;  //numer of encoder pulse for a better MEAN VELOCITY
long int t_iniziale;

void setup()
  TCCR2B = (TCCR2B & 0b11111000) | 0x01; //31.37255 [kHz]
  pinMode(STBY, OUTPUT);             //set all pins as output
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  digitalWrite(STBY, HIGH);
  pinMode(Pin, INPUT_PULLUP);
  val= digitalRead(Pin);

void loop()

   analogWrite(AIN2, pwm_value);
  if (count==0) {

  if (val!=digitalRead(Pin))
  if (count==numero_count)
   velocity=(60.0/360.0)*(1000.0*double(delta_angolo*count))/delta_t;      //rpm
   if (velocity<target_velocity && pwm_value>0)
    Serial.print(" pwm value:");
   if (velocity>target_velocity )
    Serial.print(" pwm value:");

   float rpm_counter()     // This is the function that computes the disk's speed with the hall sensor 
   float velocity=0;
   int count_hall=0;
   long int t2;
   long int t3;
   long int delta_t_hall;
  if (digitalRead(HALL)==0 && count_hall==0)
if(digitalRead(HALL)==0 && count_hall>0 && (millis()-t2>100))             
  // Serial.print(delta_t_hall);
   if (velocity>1000)
  return velocity;

This is the sketch I used, and as you can see it's very simple. I tried to Use the PID library but with no noticeable improvements maybe with the 12 bit resolution it could worth it.

It's very important to choose the right frequency of the PWM. The default frequency depends on which pin you are using as output but anyway it's in the range of (500-1000) Hz, so full audible. I set 31kHz to be sure to be out of the hearing frequencies.

If you want to add a switch just modify the program for changing the Target_velocity_disk depending on which key is pressed.

If you want to be uploaded some of your projects ...just email me or feel free to write on the integrated forum. 

My email is written at the bottom of the page

for information, advice, questions

write to my email or just write in the chat box

  • Instagram

If you want to be uploaded some of your projects ...just email me or write in the forum and discuss it

© 2023 by Gamma. Proudly created with