Hi,
I’ve been using @gfvalvo’s excellent newEncoder library with some success for a project I am working on. I now need to be able to reset my encoder parameters for various menu levels as part of an LCD menu interface.
I note that the library provides a newSettings function that allows one to dynamically reset the min / max encoder values.
bool newSettings(int16_t newMin, int16_t newMax, int16_t newCurrent, EncoderState &state);
However, I’m having trouble applying the fourth argument, EncoderState &state, which I understand is a variable of the type NewEncoder::EncoderState that is being passed by reference.
The newSettings function is also discussed in How to Change Encoder Values - #5 by cattledog where another person was also having trouble with this method but clear instructions on its use were not provided in this post.
Consider the example library sketch, CustomEncoder.ino, which I’ve used to try to figure out how to apply the newSettings method. CustomEncoder.ino creates a custom Encoder object using inheritance where the encoder “wraps around” when it hits the max / min limits - which is how I want my encoders to behave. For newSettings testing purposes, I’ve just added a flag that I manually set when I want to reset the encoder values and the main loop simply tries to apply the newSettings function if the flag is set.
I’ve not been able to get this sketch to successfully compile and consistently get the error
'EncoderState' was not declared in this scope
I’ve been researching pass by reference and this error for several days but can’t seem to overcome this error, hence this post. I'm not sure if it is a namespace / scope issue or if I'm just neglecting to declare something necessary.
Please be gentle with me as I’m new to C++ and a novice programmer.
Full sketch and error below. Note that I use Visual Code / PlatformIO rather than the Arduino IDE.
Thanks in advance!
Sketch:
#include "Arduino.h"
#include "NewEncoder.h"
// CustomEncoder.ino example
// ref: https://github.com/gfvalvo/NewEncoder/blob/master/examples/CustomEncoder/CustomEncoder.ino
// Demonstrate creation of custom Encoder using inheritance.
// This encoder "wraps around" when it hits the min or max limit
class CustomEncoder : public NewEncoder {
public:
CustomEncoder() : NewEncoder() {
}
CustomEncoder(uint8_t aPin, uint8_t bPin, int16_t minValue, int16_t maxValue, int16_t initalValue, uint8_t type = FULL_PULSE) : NewEncoder(aPin, bPin, minValue, maxValue, initalValue, type) {
}
virtual ~CustomEncoder() {
}
protected:
virtual void updateValue(uint8_t updatedState);
};
void ESP_ISR CustomEncoder::updateValue(uint8_t updatedState) {
if ((updatedState & DELTA_MASK) == INCREMENT_DELTA) {
liveState.currentClick = UpClick;
liveState.currentValue++;
if (liveState.currentValue > _maxValue) {
liveState.currentValue = _minValue;
}
} else if ((updatedState & DELTA_MASK) == DECREMENT_DELTA) {
liveState.currentClick = DownClick;
liveState.currentValue--;
if (liveState.currentValue < _minValue) {
liveState.currentValue = _maxValue;
}
}
stateChanged = true;
}
// 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.mouser.com/ProductDetail/alps/ec11e15244g1/?qs=YMSFtX0bdJDiV4LBO61anw==&countrycode=US¤cycode=USD
CustomEncoder encoder(2, 3, 0, 10, 5, FULL_PULSE);
int16_t prevEncoderValue;
// flag for when use in loop when I want the program to apply the newSettings function
bool resetEncoder = 1;
void setup() {
CustomEncoder::EncoderState state;
Serial.begin(74880);
delay(2000);
Serial.println("Starting");
if (!encoder.begin()) {
Serial.println("Encoder Failed to Start. Check pin assignments and available interrupts. Aborting.");
while (1) {
yield();
}
} else {
encoder.getState(state);
Serial.print("Encoder Successfully Started at value = ");
prevEncoderValue = state.currentValue;
Serial.println(prevEncoderValue);
}
}
void loop() {
int16_t currentValue;
CustomEncoder::EncoderState currentEncoderState;
if (resetEncoder == 1) {
encoder.newSettings(0, 8, 4, EncoderState & state);
}
if (encoder.getState(currentEncoderState)) {
currentValue = currentEncoderState.currentValue;
if (currentValue != prevEncoderValue) {
Serial.print("Encoder: ");
Serial.println(currentValue);
prevEncoderValue = currentValue;
}
}
}
Compiler Error:
Compiling .pio/build/uno/src/main.cpp.o
src/main.cpp: In function 'void loop()':
src/main.cpp:73:38: error: 'EncoderState' was not declared in this scope
encoder.newSettings(0, 8, 4, EncoderState & state);
^~~~~~~~~~~~
src/main.cpp:73:38: note: suggested alternative: 'encoder'
encoder.newSettings(0, 8, 4, EncoderState & state);
^~~~~~~~~~~~
encoder
*** [.pio/build/uno/src/main.cpp.o] Error 1
==================== [FAILED] Took 3.89 seconds=====