More than one shift is not executed (Arduino UNO)

Hello everyone, I need a hand to solve a problem in my code. I have never programmed with this type of code and I am not an experienced programmer. I designed a shifter for a university subject using an Arduino UNO. The potentiometer is used to set binary code values by turning on or off 8 LEDs depending on the entered number (minimum potentiometer = 0000000, all LEDs off; maximum potentiometer = 1111111, all LEDs on). The LEDs were connected to a shifter because there wasn't enough space on the ports. The result is displayed on an LCD screen that shows the corresponding decimal number in real time. The nearby buttons allow you to shift left or right by one bit by pressing the appropriate button. However, this only works if you press one button in one direction. If I click twice in the same direction, the number returns to the initial one, if I press buttons in opposite directions, the LEDs and the screen change value in an intermittent manner due to the delay times in the code, producing values that appear to be a bounce between the potentiometer value and the shift performed, not random values. How can I modify the code to allow for multiple shifts on the same number chosen by the potentiometer? I think the problem is how the Arduino loop starts, the first value taken is that of the potentiometer, then the shift value, and so on. However, I don't know how to fix it. Perhaps taking the potentiometer value only once would work, but how could I do this considering that the value must be taken from the loop?

#include <LiquidCrystal.h>

#define dataPin 4   // Pin for data input to 74HC595 shifter
#define latchPin 3  // Pin for latch signal to 74HC595 shifter
#define clockPin 2  // Pin for clock signal to 74HC595 shifter

#define buttonLeft 5   // Pin for the left button
#define buttonRight 6  // Pin for the right button

#define rs 12  // RS pin of the LCD
#define en 11  // Enable pin of the LCD
#define d4 10  // D4 pin of the LCD
#define d5 9   // D5 pin of the LCD
#define d7 7   // D7 pin of the LCD

// Initialize the LCD with the defined pins
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

byte currentValue = 0;  // Current value of LEDs

int buttonLeftValue = 0;
int buttonRightValue = 0;

int buttonLeftOldValue = 0;
int buttonRightOldValue = 0;

int stateLeft = 0;
int stateRight = 0;

void setup() {
  // Set the input/output modes for the pins
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(buttonLeft, INPUT);
  pinMode(buttonRight, INPUT);
  lcd.begin(16, 2);
  lcd.print("000");
}

void loop() {
  int analogValue = analogRead(A0);                      // Read the analog value from the potentiometer
  int digitalValue = map(analogValue, 0, 1023, 0, 256);  // Map the analog value to a digital value between 1 and 255

  buttonLeftValue = digitalRead(buttonLeft);    // Read the input value of the left button and store it
  buttonRightValue = digitalRead(buttonRight);  // Read the input value of the right button and store it

  // If the digital value has changed
  if (digitalValue != currentValue) {
    currentValue = digitalValue;                          // Update the current value
    digitalWrite(latchPin, LOW);                          // Set latchPin to LOW
    shiftOut(dataPin, clockPin, LSBFIRST, currentValue);  // Send the data
    digitalWrite(latchPin, HIGH);                         // Set latchPin to HIGH to transfer the data to the output pins
    lcd.setCursor(7, 0);
    char buffer[5];
    sprintf(buffer, "%03d", currentValue);
    lcd.print(buffer);  // Print the value on the LCD
  }

  // If the left button is pressed and its old value was LOW
  if ((buttonLeftValue == HIGH) && (buttonLeftOldValue == LOW)) {
    stateLeft = abs(1 - stateLeft);  // Change the state of the left button
    delay(50);                       // Add a delay to avoid accidental multiple presses
  }

  buttonLeftOldValue = buttonLeftValue;

  // If the state of the left button is 1 (pressed)
  if (stateLeft == 1) {
    currentValue = currentValue << 1;                     // Perform left shift
    if (currentValue > 255) currentValue = 0;             // Set the value to 0 if it exceeds 255
    digitalWrite(latchPin, LOW);                          // Set latchPin to LOW
    shiftOut(dataPin, clockPin, LSBFIRST, currentValue);  // Send the data
    digitalWrite(latchPin, HIGH);                         // Set latchPin to HIGH to transfer the data to the output pins
    lcd.setCursor(7, 0);
    char buffer[5];
    sprintf(buffer, "%03d", currentValue);
    lcd.print(buffer);
    delay(200);  // Add a delay to avoid accidental multiple presses
  }
  // If the left button is pressed and its old value was LOW
  if ((buttonRightValue == HIGH) && (buttonRightOldValue == LOW)) {
    stateRight = abs(1 - stateRight);  // Change the state of the left button
    delay(50);                         // Add a delay to avoid accidental multiple presses
  }
  buttonRightOldValue = buttonRightValue;

  // If the state of the right button is pressed
  if (stateRight == 1) {
    currentValue = currentValue >> 1;                     // Perform left shift
    digitalWrite(latchPin, LOW);                          // Set latchPin to LOW
    shiftOut(dataPin, clockPin, LSBFIRST, currentValue);  // Send the data
    digitalWrite(latchPin, HIGH);                         // Set latchPin to HIGH to transfer the data to the output pins
    lcd.setCursor(7, 0);
    char buffer[5];
    sprintf(buffer, "%03d", currentValue);
    lcd.print(buffer);
    delay(200);  // add delay
  }
}

thanks a lot to everyone :blush:

Just for next projects, use I2C LCD displays to save pins. And always remember you can also use analog pins like digital inputs.

Said that, in this code I can't see a lack of pins for UNO board.
I see you would need 5 digital pins for the LCD, 2 for the buttons, plus 8 LEDs the total is 15: excluding D0 and D1 (to be reserved for the serial), and A0 (for your analog input), with UNO you have 12 native digital pins, plus 5 analog used as digital ouputs, it's 17, two more than needed!
And if you use an I2C display you'll save 3 more.:wink:

2 issues I see off the bat.

Problem, bread board power rail split:

Solution, bread board power rail split:

If you are using a 9V battery like this.


Expect short run times and many issues involving low power.

I made your project in Wokwi simulation:

It has unlimited power :yum:
When I start the simulation and click on buttons, then I don't know what is going on and what is supposed to happen.

what do you expect the above to do? if stateLeft is 1 it becomes 0 and if 0 if become 1?

don't you want the button pressed to update a shift value that shifts the value read from the pot before displaying it?

I've brought Wokwi to a grinding halt nearly every time I tried to use it. The power of Wokwi is quite limited and often overstated.

Can you start a topic for that or can I help in any way ?
Wokwi has no analog simulation, and the ESP32 is not 100% simulated. But the Arduino Uno is simulated very well (clock cycle accurate), and also leds, buttons, servo motors, and so on.

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