Controlling a 12v 80 watt dc motor with an Arduino

Status
Not open for further replies.
On the serial monitor it showing the potentiometer and the battery..
the pump motor is spinning in the clockwise rotation which is the way
I want it and the motor speed is good but the cooling fan is not moving ..

Question Im not sure yet but in the code is it setup to turn the pump motor on and off depending on the battery voltage
If it is what lines are they... Thanks for all the help...
 
Last edited:
H-BOARD IRF3205 DUAL MOTOR DRIVER 10A
GND. arduino GND
PWM2. arduino 5V
DIR2. arduino GND
PWM1 arduino. PWM 3
DIR1. arduino. PWM 5

5V arduino 5V

Power + BATTERY
Moter 2 + FAN
Moter 2 - FAN
Moter 1 - PUMP
Moter 1 + PUMP
GND - BATTERY

I mentioned previously in a few post that the Motor Direction pins need to be tied to either +5 Volts or Ground. You are only looking for single direction rotation. See what works for the correct direction and tie those pins accordingly.

Question Im not sure yet but in the code is it setup to turn the pump motor on and off depending on the battery voltage
No, Much earlier I posted a full code sample to do that using Hysteresis. That code sample will need modified since I wrongly assumed the motor driver board had an enable pin. This can likely be done with an IF statement so IF the battery voltage drops below a preset level the PWM out to the motor board goes to 0. Post #90 had complete code including monitoring the battery. I explained how that code sample works and there are remarks in the code.

There are several ways to go about this. Matter of fact since you are running a fan and a pump which will only be running in a single direction I don't know why you are using an H Bridge motor controller designed to switch motor polarity. This all could have been done using two simple MOSFETs.

Somewhere back there I also mentioned how you will need to tweak the code for the pump speed where we use the map function for your sensor (pot) input. The pot will yield a number between 0 and 1023 which we map to 0 to 255 for the PWM out. What is happening is on the 0 to 255 (0 to 100% PWM) when your PWM pulse width drops below a certain number the pump stops. Therefore that code will need changed to suit your pump motor. Just as an example 0, 1023, 50, 255 where the PWM never goes below 50.You need to find what works for you.



Ron
 
Last edited:
The reason i got the H-BOARD IRF3205 DUAL MOTOR DRIVER 10A
is becouse in post #2 user dr pepper told me to get it

Instead of a relay you can use a H bridge controller, then theres no mechanicl contacts to wear out, and you could control the speed using the arduino's Pwm.

Dual Motor Driver Module H-bridge DC MOSFET IRF3205 10/15A 3-36V 30A L9110S UK | eBay
L9110S Stepper Motor Driver. This allows the trolley can quickly start can quickly kill the car. The drive uses the full two half-bridge driver chip low resistance N-channel MOSFET components. Improve power utilization.
www.ebay.co.uk
A car batt is pretty much flat at 12.3v or so, 11v would be a absolute minimum.
 
Quick question can all members read these thread posts the reason why is because im getting help by many people but it seams to me like they ether dont look at other posts or they can't see them
 
Quick question can all members read these thread posts the reason why is because im getting help by many people but it seams to me like they ether dont look at other posts or they can't see them
The thread is open to anyone to read and reply to. Unfortunately with a thread like this, having so many post, most people do not read through all of the post so do not have a full handle on what is going on. Another problem is with a project like this there are several ways to go about it with the hardware and even several ways to write the code.

What happened in this thread was when the first post you did came out none of us knew as much as we know now.
So we knew it was a motor but weren't aware it would only need to run in a single direction. The use of an H-Bridge is common when we have a bi-directional motor. In your case later it was known it was just a uni-directional pump and then the fan figured into things. This is why it is good to know as much as possible before getting into helping someone with a project. This forum has no shortage of very knowledgeable people and the more that is known the better a project can be addressed.

Anyway, your project will work out, once you have the two resistors we will see how well your divider works. Even if it is not a perfect 3:1 divider the error can be solved in the code.

Ron
 
I have the two resistors in place now and have hooked up everything this is how its wired up ..
Reloadron Said in post #90
// The Arduino Uno pin 12 is used to enable or disable the motor.
Im not sure how or what to connect to this pin..
Under my list ill add the codes from both
Reloadron and dr pepper I have combine both codes does it look right?
Or is there some stuff in there thats not needed?

Arduino-UNO
PWM 5. H-BOARD PWM 1
PWM 3. H-BOARD. DIR 1

ANALOG IN
A0. potentiometer . PIN 2
A1. RESISTORS
5V. potentiometer PIN 3
5V H-BOARD
GND. potentiometer PIN 1
GND. H-BOARD.

