Rotary Encoder and Buttons dont work

So I have a small project that I am trying to pull off but I have a problem. I have tried to find a solution based on other people's forum questions but to avail. So I have 5 buttons and a rotary encoder, (and a Bluetooth but it doesn't matter for now.) and I want them to print their value in the console. But for the buttons instead of 1 or 0 is the phrase button x pressed. As for the rotary I don't care, I want just raw numbers. i have tried simpler codes like the tutorial for 1 button copied 5 times or something but nothing changes. The buttons are always HIGH apparently and the rotary does not change its value (it is always 0). Here is my code and photos of the wiring:


#include <Button.h>
#include <Encoder.h>
#include <SoftwareSerial.h>

// Define Bluetooth module pins
SoftwareSerial bluetoothSerial(12, 4); // RX, TX pins for Bluetooth module

// Define button pins
const int buttonPins[] = {2, 5, 11, 7, 8};
const int numButtons = sizeof(buttonPins) / sizeof(buttonPins[0]);
// Create individual button objects
Button button1(buttonPins[2]);
Button button2(buttonPins[5]);
Button button3(buttonPins[11]);
Button button4(buttonPins[7]);
Button button5(buttonPins[8]);

// Define rotary encoder pins
Encoder rotaryEncoder(3, 6); // A and B pins of the rotary encoder

long encoderValue = 0;
long lastEncoderValue = 0;
unsigned long lastPrintTime = 0;

void setup() {
  // Initialize Bluetooth module
  bluetoothSerial.begin(9600);
  
  // Initialize rotary encoder
  rotaryEncoder.write(0); // Set initial position to 0

  Serial.begin(9600);
}

void loop() {
  //bluetoothSerial.print("begin");
  // Check for button presses
  int buttonState1 = digitalRead(buttonPins[2]);
  if (buttonState1 == LOW) {
    // Handle button 1 press
     //bluetoothSerial.println("Button 1 pressed");
      Serial.println("Button 1 pressed");
    }else{
      //Serial.println("F");
    }
    int buttonState2 = digitalRead(buttonPins[5]);
  if (buttonState2 == LOW) {
    // Handle button 2 press
      //bluetoothSerial.println("Button 2 pressed");
      Serial.println("Button 2 pressed");
    }
    int buttonState3 = digitalRead(buttonPins[11]);
  if (buttonState3 == LOW) {
    // Handle button 3 press
      //bluetoothSerial.println("Button 3 pressed");
      Serial.println("Button 3 pressed");
    }
    int buttonState4 = digitalRead(buttonPins[7]);
  if (buttonState4 == LOW) {
    // Handle button 4 press
      //bluetoothSerial.println("Button 4 pressed");
      Serial.println("Button 4 pressed");
    }
    int buttonState5 = digitalRead(buttonPins[8]);
  if (buttonState5 == LOW) {
    // Handle button 5 press
      //bluetoothSerial.println("Button 5 pressed");
      Serial.println("Button 5 pressed");
    }
  
  // Read and handle rotary encoder
  long newEncoderValue = rotaryEncoder.read();
  
// Print encoder value only if it has changed significantly
  if (newEncoderValue != lastEncoderValue && millis() - lastPrintTime > 100) {
    Serial.print("Encoder value: ");
    Serial.println(newEncoderValue);
    lastEncoderValue = newEncoderValue;
    lastPrintTime = millis();
  }

  //bluetoothSerial.println("Encoder value: " + String(encoderValue));
  //Serial.println(String(encoderValue));
  
  // Handle Bluetooth communication (receive and send data)
  while (bluetoothSerial.available()) {
    char receivedChar = (char)bluetoothSerial.read();
    Serial.println(char (receivedChar));
    // Handle received data from Bluetooth here
    // Example: Handle incoming commands
    // if (receivedChar == 'A') {
    //   // Do something when 'A' is received     
  }
  
  // Your other code and logic here
}
const int buttonPins[] = {2, 5, 11, 7, 8};
Button button1(buttonPins[2]);
Button button2(buttonPins[5]);
Button button3(buttonPins[11]);
Button button4(buttonPins[7]);
Button button5(buttonPins[8]);

Whoops !
The buttonPins array only has 5 levels and they are numbered 0 to 4

Can you see a problem ?

1 Like

you are right I changed them to 0-4 rookie mistake.
The problem is the same tho. buttons always are high for some reason...
I have tried ezbutton, I have tried pull_up, I have tried to change the buttons to only ground and data but nothing ever changes ...

