Press button controlled DC Motor

Hi Folks,

I’m basically using the same set up as I found as an Arduino Example here. I’m only controlling the motor with the Starter Kit Power Supply Module attached to the Bread Board and PN2222 transistor… and I don’t want the motor to ramp up and down, but I want it to switch on and off.

While I have the Power Supply Module disabled, the “Power” mode switches between “On” and “Off” as expected. Once I power the Power Supply module, the Motor only switches on very short and then turns off again.

Therefore I think my code is fine and I could imagine, some voltage that is meant for the DC motor reaches my button input and is detected as another button press.

I could imagine, this is quite a known scenario… how do I avoid such problem? How do I decouple motor and the logical inputs of the Arduino?

Please see the code below. Any help appreciated :slight_smile:

 const int pinMotor = 5;
  const int pinReset = 8;
  const int pinBoost = 9;
  const int pinPause = 10;

  int buttonState = LOW;
  int motorSpeed = 128;
  int boostTimer = 0;
  int pauseTimer = 0;
  int previousButtonState[3] = {LOW, LOW, LOW}; //previously read button states of 0) Reset 1) Boost 2) Pause
  bool ButtonUse[2] = {false, false};
  bool Power = false;

void reinitializeFunction(){
  motorSpeed = 128;
  boostTimer = 0;
  pauseTimer = 0;
  Power = false;
  
  for (int i=0; i<2; i++){
    ButtonUse[i] = false;
  }
}
  
void setup() {
  // put your setup code here, to run once:
 pinMode(pinReset, INPUT);
 pinMode(pinBoost, INPUT);
 pinMode(pinPause, INPUT);
 pinMode(pinMotor, OUTPUT);

 Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

if (Power == true){
  analogWrite(pinMotor,motorSpeed);
}
else{
  analogWrite(pinMotor,0);
}

//##############Reset Button##############
buttonState = digitalRead(pinReset);
/*Serial.print("ResetButton=");
Serial.println(buttonState);*/
if (buttonState == HIGH && previousButtonState[0] == LOW){
Serial.println("Button Pressed");
  if (Power == false){
    Power = true;
    Serial.println("Power On");
  }
  else{
    reinitializeFunction();
    Serial.println("Power Off");
  }
}
previousButtonState[0]=buttonState;
}

Are you using a pull-down resistor for your button?
Your code is missing a debounce; in its simplest form, a delay.

There are multiple starter kits; which one did you buy?
What is the"power supply module" that your talking about? What are the specs? Does it replace the 9V battery as shown in the Arduino example that you linked to?

How much power does the motor need?

Please draw your own diagram how everything is connected; take a photo of it, resize it so we don't have to download a massive file (100 .. 200 kByte should be OK) and post it here.

Once I power the Power Supply module, the Motor only switches on very short and then turns off again.

Does your Arduino still react on the button on that case (serial print statements)?

Hi sterretje,

thank you for your support. I uploaded my version of the setup.

Are you using a pull-down resistor for your button?

Yes, 1k.

Your code is missing a debounce; in its simplest form, a delay.

I added a delay which only caused the motor to run a bit longer, but still went off again.

There are multiple starter kits; which one did you buy?
What is the"power supply module" that your talking about? What are the specs? Does it replace the 9V battery as shown in the Arduino example that you linked to?

It converts 9V to 5 and 3.3V. I’m using 5V to power the motor, which is supposed to run with 3-6V.
The arduino is powered via USB.

Does your Arduino still react on the button on that case (serial print statements)?

Yes it does. When the external power is disabled (i.e. the engine doesn’t run) each button press works as expected: with each button press, I can see in the serial monitor either “Button Pressed, Power On” or “Button Pressed, Power Off”. Once I connect the external power, the motor stays off until I press the button. After short time, it turns off again. In the serial Monitor I see this with every button press:
“Button Pressed
Power On
Button Pressed
Power Off”

For me this looks like this is not caused by missing debounce (and as I understand I don’t need any when I specifically act on button states LOW to HIGH but please correct me if I’m wrong), but it rather looks like some interference with the motor voltage…

Diode is connected backwards, short circuiting the motor, causing voltage regulator to overheat and shutdown.
How much current does the motor require? That little voltage regulator probably can only supply about 500mA after dropping 9V to 5V.

You are right, the Diode is backwards - was a drawing mistake.

How much current does the motor require? That little voltage regulator probably can only supply about 500mA after dropping 9V to 5V.

Unfortunately, I have neither specs for the motor nor for the voltage regulator. But I measured 80mA at 5V.
See the corrected drawing attached…

Is your project working now? Appears you have a 2.2k base resistor, too high, 220 to 390Ω should work.
NPNMot_1.png

NPNMot_1.png

I didn't change anything about the set up, the diode was only placed wrong way round in the drawing.

Appears you have a 2.2k base resistor, too high, 220 to 390Ω should work.