H-BOARD IRF3205 DUAL MOTOR DRIVER 10A
GND. arduino GND
PWM2. arduino 5V
DIR2. arduino GND
PWM1 arduino. PWM 3
DIR1. arduino. PWM 5
5V arduino 5V
Power + BATTERY+
Moter 2 + FAN
Moter 2 - FAN
Moter 1 - PUMP
Moter 1 + PUMP
GND - BATTERY-


Code:
#define analogInPin A0
#define PWM1 3#define analogInPin A0
#define PWM1 3
#define DIR1 5
#define BATTERY A1

uint16_t sensorValue,outputValue,percentValue;
uint32_t batteryVoltage;    //32 bit to prevent overflow
uint32_t tick=0;

void setup() {
  Serial.begin(115200);
  Serial.println("\n\n\n\nHello");
  pinMode(PWM1,OUTPUT);       //set the PWM pin to output
  pinMode(analogInPin,INPUT); //set the potentiometer pin to input
  pinMode(BATTERY,INPUT);     //set the battery pin to input
  pinMode(DIR1,OUTPUT);       //set the dir pin to output
  digitalWrite(DIR1,HIGH);    //set it high - change HIGH to LOW if motor goes wrong way
}

void loop(){
  // Read the PWM value of the input potentiometer.
  sensorValue = analogRead(analogInPin);
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // map pump speed percent of full scale
  percentValue = map (outputValue, 0, 255, 0, 100);
  // change the analog out value:
  analogWrite(PWM1, outputValue);
  batteryVoltage=analogRead(BATTERY);
  if((millis()-tick)>100){    //display 10 times per second
    tick=millis();
    Serial.print("Potentiometer Value = ");
    Serial.println(sensorValue,DEC);
    //convert battery reading to voltage (in milliVolts)
    batteryVoltage*=15000;  //*5000*3
    batteryVoltage/=1024;
    Serial.print("Battery Voltage = ");
    Serial.println(batteryVoltage,DEC);
  }
}
// InputHysteresis.ino Turn a motor On and Off based on Battery Voltage.
// We want the motor to run only when the battery voltage exceeds a preset level.
// We also want a potentiometer to be able to set the motor speed when the motor is enabled.
// Define the baud rate for the serial port.
#define BAUD_RATE 9600

// This assumes A0 for Battery Voltage input and A1 for Motor Speed input.
// Battery Voltage allows a digital out for the motor to run or not run.
// Motor Speed controls a PWM output siganl to the motor.
#define INPUT1_PIN A0
#define INPUT2_PIN A1

// PWM Constants
const int analogInPin = A1;  // Analog input pin that the potentiometer is attached to
const int pwmOutPin = 5; // Analog output pin that the LED is attached to

// The Arduino Uno built in LED is used for test purposes pin 13.
// The Arduino Uno pin 12 is used to enable or disable the motor.
#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
/****************************************************************/
// Global variables.
// The state of the motor enable output pin can be captured with only two values, High or Low Battery Voltage.
// Battery Voltage is represented by a single bit.
// The following statement defines two symbolic values, one for each possible state.
enum state_t { IS_LOW, IS_HIGH };

// Declare the state variable as a symbolic value.
enum state_t state = IS_LOW;

// The hysteretic response is defined by using two thresholds.
const int high_threshold = 881;
const int low_threshold  = 819;
// The PWM Functions
int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)
int percentValue = 0;       // pump speed percent full scale

// Standard Arduino initialization function to configure the system.
void setup()
{
  // initialize the Serial port
  Serial.begin( BAUD_RATE );

  // configure our trivial I/O
  pinMode( LED_BUILTIN, OUTPUT );
  pinMode( 12, OUTPUT);

  // the LED and pin 12 start out High to match the initial state.
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(12, HIGH);
}

/****************************************************************/
// Standard Arduino polling function.