Why did you #include the Button library, create 5 instances of buttons named button1 to button5 and then not use them ?

How are the button inputs wired ?
Is there anything keeping them in a known state when the button is is not pressed ?

I have changed the code so many times at this point I am confused. I used the buttons on a previous iteration of the code but not on this.
The buttons are wired as the tutorial on the Arduino page. One pin has 5 volts the next to it has ground with a 10kΩ resistor and the data are on the opposite side of the ground (diagonally from the 5V).

If you are going to read the button pins directly using digitalRead() then I suggest that you remove all references to the Button library from the code as it may be using INPUT_PULLUP as the pinMode()

Sorry, but I cannot follow your description of how the buttons are wired. Please post a link to the page that you are referring to

So the buttons are like this https://www.arduino.cc/en/Tutorial/BuiltInExamples/Button

About the code instead of :

int buttonState5 = digitalRead(buttonPins[8]);
  if (buttonState5 == LOW) {

I had it like this but I was getting a weird error...

if (button1.read()) {

So you are suggesting to revert to the simple code with

pinMode(buttonPin, INPUT);

and do it like 5 times ?

Follow the advice of @Delta_G

Personally I would use INPUT_PULLUP in pinMode() to turn on the built in pullup resistor, wire the button to take the pin to GND when the button is pressed and test for LOW in the code when you want to test for a button press using digitalRead()

That way you will know exactly what the code is doing and will not need to understand or guess what the library is doing

2 Likes

To be honest when it was 1 button it worked fine, when I put one more its value was always read as HIGH. Then I just left one button and I wired the rotary encoder. both work fine. Then I tried to put the other buttons on and it started to read all the values as high and to not read the rotary at all. After that whatever I did just didn't work. (even when I disconnected everything and left just a button that button's value was always high...) but I am gonna follow both your instructions and start again with one button. Also @UKHeliBob I don't understand what the wiring should be. You mean this ? -> Arduino Push Button - Complete Tutorial - The Robotics Back-End

Thanks, I'll do that and see where it takes me.

So I can see if the button is working normally, right?
I was thinking if the shit hits the fan to change all the buttons to photoresistors so I can "simulate" a touch button (I have done this in another project, not very safe since the light is always changing but It worked fine for me)

So i copy pasted the code and wired the button as you suggested the button still doesn't change its value. It is stuck on HIGH. So I took the multimeter and did a check. The results were weird cause without an arduino the measurements were 23 (on he 2000m scale) but not while I press the button, only the second I touch the 2 heads to the button. After that I put the arduino and run it I put the multimeter on the 2 ends of the button and the measurements were 170 on the 200m scale .. i think the buttons don't have enough power ?

using the Toggle library from @dlloyd and the encoder library and a simple custom class to regroup a button name and pin for a nice print out to the serial monitor

#include <Encoder.h>                        // https://www.pjrc.com/teensy/td_libs_Encoder.html
#include <Toggle.h>                         // https://github.com/Dlloydev/Toggle

const byte encoderCLKPin = 6;
const byte encoderDTPin  = 3;
Encoder encoder(encoderDTPin, encoderCLKPin);
long encoderPosition;

class Buttons {
  public:
  const char * name;
  const byte pin;
  Toggle button;

  Buttons(const char *n, const byte p)  : name(n), pin(p), button(p) {};
};

Buttons buttons[] = {{"green", 2}, {"white", 5}, {"yellow", 11}, {"blue", 7}, {"red", 8}};

bool encoderChanged() {
  long newPos = encoder.read() >> 2;   //  4 ticks par click, divide by 4
  if (newPos != encoderPosition) {
    encoderPosition = newPos;
    return true;
  }
  return false;
}

void setup() {
  for (Buttons& b : buttons) b.button.begin(b.pin);
  Serial.begin(115200);
}

void loop() {
  if (encoderChanged()) Serial.println(encoderPosition);
  for (Buttons& b : buttons) {
    b.button.poll();
    if (b.button.onPress()) {
      Serial.print(b.name);
      Serial.println(" pressed");
    }
    if (b.button.onRelease()) {
      Serial.print(b.name);
      Serial.println(" released");
    }
  }
}

I think that the leads on the buttons are not long enough to make a connection to the metal contacts inside the breadboard

Let's connect those split rails ...

image

eagle eyes !! :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.