ФУНКЦИЯ map

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

Уважаемые форумчане, кто может подскажет как сделать чтобы функция map работала в режиме float.

 

vk007
Offline
Зарегистрирован: 16.06.2015

Функция 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;
}

Написать свою.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015
[code]
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
Функция map() оперирует целыми числами. При пропорциональном переносе дробная часть не округляется по правилами, а просто отбрасывается.
}

[/code]

 

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

при вызове  map получаем цисло без запятой,  а нужно два знака после 100,00

 

vk007
Offline
Зарегистрирован: 16.06.2015

Как скажете. Ну ежели лень по образцу написать свою, предлагаю второй вариант - умножайте исходные данные на 100.0, результат делите на 100.0. Тоже не подходит?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

oleg_kazakof пишет:

при вызове  map получаем цисло без запятой,  а нужно два знака после 100,00

У чисел не бывает какого-то определенного числа знаков после запятой. Бывают разные типы чисел: целые (без дробной части) и вещественные (с дробной частью). Количество знаков после запятой - свойство не самого числа, а способа его преобразования в строку (когды вы видите на экрне число, на самом деле это уже не число, а строка символов).

Пишите, как Вам посоветовали, собственную map для вещественных чисел, и будет Вам столько знаков после запятой, сколько захотите.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Бывают очень даже. Двоично-десятичные числа с 3-я знаками после запятой. Ну и Кобол можно ещё вспомнить.. :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Еще бывают числа с фиксированной точкой - у них количество знаков после запятой определяется "конструкцией". Еще есть трехзначная логика, а также числа переменной длины. Много чего есть, особенно если поковырять историю вычислительной техники, а также всякие курьезные проекты. Вопрос в том, реализованы ли они в Ардуино. Мы ведь здесь разбираем конктретный вопрогс, а не демонстрируем свою эрудицию.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

Спасибо за участие в проблеме,  пока нет времени проверить советы.

RE:для andriano   # при вызове map получаем число без запятой, а нужно два знака после 100,00

          Ваши раcсуждениях о числах несомненно правильны. Исправлю вопрос: нужно минимум два знака после запятой 100,00********

        остальные ************ не принципиальны.

 

 

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

oleg_kazakof пишет:

Спасибо за участие в проблеме,  пока нет времени проверить советы.

RE:для andriano   # при вызове map получаем число без запятой, а нужно два знака после 100,00

          Ваши раcсуждениях о числах несомненно правильны. Исправлю вопрос: нужно минимум два знака после запятой 100,00********

        остальные ************ не принципиальны.

А что вам мешает внимательно прочитать пост vk007?

and361
Offline
Зарегистрирован: 25.03.2018

Сваял 8ми канальный вольтметр в образовательных целях, https://www.youtube.com/watch?v=yqLK2cNlzLk   там же полный скетч

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

аналогично, при вызове  map получаем число без запятой,  а нужно два или более знака после 100,00

попробовал совет выше:

---------------------------

int x;

x = map(adc0, 23000, 23800, 3000, 1500) *100.0 /100.0;

lcd.print(x);

---------------------------

получаем то же число, что и без математических функций *100.0 /100.0 - а хочется результат типа 16,87 вместо 1687. 

