KY40 and while loop

When the while loop is not active, the KY40 button state reads correctly when pressed or released.

But when the while IS active, the KY40 button state in the while loop always reads HIGH and the while loop never exits.

Help please. This shouldn't be difficult, but I'm at a loss.

//This works to read a KY40 button switch OK, but without the while loop.
//With the while loop active, it (the while loop) ignores the button switch (always HIGH), and never exits the loop!!

int KYSW;
int SW=4;// connected to KY40 SW pin

void setup() {
pinMode(SW, INPUT_PULLUP);
Serial.begin(9600);
}

void loop() {
KYSW = digitalRead (SW);
delay(1000);
Serial.println(KYSW);                                                                                                                              

while(KYSW = HIGH){
delay(1000);
Serial.println ("Keep looping");
Serial.print (KYSW);
}
Serial.print ("While Exited");
delay(1000);
}

You never re-read the input so KYSW will never change, also KYSW = HIGH sets a value, you need KYSW == HIGH.

Thanks MISSDREW :slight_smile:

Both your corrections saved my day.

I'm always confusing = with ==.

A related KY40 difficulty in my Unit Conversion project.

A part of my KY40 SW and encoder read sketch,, I'm unable to use the KY40 encoder reads outside void loop.
I think it's due to the volatile byte type assigned to encoderPos that is used as part of the KY40 Interrupt routine.

volatile byte encoderPos = 0

If I try to use encoderPos (after the KY40 knob is turned) in a function outside the void loop, encoderPos is always !, e.g. .....

void INCHCENTIMETER () {
Serial.print("This is INCHCENTIMETER)");
delay(5000);
a=encoderPos;  
b=encoderPos*2.54; 
c=encoderPos/2.54;

After a KY40 encoderPos read in void loop, I tried this (still in void loop) VAL=encoderPos, where VAL type is INT or else FLOAT.
Either type assignment works OK within void loop, but when accessed in functions outside void loop (e.g. INCHCENTIMETER) , VAL always = 1.

void INCHCENTIMETER () {
Serial.print("This is INCHCENTIMETER)");
delay(5000);
a=VAL;  
b=VAL*2.54; 
c=VAL/2.54;

Is there any way to maintain the actual encoder read outside void loop ???

Help is always appreciated.

You can declare encoderPos as a global variable and it will be available, eh... globally.

byte encoderPos = 0;

void yourFunction() {
  //do something based on the value of encoderPos
}

void setup() {
}

void loop() {
  // put your main code here, to run repeatedly:
}

A variable is available in the scope (typically between {...}) where it is declared. When execution leaves the scope, it is discarded, and recreated next time the scope is entered.
If its made volatile, it will retain its value until next time the scope is entered, but still not available outside its scope.

Google "c++ scope"

Thanks, but encoderPos is already a global.

How about using the encoder-library NewEncoder written by user gfvalvo

here is a demo-code that shows how to use it

/* SingleEncoder.cpp
   Created on: Jul 25, 2018
   Author: GFV  see https://github.com/gfvalvo/NewEncoder
*/
#include "Arduino.h"
#include "NewEncoder.h"

// Pins 2 and 3 should work for many processors, including Uno. See README for meaning of constructor arguments.
// Use FULL_PULSE for encoders that produce one complete quadrature pulse per detnet, such as: https://www.adafruit.com/product/377
// Use HALF_PULSE for endoders that produce one complete quadrature pulse for every two detents, such as: https://www.adafruit.com/product/377
// NewEncoder encoder(IO_Pin_A, IO_Pin_B, MinValue, MaxValue, InitialValue, HALF_PULSE); //HALF_PULSE FULL_PULSE

NewEncoder encoder(2, 3, -32000, 32000, 0, FULL_PULSE);

int16_t prevEncoderValue;

void setup() {
  int16_t value;

  Serial.begin(115200);
  //delay(2000);
  Serial.println(F("Starting"));
  if (!encoder.begin()) {

    Serial.println(F("Encoder Failed to Start. Check pin assignments and available interrupts. Aborting."));
    while (1) {
    }
  } else {
    value = encoder;
    Serial.print(F("Encoder Successfully Started at value = "));
    Serial.println(value);
  }
}

void loop() {
  int16_t currentValue;
  bool up, down;

  up = encoder.upClick();
  down = encoder.downClick();
  if (up || down) {
    currentValue = encoder;
    if (currentValue != prevEncoderValue) {
      Serial.print(F("Encoder: "));
      Serial.println(currentValue);
      prevEncoderValue = currentValue;
    } else if (up) {
      Serial.println(F("Encoder at upper limit."));
    } else {
      Serial.println(F("Encoder at lower limit."));
    }
  }
}

best regards Stefan

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