Usb controlled rotating display with Arduino Nano and python

Source code https://github.com/intellar/arduino_turntable

 

Low cost turntable (rotating display stand) controlled via usb using Arduino Nano and python
(2022-10)

This project consists in converting a low cost motorized turntable into an ultra low cost programmable turntable controlled with python. The usb link is very simple and can be accessed from linux (ex. raspberry pi) and windows. A quick search on the internet will reveal some very customisable turntable, with usb drivers and api, remote control and other attractive features. However, the cost of the devices makes them much less attractive. Here, we modify a table available for less than 15$, adding a 5$ arduino nano board and some simple electronics to control the motor in the table. Once assembled, the rotation of the table are controlled directly from python, using serial communication over the usb connection of the arduino board.

Hardware
Budget turntable found on amazon ( motorized rotating display stand )
Arduino nano compatible board ( canaduino nano v3 at the time of development )
ULN2003 board ( low cost standard stepper motor controller )


Final result video

The low cost table selected for this project comes with simple control buttons and power from usb. 

Surprisingly, the difficult part of the project is to open the case of the table. The are four clamps under the cover that need to be forced open while pulling the cover up, as shown in the storyboard below. It is important not to damage the clamps since they are needed intact when reassembling the turntable after modification.

With the cover removed, the stepper motor model is exposed, and in this case is based on the 28byj-48 design. It can not be controlled directly by the arduino nano, an interface board is needed to prevent electrical interferences from the motor. The low cost ULN2003  is ideal for this task, easy to find already assembled for less than 2$.  

The low cost ULN2003 is used as interface between the arduino nano and the stepper motor.

The integration of the arduino and uln2003 in the turntable case is straightforward since there is plenty of space. A first set of four pin header was added to the digital pins d2,d3,d4,d5, and a second set of three pin headers was added for the alimentation (only two are required but it was easier to solder when grouped).

The ULN2003 is directly connected to the stepper motor, and to the arduino board. To ensure the added board would not interfere with the table movement, the ULN2003 was kept close to the motor at the bottom of the case, and the arduino was fitted in the battery compartment. The original control board of the turntable must be removed beforehand. 

Once everything is connected, the table can be controlled with a simple arduino program The following video is a quick demontration of the table operating while the case was opened, the speed of rotation is changed while the table turns :

After reassembling the turntable, the hardware part of the project is completed. The table and the arduino are alimented directly by the usb connection so it only need to be connected to a pc, or a usb power supply to work.  Some care was taken to ensure everything would hold in place once the table is reassembled. Two plastic stopper are fixed over the cabling to prevent them from interfering with the rotating clamp of the cover.

The arduino is highly versatile and can be programmed and interfaced with multiple type of devices to control the table. For example, a bluetooth board HC-06 can control the rotation from a cellphone, a movement detector could initiate rotation when hands are near, etc. Your imagination is the limit. 

The bluetooth module HC-06 can be used to interface a cellphone with the table, more precisely with the arduino. A wiser choice is to use the arduino nano 33 BLE from the start, but this module is low cost, making the combination with a basic arduino board less expensive than the integrated solution.

In this project, the objective is to control the table from a python program running on a raspberry pi. So the next part consists in writing a simple arduino program to receive and execute command from the serial interface, and the counterpart program in python to communicate with it. A basic protocol is defined, where a byte array contains the command:

Fn : Forward rotation of n steps
Rn : Reverse rotation of n steps
Dn : Delay between steps in ms, this controls the speed of rotation. 1ms is the fastest.

The code on the arduino side include a function to make a single step with the stepper motor, and a control loop.  The onestep function can be written in much less lines, but this version is easier to visualize. 

Code, arduino initialization and stepper control

int delayms = 5;
int direction = 1;
int nbRemainingSteps = 0;
void setup(){
  pinMode(PIN_D2,OUTPUT);
  pinMode(PIN_D3,OUTPUT);
  pinMode(PIN_D4,OUTPUT);
  pinMode(PIN_D5,OUTPUT);
  Serial.begin(115200);
  Serial.setTimeout(1);
  nbRemainingSteps = 0;
  delayms = 5;
  direction = 1;
}
void write(int a,int b,int c,int d){
  digitalWrite(PIN_D2,a);
  digitalWrite(PIN_D3,b);
  digitalWrite(PIN_D4,c);
  digitalWrite(PIN_D5,d);
}
void onestepFwd(){
  write(1,0,0,0);
  delay(delayms);
  write(1,1,0,0);
  delay(delayms);
  write(0,1,0,0);
  delay(delayms);
  write(0,1,1,0);
  delay(delayms);
  write(0,0,1,0);
  delay(delayms);
  write(0,0,1,1);
  delay(delayms);
  write(0,0,0,1);
  delay(delayms);
  write(1,0,0,1);
  delay(delayms);
}
void onestepRev(){
  write(1,0,0,1);
  delay(delayms);
  write(0,0,0,1);
  delay(delayms);
  write(0,0,1,1);
  delay(delayms);
  write(0,0,1,0);
  delay(delayms);
  write(0,1,1,0);
  delay(delayms);
  write(0,1,0,0);
  delay(delayms);
  write(1,1,0,0);
  delay(delayms);
  write(1,0,0,0);
  delay(delayms);
}

The next part is the control loop running on the arduino. The function listen on the serial port. When a command is received, it parse the string and initiate a rotation or change the speed. It also send back an acknowledge with the interpreted command.

Code, arduino control loop

void loop()
{
  if(nbRemainingSteps > 0)
  {
    if(direction>0)
      onestepFwd();
    else
      onestepRev();
    nbRemainingSteps--;
  }else
  {
    write(0,0,0,0);
    delay(1);
  }
  if(Serial.available()) {
      String data = Serial.readString();
      data.trim();
      char cmd = data[0];
      String arg = data.substring(1,data.length());    
      if(cmd == 'F')
      {
        direction = 1;
        nbRemainingSteps = arg.toInt();
        Serial.print(cmd);
        Serial.print(nbRemainingSteps);
      } 
      if(cmd == 'R')
      {
        direction = -1;
        nbRemainingSteps = arg.toInt();
        Serial.print(cmd);
        Serial.print(nbRemainingSteps);
      }
      if(cmd == 'D')
      {
        delayms = arg.toInt();
        if(delayms<1)
        {
          delayms = 1;
          Serial.print(cmd);
          Serial.print(" invalid delay");
        }else
        {
          Serial.print(cmd);
          Serial.print(delayms);
        }
      }       
    }
}


The python program is simplier than the Arduino program. We use the pyserial library,  which can be installed on python with the command:
pip install pyserial
Once installed, it allows to open a serial port over usb, and communicate with the arduino. This is an example of python loop that accept a user input to control the table:

Code, python example to control the table 

import serial, time
turntable = serial.Serial('COM5', 115200, timeout=.1)
while True:
    cmd = input("Command (F10: forward steps, R10: reverse steps,  D10: delay in ms between steps, 1 to inf ) :")
    turntable.write(bytes(cmd, 'utf-8'))
    time.sleep(0.05)
    data = turntable.readline()
    print("Received:"+str(data))
    time.sleep(0.1)

This completes the project. The table can be controlled from windows, linux, etc, thanks to python. Let us know if this project helped you, or how you used this idea in your projet!  




intellar@intellar.ca