SirSour
Published © GPL3+

Speed controller for power motors, with reverse

This project describes how to make a DIY speed controller for DC motors for Remote Controlled (RC) models, using one power transistor.

IntermediateFull instructions provided6,461
Speed controller for power motors, with reverse

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Resistor 10K
×1
6V Motor (up to 8A or 48W)
×1
MJ11016 Motorola Darlington Power Transistor
×1
G6CU-2117P-US OMRON latching relay
×2
6V Lead acid battery
×1

Story

Read more

Custom parts and enclosures

Configuration diagram

This is the actual connection diagram.

Improved configuration diagram

This is an improved version of the connection diagram with no use of the RC receiver's battery pack but the use of the 6V battery which powers both Arduino and motor.

Schematics

Configuration diagram

This is the actual connection diagram.

Improved configuration diagram

This is an improved version of the connection diagram with no use of the RC receiver's battery pack but the use of the 6V battery which powers both Arduino and motor.

Code

The intermediate code

C/C++
This is the code for Arduino in order to understand the signals from the RC receiver.
/*
  Speed Controller (intermediate code) by G. Souris @2017
 */
int chnthr; //the name of the variable term for throttle channel's input signal

void setup() {
  pinMode(5, INPUT); //pin no. 5 to read the signal from receiver
  Serial.begin(9600);
}

void loop() {
  chnthr = pulseIn(5, HIGH, 25000); //this reads the duration of the reciver's signal in ms
  Serial.println(chnthr);

   delay(1); 
}

The final code

C/C++
This is the code for Arduino which takes the signal from the RC receiver, translates it into digital signal 0-5V, sends it to the power transistor which drives the motor.
The software also opens/closes the two latched relays for the forward/reverse direction of the motor.
/*
  Speed Controller by G. Souris @2017
 */
int chnthr; //the name of the variable term for throttle channel's input signal
int voltmotor; //the name of the variable term for voltage out to the power transistor which drives the motor

void setup() {
  pinMode(5, INPUT); //pin no. 5 to read the signal from receiver
  pinMode(3, OUTPUT); //pin no. 3 to drive the motor
  pinMode(6, OUTPUT); //pin 1 of latched relay coil No. 1 
  pinMode(9, OUTPUT); //pin 8 of latched relay coil No. 1
  pinMode(10, OUTPUT); //pin 1 of latched relay coil No. 2
  pinMode(11, OUTPUT); //pin 8 of latched relay coil No. 2
  analogWrite(6, 0); //pulse to pin 1 of latched relay coil No. 1
  analogWrite(9, 0); //pulse to pin 8 of latched relay coil No. 1
  analogWrite(10, 0); //pulse to pin 1 of latched relay coil No. 2
  analogWrite(11, 0); //pulse to pin 8 of latched relay coil No. 2
}

void loop() {
  chnthr = pulseIn(5, HIGH, 25000); //this reads the duration of the reciver's signal in ms

if(chnthr <1200 and chnthr> 800) //throttle is in forward motion
  {
  analogWrite(6, 250);  delay(30); analogWrite(6, 0); //pulse to open the relay No. 1 for forward motion
  analogWrite(10, 250);  delay(30); analogWrite(10, 0); //pulse to open the relay No. 2 for forward motion
  voltmotor=map(chnthr, 1200, 800, 0, 255); //this scales the receiver's signal from ms to 0-5V
  analogWrite(3,voltmotor);} //sends voltage to the power transistor to drive the motor
  
  else if(chnthr >1300 and chnthr< 1700) //throttle is in reverse motion
  {
  analogWrite(9, 250);  delay(30); analogWrite(9, 0);  //pulse to open the relay No. 1 for reverse motion
  analogWrite(11, 250);  delay(30); analogWrite(11, 0); //pulse to open the relay No. 2 for reverse motion
  voltmotor=map(chnthr, 1300, 1700, 0, 255); //this scales the receiver's signal from ms to 0-5V
  analogWrite(3,voltmotor);} //sends voltage to the power transistor to drive the motor
  
  else  //throttle is idle
  {voltmotor=0;
  analogWrite(3,voltmotor);} //sends no voltage to the power transistor

  delay(1); //Break of 1 ms until the next reading of signal
}

An improved final code

C/C++
Same as the final code but with some improvements in smoothing out signals.
/*
  Speed Controller
 */
int chnthr;
int chnthr1;
int chnthr2;
int chnthr3;
int chnthr4;
int chnthr5;
int voltmotor;
int bypassRLfwd;
int bypassRLbwd;

void setup() {
  pinMode(5, INPUT);
  pinMode(3, OUTPUT);
  pinMode(6, OUTPUT); //latched relay
  pinMode(9, OUTPUT); //latched relay
  pinMode(10, OUTPUT); //latched relay
  pinMode(11, OUTPUT); //latched relay
  analogWrite(6, 0);
  analogWrite(9, 0);
  analogWrite(10, 0);
  analogWrite(11, 0);
  bypassRLfwd=0; bypassRLbwd=0;
  //Serial.begin(9600);
}

void loop() {
  chnthr1 = pulseIn(5, HIGH, 25000);delay(1); 
  chnthr2 = pulseIn(5, HIGH, 25000);delay(1);
  chnthr3 = pulseIn(5, HIGH, 25000);delay(1);
  chnthr4 = pulseIn(5, HIGH, 25000);delay(1);
  chnthr5 = pulseIn(5, HIGH, 25000);
  chnthr=(chnthr1+chnthr2+chnthr3+chnthr4+chnthr5)/5;
  //Serial.println(chnthr);

if(chnthr <1200 and chnthr> 0) {
  if (bypassRLfwd==1) {goto motorfwd;}
  else {  
  analogWrite(6, 250);  delay(30); analogWrite(6, 0);
  analogWrite(10, 250);  delay(30); analogWrite(10, 0);
  bypassRLfwd=1;bypassRLbwd=0;}
  motorfwd:
  if (chnthr>=800) {voltmotor=map(chnthr, 1200, 800, 0, 255);}
  else {voltmotor=255;}
  //Serial.println (voltmotor);
  analogWrite(3,voltmotor);}
  
  else if(chnthr >1300 and chnthr< 2000) {
  if (bypassRLbwd==1) {goto motorbwd;}
  else { 
  analogWrite(9, 250);  delay(30); analogWrite(9, 0);
  analogWrite(11, 250);  delay(30); analogWrite(11, 0);
  bypassRLbwd=1;bypassRLfwd=0;}
  motorbwd:
  if (chnthr<=1700) {voltmotor=map(chnthr, 1300, 1700, 0, 255);}
  else {voltmotor=255;}
  //Serial.println (voltmotor);
  analogWrite(3,voltmotor);}
  
  else
  {voltmotor=0;
  //Serial.println (voltmotor);
  analogWrite(3,voltmotor);}

}

Credits

SirSour
1 project • 2 followers

Comments