void loop()
{
  // Read the PWM value of the input potentiometer.
  sensorValue = analogRead(analogInPin);
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // map pump speed percent of full scale
  percentValue = map (outputValue, 0, 255, 0, 100);
  // change the analog out value:
  analogWrite(pwmOutPin, outputValue);
  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(sensorValue);
  Serial.print("\t Speed Output = ");
  Serial.print(outputValue);
  Serial.print("\t Motor Speed Percentage = ");
  Serial.println(percentValue);

  // wait 500 milliseconds before the next loop for the analog-to-digital
  // converter to settle after the last reading:
  delay(500); // Allow 0.5 Second and continue

  // Read the Battery Voltage level.
  int input1 = analogRead(INPUT1_PIN);
  float battVolt = (input1 * 5.0) / 1023 * 3;
      Serial.print ("\t Battery Voltage is  ");
      Serial.print (battVolt);
      Serial.println ("  Volts");
delay(1000);
    
  if (state == IS_HIGH) {
    if (input1 < low_threshold) {
      Serial.print("Low observed at input level ");
      Serial.println(input1);
      Serial.println("Transitioning to the IS_LOW state.");
    
      state = IS_LOW;
      digitalWrite(LED_BUILTIN, LOW);
      digitalWrite(12, LOW);
    }

  } else { // state must be IS_LOW
    if (input1 > high_threshold) {
      Serial.print("High observed at input level ");
      Serial.println(input1);
      Serial.println("Transitioning to the IS_HIGH state.");
    
      state = IS_HIGH;
      digitalWrite(LED_BUILTIN, HIGH);
      digitalWrite(12, HIGH);
    }
  }
}

/****************************************************************/



#define DIR1 5
#define BATTERY A1

uint16_t sensorValue,outputValue,percentValue;
uint32_t batteryVoltage;    //32 bit to prevent overflow
uint32_t tick=0;

void setup() {
  Serial.begin(115200);
  Serial.println("\n\n\n\nHello");
  pinMode(PWM1,OUTPUT);       //set the PWM pin to output
  pinMode(analogInPin,INPUT); //set the potentiometer pin to input
  pinMode(BATTERY,INPUT);     //set the battery pin to input
  pinMode(DIR1,OUTPUT);       //set the dir pin to output
  digitalWrite(DIR1,HIGH);    //set it high - change HIGH to LOW if motor goes wrong way
}

void loop(){
  // Read the PWM value of the input potentiometer.
  sensorValue = analogRead(analogInPin);
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // map pump speed percent of full scale
  percentValue = map (outputValue, 0, 255, 0, 100);
  // change the analog out value:
  analogWrite(PWM1, outputValue);
  batteryVoltage=analogRead(BATTERY);
  if((millis()-tick)>100){    //display 10 times per second
    tick=millis();
    Serial.print("Potentiometer Value = ");
    Serial.println(sensorValue,DEC);
    //convert battery reading to voltage (in milliVolts)
    batteryVoltage*=15000;  //*5000*3
    batteryVoltage/=1024;
    Serial.print("Battery Voltage = ");
    Serial.println(batteryVoltage,DEC);
  }
}
// InputHysteresis.ino Turn a motor On and Off based on Battery Voltage.
// We want the motor to run only when the battery voltage exceeds a preset level.
// We also want a potentiometer to be able to set the motor speed when the motor is enabled.
// Define the baud rate for the serial port.
#define BAUD_RATE 9600

// This assumes A0 for Battery Voltage input and A1 for Motor Speed input.
// Battery Voltage allows a digital out for the motor to run or not run.
// Motor Speed controls a PWM output siganl to the motor.
#define INPUT1_PIN A0
#define INPUT2_PIN A1

// PWM Constants
const int analogInPin = A1;  // Analog input pin that the potentiometer is attached to
const int pwmOutPin = 5; // Analog output pin that the LED is attached to

// The Arduino Uno built in LED is used for test purposes pin 13.
// The Arduino Uno pin 12 is used to enable or disable the motor.
#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
/****************************************************************/
// Global variables.
// The state of the motor enable output pin can be captured with only two values, High or Low Battery Voltage.
// Battery Voltage is represented by a single bit.
// The following statement defines two symbolic values, one for each possible state.
enum state_t { IS_LOW, IS_HIGH };

// Declare the state variable as a symbolic value.
enum state_t state = IS_LOW;

// The hysteretic response is defined by using two thresholds.
const int high_threshold = 881;
const int low_threshold  = 819;
// The PWM Functions
int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)
int percentValue = 0;       // pump speed percent full scale

// Standard Arduino initialization function to configure the system.
void setup()
{
  // initialize the Serial port
  Serial.begin( BAUD_RATE );

  // configure our trivial I/O
  pinMode( LED_BUILTIN, OUTPUT );
  pinMode( 12, OUTPUT);

  // the LED and pin 12 start out High to match the initial state.
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(12, HIGH);
}

/****************************************************************/
// Standard Arduino polling function.

