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);
}
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. .....
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.
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.
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."));
}
}
}