Button floating and working when im close to the circuit

Hello,

I am trying to make a linear actuator. I have everything done exept for the code to make the linear actuator extend and retract in a loop when i press a button. The linear actuator uses a dc motor. I managed to make it sweep. So it runs for a few sec, reverse directions, and runs for few seconds again. Now i want the program to start when i press a button. Yet the button seems to float. Ive tried using an internal pullup, but this doesnt seem to work at all. When i use a push button with external resistor (10k) the button is floating and it responds like an motion sensor. Whenever my hand is nearby it acts as if i press it. But trying to fix this with internal pullup didnt work. Ive looked for solutions in this forum but nothing seems to work for me. Im also very inexperienced so that could very much be the problem. The example program also did not work. Here it is also floating and the led burns when im getting close.

I used a dual relay to control the direction of rotation. The relay didnt show up in the drawing program. In the circuit drawing i used 2 slide buttons and an rgb to mimic a dual channel relay. I dont think the problem has anything to do with this circuit since the sweep itself works perfetly.

Below it shows the code for external resistor as well as the code for internal pullup.
code with internal pullup:

#define CW 7 //CW is defined as pin #7//

#define CCW 8 //CCW is defined as pin #8//
const int buttonPin = 2; 
int buttonState = 0;  
void setup() { //Setup runs once//

pinMode(CW, OUTPUT); //Set CW as an output//

pinMode(CCW, OUTPUT); //Set CCW as an output//
pinMode(buttonPin, INPUT);
}

void loop() { //Loop runs forever//
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {

digitalWrite(CW,HIGH); //Motor runs clockwise//

delay(1000); //for 1 second//

digitalWrite(CW, LOW); //Motor stops//

digitalWrite(CCW, HIGH);//Motor runs counter-clockwise//

delay(1000); //For 1 second//

digitalWrite(CCW, LOW); //Motor stops//

}
}
//end of code//

Code when trying the external resistor:

#define CW 7 //CW is defined as pin #7//

#define CCW 8 //CCW is defined as pin #8//
const int buttonPin = 2; 
int buttonState = 0;  
void setup() { //Setup runs once//

pinMode(CW, OUTPUT); //Set CW as an output//

pinMode(CCW, OUTPUT); //Set CCW as an output//
pinMode(buttonPin, INPUT);
}

void loop() { //Loop runs forever//
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {

digitalWrite(CW,HIGH); //Motor runs clockwise//

delay(1000); //for 1 second//

digitalWrite(CW, LOW); //Motor stops//

digitalWrite(CCW, HIGH);//Motor runs counter-clockwise//

delay(1000); //For 1 second//

digitalWrite(CCW, LOW); //Motor stops//

}
}
//end of code//

teun-lll:
code with internal pullup:

pinMode(buttonPin, INPUT);

Ummm, no.

sayHovis:

pinMode(buttonPin, INPUT);

Ummm, no.

ah i messed it up. i did change it to INPUT_PULLUP when i was testing

Did you remember to test for a button press being LOW? Your code is using HIGH instead, which for a pullup is the default state when the button is not pressed.

Your diagram shows 1 button with an external pull down resistor and another button connected to the same pin, which you are saying has the internal pull up enabled. That puts the internal and external resistors in series. That's never going to give consistent results. Use different pins. Well, I say that's what you have, difficult to tell as I can't tell which way round the buttons are connected. Please use a proper circuit diagram in future, even if hand drawn and photographed.

What is that mess with 2 switches with what looks like an LED shining on them? I say 'looks like' because the connections are weird for an LED. You also need resistors in series with the LED (if it is and LED), you can't connect them without resistors (OK, you CAN connect them without resistors, but the LED or the Arduino output, or both, won't last long).

PerryBebbington:
(OK, you CAN connect them without resistors, but the LED or the Arduino output, or both, won't last long).

That's why I buy this style.

there are 2 obvious problems you have to fix:

1). With a pull-up resistor the unconnected state of the input is HIGH (button off). You need to be checking for LOW to see if the button is pressed.

  1. Buttons are mechanical closures and WILL bounce when you press them. You must debounce the input either in hardware or software. There are implementations of software debounce available. Just google for them.

