Encoder code stops perfect one way, not the other?

I'm using an Encoder to set a Temperature in a climate control system for my old jeep. To eliminate the vacuum lines all together.

What i want to do is to have a set temperature between 50F and 100F for the air temp blowing out. The full automatic will come later. I also wanted to turn the knob clockwise until 99 then display "Hot" and no matter how many times the knob is turned clockwise it will only require one "click" (detent) counterclockwise to go down from "Hot" to 99* so far using the Encoder.h library from Encoder Library, for Measuring Quadarature Encoded Position or Rotation Signals I have managed to do that.

However the problem comes when i want to set the low temp. Turning CC (counterclockwise) it counts down to 51*F then on the next click displays "Max" exactly how it should. HOWEVER, thats it. No matter how many times i turn the knob it will not display anything other than "Max" I'm completely stumped.

Here's the part of my Code that i'm concerned with.

#include "Encoder.h"
Encoder tempKnob (3,4);

//other inputs or variables                                                 
int oldTemp =-999;                                   //placeholder for temp value
byte T = 0;

void loop() {
  //Temperature encoder read
  int newTemp = tempKnob.read();
   if (newTemp != oldTemp) {
     oldTemp = newTemp;
     T=(newTemp/4);
  }
  // oled display
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
}


void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_gdr11r);       //font set Gentium size 25 r= 1 - 127 only
  u8g.drawStr( 5, 14, "Manual");      //set location for mode display
  u8g.setFont(u8g_font_gdr25r);       //font set Gentium size 25 r=1-127 only
  u8g.setPrintPos (0,45);             //set location for temp display
  if (T >= 100) {                     //condition for max heat
     u8g.print("Hot");                //display hot
     tempKnob.write(400);             //write encoder to 400 gets divided by 4 in byte "T"
  }
  if (T <= 50) {                      //condistion for max cool
     u8g.print ("Max");               //display max
     tempKnob.write (200);            //write encoder to 200 gets divided by 4 in byte "t"
  }   
  else if ((T > 50) && (T < 100)) {   //condition to display number for temp
    if (T < 100) {                    //if only 2 digits
      u8g.print("  ");                //space to the right
      }
    u8g.print(T);                     //display set temp
    u8g.drawCircle(60, 23, 3);        //circle representing degree
  }
  
}

So far i have tried;
Changing the "if" to "else if"
Changing the tempKnob.write () to all sorts of variables above and below 200
Changing the "<=" to less "<" only. and even "=="

I'm sure its something simple that i'm missing. But i can't for the life of me figure it out.

Thank you!
Brian

I'm not sure if it will solve your problem but I would organize the IF statements in a top to bottom sequence to simplify the logic

if (T >= 100) {

}
 else if (T > 50) {

}
else {

}

...R

I've tried every combination of "if"s and "else"s i can think of. still nothing. :frowning:

I would be suspicious of this line

    tempKnob.write (200);            //write encoder to 200 gets divided by 4 in byte "t"

What does it do exactly and what does the parameter mean ?

UKHeliBob:
I would be suspicious of this line

    tempKnob.write (200);            //write encoder to 200 gets divided by 4 in byte "t"

What does it do exactly and what does the parameter mean ?

I goofed on my notes. it should be an uppercase "T" not a lower case. But the idea is that it will not allow "T" to go below 50. the 200 gets divided by 4 in the line

     T=(newTemp/4);

It works perfect on the upper end of the scale.

if (T >= 100) {                     //condition for max heat
     u8g.print("Hot");                //display hot
     tempKnob.write(400);             //write encoder to 400 gets divided by 4 in byte "T"
  }

Thats what has me so confused. Why it will work one way but not another.

Dingo509:
I've tried every combination of "if"s and "else"s i can think of. still nothing. :frowning:

Have you tried this one

  if (T >= 100) {                     //condition for max heat
     u8g.print("Hot");                //display hot
     tempKnob.write(400);             //write encoder to 400 gets divided by 4 in byte "T"
  }

  else if (T > 50) {   //condition to display number for temp
    if (T < 100) {                    //if only 2 digits     <--------this test is unncessary, it will always be true
      u8g.print("  ");                //space to the right
      }
    u8g.print(T);                     //display set temp
    u8g.drawCircle(60, 23, 3);        //circle representing degree
  }
  
  else  {                      //condistion for max cool
     u8g.print ("Max");               //display max
     tempKnob.write (200);            //write encoder to 200 gets divided by 4 in byte "t"
  }

...R

No i hadn't thought of that combination!

However. No joy, same result.

I've went thru the library documentation and even tried running both encoder pins to interrupt pins are the arduino. which by my research are pins 2, and 3? i thought maybe the pin rotating one direction was triggering the interrupt and not rotating the other. Still no change.

The only way i can get it to do anything other than resetting it, is to change this line...

 tempKnob.write (200);            //write encoder to 200 gets divided by 4 in byte "T"

To this...

tempKnob.write (203);            //write encoder to 200 gets divided by 4 in byte "T"

It works, but changes the "feel" of the reaction between detents and display. Now of course the curiosity sets it and wonders why? Maybe its just me, but that seems like a cheating way to do it?

    tempKnob.write (200);            //write encoder to 200 gets divided by 4 in byte "t"

the idea is that it will not allow "T" to go below 50.

Using that logic
tempKnob.write(400);would not let it go below 100

Are you sure that
tempKnob.write (200);is not setting the maximum temperature ?

Dingo509:
No i hadn't thought of that combination!

Rather a waste of my time to have mentioned it in Reply #1 ???

However. No joy, same result.

Explain the problem again - maybe I will figure it out from a slightly different description

Edit to add ...

Maybe the problem is that when your T value is <= 50 you want it to rise above 50 with a single encoder pulse. If that is the case you need to set the encoder value (tempKnob.write) to a number which calculates to T = 49. But 49 * 4 = 196 and 196 + 1 = 197 and, with binary maths 197 / 4 = 49 --- which is no good (still below 50).

A very simple solution is to base your IFs on the actual values - not values / 4. You can use v/4 for display.

...R