Go Down

Topic: Motor speed control - phantom inputs (Read 2352 times) previous topic - next topic

nealk2k3

I am trying to digitally control the speed of a motor with two buttons; one to increase its speed, and one to decrease.
I wired up the buttons first (using 10K pull-down resistors) and used the serial output to confirm that they were behaving as desired.  Pressing the 'up' button incremented and printed out the current speed selection, up to a maximum of 10, and the down button worked similarly.

When I connect up the motor however, whilst the speed control seems to work, I seem to get random button press events which cause the motor to slow back down again.  I can see they are registering as button presses as the button press code is firing and printing to the serial out.  I can't see what could be causing this in the code and so I am assuming it is to do with my circuit, perhaps a current issue.  I was originally powering the circuit from my laptop's USB port but I have switched to a bench PSU and this has not helped.  My electronics knowledge is rudimentary, and my components store is limited to what comes in the kit (although I had assumed the components supplied would play nicely with each other?)
Any suggestions as to what I miht be doing wrong would be greatly appreciated.  Thanks.
Here is my circuit
http://www.freeimagehosting.net/4l9o8
Here is my sketch:

const int upButton = 7;
const int downButton = 8;
const int motorOut = 12;

//button press vars
int on = 1;
boolean press = false;

const int MAX_SPEED = 10;
int cycle = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(upButton, INPUT);
  pinMode(downButton, INPUT);
  pinMode(motorOut, OUTPUT);
}

void updateSpeed()
{
  if(digitalRead(upButton) == HIGH)
  {
    if(!press && on < MAX_SPEED)
    {
      on = on + 1;
      press = true;
      Serial.println(on);
    }
  }
  else if(digitalRead(downButton) == HIGH)
  {
    if(!press && on > 0)
    {
      on = on - 1;
      press = true;
      Serial.println("down");
    }
  }
  else
  {
    press = false;
  }
}

void spin()
{
  cycle = (cycle+1)%(on+1);
  if(on > 0 & (cycle < on | cycle == MAX_SPEED))
  {
    digitalWrite(motorOut, HIGH);
    //Serial.println("on");
  }
  else
  {
    digitalWrite(motorOut, LOW);
      //  Serial.println("off");
  }
}

void loop()
{
  updateSpeed();
  spin();
}

DuaneB

Hi,
   You should be using analogWrite, google should return lots of examples for analogWrite Arduino Motor

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

nealk2k3

#2
May 10, 2012, 01:18 pm Last Edit: May 10, 2012, 01:20 pm by nealk2k3 Reason: 1
I have seen examples using analogWrite to vary the voltage supplied to a motor, but I have heard that whilst that works for an ideal motor, in real life a motor's speed does not vary linearly with its voltage and so it is better to use a pulsing approach, where the motor is either fully on or fully off at varying ratios.  Should a digital output not be suitable for this (with an appropriate resistor)?

DuaneB

Hi,
   You need to read up on what analogWrite does.

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

nealk2k3

OK, I moved the motor to pin 11 and replaced my spin() function with:

  byte speed = (255/MAX_SPEED)*on;
  analogWrite(motorOut, speed);

the speed control still works but I still get the random button presses.

DuaneB

Two more things you can do

1) No idea what press is for, so you can probably remove it

2) You are probably getting 'bounce' from your buttons, look up 'Arduino Switch Debounce' lots of ways to cure it.

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

nealk2k3

The switches could do with debouncing, true, but the random button presses occur when I'm not even touching the switches, so it's not a bounce problem.  The 'press' boolean prevents a single press from being registered multiple times; it forces the arduino to wait until the button has been released before registering another press.  The lack of debouncing does sometimes cause a single press to be registered twice, but the problems I'm talking about occur outside of that issue.

DuaneB

#7
May 10, 2012, 02:04 pm Last Edit: May 10, 2012, 02:07 pm by DuaneB Reason: 1
Hi,
   Looking at your circuit, your resistors appear to be in the wrong place. Look up 'Pull Up Resistor' for more info

   You should also look up decoupling capacitors, with a motor you should at least have 0.1 uf decoupling capacitor although its common to use three. You should also have a larger one to fill in for the power supply when the motor starts.

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

nealk2k3

Oh, that's a mistake in the diagram; they are wired correctly so as to be in-circuit when the switches are open.  I have tried adding a couple of decoupling capacitors across the rails but it didn't seem to help.  The best I have here is a 100uF and a 220uF.  I tried putting both in.

DuaneB

Heres a quick and easy test, take out the capacitors, replace the motor with an LED and current limiting resistor. My guess is that you will not see phantom inputs. If you put the motor back in, I assume you will see phantom inputs as a result of electrical noise coming from the motor.

If you have any scrap electronics in the house it will almost certainly have a few .1uf capacitors inside which should help to surpress the motor noise.

Try the test and see if it helps.

Duane B

rcarduino.blogspot.com



Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

nealk2k3

The LED did not show any signs of phantom inputs as you predicted.  The best I could find is a 1uF capacitor which I have put across the motor.  It seems to have helped a bit so I think if I get one with a more appropriate value and maybe put two or three of them in then my problems should be over.

Thanks for all your help.

More information about capacitors across motors here for anyone who's interested: http://www.pololu.com/docs/0J15/9

dc42

It sounds to me that the pushbutton inputs are picking up noise from the motor. Here are some suggestions:

1. Keep the wires to the pushbutton away from the wires to the motor.

2. Reduce the 10K pulldown resistors to 1K.

3. If  the problem persists, connect a small capacitor (e.g. 1000pF) across each pushbutton.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

nealk2k3

That seems to have done it!  I had some 560 ohm resistors so I replaced the 10Ks on the switches with them and now it seems very stable.

Thanks.

Go Up