Arithmatic error

Hi everyone, I'm new on here, having managed so far by just reading other's past experiences.
I have a temp/hum sensing project that has a set point controlled by two rotary switches.
I can read the binary information from the switches, and decode it into integers. My set point is always going to be in the 20 - 30 °C range, so I used the two rotary switches for units, and tenths. (i.e. 2X.X°C)
The rotary switches decoded binary output is assigned the the integers: htUnits, and htTenths.
I'm relatively confident that the hardware is correct as if I just type
hightempAlarm = htTenths;
then the display shows the correct number (03.0 for instance when the Tenths switch is rotated to number 3).
However when I try and use the full code
either
hightempAlarm = 20 + htUnits + ((float)htTenths / 10.0);
or
hightempAlarm = (200 + (10 * (float)htUnits) + (float)htTenths) / 10.0;
then everything works, except when Tenths rotary switch is turned to 3 then it displays 2, and when turned to 4 it displays 3.
I can't understand this as everything else (every other combination) seems to work fine. There are no issues with the Units under any circumstances, only the Tenths.
I'd greatly appreciate any help anyone could offer.

Ian

_4TempHumDisp_rotary.pde (20.5 KB)

Why bother with fractions?
Just multiply everything up by 10 and use integers.

(Suggest you look at arrays and for loops - your code is at least 300 lines too long - it'll be worth it in the long run)

If you replace rotSetUnits1/2/3/4 by an array and likewise for rotSetTenths1/2/3/4, then its trivial to correctly set htUnits and htTenths thus:

void rotSetInterpret() {
  int htUnits = 0;
  int htTenths = 0;
  for (byte i = 3 ; i >= 0 ; i--)
  {
    htUnits = (htUnits << 1) + (rotSetUnits[i] ? 1 : 0) ;
    htTenths = (htTenths << 1) + (rotSetTenths[i] ? 1 : 0) ;
  }
  
  .....

I've used 0..3 for the array indices rather than 1..4 as that's standard practice. The relevant other changes are:

boolean rotSetTenths [4] ;
boolean rotSetUnits [4] ;
  digitalWrite(13, HIGH);   // set the units high whilst they're read
  delay(10);
  rotSetUnits[0] = digitalRead(A5);
  rotSetUnits[1] = digitalRead(A4);
  rotSetUnits[2] = digitalRead(A3);
  rotSetUnits[3] = digitalRead(A2);
  digitalWrite(13, LOW);   // set the units low after reading
  digitalWrite(8, HIGH);   // set the tenths high whilst they're read
  delay(10);
  rotSetTenths[0] = digitalRead(A5);
  rotSetTenths[1] = digitalRead(A4);
  rotSetTenths[2] = digitalRead(A3);
  rotSetTenths[3] = digitalRead(A2);
  digitalWrite(8, LOW);   // set the tenths low after reading
  rotSetInterpret();

Wow thanks guys, that's been incredibly helpful.
AWOL I guess that's the obvious way to go. I've done it and it works. Don't know why I didn't think of it before, I guess a fresh pair of eyes was what it needed.
I've put in hightempAlarm = 200 + (10 * htUnits) + htTenths; and don't worry I haven't forgotten the likes of if ((10 * hightemp) >= hightempAlarm)
Otherwise I'd never hit set point :slight_smile:

MarkT, some of that makes a lot of sense, the rest is beyond my understanding at this point. I know my code is messy, its a work in progress. The thing is I need it to work soon, we frequently have air handling units overheating and it needs sorting ASAP. I've done my best with my limited understanding to get things going quickly. I will endeavour to comprehend the neater ways to code it and fix it up at a later date.
Thanks for the help though. Its certainly a starting point for me to neaten things up. I guess I'm spoiled with 30KB of memory to play with :slight_smile:
Would've needed to be a lot tidier if big modern chips weren't so available.

Thanks again guys, I was scratching my head for a few days trying to sort that one