Приведение типов

Подскажите пожалуйста как грамотно сделать такое. Мне нужно с датчика взять значение, оно там float, и перевести его в беззнаковое двухбитное целое uint16_t увеличив в 100 раз.
Я делаю сейчас так:

  int vol = (int)(readCurrentAC(PIN_ASC1) * 100);
  if (vol < 0) Pump[0].Relay.Curr = 0;
  else Pump[0].Relay.Curr = (uint16_t)vol;

Два преобразования на одно действие. Может можно как-то грамотнее сделать?
Сначала в Int для избавления от минуса. Если без него, то при минусовом float uint16_t переполняется и слишком большое значение получает.

Что за датчик, что во float выдаёт?
И как int избавляет от минуса?
Я понимаю, если бы abs() был, но int…

Не сам датчик, а функция readCurrentAC. Переписывать ее и подстраивать под себя не хочется. Датчик ACS712

Получаем изначально во float (и получили например -0,01) *100 и переводим в int = -1 Далее if vol < 0 …

Переписать дешевле, чем акробатику с float устраивать. Все равно там целочисленный тип с analogread прилетает. Заодно потенциально не вылетите за 65535 при конверсиях. И в точности не потеряете.

А так - constrain(), например. Но это будет то же самое, только заметенное под коврик.

1 лайк

Вот она вся:

Спойлер
#define ADC_COUNT 1023
#define ADC_COUNT_ACS712_1A 37.88
#define RMS 0.707
#define FAULT_ADC 0.011

float readCurrentAC(const uint8_t _pin) {
  int sensorValue = 0;
  int maxValue = 0;
  int minValue = ADC_COUNT;
  float sensorCurrent = 0;
  float sensorCurrentRMS = 0;
  unsigned long startTime = millis();
  while ((millis() - startTime) < 60) {
    sensorValue = analogRead(_pin);
    if (sensorValue > maxValue) {
      maxValue = sensorValue;
    } else if (sensorValue < minValue) {
      minValue = sensorValue;
    }
  }
  maxValue -= maxValue * FAULT_ADC;
  minValue += minValue * FAULT_ADC;
  sensorCurrent = (((maxValue)-minValue) / 2.0) / ADC_COUNT_ACS712_1A;
  sensorCurrentRMS = sensorCurrent * RMS;
  return sensorCurrentRMS;
}

Я, если честно, не понимаю как ее можно переписать, чтобы она выдавала целыми. В итоге все равно сведется к моему способу или constrain(). Ну а по поводу constrain() - это примерно тоже что я и сделал изначально… Я думал может каким “хакерским способом” можно преобразовать float в целое беззнаковое, учитывая минусовое значение во float…
В принципе, не критично, оставлю как есть либо заменю беззнаковое на знаковое. И будет тоже самое, но на одно преобразование меньше))

Хакерским способом можно в int сбросить старший бит (минус). Но в данном случае это только выпендреж.

auto vol = readCurrentAC(PIN_ASC1) * 100;
Pump[0].Relay.Curr = vol < 0 ? 0 : vol

остальное ненужный шум

2 лайка

+1 . Только round() можно добавить для красоты восприятия.

Сразу величины помножить на коэффициент, выводящий их в область целых чисел?

Рано Вам ещё хакерскими способами, Вы бит от байта не отличаете. Так что сделали, работает и радуйтесь.

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

@TempArd , откажитесь от этой библиотеки, ее автору нельзя доверять. (в принципе, чтобы понять это, даже не обязательно было лезть в исходник, достаточно обнаружить, что функция выдает результат в float, на что сразу обратил внимание sadman).

2 лайка

Может и рано, но скорее уже поздно… Евгений, при всем моем уважении, ну не делайте выводов раньше времени. Опечатался, не двухбитная а двухбайтная конечно же переменная (я же ее тип привел uint16_t)
Я на этом форуме(еще на старом) уже лет 15. В основном читаю, вопросы задаю очень редко раз в несколько лет))) И всегда в них уточняю, что я не программист, это мое домашнее хобби с юношеских лет. Лично к вам как к программисту у меня большое уважение. Вы действительно грамотный и профессионал в своем деле. И Вы один из немногих которые дают развернутый подробно и с вариантами решений и пояснений к коду. Респект. И мне давно также помогли очень. Но почему на этом форуме завелась какая-то зараза, многие хотят задрать нос и считают необходимым ткнуть пальцем в любое малозаметное слабое место в вопросе???
Да, не спорю, много, очень много есть хамских вопросов… сам ели сдерживаюсь, чтобы не пособачиться тут… Но иногда вижу, что вопрошающий старается, объясняет свой вопрос, но в первом же ответе получает от какого нибудь умника по голове и все, его конечно же подхватывают другие, причем скорее всего, что бы выглядеть в глазах других таким же мачо(буквы перепутал местами)
До смешного вы (это всем) тут друг друга уже тыкаете)))
Все вроде уже взрослые (пожилые даже) мужики, а как в детском саду, ищите слабого и давай его учить жизни…
Причем сами себе (я про постояльцев) делаете подобные замечания но все со временем только хуже становится… :slight_smile:
80% срача в темах просто на пустом месте.

2 лайка

Так может люди просто отдыхают? И наставляют на путь истинный указывая на ошибки. Ну чем плохо то? Нет, ну прям ранимые какие то! Ну если дуб - так и признавай, и посмеёмся вместе, чего из себя изображать лучшего чем ты есть на самом деле!

У меня вот ощущение, что 80% срача оттого, что добродушную шутку и подтрунивание воспринимают как наезд и обижаются (или начинают огрызаться).

Хорошо, по теме

Будет или НЕ будет?

В принципе мне это не нужно для какой-то точности, это просто датчик тока (работает нагрузка или нет, и не перегружена ли она (работает в натяг, насос))

Но к

прислушаюсь.
Ради интереса, хоть мне Евгений и посоветовал, раз работает, то оставить так :slight_smile: Я, в общем то согласен, но… Как переделать для вывода целочисленного значения?
С математикой у меня тоже не супер… Будет достаточно, если все вещественные константы умножить на 1000 и сделать целыми, а результат потом / 100 и % 100
Если кому не сложно, можете переделать readCurrentAC выше для вывода целых * 100. Ну т.е. выдала результат 257 - это значит 2 ампера 57 сотых…

Я полностью с Вами согласен, и именно это и нужно понимать при ответах :slight_smile:
Сам лично остаюсь до последнего в уважительном ритме :slight_smile:

Это все понятно, но дело в том, что заходишь на форум вопрос решать а не смеяться :)) Когда со стороны - это забавно, а когда хочется решить вопрос, а кому-то весело и других задорит, и конечно же авторский вопрос уходит в глум, а автор понятно дело злится. Всем добра!)

Вот смотрите, сам датчик ничего “вещественного” не выдаёт. А далее, следите за руками:

  1. автор библиотеки зачем-то привёл всё к float;
  2. теперь Вы хотите приводить обратно.

Н проще ли убрать п. 1, тогда и в п.2 нужды не будет.

1 лайк

Ну, так это от вас зависит. Когда нормально формулируешь проблему, когда задаёшь логичные вопросы - поверьте, никто не будет стебаться, не будет повода.

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