Здравствуйте, форумчане. Делаю проект бортового компа. Столкнулся с проблемой измерения скорости автомобиля. Штатный датчик скорости находится в коробасе и выдает 4073 импульса на 1 километр пройденного пути. О чем гласит наклейка на приборной панели. Датчик представляет из себя обычный геркон, который замыкает подтянутый к 5 вольтам вход приборки на землю. 4073 импульса на штатных колесах 15 дюймов. У меня штатные. Но когда я начинаю движение, мой код выдает скорость приблизительно в 1.5 раз больше реальной. Скорость измеряю в прерываниях по INT0( по спаду, внутренняя подтяжка включена), и по прерыванию CTC таймера 1. Прерывание таймера настроено каждую секунду. Думал, дребезг. Поставил на вход кондер 0.1 мкф и на землю. Показания стали в 4 раза меньше реальной скорости авто. Поставил 0.01 мкФ. Ничего не изменилось, показания также ниже в 4 раза. Куда копать? Код привожу.
Код:
ISR(INT0_vect) { // 1000/imp - это расстояние, пройденное за 1 импульс в метрах. 1000 метров/на 4073 импульса =0,24551 метра за 1 импульс. cnt_pobeg++; // счетчик пришедших спадов probeg=probeg+0.00024551; // увеличиваем пробег с каждым импульсом (в км)
}
ISR(TIMER1_COMPA_vect) { // Режим CTC, вызов каждую 1 сек speed_m_s=(float)cnt_pobeg*0.24551; // Скорость в метрах/сек cnt_pobeg=0; }
while(1) { speed_km_h= (speed_m_s*3.6); sprintf(val_1,"%.0f",speed_km_h); // Выводим скорость км/ч }
Посчитайте в км, метрах, сантиметрах или меньше, но уберите этот float. В этой функции/задаче нет смысла из этих числа с плавающей запятой. И пусть таймеры считают мелкие функции (x++ примерно), а если нужно распечатать (напр. время отчета истекло): флаг = 1 и вывести в основной цикл (может за время х из какого-нибудь отчета). Таким образом, вероятность накопленной ошибки из-за скорости обработки становится незначительной.
Я считаю в метрах. Поэтому float. В километрах тоже будет float. Единственный вариант это считать в см. Но дальше в программе, в основном цикле всё равно я приду к float. Т.к. 1км/ч=1м/c *3.6. Если вас не затруднит, приведите код, как сделали бы вы.
Вообще, внимание надо обращать не столько на то, как считать, а больше на то, что потом будет делаться. float не обладает достаточной точностью и ошибка будет накапливаться, если его суммировать, а double сожрёт напрасно ресурсы. Считайте только импульсы и время. Всё. Они у Вас уже есть, они целые. Всякие дробления и приведения к чему-либо делайте непосредственно перед выводом на экран, использовании в расчетах чего-то и т.д.
probeg вообще не инкрементируется. Возможно не обратил внимания на него. Т.к с кондером он точно не инкрементировался, а без кондера смотрел скорость и не глянул пробег. Завтра скажу точно.
Добавлено after 4 minutes 57 seconds: Заказал себе генератор прямоугольных импульсов на 555. Буду пробовать имитировать датчик скорости. О результатах отпишусь.
Один аргумент для переписывания кода без чисел с плавающей запятой (скорость обработки еще не добавили в "минусов"): Понимаете, что float в AVR составляет 32 бита: знак(1 бит), експонента(8 бита), мантиса(23 бита). Т.е. наименьший шаг изменения в 1 бит равен на 2^-23 = 0,00000011920928955078125 .
Теперь вычислите со своему числу 0.00024551 сколько есть погрешности на каждом сборе и как ошибка "накапливается". Если хотите и 100 чисел после зпетаю написать у коеффициента, то там есть 7 цифры после запетаю (и то с условием для 7-мое).
Что float не позоляет иметь достаточную точность - это всерьёз рассматривать не приходится. Другое дело, как правильно заметили выше, скорость обработки float оставляет желать. Накапливать сумму по прерываниям следует в целых числах, да и вывод на индикацию в целых (точнее - с фиксированной точкой) не представляет трудности. Нужно присмотреться к аппаратной части. Поддомкратить кар и осциллом посмотреть - что там за импульсы? Ну или есть автономный осцилл - погонять с приятелем по реальной трассе, а он пусть смотрит импульсы. Дребезг - убрать программно. Или кондёр + триггер Шмитта. Или одновибратор. Просто кондёр - решение слабое и бесперспектвное. В общем-то, задача не из суперсложных. И ещё неизвестно - не гадят ли помехи из бортовой сети. Как организовано питание?
_________________
Последний раз редактировалось Jack_A Вс сен 03, 2023 22:34:15, всего редактировалось 2 раз(а).
Что float не позволяет иметь достаточную точность - это всерьёз рассматривать не приходится.
Увы, но ещё как приходится. Будучи начинающим программистом я из-за этого допускал множество ошибок. Float годен для промежуточных результатов или с коротким сроком жизни. Но в данном случае пофиг. Вся беда в том, что часто программисты отождествляют микроконтроллер с собой: - температура нужна в градусах Цельсия, а датчик выдает в каких-то милливольтах на Кельвин, а у нас 10-битный АЦП? Окей, ща напишем приведение к Цельсиям и будет хорошо, насобираем статистику, построем ПИД-регулятор... Но зачем? АЦП выдал некое значение. Целочисленное. Можно прекрасно работать с ним, и лишь тогда, когда необходимо показать человеку, перевести в человеческий вид. Так и здесь. Чем плохи импульсы? Только тем, что человеку они непонятны. Но не ему же с ними работать...
А не проще посчитать количество импульсов с датчика за определённое время, а время счёта подобрать так, чтобы количество посчитанных за это время импульсов получалось равным скорости?
зы.. Время счёта, кажется, получается что-то в районе 0,9 секунды..
это зависит от того, что с ними делать дальше. Выводить на экран скорость каждые 0.9 секунды например - да, а если ещё считать суточный пробег... если действий всяких много, то надо делать что-то базовое. Это как у механиков: нельзя размечать множество, например, отверстий, отмеряя следующее от предыдущего. Должна быть некая база, от которой все измерения откладываются, тогда нет накопления погрешности.
Вообще- странное число- 4073.. видимо, ТС его получил "экспериментальным путём" Обычно у европейских автомобилей идёт 1000 оборотов датчика на километр пробега, а у американских 1000 оборотов на милю (624 оборота на километр) У советских "жигулей" 1000 оборотов привода спидометра на километр, у Волги- 624. У ВАЗ-ов 6 импульсов на оборот, стоит, на сколько я понял, датчик холла.. Реально у вас- 4000 импульсов на километр, а эти "73" из-за того, что, обычно, производители стараются сделать так, чтобы спидометр чуть завышал показания- меньше шансов нарушения скоростного режима.
Надо сосчитать, проехав километр. Но вообще, почему должно быть круглое число? Немного разницы в диаметре колёс и асфпальт/песок - наверняка даст разное число. Точное только на оборот вала КПП, а на расстояние - сомнительно...
Добавлено after 2 minutes 31 second: Надо современное авто брать там подцепился к CAN и всё...
4073 импульса на 1 км пути это я не из пальца высосал. Это на приборке наклейка такая есть. Это древний немец. Спидометр у него аналоговый, одометр - шаговый двигатель. Управляет этим делом микросхема UAF2115. По поводу быстродействия пересчета float, да наверно ест ресурсы. Но как я думаю, успевает все посчитать, т.к. все таки склоняюсь к дребезгу или наводкам. Считает больше, чем в реальности скорость. Ошибка накопления может быть, но не критичная. Да и речь то о текущей скорости. Какое там накопление? Во внешнем прерывании инкрементируется счетчик пришедших спадов(тот же период). А в прерывании таймера раз в секунду этот счетчик умножается на определенный коэффициент и сбрасывается. И уже в основном цикле идет вывод на экран. Ну и соответственно по этим данным будет расчет расхода топлива на 100 км и суточный счетчик пробега.
Добавлено after 2 minutes 46 seconds: Да, заметил, что на остановленном авто скорость таки прыгает 1-3 км/ч, хотя должна показывать ноль. Скорее всего наводки идут.
Добавлено after 8 hours 21 minute 2 seconds: Так, подцепил ослик. Никакого криминала я не увидел. Все четко. Но и ложняки пропали. Но скорость все равно больше показывает раза в полтора. На разных развертках смотрел, нет дребезга. Щуп по идее не должен влиять. Делитель 1:10 да и емкость у него пикофарады. Приедет генератор импульсов, буду дальше ковырять. На видео видно галюны на стоящем авто. https://youtu.be/H0ITuELXgc8?si=hnn73yLYZcnPZt8M
А у меня схожая мысль возникла. Возможно эти 4073 импульса именно только для одометра. А скорость это другой выход этой микросхемы и там типа микро или миллиамперметра. И есть резистор токоограничительный. Но это нужно будет проверить с помощью генератора импульсов. Ну и возможно еще кину эти пульсы на вход по захвату таймера. Все-таки 2 прерывания использовать- это борщ наверно.
Добавлено after 5 minutes 1 second: 888888 - Это пробег в км в нижней строчке. 888888.0 - это пробег с учетом сотен метров на последних секундах видео. Там меню где 888888.0 и вторая строчка это км,ч. Которая дергается 1-3-2-4. Спидометр в км.ч.
Добавлено after 2 minutes 9 seconds: Алгоритм вывода пробега такой: выключили зажигание- текущий пробег пишется в EEPROM. Вклюсили зажигание - читается и выводится. Но я проехал 12 км, и ничего не поменялось.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения