0

I am new to arduino and I want to make a project where I have a motor spinning clockwise then when a button is pressed it spins anti-clockwise and if it is pressed again it goes back to clockwise etc... Unfortunately I am having trouble getting this to work. How I was aiming to make it work was to have a variable and whenever a button is pressed the value of that variable changes from HIGH to LOW to HIGH and so on and based on that variable the motor spins in either direction. I have got this code so far:

const int buttonPin = 8;     // the number of the pushbutton pin

// variables will change:
int buttonState = 0;         //variable to change status

void setup() {

 Serial.begin(9600);
 pinMode(buttonPin, INPUT);
}

void loop() {
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);
 Serial.print("Digital value: ");
 Serial.println(buttonState);
 delay(150);
}
2
  • 1
    so, what is your question? ... you are doing good so far
    – jsotola
    Mar 9, 2022 at 21:26
  • use the Bounce2 library to read the button
    – Juraj
    Mar 10, 2022 at 5:24

3 Answers 3

2

You've made a good start by first working with the button by itself (no motor) to keep your experiments simple. You've probably noticed that buttonState changes when you press or release the button, where your description says you want it to change each time you press the button. That means you have to ignore the releases, and invert the buttonState only on the presses.

Make that change next.

When you test that, you may discover that the buttonState changes several times when you press it once. Mechanical switches may make/break... several times at each change. (It's called bouncing even though it isn't "bouncing" but the two contacts grating across one another. The result is the same.) There are several ways to deal with that, but the simplest is to wait 20-30 milli-seconds after you first see a change; read it again, and if it is still in the new state, accept that, otherwise ignore it. That time delay is approximate; you might need to adjust it for a particular button.

Once you've decided that the button really has been pressed, then change the direction of the motor.

1
  • Thank you that is a good explanation Mar 10, 2022 at 7:40
1

I would recommend that you "debounce" the button input first. Instead of re-inventing the wheel, you could use an existing library: Bounce2.

Using the conditioned input, you could simply manipulate a counter to determine state.

// Connect one end of a N.O. push button switch to
// GND and the other end to pin 2 of the Arduino.
#include <Bounce2.h>
byte buttonState = 0;
const byte modeButtonPin = 2;
const unsigned long debouncerInterval = 50;  // Time in ms.

Bounce modeButton = Bounce();

void setup(){
  Serial.begin(9600);
  pinMode(modeButtonPin, INPUT_PULLUP);
  modeButton.attach(modeButtonPin);
  modeButton.interval(debouncerInterval);
}

void loop(){
  if(modeButton.update()){
    if(modeButton.read() == 0){
      buttonState++;
      if(buttonState > 1){buttonState = 0;}
      Serial.println(buttonState);
    }
  }
}
0

First I would make create an enumeration type and motor direction variable (instead of the button state):

enum EMotorDirection
{
    CLOCK_WISE,
    COUNTER_CLOCK_WISE
}

EMotorDirection _motorDirection = CLOCK_WISE;

Then read the button and when it has changed (make a variable `_previousButtonState), adjust the motor direction.

int _previousButtonState = LOW;

In the loop function:

int buttonState = digitalRead(buttonPin);
// Debounce buttonState;
if (buttonState != _previousButtonState)
{
   if (_motorDirection == CLOCK_WISE)
   {
       _motorDirection = COUNTER_CLOCK_WISE;
   }
   else
   {
       _motorDirection = CLOCK_WISE;
   }
   SwitchMotorDirection();

   _previousButtonState = buttonState;
}

And create the function SwitchMotorDirection

void SwitchMotorDirection()
{
   if (_motorDirection == CLOCK_WISE)
   {
       // Control motor clock wise
   }
   else
   {
       // Control motor counter clock wise
   }
}

The above example is not compiled, and also it could be smaller, but serves as a explanatory example, with the advantage to separate the UI (button), state machine (state variable), and hardware (motor).

Below is the complete code, which compiles. The bouncing has to be implemented (check the link for that above), and the actual motor driving.

// Types

enum EMotorDirection
{
    CLOCK_WISE,
    COUNTER_CLOCK_WISE
};

// Constants
const int _buttonPin = 8;     // the number of the pushbutton pin

// Global variables
int             _previousButtonState = LOW;
EMotorDirection _motorDirection      = CLOCK_WISE;

// Function prototypes
void SwitchMotorDirection();

// Functions

void setup() 
{
  Serial.begin(9600);
  pinMode(_buttonPin, INPUT);  
}

void loop() 
{
  int buttonState = digitalRead(_buttonPin);
  // Debounce buttonState;
  if (buttonState != _previousButtonState)
  {
     if (_motorDirection == CLOCK_WISE)
     {
         _motorDirection = COUNTER_CLOCK_WISE;
     }
     else
     {
         _motorDirection = CLOCK_WISE;
     }
     SwitchMotorDirection();
  
     _previousButtonState = buttonState;
  }    
}

void SwitchMotorDirection()
{
   if (_motorDirection == CLOCK_WISE)
   {
       // Control motor clock wise
   }
   else
   {
       // Control motor counter clock wise
   }
}
2
  • I am very new and I have no idea how to compile this could you maybe tell me? Mar 10, 2022 at 14:04
  • I added the code which compiles. Mar 10, 2022 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.