Расчет с использованием препроцессора дает неверное значение - PullRequest
0 голосов
/ 13 марта 2020

Я почти уверен, что это распространенная ошибка новичка, но я не знаю правильных слов для поиска существующего ответа.

Я определил несколько последовательных макросов препроцессора:

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

Позже я использую эти значения, чтобы вычислить значение и присвоить его переменной. Вот два примера:

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

Здесь temp всегда 0. Так как мое предположение было / является проблемой с типом данных, я также попытался uint32_t temp. Однако в этом случае temp всегда было 255.

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

millis() возвращает возрастающее значение unsigned long (миллисекунды с момента запуска). Здесь h слишком быстро увеличивает коэффициент в 4 раза. То же самое для unsigned long h. Когда я пытался обойти это путем деления на 4*DURATION, h всегда было 0.

Это проблема типа данных? Если или нет, как я могу решить это?

1 Ответ

1 голос
/ 13 марта 2020

Этот код работает на Arduino Uno и ESP32, как и ожидалось

    #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
    }

Среда ArduinoIDE 1.8.12 / avr core 1.8.2 и ESP32 1.04.
На каком оборудовании вы компилируете? Попробуйте тестовую программу, она делает (по крайней мере, на протестированном оборудовании) то, что должна. РЕДАКТИРОВАТЬ: Для справки OP использует Attiny85 (Digispark), где определения размера var более критичны, чем в UNO / ESP вместо Serial, вы бы использовали SerialUSB.
Совет для будущих лиц, обращающихся за поддержкой -> всегда указывайте в своей среде (HW & SW) микроконтроллеры из-за возможных аппаратных спецификаций c проблем

...