false positive with digitalRead()

Hi.
Sorry for bad English.

I am trying to build my own fan, with 3 different speed levels.
The circuit includes:

  • a button to switch mode
  • two Leds to express mode (00,01,10,11)
  • dc motor (the fan)

Here is the code:

const int led1 = 5;
const int led2 = 6;
const int button = 4;
const int dcMotor = 9;
const int speeds[] = {0, 150, 200, 255};
int mode = 0;

void setup() {
  pinMode(button, INPUT);
  pinMode(led1, OUTPUT);  
  pinMode(led2, OUTPUT);
  pinMode(dcMotor, OUTPUT);
  digitalWrite(led1, 0);
  digitalWrite(led2, 0);
  analogWrite(dcMotor, 0);                    // ** Notice this line
  Serial.begin(9600);
}

void loop() {
  if(digitalRead(button) == HIGH){        // ** Notice this line
    mode = (mode+1)%4;
    Serial.println("mode changed");       // for debugging
    digitalWrite(led1, mode%2==1 ? 1 : 0);
    digitalWrite(led2, mode>=2 ? 1 : 0);
    delay(300);  // for debounce
  }
}

(The code is not finished yet)

So the problem is that whenever I change the speed of the motor to max, by writing analog value of 255 to dcMotor in setup(), then the if() statement in loop() is executing even though I am not pressing the button.
I tried to debug that and it keeps execute the if() statement event though pin 4 (button) is connected to GND.

The circuit itself is built very well (no shorts/cuts) on a new breadboard, so I believe that all the contacts are fine.
I don't know where the problem is as I spent hours on this issue.
Any Ideas? Thanks.

aaaaaaaaaadi:

  pinMode(button, INPUT);

Where's your pull-up resistor for the switch?

How are you driving the fan?

Pieter

How is the input wired ?
You are checking for HIGH on the input so I assume that the switch takes the input HIGH. However, what state is it in when the switch is not closed ? Do you have a pulldown resistor in place to hold the input LOW except when the switch is used or is it floating at an uncertain voltage ?

Consider using INPUT_PULLUP in the pinMode() to turn on the built in pullup resistor, change the circuit to take the input LOW when the switch is closed and change the program logic to match.

Pieter and HeliBob
thanks for replying

the motor is connected as explained in this tutorial:

and the button is connected as explained in this tutorial:

so normally when button is not pressed the state of the 'button' pin is LOW

NOTE: the circuit works PERFECTLY when I change the motor speed to 0 in setup() , so as long as the button is not pressed the mode keeps the same and when I press the button then the mode increases

aaaaaaaaaadi:
NOTE: the circuit works PERFECTLY when I change the motor speed to 0 in setup() , so as long as the button is not pressed the mode keeps the same and when I press the button then the mode increases

Do you power the motor with the Arduino? Could it be that the motor draws too much current and the reference voltage has dropouts so the comparator interprets the LOW pin as HIGH? Just a thought.

Cheers,
Mark

MarkGoingToSpace:
Do you power the motor with the Arduino? Could it be that the motor draws too much current and the reference voltage has dropouts so the comparator interprets the LOW pin as HIGH? Just a thought.

Cheers,
Mark

I got your thought and did some tests

It turns out that when motor is on at full speed :

  • current from Arduino to bjt's base = 10.6 mA
  • I couldn't measure current from Arduino to the motor (my DMM is limited to 200mA) , but I assume it is arround 400-500mA as beta parameter of practical transistor is around 50 (50*10.6mA=530mA)
  • the arduino is connected to my laptop through usb cable, therefore the maximum current that the arduino can supply is 500mA
  • the HIGH voltage of the arduino (5V pin) drops to 3.1-3.15V

I guess that the problem has something to do with what you've said
Thank you

So how do I handle this? Should I add 5V battery to the circuit or is there another solution that you can think of?

Power the motor separately indeed