Спидометр, работающий с помощью геркона
- Войдите на сайт для отправки комментариев
Добрый вечер! Пробую собрать спидометр (для велосипеда) - довольно распространённая тема для данного сайта, но хочу сделать всё сам, а не тупо копировать коды и собирать по картинкам.
Написал, собственно говоря, код. Много раз правил (куда ж без ошибок - зато постепенно совершенствуюсь в этом), почти удалось избежать дребезга. Но проблема в неадекватности результатов, выдаваемых платой в монитор последовательного порта.
<!--break-->
Почему-то, выдаётся 0, затем, после первого срабатывания, выдаётся одна и та же цифра, которая, как бы я ни менял частоту срабатывания геркона (физически), не меняется. Вопрос следующий - что не так в этом коде?
На названия переменных прошу не обращать внимания - обожаю издеваться над их названиями. Да, кстати, про то, что создавать по две переменные для проверки от дребезга и проверки того, пришло ли время вычислять или ещё рано, было не обязательно и можно было бы написать этот код проще, догадываюсь, но вопрос в другом. Возможно, я что-то забыл в этом коде или что-то не учёл.
int gerkontime1 = 0; //эти две переменные нужны для того, чтобы оберечься от дребезга геркона int gerkontime2 = 0; int kofficient = 0; //эта переменная впоследствии будет являться количеством секунд с последнего сброса переменной gerkon при подсчёте скорости (знаю, не так назвал, но лень было менять название во всём коде, поэтому оставил) int gerkon =0; // собственно, количество полных оборотов колеса int time24 =0; //переменная для подсчёта миллисекунд с последнего сброса количества оборотов int dlina = (3,14)*65; //радиус = 1/2 диаметра 26 дюймов (1 дюйм=2,5 см) int mvsekundu = 0; //в этой переменной будет скорость в м/с int realskorost =0; // в этой переменной будет новая скорость, а в следующей - старая int starayaskorost =0; void setup() { Serial.begin(9600); pinMode(2, INPUT); //геркон digitalWrite(2, HIGH); attachInterrupt(0, contact, RISING); //прерывание } void contact () { int time1=millis()-time24; // постоянно мониторим, сколько времени прошло с момента последнего сброса gerkontime2 = millis() - gerkontime1; if (gerkontime2 <=500) { // если с момента срабатывания геркона прошло менее 500 миллисекунд, значит это дребезг и ничего не надо делать } else { if (time1<4000) { ++gerkon; //ещё один полный оборот колеса } if (time1>=4000) { //если прошло более 4 секунд, делаем вычисления starayaskorost = realskorost; // бывшая realskorost теперь уже starayaskorost)) kofficient = time1/1000; // поскольку здесь более 4 секунд, не факт, что велосипедист едет очень медленно и после срабатывания геркона на 3 секунде, не может следующее срабатывание быть не на 4, а на 5 или 6. int dlina4 = (dlina/100)*kofficient; //длина окружности была указана в сантиметрах, переводим в метры и умножаем на количество оборотов mvsekundu = dlina4/kofficient; //теперь находим скорость в метрах в секунду realskorost = mvsekundu*3,6; //переводим в км/ч time24 = millis(); gerkon = 0; //обнуляем переменную gerkon и обновляем переменную time24 } gerkontime1 = millis(); //это всё для той же защиты от дребезга, при первом срабатывании геркона записывается текущее время } } void loop() { int time1=millis()-time24; //на всякий случай, постоянно обновляем переменную time1 и выводим на экран результат вычислений Serial.println(realskorost); Serial.println(" km/h"); }
миллис в прерывании не работает - да тебе и не нужно, должно успевать подхватывать клик геркона опросом пина в лупе
для фильтрации дребезга подключи параллельно геркону конденсатор 0.1 микрофарад через резистор 500 Ом
здесь класс титановый велосипед StopWatch. код, как считать время между событиями - как вычислить скорость, зная длину обода колеса и время одного оборота, догадаешься сам
Тут товарищ про время дребезга написал. Может поможет чем.
миллис в прерывании не работает
Так вот, в чём дело, ясно, сейчас попробую по-другому. Спасибо за информацию
в лупе у меня 15000 оборотов/мин фиксирует без проблем - выше нечем проверить
но я использую не геркон (нафик, 21 век) - а цифровой датчик хола (тем более цена не сильно выше геркона) (что было в магазине - то и взял ss441a)
это автоматом исключает дребезг и иные подобные проблемы, да и максимальная частота срабатывания в сотни раз выше, чем у любого геркона
и кстати да - точность весьма условная , тк внутренний таймер дает ну совсем не точно время - у меня уж 1 секунда в минуту набегает :(
по хорошому бы ставить ЖПС и брать время с него для синхронизации, а также для коррекции спидометра, тк механический всегда будет врать
У меня на машине стоит на герконе, вполне нормально работает. На датчике холла пробовал, тоже были проблеммы. Тоже брал ss441.
миллис в прерывании не работает
Так вот, в чём дело, ясно, сейчас попробую по-другому. Спасибо за информацию
микрос вроде дрлжен работать
и кстати да - точность весьма условная , тк внутренний таймер дает ну совсем не точно время - у меня уж 1 секунда в минуту набегает :(
что там успевает набегать за время одного оборота колеса?
больше будет врать на спущенных или перекаченных шинах.
вот на дигиспарк делали в опросе лупа тахометр, на герконе
http://arduino.ru/forum/programmirovanie/nuzhna-pomoshch-po-takhometru-na-digispark-e?page=2#comment-324915
ну учитывая, что это велосипед - число оборотов мизерное будет
значит и погрешность можно не учитывать, да и использовать можно 2-4-6-8 магнита для повышения точности на низких оборотах
да и даже на 20" колесах на велике маловероятно больше 10 оборотов/с - тоесть 100мс всего....
параллельно геркону поставить конденсатор 100пф (примерно 5-7мс дает) - это избавит от дребезга и этого хватит фиксировать даже с 4 и даже с 6 магнитов за оборот без проблем
и что за рпоблемы с датчиком хола могут быть?! о_О может быть вы просто не правильно магнит повесили?? ведь 441 НЕ униполярный - он работает от ЮЖНОГО оплюса только - если верхногами магнит - он будет глючить и не срабатывать
но можно взять и унипорлярный - которому пофик на полюс.... (я брал 441 только потому, что он самый дешевый из поналичию был)
ну учитывая, что это велосипед - число оборотов мизерное будет
ещё раз повторяю - ОДИН оборот, считаем скорость: длина_обода/время_оборота. О_О
кстати можно схитрить и взять ВАЗовский датчик хола - он с встроенным магнитом уже - и поставить его на тормозной диск, нарезав в нем зубчики нужное число (принцип работы как у оптипары получается, только не свет, а магнитное поле проходит/не проходит
Для повышение точности надо не по одному обороту считать. Точность ход внутреннего таймера кварцем определяется. Обычно там все сильно лучше чем описали.
ну учитывая, что это велосипед - число оборотов мизерное будет
ещё раз повторяю - ОДИН оборот, считаем скорость: длина_обода/время_оборота. О_О
1 оборот в секунду для 20" колеса = 7км/ч примерно
для 24" уже 10км/ч... значит на скорости ниже этой он будет врать, или делать обновление раз в 2-4-10 секунд - но это дерганые цифры....
если делать более-менее плавно - то хотябы 4-5 раз в секунду надо считать скорость
а т.к. крутить колесо быстрее не получится, не повышая скорости - то остается увеличение числа срабатываний на каждый оборот
1 оборот в секунду для 20" колеса = 7км/ч примерно
верно.
для 24" уже 10км/ч... значит на скорости ниже этой он будет врать, или делать обновление раз в 2-4-10 секунд - но это дерганые цифры....
внимательно конспектирую... ещё раз - с какой точно скорости начинает врать?
если катить велосипед со скоростью 0.5км/ч, то на сколько соврёт?
1 оборот в секунду для 20" колеса = 7км/ч примерно
для 24" уже 10км/ч... значит на скорости ниже этой он будет врать
Не выдумывайте проблем, где их нет. Как раз на низкой скорости у вас относительная погрешность наименшая, менее процента. И врать соответственно будет в сотых долях км/ч.
Для повышение точности надо не по одному обороту считать. Точность ход внутреннего таймера кварцем определяется. Обычно там все сильно лучше чем описали.
для повышения точности до какого знака после запятой? О_О
до первого. сотые врядли кому интересны. Даже десятые - я бы усомнился что необходимы, но 2 знакоместа разумно использовать нужно.
2 знакоместа разумно использовать нужно.
ок.
а брать более одного оборота, что нам это даст?
на данном этапе меня интересует источник ошибки рассчёта скорости - как так: на более, чем одном обороте ошибка не накапливается, а уменьшается в n-оборотов раз? или как?
*пока я увидел реальный источник ошибки - это миллис() на МК с непрецизионным кварцем. но это решается поправочным коэффициентом, а не увеличением времени измерения.
угу. относительная в n раз. Курс метрологии читайте. Реальных источников ошибки много, кварц тут мене всего как раз (там и у хреновенького 10^-8), а вот дискретность измерения времени на миллис 1мсек. значить относительная погрешность времени ( и скорости по одному обороту тоже) для интервала 1сек будет порядка тысячной, а для интервала 0,1сек - порядка сотой. По 10 оборотах относительная погрешность снова будет в тысячных. На самом деле вопрос сложней, характер погрешности, какое распределение вероятности и пр надо учитывать. Но для начала так.
чем ниже скорость (ниже число оборотов) - тем дольше измерение её
чем дольше измерение - тем больше погрешность в каждый момент времени между измерениями
если у вас 1 импульс за 1 одорот - то идя пешком или двигаясь со скоростью пешегода (немного быстрее) - ваша скорость может несколько раз изменится между моментами замера - и вы этого не увидите никак
--------- по коду
29
gerkontime2 = millis() - gerkontime1;
30
if
(gerkontime2 <=500) {
31
// если с момента срабатывания геркона прошло менее 500 миллисекунд, значит это дребезг и ничего не надо делать
2 оборота колеса в секунду (10-20км/ч в зависимости от колеса) - выше уже не посчитает - будет думать, что дребезг )
дребезг не более 10мс стоит учитывать
-------
дальше у вас замер идет 4 секунды!!
на скорости 10км/ч за 4 с успеете проехать 4-6 метров
но вы же можете двигаться 4 метров со скоростью 5км/ч, и 1 метр на 20км/ч - а прибор вам покажет 8км/ч......
-------
это канешно дело барина... но я бы из рассчета не менее 6 (или 8) импульсов за 1 оборот для велосипеда
а вывод на экран с частотой 5 раз/с
угу. относительная в n раз. Курс метрологии читайте. Реальных источников ошибки много, кварц тут мене всего как раз (там и у хреновенького 10^-8), а вот дискретность измерения времени на миллис 1мсек. значить относительная погрешность времени ( и скорости по одному обороту тоже) для интервала 1сек будет порядка тысячной, а для интервала 0,1сек - порядка сотой. По 10 оборотах относительная погрешность снова будет в тысячных. На самом деле вопрос сложней, характер погрешности, какое распределение вероятности и пр надо учитывать. Но для начала так.
юзать микросекунды Я запретил вероятностным метрологам?
на сколько порядков уменьшится дискретность измерения времени одного оборота колеса?
а вывод на экран с частотой 5 раз/с
вывод на экран каждый ОДИН оборот колеса. О_О
дальше у вас замер идет 4 секунды!!
на скорости 10км/ч за 4 с успеете проехать 4-6 метров
но вы же можете двигаться 4 метров со скоростью 5км/ч, и 1 метр на 20км/ч - а прибор вам покажет 8км/ч......
Бля. Ну возьми ж пощитай. Этож средняя школа 10км/ч это 2,77(7) м/сек и за 4 сек это 11 м. Диаметр 24 дюйма 60см длина окружности около 1,9м и соответственно пошти 6 оборотов в 4 сек, а точней 1,46об.сек т.е. каждые 700мсек на оборот и погрешность от измерения времени дискретностю 1мсек получим порядка 1/700 т.е. 0,15%. Т.е. если не налажать в коде то скорость будет обновлятся каждые 0,7сек с точночстю сильно более 2 знаков 0,15% от 10км/час. Все в расчете пропорционально при скорости 1км/ч раз в 7 сек будет обновлятся скорость с точностью 0,015%. Разумеется скорость средняя за оборот. А вот при скорости 99км/ч от заслуженого подсрача за незнание математики с физикой погрешность становится 1,5% от т.е. 1,5км/час что уже заметно в младшем разряде.
чем дольше измерение - тем больше погрешность в каждый момент времени между измерениями
я всегда подозревал, что в стоячем автомобиле спидометр безбожно врёт, но умело скрывает. О_О
чо вы спорите, у человека университетское "образование"
Нафига человеку измерять скорость в с разрядностью выше чем 1 оборот колеса? велокомпутеры считают один оборот колеса и никто не жалуется.
Да и ТС куда-то уже потерялся
Нафига человеку измерять скорость в с разрядностью выше чем 1 оборот колеса? велокомпутеры считают один оборот колеса и никто не жалуется.
читай вероятностную метролохию дискретности измерений.
к примеру - у стоячего автомобиля скорость может быть любая.
невозможно узнать - колёса сука не крутятся. О_О
зато можно принять сто если небыл, например, сделан оборот за 5 секунд, то скорость равна 0
например, сделан оборот за 5 секунд, то скорость равна 0
только на противоугонку такой датчик скорости не ставь - цигане закатят твой автомобиль на трал со скоростью менее одного оборота за пять секунд.
зато можно принять сто если небыл, например, сделан оборот за 5 секунд, то скорость равна 0
Точней, если от предыдущего срабатывания датчика прошло более допустим 5 сек, то скорость 0.
Я понял, в чём была ошибка в коде - вот в этой строчке:
Надо было умножать длино окружности колеса не на общее количество секунд с момента прошлого обнуления, а на количество оборотов колеса
Нет, всё равно не работает. Что-то не так именно в коде, в вычислениях, геркон тут не причём, и с ним можно это организовать. Но вот что не так в коде, всё же логично: сначала получаем количество секунд с последнего обнуления, затем вычисляем пройденный за это время путь, затем делим этот путь на количество секунд, таким образом узнаем скорость в метрах в секунду, а затем переводим в километры в час. Что тут не так, я не пойму?
Выводите промежуточные значеня. Так локализуете где именно не так. Отладка нужна любому свежему коду.