Round up or down a value

I am using a stepper motor to tilt my blinds. Pressing the buttons, one will turn 100 steps one direction (CW) and the other 100 steps the other way (CCW).

However occasionally the user may stop the stepper by pressing any button and the position could be, for example 143.

If the user press CW or CCW buttons again I want the number to either round up to 200 or round down to 100 depending on the button pressed. Lambda ceiling or round might be a clue but not sure how to write it.

Thanks

floor(143 / 100) * 100 == 100
ceil(143 / 100) * 100 == 200

For your specific problem:

// CW:
return floor(x / 100) * 100 + 100;
// CCW:
return ceil(x / 100) * 100 - 100;

Genius! Thank you Jorg.

1 Like

Hi,

Let’s say X = 142, therefore output should be 100 to go down and 200 to go up.
Let’s now say X = 200, therefore output should be 100 to go down and 300 to go up.

floor(x / 100) * 100 + 100
works flawlessly to step up to next hundred, even if x is 200.

However,
ceil (x / 100) * 100 - 100
does not work. if X=142, the output is 0 (should be 100). if X=200, the output is 100.

// CCW from 142:
ceil (142 / 100) * 100 - 100  
== ceil(1.42) *100 - 100 
== 2 * 100 - 100
== 100  // correct

// CCW from 200:
ceil (200 / 100) * 100 - 100  
== ceil(2) *100 - 100 
== 2 * 100 - 100
== 100  // correct

I don’t see any error here. Did you use floor() instead of ceil()?
Try to debug your code by returning intermediate results. This way you can narrow down the point, where your calculations deviate from the expected result.

Hi Jorg,

Your logic is sound, and when I placed in to ESPHome, of course it works! But debugging in ESPHome can be challenging, so I used ‘Online C++ Debugger - online editor’ to test the code.

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
    int value = 280;
 
   cout << "\n    Next value of " && cout << value && cout << " is: " && cout << floor (value/100) * 100 + 100;
   cout << "\nPrevious value of " && cout << value  && cout << " is: " && cout << (ceil (value/100))*100-100;
    return 0;
}

This produced the following result:

 Next value of 280 is: 300

Previous value of 280 is: 100

My apologies - thank you again for your help.

1 Like