I spent hours refreshing my transistor knowledge to calculate the base resistor. As I don't have too much experience, I rather wanted to rely on the calculated values.
To allow ~80mA for the motor and the PN2222 beta =100, I calculated even a base resistor of 5.1k..
As I understand with the given motor currents, a lower base resistor should not destroy the transistor, but 2k should not limit the current flow either.
Anyways thanks for the tip, I will try that out later, but it shouldn't cause the problem I'm seeing here, right?

I continued working on the rest of the code. In total there are 3 buttons connected via pull-up resistors to ground.
When ever the motor is started, all 3 digital inputs seem to get triggered. Also while the Motor is running, my USB port on my computer freaks out and I hear repeatedly the sound of connecting/disconnecting USB.
I added a photo of the set-up, in case I wired up something completely wrong, but I can’t find the issue.

Also while the Motor is running, my USB port on my computer freaks out and I hear repeatedly the sound of connecting/disconnecting USB.

Please add this print line to setup() and verify that the code is resetting. If so, it would appear to be a power issue.

void setup() {
  // put your setup code here, to run once:
 pinMode(pinReset, INPUT);
 pinMode(pinBoost, INPUT);
 pinMode(pinPause, INPUT);
 pinMode(pinMotor, OUTPUT);

 Serial.begin(9600);
Serial.println("Code leaving setup()");
}

Just done, I can only see the set up only being executed after restarting the Arduino, not after starting the motor.. It doesn't seem to be a power issue. Powering the motor without the buttons did not show any issue.

nihilbaxter85:
Unfortunately, I have neither specs for the motor nor for the voltage regulator. But I measured 80mA at 5V.

Regulator specs are embarrassingly easy to find if only you check the number printed on it and look up its datasheet.

The motor current: measured when powered over USB or that (totally inadequate) 9V block battery which won’t deliver much more than 80 mA to begin with? I have an identical looking motor here (can’t tell if it’s the same type, but it does pass the duck test for it), and measure ~2Ω coil resistance, meaning 2.5A stall current, and probably some 300-500 mA for running unloaded.

Does your motor switch on when you connect the base of the transistor (through the resistor) directly to +5V? That’s one of the key tests to do. Make sure your transistor switch works.

nihilbaxter85:
I spent hours refreshing my transistor knowledge to calculate the base resistor. As I don’t have too much experience, I rather wanted to rely on the calculated values.
To allow ~80mA for the motor and the PN2222 beta =100, I calculated even a base resistor of 5.1k…

That beta is for amplification applications; you’re looking for switching applications for which you want saturation, and a beta of more like 10-20. The transistor can switch up to 600 mA which should be enough for this motor, albeit just. At these currents the breadboard itself also starts to get in the way.

nihilbaxter85:
Also while the Motor is running, my USB port on my computer freaks out and I hear repeatedly the sound of connecting/disconnecting USB.

That’s probably because you’re overloading the USB port with that motor.

Regulator specs are embarrassingly easy to find if only you check the number printed on it and look up its datasheet.

There is not even one letter on the motor.. The only information I got as part of the Kit's overview is "3-6V Motor".

Does your motor switch on when you connect the base of the transistor (through the resistor) directly to +5V? That's one of the key tests to do. Make sure your transistor switch works.

On/Off/Speed control via PWM works fine. The problems started when adding the press buttons.

That's probably because you're overloading the USB port with that motor.

The motor is powered with the 9V block + power supply module. The chip on the power supply module is an AMS1117, per datasheets it's supposed to deliver up to 1A.
The arduino is powered separately via USB. Aruino and Power Supply have common ground.

So no matter what causes the unintended triggers to the inputs, I added some debounce logic and the buttons work now as intended.
@sterretje, you probably think "told you".. xD For some reason I thought I wouldn't need any because I was observing the signal edge (LOW to HIGH), but now I learned debounce helps for any kind of unexpected noises...

But still I wonder what causes the interference and my Computer USB port going crazy. It even disables my mouse on another USB port.. and I could imagine it might cause some damage on the arduino, too..
As the interference is continuously and not only when starting/stopping the motor, maybe it is induced from the motor brushes/sparks? Might a capacitor help reducing voltage peaks? Unfortunately, I don't have an oscilloscope to see what's going on..

nihilbaxter85:
The motor is powered with the 9V block + power supply module. The chip on the power supply module is an AMS1117, per datasheets it's supposed to deliver up to 1A.

That regulator can only deliver 1A if it's being supplied 1A. Not going to happen from a 9V block battery. That 80 mA sounds about right. Now if you use a power source that can actually deliver... such as a 2-3A mobile phone charger... you'll see your motor spin a lot faster!

As the interference is continuously and not only when starting/stopping the motor, maybe it is induced from the motor brushes/sparks?

Very well possible.

Solder a 100 nF ceramic between the contacts, and if that's not enough (or you just want to be sure) add two more between each contact and the metal housing. That should do the job.

nihilbaxter85:
The motor is powered with the 9V block + power supply module. The chip on the power supply module is an AMS1117, per datasheets it's supposed to deliver up to 1A.

There's the trick: Only if it has a heatsink. On that module it does not. :astonished:

