DC Motor Position Control Using Potentiometer – Arduino Compatible
- Rajkumar Sharma
- 991 Views
- medium
- Tested
- SKU: EL138890
- Quote Now
The project presented here is an Arduino-compatible motor control board. The board consists of an ATMEGA328 microcontroller, LMD18201 H-Bridge, and 2 x potentiometers. This closed-loop servo system provides position control using a feedback potentiometer mounted on the output shaft of the gearbox and provides position control by turning the shaft of the reference potentiometer, the motor-gearbox output shaft follows the reference potentiometer. The project can also be used in other applications that require Arduino-compatible hardware and H-Bridge.
The project requires a special mechanism, where the DC motor’s output shaft is mechanically coupled with the potentiometer shaft using a reduction gear. Approx. reduction ratio 15-50: 1. When the reference pot is turned, the motor shaft follows the position. This will provide a maximum rotation of 270 degrees. Multi-rotation is possible with the help of a multiturn potentiometer.
Arduino Code
Arduino example code is available and the board can be programmed using the CN2 connector, the same connector helps burn the boot-loader to a new ATMEGA328 chip.
Refer to the following link for more info about Arduino programming: https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoToBreadboard
This is a modified code, original author of the code: http://geekeeceebee.com
Arduino Pins vs H-Bridge LMD18201
- Arduino D5 = PWM
- Arduino D6 = Direction
- Arduino D8 = Brake (Not Used -Optional)
- Arduino A0 Reference Potentiometer, A1 Feedback Potentiometer
Features
- Power Supply Motor 12V to 40V (48V Max)
- Motor Load 3A (Peak 6A)
- Logic Supply 5V DC @ 20mA
- On Board Jumper J1 for Brake, Closed for Normal Operations
- On Board Programming Connector for Arduino IDE
- Screw Terminals for Motor and Power Supply
- 2 X 3 Pin Male Header for Feedback and Reference Potentiometers
- Arduino Compatible
- PCB Dimensions 47.63 x 42.55mm
- 4 x 3MM Mounting Holes
Connection & Other Details
- CN1: Optional Do Not Install
- CN2: Programming Connector Pin 1 = Tx, Pin 2 = Rx, Pin 3 = Reset, Pin 4 = GND, Pin 5 = VCC, Pin 6 = D11, Pin 7 = D12, Pin 8 = D13
- CN3: Pin 1 = Motor Power Supply, Pin 2 = GND
- MG1: Pin 1 = Motor 1, Pin 2 = Motor 2
- P1: Reference Potentiometer
- P2: Feedback Potentiometer
- J1: the jumper must be closed to enable the Brake for normal operation.
Schematic
Parts List
NO | QNTY | REF | DESC | MANUFACTURER | SUPPLIER | SUPPLIER PART NO |
---|---|---|---|---|---|---|
1 | 3 | CN1,R3,C7 | DNP | |||
2 | 1 | CN2 | 8 PIN MALE HEADER PITCH 2.54MM | WURTH | 732-5321-ND | |
3 | 1 | CN3 | 2 PIN SCREW TERMINAL PITCH 5.08MM | PHOENIX | 277-1247-ND | |
4 | 1 | C1 | 10uF/10V CERMIC SMD SIZE 0805 | YAGEO/MURATA | ||
5 | 3 | C2,C4,C6 | 100nF/50V CERAMIC SMD SIZE 0805 | YAGEO/MURATA | ||
6 | 2 | C3,C8 | 10nF/50V CERAMIC SMD SIZE 1206 | YAGEO/MURATA | ||
7 | 1 | C5 | 220uF/50V | RUBYCON | 1189-1654-1-ND | |
8 | 2 | C9,C10 | 22PF/50V CERAMIC SMD SIZE 0805 | YAGEO/MURATA | ||
9 | 1 | J1 | 2 PIN MALE HEADER PITCH 2.54MM | WURTH | 732-5315-ND | |
10 | 1 | MG1 | 2 PIN SCREW TERMINAL PITCH 5.08MM | PHOENIX | 277-1247-ND | |
11 | 2 | P1,P2 | 10K POTENTIOMETER | CTS ELECTRO | CT2159-ND | |
12 | 2 | R1,R4 | 10K 5% SMD SIZE 0805 | YAGEO/MURATA | ||
13 | 2 | R2,R5 | 0E SMD SIZE 0805 | YAGEO/MURATA | ||
14 | 1 | R6 | 1M 5% SMD SIZE 0805 | YAGEO/MURATA | ||
15 | 1 | U1 | LMD18201 | TI | LMD18201T/NOPB | |
16 | 1 | U2 | ATMEGA328TQPF-32 | MICROCHIP | ATMEGA328PB-AURCT-ND | |
17 | 1 | X1 | 16Mhz | ECS INC | X1103-ND | |
18 | 1 | JUMP | SHUNT FOR JUMPER J1 | SULLINS CONNECT | S9001-ND |
Connections
Gerber View
Code
//GeeKee CeeBee // ************ DEFINITIONS************ int potPin = A0; // Reference Potentiometer int encoder_pot = A1; // Position Feedback sensor int val = 0; int encoder_val =0; float kp = 0.2; float ki = 0.00000 ; float kd = 2.00; float Theta, Theta_d; int dt; unsigned long t; unsigned long t_prev = 0; int val_prev =0; float e, e_prev = 0, inte, inte_prev = 0; float Vmax = 12; float Vmin = -12; float V = 0.1; const byte PWMPin = 5; const byte DirPin1 = 6; const byte DirPin2 = 8; //***Motor Driver Functions***** void WriteDriverVoltage(float V, float Vmax) { int PWMval = int(255 * abs(V) / Vmax); if (PWMval > 255) { PWMval = 255; } if (V > 0) { digitalWrite(DirPin1, HIGH); digitalWrite(DirPin2, LOW); } else if (V < 0) { digitalWrite(DirPin1, LOW); digitalWrite(DirPin2, HIGH); } else { digitalWrite(DirPin1, LOW); digitalWrite(DirPin2, LOW); } analogWrite(PWMPin, PWMval); } void setup() { Serial.begin(9600); pinMode(DirPin1, OUTPUT); pinMode(DirPin2, OUTPUT); } void loop() { val = analogRead(potPin); // Read V_out from Reference Pot encoder_val =analogRead(encoder_pot); // Read V_out from Feedback Pot t = millis(); dt = (t - t_prev); // Time step Theta = val; // Theta= Actual Angular Position of the Motor Theta_d = encoder_val; // Theta_d= Desired Angular Position of the Motor e = Theta_d - Theta; // Error inte = inte_prev + (dt * (e + e_prev) / 2); // Integration of Error V = kp * e + ki * inte + (kd * (e - e_prev) / dt) ; // Controlling Function if (V > Vmax) { V = Vmax; inte = inte_prev; } if (V < Vmin) { V = Vmin; inte = inte_prev; val_prev= val; } WriteDriverVoltage(V, Vmax); Serial.println(Theta_d); Serial.print(" \t"); Serial.print(Theta); Serial.print(" \t "); t_prev = t; inte_prev = inte; e_prev = e; delay(10); }
Photos
Video