Скажите чайнику - где копать, или, как корректно прописать формулу чтобы выводило дробные числа.. :(

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

and361 пишет:

хочется результат типа 16,87 вместо 1687. 

1687/100.00 = 16.87

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

and361 пишет:
Скажите чайнику - где копать, или, как корректно прописать формулу чтобы выводило дробные числа.. :(
  Вот скажите как чайник чайнику, а вы просто функции писать на Си можете, или вас надо отправлять читать Ветхий Завет.   https://nsu.ru/xmlui/bitstream/handle/nsu/9058/kr.pdf

and361
Offline
Зарегистрирован: 25.03.2018

 x = map(adc0, 23000, 23800, 3000, 1500)  /100.00;

 

результат = 16 , все что после дробного значения функция map отбросила. Такой вариант уже пробовал. 

Информатики в школе не было, так уж случилось. 

 

 

 

negavoid
Offline
Зарегистрирован: 09.07.2016

мде :)

float map_float(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

 

and361
Offline
Зарегистрирован: 25.03.2018

подставил свои значения:

-------------

float map_float(float x, float 23000, float 23800, float 3000, float 1500);
  return (x - 23000) * (1500 - 3000) / (23800 - 23800) + 3000;
 
  // x = map(adc0, 23000, 23800, 3000, 1500);
 
----------------
получил ошибку компилятора arduino ide вида:

expected ',' or '...' before numeric constant

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Этташотакое? О_о

and361
Offline
Зарегистрирован: 25.03.2018

Ну кто нибудь пропишите пожалуйста корректно, весь прожект из за запятой встал.

3 дня назад впервые ардуину в руках держал. :(

еще нагуглил можно использовать float вместо int.

----

float x;

---

так оно просто тупо добавляет запятую и пару нулей к результату. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

and361 пишет:
3 дня назад впервые ардуину в руках держал. :(

А компьютер вы держали 5 дней и то между ног. Компьютер это не учитель, если вы криво набираете, то он так и работает.

and361
Offline
Зарегистрирован: 25.03.2018

qwone пишет:

[А компьютер вы держали 5 дней и то между ног.

словесный понос любого дебила, пытающегося завоевать дешевый авторитет на чайниках никому не интересен, жаль что ни одна конфа не заносит таких автоматом в >null >del как несущий полезной информации на 0%.

Вопрос остался актуален. :( Если все так сложно с функцией map, если уж она и по документации с дробными числами не работает, может имеет смысл его упростить выносом математики как то отдельно?

Если да, то вопрос - как проще сделать из результата функции map 1000 скажем, 10,00 c выводом в порт и в lcd? Заранее спасибо.

 

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

and361 пишет:
словесный понос любого дебила, пытающегося завоевать дешевый авторитет на чайниках никому не интересен, жаль что ни одна конфа не заносит таких автоматом в >null >del как несущий полезной информации на 0%.
А смысл вам помогать. Вы как дырявое сито, куда не лей , все на пол будет.

float map_float(float x, float 23000, float 23800, float 3000, float 1500); //<- вот нахрена вы сюда ; воткнули
  return (x - 23000) * (1500 - 3000) / (23800 - 23800) + 3000; //<- а цифры воткнули зачем. Это же функция

А так вы не состоянии ни правильно выложить скетч на форум ни правильно взять. Пороть вас что ли за это. Так я далеко. Авторитет на вас. Так даже это как с козла молока. Только в игнор или глум над вами. 

https://www.youtube.com/watch?v=FxmG4_Q4zGA

winartem
Offline
Зарегистрирован: 31.01.2021

Добрый день.  Можете смеятся, но я наступил на те же грабли.

y=map ( x, 10, 1010, 10, 30) // нужно преобразовать в величины со знаками, после запятой.

Пишу по формуле:

y= long map ( long x, long 10, long 1010, long 10, long 30)
{
  return ( x - 10)*(30 - 10) / (1010 - 10) + 10
}
/*получаю ошибки: mod7:1: error: expected primary-expression before 'long'
                  mod7:1: error: expected `;' before 'long' */

Не пинайте, прошу напишите как надо, вроде ж точно повторил формулу. В Return также вставил цифры, потому что in_min, in_max, out_min, out_max это  10, 1010, 10 , 30 соответственно.

 

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А что Вы хотели сказать "long" в строке №1?

И что значит "y="?

Как одно с другим сочетается?

sadman41
Offline
Зарегистрирован: 19.10.2016

Чью формулу повторили?

Я бы посмеялся, но мне плакать хочется. Один попытался борщ из кило гвоздей сварить, второй у него рецепт попросил. Может уже перестанете делать очевидно глупые вещи?

winartem
Offline
Зарегистрирован: 31.01.2021

andriano пишет:

А что Вы хотели сказать "long" в строке №1?

И что значит "y="?

Как одно с другим сочетается?

Заменил  map()   в своём скетче : y = map(x, 10, 1010, 10, 30) по формуле ниже. 


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

Попытаюсь пояснить подробней:

Вот кусок рабочего кода, с помощью его я переменным резистором выставляю желаемую температуру в помещении. 
 
sensor_room_pump = analogRead(A3);
 sensor_room_pump = constrain(sensor_room_pump, 10 , 1010);
 room_pump = map(sensor_room_pump, 10, 1010, 10, 30);
//sensor_room_pump считывает с аналогового входа А3 (переменный резистор).  
//Ограничиваем значения от 10 до 1010
//присваиваем переменной room_pump значение от 10 до 30 с помощью функции map. 

Всё работает, но откидывает десятые, мне нужно точнее задавать температуру.

Переделываю код в такой:

sensor_room_pump = analogRead(A3);
  sensor_room_pump = constrain(sensor_room_pump, 10 , 1010);
  room_pump = long map( long sensor_room_pump , long 10, long 1010, long 10, long 30)
{
 return ( sensor_room_pump - 10)*(30 - 10) / (1010 - 10) + 10
}

Понимаю, что где-то бред в коде написал, но не знаю именно что.

 

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Я бы посоветовал прочитать статью типа "функции в языке Си". Потому что бред тут все.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

winartem, сравните третьи строки в своих втором и третьем фрагментах.

 

PS. А вообще, sadman41 прав: невозможно написать программу методом обезьяны с пишущей машинкой - нужно понимать, что пишешь.

winartem
Offline
Зарегистрирован: 31.01.2021

andriano пишет:

winartem, сравните третьи строки в своих втором и третьем фрагментах.

 

PS. А вообще, sadman41 прав: невозможно написать программу методом обезьяны с пишущей машинкой - нужно понимать, что пишешь.

сравнил: добавлено спереди тип данных Long. Больше ничего.  Понимаю, что спотыкаюсь об что-то простое, но не знаю где.  

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

winartem пишет:

сравнил: добавлено спереди тип данных Long. Больше ничего.  Понимаю, что спотыкаюсь об что-то простое, но не знаю где.  

Читайте Кернигана и Ритчи.

От корки и до корки.

И в раздел "Программирование" больше не заходите, пока не прочитаете.

А здесь такие вопросы размещать - просто неприлично.

anatoli_nik
Offline
Зарегистрирован: 17.01.2019

Жертвы ЕГЭ...... А что будет дальше?.....

winartem
Offline
Зарегистрирован: 31.01.2021

Ребята, да не программист я, совсем в другой сфере работаю. Всего-то нужно было перевести значения с целых чисел в числа с плавающей точкой . От корки до корки изучать книги по программированию на языке Си, чтобы потом эта информация наверняка не пригодилась, не знаю целесообразно ли. Может, ошибся с разделом форума, извините, просто тема уже эта тут существовала.

Какое ЕГЭ? 25 лет назад школу закончил, Кого то может ещё и на свете не было. Не было тогда и компьютеров у нас.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

winartem, а этом форуме принцип простой: кто хочет научиться, тому помогут. Совершенно бесплатно.

А кто учиться не хочет, но нужен конкретный проект, - тому единственная дорога в платный раздел "Ищу исполнителя".

Als
Offline
Зарегистрирован: 17.05.2015
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void setup() 
{
  Serial.begin(115200);
}

void loop()
{
  Serial.println( fmap(50, 0, 100, 0, 110 ) );
  Serial.println( fmap(50, 0, 100, 100, 0 ) );
  Serial.println( fmap(40, 0, 100, 100, 0 ) );
  Serial.println( fmap(1,  0, 100, 0,  10 ) );
  delay(1000);
}

 

Als
Offline
Зарегистрирован: 17.05.2015

Ребята, да не медик я, совсем в другой сфере работаю. Всего-то нужно было...

Pyotr
Offline
Зарегистрирован: 12.03.2014

Als, в 13 строке считать через fmap()  избыточно. Там нужно найти "вес" или "цену" входной единицы и умножить на количество этих единиц.

float val = 110/100*50;

В строку 3 Вашего скетча подставьте нули вместо минимальных значений и получите такой результат.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Pyotr пишет:

float val = 110/100*50;

Поправлю. 

float val = 110.0/100*50;

иначе считать будет всё равно в целых, и над результатом придётся долго сидеть в тягостном недоумении

 
Kakmyc
Offline
Зарегистрирован: 15.01.2018

ТС у тебя весь map() сводится к простым арифметическим действиям:
1. y=х*1.1
2. y=MAX-x
3. см 2
4. y=x/10

Зачем ты людей по такой фигне дергаешь ?
Учебник математики почитай за 3ий класс

Pyotr
Offline
Зарегистрирован: 12.03.2014

DetSimen пишет:

Pyotr пишет:

float val = 110/100*50;

Поправлю. 

float val = 110.0/100*50;

иначе считать будет всё равно в целых, и над результатом придётся долго сидеть в тягостном недоумении

 

Дим, зато меня никто из стариков не упрекнет, что я даю готовый код новичкам, над которым уж совсем ненадо думать))))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Pyotr пишет:

Дим, зато меня никто из стариков не упрекнет, что я даю готовый код новичкам, над которым уж совсем ненадо думать))))

