Using KY-040 encoder to change a numerical value

I’m trying to use this rotary encoder to make an Altimeter using a BNO180 pressure sensor with adjustable base pressure in Hg (ie 29.92Hg for standard sea level pressure)

Using other tutorials I have this code working to increase a value from 0 and up. However, Id like to set a minimum value of 28.00 and a max value of 31.00 with numbers increasing or decreasing by 0.01 for each position of the encoder.

Heres the code:
#include <ClickEncoder.h>
#include <TimerOne.h>
#include <LCD5110_Graph.h>

LCD5110 lcd(8,9,10,12,11);
extern unsigned char SmallFont;
extern unsigned char TinyFont;

ClickEncoder *encoder;
int16_t last, value;

void timerIsr() {
encoder->service();
}

void setup() {

lcd.InitLCD();
lcd.setFont(TinyFont);
lcd.print(“Rotary Endcoder”,CENTER,0);
lcd.print(“DEMO”,CENTER,20);
lcd.update();
delay(2000);
lcd.setFont(SmallFont);
encoder = new ClickEncoder(A1, A0, A2);
encoder->setAccelerationEnabled(false);

Timer1.initialize(1000);
Timer1.attachInterrupt(timerIsr);
last = -1;
}

void loop() {
int encoderValue;
int encoderPosition;
lcd.setFont(SmallFont);
char encoderValueArray[3];
char encoderPositionArray[3];

value += encoder->getValue();

if (value/4 != last) {
encoderValue = value/4;
encoderPosition = encoderValue%20;

last = encoderValue;

lcd.clrScr();
lcd.print(": ",LEFT,0);
dtostrf(encoderValue, 3, 0, encoderValueArray);
lcd.print(encoderValueArray,LEFT+0,0);

//Serial.print("\n");
lcd.update();
}

ClickEncoder::Button b = encoder->getButton();
if (b != ClickEncoder::Open) {
#define VERBOSECASE(label) case label:lcd.setFont(TinyFont);lcd.print(#label,CENTER,40);lcd.update(); break;
switch (b) {
VERBOSECASE(ClickEncoder::Pressed);
VERBOSECASE(ClickEncoder::Held)
VERBOSECASE(ClickEncoder::Released)
VERBOSECASE(ClickEncoder::Clicked)
case ClickEncoder::DoubleClicked:
encoder->setAccelerationEnabled(!encoder->getAccelerationEnabled());
break;
}
}
}

However, Id like to set a minimum value of 28.00 and a max value of 31.00 with numbers increasing or decreasing by 0.01

I'd set a minimum value of 2800 and a maximum of 3100, and use an increment of 1.

How do I set those values? I need 0.01 increments

I need 0.01 increments

And that’s what you’ll get, when you multiply those final values by 0.01.

How do I set those values?

int16_t last, value = 2800;

You’ll need to look up the max and min macros in the language reference.

CtrlAltElite:

int16_t last, value = 2800;

When I do that, it starts off reading 700.
So I guess I have to set 11200

Oh yeah, I missed the divide by four

Doing that worked.

However when I put *0.01 Into:

if (value/4 != last) {
encoderValue = value/4*0.01;

The display drops to only showing the first 2 digits. 2800 becomes 28

Made this change

dtostrf (encoderValue, 3, 2, encoderValueArray);

and now it's showing 28.00 but the .00 doesn't change, just the 28 (eventually depending on which way I turn)

Here’s the complete updated code I’m using just to get this encoder pressure setting to work.

#include <ClickEncoder.h>
#include <TimerOne.h>
#include <LCD5110_Graph.h>

LCD5110 lcd(8,9,10,12,11);
extern unsigned char SmallFont[];
extern unsigned char TinyFont[];

ClickEncoder *encoder;
int16_t last, value = 11200;

void timerIsr() {
encoder->service();
}

void setup() {
 
lcd.InitLCD();
lcd.setFont(SmallFont);
 
lcd.print("Altimeter",CENTER,15);
lcd.update();
delay(2000);
lcd.setFont(SmallFont);
encoder = new ClickEncoder(A1, A0, A2);
encoder->setAccelerationEnabled(false);

Timer1.initialize(1000);
Timer1.attachInterrupt(timerIsr); 
last = -1;
}

void loop() {  
int encoderValue;
lcd.setFont(SmallFont);
char QNH[3]; 

 
value += encoder->getValue();
 
if (value/4 != last) {
encoderValue = value/4*0.01;
 
last = encoderValue;
 
lcd.clrScr();
dtostrf(encoderValue, 3, 2, QNH);
lcd.print(QNH,LEFT,0);
lcd.update();
}
 

}

result:
28.00
Turn 1-99 positions CW
28.00
Should be
28.01, 28.02, 28.03 etc
And if I go the other direction from starting point:
Turn one position CCW
27.00
Should be
27.99
However, I want a min value of 28.00 and a max of 31.00 but consintrating here on getting the 2 decimal values to show before putting in constraints

Don't use floating point at all!

If you divide an integer, say 2834, by 100, you'll get 28.

If you use the modulo operator % on 2834, like 2834 % 100, you'll get 34.

Or you can do the operation manually by multiplying the result of the division by 100, and subtracting the result from the original number, e.g. 2834 - ( (2834 / 100) * 100) = 34.

The only thing you need to be careful of now is a leading zero in the fractional part, which can be printed with a simple test to see if the fraction is less than 10

I.made some changes and got it to work.

Mainly, I changed "int encoderValue" to Float

 void loop() {  
float q = value/4*0.01;
lcd.setFont(SmallFont);
char qnh[3]; 


value += encoder->getValue();

if (value != last) {
last = value;


Serial.print("QNH: ");
Serial.println(q);
lcd.clrScr();
lcd.print("QNH: ",LEFT,0);
dtostrf(q, 3, 0, qnh);
lcd.print(qnh,LEFT+25,0);
lcd.update();
}


}

Mainly, I changed "int encoderValue" to Float

! facepalm !