Умножение вместо деления
- Войдите на сайт для отправки комментариев
Втр, 20/10/2015 - 23:56
Привет всем.
Наблюдается неадекватнная реакция ардуины на арифметические действия.
Вот код, по логике всё хорошо:
//******************************************************************** unsigned long millis_tah; volatile int sz1=0; volatile unsigned long tah; unsigned long tah_new; //******************************************************************** void setup(){ attachInterrupt(1, tachometer, CHANGE); pinMode(11, OUTPUT); } void loop() { { digitalWrite(11, HIGH); delay(tah_new); digitalWrite(11, LOW); delay(tah_new); } } void tachometer(){ tah=((millis()- micros_tah)); //измеряем частоту на входе тахометра по прерыванию micros_tah= millis(); tah_new=tah*1.5; //тут умножаем sz1=0; }
Но, как только подаём 50Гц скетчу, начинается жесть... 50*1,5=33,3(3) для ардуины...
По идее 50/1,5=33,3...
Ок, проверяем в обратную сторону, 50/1,5=75 (опять же так считает ардуина)
Вопрос, что с ней блин не так?
Нижний график =50Гц, верхний =33,3Гц (после "умножения").
Есть идеи?
Разберись с типами.
Ты int на float умножаешь и записываешь в int
Ок, пусть коэффицент будет равен 2. Два не флоат? В итоге получаем 50*2=25 и 50/2=100 (по мнению Ардуины). Так что боюсь тут дело не в объявлении переменных...
Опиши словами алгоритм.
Еще у тебя переменные не инициализированы.
micros_tah нигде не объявлено.
2-5 - бредятина с объявлением.
Берём сигнал с мозга машины, пихаем его в ардуину, далее по изменению фронтов считаем время между импульсами, посчитанное время равно периоду сигнала, период умножаем на 1,5(да вообще без разницы) и подпихиваем его в луп, на подачу ШИМ с преобразованной частотой. Точка.
"переменные не инициализированы." Как воспринимать сиё замечание?
Со второй по пятую включительно?
Извиняюсь, опечатка с micros_tah, она объявлена как millis_tah, пока редактировал упустил.
Ну ты же период измерил. Не частоту. Умножил период на 1.5, увеличил значить и вывел. А значить частоту уменшил. Все норм...
Ну ты же период измерил. Не частоту. Умножил период на 1.5, увеличил значить и вывел. А значить частоту уменшил. Все норм...
Всё верно.... Спасибо, мозги не работают ничерта
Можно закрывать...
Ченч в интеррапте сильно не люблю, предпочитаю райз , или фалл, как то олнозначнее...
Вообще-то если целую величину нужнор увеличить в 1.5 раза, то обычно сначала умножают ее на 3, а потом делят на 2.
(вместо деления на 2 можно сдвинуть на 1 вправо, но, по идее, компилятор должен это сделать сам)
Если уж лезть в дебри оптимизации, а это иногда полезно, то умножение целого на 3 это сдвинуть его влево на 1 и прибавить исходное. После этого сдвинем вправо на 1, т.е. делим на 2. Вот и результат умножили на 1,5 без умножения. Так делают истиные ценители извращений :)
Нет, любители извращений как раз масштабируют целые путем перевода их в вещественные и обратно.
Вообще-то если целую величину нужнор увеличить в 1.5 раза, то обычно сначала умножают ее на 3, а потом делят на 2.
(вместо деления на 2 можно сдвинуть на 1 вправо, но, по идее, компилятор должен это сделать сам)
Коэффицент равный 1,5 требуется использовать если в прерывании (CHANGE), а если (RISING или FALLING) то там уже будет 3, то есть целое число