void loop()
{
  // Read the PWM value of the input potentiometer.
  sensorValue = analogRead(analogInPin);
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // map pump speed percent of full scale
  percentValue = map (outputValue, 0, 255, 0, 100);
  // change the analog out value:
  analogWrite(pwmOutPin, outputValue);
  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(sensorValue);
  Serial.print("\t Speed Output = ");
  Serial.print(outputValue);
  Serial.print("\t Motor Speed Percentage = ");
  Serial.println(percentValue);

  // wait 500 milliseconds before the next loop for the analog-to-digital
  // converter to settle after the last reading:
  delay(500); // Allow 0.5 Second and continue

  // Read the Battery Voltage level.
  int input1 = analogRead(INPUT1_PIN);
  float battVolt = (input1 * 5.0) / 1023 * 3;
      Serial.print ("\t Battery Voltage is  ");
      Serial.print (battVolt);
      Serial.println ("  Volts");
delay(1000);
    
  if (state == IS_HIGH) {
    if (input1 < low_threshold) {
      Serial.print("Low observed at input level ");
      Serial.println(input1);
      Serial.println("Transitioning to the IS_LOW state.");
    
      state = IS_LOW;
      digitalWrite(LED_BUILTIN, LOW);
      digitalWrite(12, LOW);
    }

  } else { // state must be IS_LOW
    if (input1 > high_threshold) {
      Serial.print("High observed at input level ");
      Serial.println(input1);
      Serial.println("Transitioning to the IS_HIGH state.");
    
      state = IS_HIGH;
      digitalWrite(LED_BUILTIN, HIGH);
      digitalWrite(12, HIGH);
    }
  }
}

/****************************************************************/
 
You can't just lump bits of code together and expect them to work. The code needs to make sense to the computer.

So, in the order they appear,
The defines
Code:
#define analogInPin A0
#define PWM1 3
#define DIR1 5
#define BATTERY A1
These are just for convenience so we don't have to remember what's connected to what pin. Whenever we write PWM1 it will be replaced with 3 - we could have just remembered 3 but PWM1 gives us a clue what it might be. We should add PWM2 and DIR2 to these but we need to connect them to pins first. There are many thoughts on how code should be written - I prefer constants (like pin numbers) to be UPPERCASE - others do it there own way.

Then comes the variables,
Code:
uint16_t sensorValue,outputValue,percentValue;
uint32_t batteryVoltage;    //32 bit to prevent overflow
uint32_t tick=0;
uint16_t just means it's a variable that's an unsigned integer with 16 bits (guess what uint32_t means). Note the text "//32 bit to prevent overflow" - anything that starts with // is a comment and is just for humans to read and is ignored by the compiler/computer.

Then comes the setup code,
Code:
void setup() {
  Serial.begin(115200);
  Serial.println("\n\n\n\nHello");
  pinMode(PWM1,OUTPUT);       //set the PWM pin to output
  pinMode(analogInPin,INPUT); //set the potentiometer pin to input
  pinMode(BATTERY,INPUT);     //set the battery pin to input
  pinMode(DIR1,OUTPUT);       //set the dir pin to output
  digitalWrite(DIR1,HIGH);    //set it high - change HIGH to LOW if motor goes wrong way
}
This is where we initialize things - Start the serial port so we can print on the Serial monitor.
Then set the various pins to input or output as needed.
We also set the DIR1 pin to 5V with the last line.

Next is the main code,
Code:
void loop(){
  sensorValue = analogRead(analogInPin);              // Read the PWM value of the input potentiometer.
  outputValue = map(sensorValue, 0, 1023, 0, 255);    // map it to the range of the analog out:
  percentValue = map (outputValue, 0, 255, 0, 100);   // map pump speed percent of full scale
  analogWrite(PWM1, outputValue);                     // change the analog out value:
  batteryVoltage=analogRead(BATTERY);
  if((millis()-tick)>100){    //display 10 times per second
    tick=millis();
    Serial.print("Potentiometer Value = ");
    Serial.println(sensorValue,DEC);
    //convert battery reading to voltage
    batteryVoltage*=15000;  //*5000*3
    batteryVoltage/=1024;
    Serial.print("Battery Voltage = ");
    Serial.println(batteryVoltage,DEC);
  }
}
This is run many times per second and is the main code. Note the indenting - this shows where a "block" of code begins/ends. A block that's more than 1 line starts with a curly brace { and ends with a closing brace}. So tha opening brace on the line void loop(){ is matched to the one at the very end. The closing brace above the end one matches to the one on the line if((millis()-tick)>100){.

Switching it around a bit we can start deciding things dependant on the battery voltage.

Here is a simplified version including hysteresis'
Code:
#define analogInPin A0
#define PWM1 3
#define DIR1 5
#define BATTERY A1

