Chickenmarkus
Chickenmarkus

Reputation: 1161

Calculation with preprocessor-defines yields incorrect value

I am pretty sure it is a common mistake of a beginner but I don't know the correct words for finding an existing answer.

I have defined some consecutive preprocessor macros:

#define DURATION        10000
#define NUMPIXELS       60
#define NUMTRANSITION   15
#define UNITS_PER_PIXEL 128
#define R   ((NUMPIXELS-1)/2 + NUMTRANSITION) * UNITS_PER_PIXEL

Later I use these values to calculate a value and assign it to a variable. Here two examples:

// example 1
uint16_t temp;    // ranges from 500 to 10000
temp = 255 * (temp - 500) / (10000 - 500);

Here, temp is always 0. Since my guess was/is an issue with the datatype, I also tried uint32_t temp. However, temp was always 255 in this case.

// example 2
uint32_t h = millis() + offset - t0 * R / DURATION;

millis() returns an increasing unsigned long value (milliseconds since the start). Here, h increases a factor of 4 too fast. The same for unsigned long h. When I tried a workaround by dividing by 4*DURATION, h was always 0.

Is it an datatype issue? If or if not, how can I solve it?

Upvotes: 0

Views: 55

Answers (1)

Codebreaker007
Codebreaker007

Reputation: 2989

This code works on Arduino Uno and an ESP32 as expected

    #define DURATION        10000
    #define NUMPIXELS       60
    #define NUMTRANSITION   15
    #define UNITS_PER_PIXEL 128
    #define R   ((NUMPIXELS-1)/2 + NUMTRANSITION) * UNITS_PER_PIXEL
    uint32_t t0 = millis();

    void setup() {
      // put your setup code here, to run once:
      Serial.begin (115200);
      //Later I use these values to calculate a value and assign it to a variable. Here two examples:

      // example 1

      randomSeed(721);
    }

    void loop() {
     // For UNO /ESP use uint16_t temp = random(500,10000);    // ranges from 500 to 10000
     // for ATtiny85 (DigiSpark)
    uint32_t temp = random(500,10000);    // ranges from 500 to 10000
      temp = 255 * (temp - 500) / (10000 - 500);

      // Here, temp is always 0. Since my guess was / is an issue with the datatype, I also tried uint32_t temp. However, temp was always 255 in this case.

      // example 2
      Serial.println(temp);
      uint16_t offset = random(2000, 5000);
      uint32_t h = millis() + offset - t0 * R / DURATION;
      Serial.println(h);
    delay (5000); // Only to prevent too much Serial data, never use in production
    }

Environment ArduinoIDE 1.8.12/ avr core 1.8.2 and ESP32 1.04.
What hardware are you compiling to? Try the test program, it does (at least on the tested hardware) what it should. EDIT: For reference OP uses Attiny85 (Digispark) where var size defs are more critical than on UNO /ESP -instead of Serial you would use SerialUSB.
Tip for future support requesters -> always reference your environment (HW & SW) with microcontrollers because of possible hardware specific issues

Upvotes: 1

Related Questions