nihilbaxter85:
So no matter what causes the unintended triggers to the inputs, I added some debounce logic and the buttons work now as intended.

Can't see code for that but debounce code is never optional for a toggle function. Switches bounce, you see. :grinning:

nihilbaxter85:
But still I wonder what causes the interference and my Computer USB port going crazy. It even disables my mouse on another USB port.

Now that is extremely puzzling. :fearful:

nihilbaxter85:
and I could imagine it might cause some damage on the arduino, too..

Extremely unlikely. Only over-voltage or current would damage it.

wvmarle:
That regulator can only deliver 1A if it's being supplied 1A. Not going to happen from a 9V block battery. That 80 mA sounds about right.

Not sure what the current capacity of the battery is; being alkaline it could actually be in the order of an Amp. Found this by way of reference but it does not specify internal resistance however it appears to be assembled from six of these suggesting at most 2 Ohms.

Alright, I dug a bit in my cable drawer and found a 12V 1500mA power supply.
With 50% duty cycle, the motor draws 80mA, with 100% it’s 160mA. Seems like the voltage regulator can still handle that current without heatsink, otherwise I wouldn’t expect exactly double the current with 100% duty cycle.
Also the USB issue is gone with the new power supply.

Can’t see code for that but debounce code is never optional for a toggle function. Switches bounce, you see. :grinning:

It seemed to be working without the motor running, but you’re right. I will use debounce in futur. Btw, see the code below with debounce.

The whole idea of the set up is to add boost and pause buttons for every player to a Looping Louie game. If you don’t know that, have a look here. :slight_smile:
Biggest challenge will be to fit everything in the game without getting tangled in cables…

Thank you everyone for your support!! :smiley:

  const int pinMotor = 5;
  const int pinReset = 8;
  const int pinBoost = 9;
  const int pinPause = 10;
  const int buttonEffect = 2000;
  const int debounceTime = 100;

  int reading = LOW;
  int buttonState[3] = {LOW, LOW, LOW};
  int motorSpeed = 128;
  int previousButtonState[3] = {LOW, LOW, LOW}; //previously read button states of 0) Reset 1) Boost 2) Pause
  bool buttonUse[2] = {false, false};
  bool Power = false;
  long buttonTimer = 0;
  long debounceTimer = 0;

void reinitializeFunction(){
  motorSpeed = 128;
  Power = false;
  buttonTimer = 0;
  
  for (int i=0; i<2; i++){
    buttonUse[i] = false;
  }
}
  
void setup() {
  // put your setup code here, to run once:
 pinMode(pinReset, INPUT);
 pinMode(pinBoost, INPUT);
 pinMode(pinPause, INPUT);
 pinMode(pinMotor, OUTPUT);

 Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
if (buttonTimer > 0 && millis()-buttonTimer>buttonEffect){
  motorSpeed=128;
  Serial.println("Motor back to normal speed");
  buttonTimer=0;
}

if (Power == true){
  analogWrite(pinMotor,motorSpeed);
}
else{
  analogWrite(pinMotor,0);
}

//##############Reset Button with debounce##############
reading = digitalRead(pinReset);
if (reading != previousButtonState[0]){
  debounceTimer=millis();
}
if (millis()-debounceTimer > debounceTime){
  if (reading!=buttonState[0]){
    buttonState[0]=reading;
    if (buttonState[0] == HIGH){
      Serial.println("Reset Button Pressed");
      if (Power == false){
        Power = true;
        Serial.println("Power On");
      }
      else{
        reinitializeFunction();
        Serial.println("Power Off");
      }
    }
  }
}
previousButtonState[0]=reading;

//##############Boost Button with debounce##############
reading = digitalRead(pinBoost);
if (reading != previousButtonState[1]){
  debounceTimer=millis();
}
if (millis()-debounceTimer > debounceTime){
  if (reading!=buttonState[1]){
    buttonState[1]=reading;
    if (buttonState[1] == HIGH){
      Serial.println("Boost Button Pressed");
      if (buttonUse[0]==false){
        buttonTimer = millis();
        motorSpeed = 255;
        Serial.println("Motor boosted");
        buttonUse[0]=true;
      }
    }
  }
}
previousButtonState[1]=reading;

//##############Pausd Button with debounce##############
reading = digitalRead(pinPause);
if (reading != previousButtonState[2]){
  debounceTimer=millis();
}
if (millis()-debounceTimer > debounceTime){
  if (reading!=buttonState[2]){
    buttonState[2]=reading;
    if (buttonState[2] == HIGH){
      Serial.println("Pause Button Pressed");
      if (buttonUse[1]==false){
        buttonTimer = millis();
        motorSpeed = 0;
        Serial.println("Motor paused");
        buttonUse[1]=true;
      }
    }
  }
}
previousButtonState[2]=reading;

}

Not going to work for long. Use an old mobile phone charger, 5V is what you need.

Just do the math: 80 mA for the Uno + 80 mA for the motor is already 160 mA. (12-5)V * 160 mA = 1120 mW dissipation. That regulator struggles to do 700 mW continuously...