uint16_t sensorValue,outputValue;
uint32_t batteryVoltage;    //32 bit to prevent overflow
uint32_t tick=0;
boolean motorRun;

void setup() {
  Serial.begin(115200);
  Serial.println("\n\n\n\nHello");
  pinMode(PWM1,OUTPUT);       //set the PWM pin to output
  pinMode(analogInPin,INPUT); //set the potentiometer pin to input
  pinMode(BATTERY,INPUT);     //set the battery pin to input
  pinMode(DIR1,OUTPUT);       //set the dir pin to output
  digitalWrite(DIR1,HIGH);    //set it high - change HIGH to LOW if motor goes wrong way
  motorRun=false;
}

void loop(){
  batteryVoltage=analogRead(BATTERY);         //convert battery reading to voltage
  batteryVoltage*=15000;  //*5000*3  
  batteryVoltage/=1024;
  sensorValue = analogRead(analogInPin);      // Read the PWM value of the input potentiometer. 0 to 1023
  outputValue = sensorValue/4;                // convert 0-1023 to 0-255
  if(motorRun==true){
    if(batteryVoltage<=11900)       //this is the cutoff voltage in mV
      motorRun=false;
  }else{
    if(batteryVoltage>12250)        //this is the restart voltage in mV
      motorRun=true;
  }
  if(motorRun==true)
    analogWrite(PWM1, outputValue);                     // change the analog out value:
  else
    analogWrite(PWM1,0);
  if((millis()-tick)>100){    //display 10 times per second
    tick=millis();
    Serial.print("Potentiometer Value = ");
    Serial.println(sensorValue,DEC);
    Serial.print("Battery Voltage = ");
    Serial.println(batteryVoltage,DEC);
    if(motorRun)
      Serial.println("The motor is running.");
     else
      Serial.println("The motor is stopped.");
  }
}

If you attach DIR2 and PWM2 to Arduino pins we can get the fan working too.

HTH,

Mike.
Edit, in the above code the motor is set to turn off when the battery drops below 11900 mV (11.9V) and switch back on at 12250mV(12.25V).
 
Code isnt my best thing so I try not to get too involved here.
While a H bridge can reverse a motor its still a acceptable means of controlling the speed of a motor.
 
As the OP is a complete beginner I tried to make the code as simple as possible. Hopefully, they'll be able to start to follow what it does.

Mike.
 
As the OP is a complete beginner I tried to make the code as simple as possible. Hopefully, they'll be able to start to follow what it does.

Mike.
Well you gave it a nice flow making it easy to follow with good remarks explaining what is going on. That's important since the OP is merely doing a copy and paste. Pretty cool!

Ron
 
When it comes to novices then I find keeping it as simple as possible is the best way. When they know more then we can write "better" code. Personally, I hate having constants in the code (I.E. the mV values) but if it help novices follow it then so be it.

Mike.
 
Thanks guys.
So If I attach DIR2 from the H-board to PWM2 on the Arduino I can get the fan working too.
DIR2 is connected to ground so I connect PWM2 to ground as well?
I just don't want to burn out anything...

After I attach these it should work with Pommie code in post #168 ..
 
Last edited:
Thanks for all the help it works great now my daughters pool pump is completely off grid its been cutting on and off all day and now i don't have to worry so much about it damaging the batteries.. the solar panels charge the batteries then it cuts on and when the battery gets low it cuts off so it can be recharged for the next time
 
This is not an overt attack, just an observation of this thread as compared to numerous others, which eventually seem to play out the same way.....

There appears to be an excessively-large amount of secrecy when an initial thread is started. Why that is, I have no idea, but details often tend to be pretty scant and helpers almost have to pry information from the close-to-death clutches of those seeking help, lest they take the relevant information to the grave.

It is only when a satisfactory solution is achieved, that the full extent of the initial proposal/requirements become apparent.
If there had been FULL disclosure at the outset, many threads would likely not have to stretch to multiple pages.

My 2c
 
I think many posters post questions about their solution rather than the original problem.

Mike
 
Good deal and glad the project is doing what was desired of it.

Ron
 
I think what happens here a new to this or similar forum person is directed by a friend or family member to come here. Possibly by someone who also received help. The new member is in unfamiliar territory and not pursuing a career goal in electronics but just needs a project to accomplish a certain task. They know "about" what they expect or want their project to do but often lack the technical background to express in text what they want. Initially those wanting to help just ask more questions to better refine a solution. Eventually enough information is dragged out and things begin to come together.

Ron
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…