Как вернуть значение из нецелочисленного ввода между 0-5 из диапазона вывода 0-320 в методе map()
Я экспериментирую с использованием метода map() в скетче ArduinoIDE, пытаясь получить положение пикселя для горизонтального измерителя в диапазоне 0–320 из входного значения в диапазоне 0–5. Однако, когда я это делаю, я вижу в методе, что ввод должен быть «длинным». Вот мой пример кода:
float voltage = 2.5;
float meterPosition = map(voltage, 0, 5, 0, 320);
tft.fillRect(0, 0, meterPosition, 10, TFT_GREEN);
tft.setCursor(10, 70);
tft.setTextSize(3);
tft.println(voltage);
tft.println(meterPosition);
Но когда я запускаю это, несмотря на то, что входное значение составляет 50% входного диапазона, я ожидал, что значениеmeterPosition будет 160, но оно равно 128, я думаю, из-за того, что значения для этого метода должны быть типа 'long ' и поэтому значение 'float' округляется и становится типом 'long' (думаю, именно это и происходит!!).
Меня смущает функция метода map(), если вы не можете сопоставить какой-либо диапазон с любым другим диапазоном без использования десятичных знаков в качестве входных данных. Я явно что-то здесь упускаю, так что же мне нужно изменить в коде метода map(), чтобы он работал в моем примере, пожалуйста, если я не могу использовать числа с плавающей запятой ?
Спасибо. Джон
@John, 👍0
Обсуждение2 ответа
Лучший ответ:
Как вы уже заметили, функция map()
предназначена для работы с
длинный
тип данных. Вот его реализация:
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Если вы хотите использовать числа с плавающей запятой, вы можете написать версию этой функции.
который работает с float. Обратите внимание, однако, что, поскольку вы используете нули
как для in_min
, так и для out_min
выражение упрощается до
становится тривиальным:
float meterPosition = voltage * 320 / 5.0;
Однако я бы предложил два небольших изменения в этом выражении:
добавьте скобки вокруг
(320 / 5.0)
: тогда это соотношение будет оценивается во время компиляции, и вы сэкономите дорогостоящее время выполнения деление с плавающей запятойокруглить до ближайшего целого числа, чтобы свести к минимуму ошибку: ваш позиция пикселя в любом случае должна быть целым числом.
С этими предложениями у нас есть:
int meterPosition = round(voltage * (320 / 5.0));
Не забывайте .0
в 5.0
, иначе вы получите целое число
подразделение.
Обратите внимание, что использование map()
с диапазонами, масштабированными с коэффициентом 100, не является
ужасно хорошая идея: вы потратите довольно много циклов процессора, выполняя
бесполезные вычисления, а результат будет испорчен двумя округлениями
ошибки вместо одной.
Извините за мою глупость! Я думаю, что понял, как это сделать, это просто вопрос масштабирования входных значений и диапазона ввода на 100.
- C++ против языка Arduino?
- ошибка: ожидаемое первичное выражение перед токеном ','
- Ввести идентификатор чипа ESP32 в строковую переменную (новичок в Arduino/C++)
- Передача функции-члена класса в качестве аргумента
- Улучшенное циклическое переключение цветов RGB.
- Какие есть другие IDE для Arduino?
- Несовместимые типы при назначении «uint8_t {aka unsigned char}» на «uint8_t [1] {aka unsigned char [1]}»
- Как преобразовать массив символов в строку в arduino?
Как насчет того, чтобы просто сказать «floatmeterPosition = voltage * 64.0;»?, @6v6gt