Also, depending on how long your wires are and whether they are shielded you could be experiencing noise on the wire. If debounce doesn’t fix it (I suspect it will) you may have to add an RC filter.

On the point of debouncing, here is some simple demonstration code that shows one way of debouncing button inputs.

/* Simple button debounce for 4 buttons. Increments a count and sends the updated count to the serial monitor once per button press */
/* Tested on an Uno */
/* Connect simple push to make buttons between 0V and pin 2, 0V and pin 3, 0V and pin 4 and between 0V and pin 5 */

#define noOfButtons 4     //Exactly what it says; must be the same as the number of elements in buttonPins
#define bounceDelay 20    //Minimum delay before regarding a button as being pressed and debounced
#define minButtonPress 3  //Number of times the button has to be detected as pressed before the press is considered to be valid

const int buttonPins[] = {2, 3, 4, 5};      // Input pins to use, connect buttons between these pins and 0V
uint32_t previousMillis[noOfButtons];       // Timers to time out bounce duration for each button
uint8_t pressCount[noOfButtons];            // Counts the number of times the button is detected as pressed, when this count reaches minButtonPress button is regared as debounced 
uint8_t testCount[noOfButtons];             //Test count, incremented once per button press

void setup() {
  uint8_t i;
  uint32_t baudrate = 115200;
  Serial.begin(baudrate);
  Serial.println("");
  Serial.print("Serial port connected: ");
  Serial.println(baudrate);
  for (i = 0; i < noOfButtons; ++i) {
    pinMode(buttonPins[i], INPUT_PULLUP);
    Serial.print("Testcount ");
    Serial.print(i);
    Serial.print(" = ");
    Serial.println(testCount[i]);
  }
}

void loop() {
  debounce();
  delay(10);     //Your other code goes here instead of this delay. DO NOT leave this delay here, it's ONLY for demonstration.
}

void debounce() {
  uint8_t i;
  uint32_t currentMillis = millis();
  for (i = 0; i < noOfButtons; ++i) {
    if (digitalRead(buttonPins[i])) {             //Input is high, button not pressed or in the middle of bouncing and happens to be high
        previousMillis[i] = currentMillis;        //Set previousMillis to millis to reset timeout
        pressCount[i] = 0;                        //Set the number of times the button has been detected as pressed to 0
      }
    else {
      if (currentMillis - previousMillis[i] > bounceDelay) {
        previousMillis[i] = currentMillis;        //Set previousMillis to millis to reset timeout
        ++pressCount[i];
        if (pressCount[i] == minButtonPress) {
          ++testCount[i];
          Serial.print("Button ");
          Serial.print(i);
          Serial.print(" testcount = ");
          Serial.println (testCount[i]);
        }
      }
    }
  }
}

This is the debounce function I use. You can use it for any input but each input has to have a separate currentState, lastReading, and lastTimeMs. It returns the current stable state of the input. It does not account for rollover in millis() but I don't run my board for man than 50 days anyhow.

byte debounceInput(byte debouncePin, volatile byte& currentState, byte& lastReading, unsigned long& lastTimeMs)
{
  // Read the input pin
  byte currentReading = digitalRead(debouncePin);

  if (currentReading != lastReading) 
  { 
    // Pin state just changed.  Reset the time and record the last reading value.
    lastTimeMs = millis(); 
    lastReading = currentReading;
  }
  else if (currentState != currentReading && ((millis() - lastTimeMs) >= debounceHoldMs))
  {
    // 
    // If we got here then we know:
    //
    // 1) current reading equals the last reading, 
    // 2) the current state does not equal the current reading, and 
    // 3) the curent reading has been stable for at least debounceHoldMs,
    //
    // Therefore we need to report a new current state
    //
    currentState = currentReading;
  }
  else
  {
    // nothing
  }

  // The currentState is returned via the currentState reference and as a return
  // value.  You pick.
  return currentState;
}