Лучше дать направление, чем неправильный код.  Для новичков же твой код выглядит с виду пристойно, но не работает, как должен с его точки зрения. Дьявол то в нюансах, до которых надо дорасти.  

kolyn
Offline
Зарегистрирован: 18.01.2019

DetSimen пишет:

Лучше дать направление, чем неправильный код.  Для новичков же твой код выглядит с виду пристойно, но не работает, как должен с его точки зрения. Дьявол то в нюансах, до которых надо дорасти.  

+100500. 

Als
Offline
Зарегистрирован: 17.05.2015

Kakmyc пишет:
ТС у тебя весь map() сводится к простым арифметическим действиям: 1. y=х*1.1 2. y=MAX-x 3. см 2 4. y=x/10 Зачем ты людей по такой фигне дергаешь ? Учебник математики почитай за 3ий класс

Дык, это, я даже не знаю что сказать...

естественно я в примерах привёл простые случаи которые в уме можно проверить, чтоб оценить как функция работает.

С всеми нулями отработает как и штатная функция, разве нет?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Als пишет:

Kakmyc пишет:
ТС у тебя весь map() сводится к простым арифметическим действиям: 1. y=х*1.1 2. y=MAX-x 3. см 2 4. y=x/10 Зачем ты людей по такой фигне дергаешь ? Учебник математики почитай за 3ий класс

Дык, это, я даже не знаю что сказать...

естественно я в примерах привёл простые случаи которые в уме можно проверить, чтоб оценить как функция работает.

С всеми нулями отработает как и штатная функция, разве нет?

Не нужно приводить примеры, нужно приводить код, с которым проблемы.
Иначе это введение в заблуждение тех от кого ждут ответа.

И в любом случае, даже с любыми другими значениями, в вашем случае, можно все параметры умножить на 100, а после вычисления перевести в float и точно так же поделить.
Хотя и это бред, если учесть для каких целей вам это понадобилось.
В вашем случае (отопление), десятые и сотые градусов , никакого значения не имеют, т.к. разброс температуры в любом случае будет +/-5°С, из за инертности системы во первых и из за неравномерности нагрева во вторых.

b707
Offline
Зарегистрирован: 26.05.2017

Народ, по-моему вы что-то напутали. Участник Als не спрашивает, он отвечает на вопрос

Kakmyc
Offline
Зарегистрирован: 15.01.2018

b707 пишет:

Народ, по-моему вы что-то напутали. Участник Als не спрашивает, он отвечает на вопрос

Ну а нафига он тогда отвечает на то, что было адресовано ТС ?