Спидометр, работающий с помощью геркона

Экран
Offline
Зарегистрирован: 20.12.2017

Добрый вечер! Пробую собрать спидометр (для велосипеда) - довольно распространённая тема для данного сайта, но хочу сделать всё сам, а не тупо копировать коды и собирать по картинкам.

Написал, собственно говоря, код. Много раз правил (куда ж без ошибок - зато постепенно совершенствуюсь в этом), почти удалось избежать дребезга. Но проблема в неадекватности результатов, выдаваемых платой в монитор последовательного порта.

<!--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");



}

 

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

миллис в прерывании не работает - да тебе и не нужно, должно успевать подхватывать клик геркона опросом пина в лупе

для фильтрации дребезга подключи параллельно геркону конденсатор 0.1 микрофарад через резистор 500 Ом

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

Rootware
Offline
Зарегистрирован: 11.01.2018

Тут товарищ про время дребезга написал. Может поможет чем.

Экран
Offline
Зарегистрирован: 20.12.2017

Клапауций 298 пишет:

миллис в прерывании не работает

Так вот, в чём дело, ясно, сейчас попробую по-другому. Спасибо за информацию

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

в лупе у меня 15000 оборотов/мин фиксирует без проблем - выше нечем проверить

но я использую не геркон (нафик, 21 век) - а цифровой датчик хола (тем более цена не сильно выше геркона) (что было в магазине - то и взял ss441a)

это автоматом исключает дребезг и иные подобные проблемы, да и максимальная частота срабатывания в сотни раз выше, чем у любого геркона

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

и кстати да - точность весьма условная , тк внутренний таймер дает ну совсем не точно время - у меня уж 1 секунда в минуту набегает :(

по хорошому бы ставить ЖПС и брать время с него для синхронизации, а также для коррекции спидометра, тк механический всегда будет врать

s1981
Offline
Зарегистрирован: 22.12.2013

У меня на машине стоит на герконе, вполне нормально работает. На датчике холла пробовал, тоже были проблеммы. Тоже брал ss441.

evgta
Offline
Зарегистрирован: 02.09.2016

Экран пишет:

Клапауций 298 пишет:

миллис в прерывании не работает

Так вот, в чём дело, ясно, сейчас попробую по-другому. Спасибо за информацию

микрос вроде дрлжен работать

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

ELITE пишет:

и кстати да - точность весьма условная , тк внутренний таймер дает ну совсем не точно время - у меня уж 1 секунда в минуту набегает :(

что там успевает набегать за время одного оборота колеса?

больше будет врать на спущенных или перекаченных шинах.

evgta
Offline
Зарегистрирован: 02.09.2016

вот на дигиспарк делали в опросе лупа тахометр, на герконе

http://arduino.ru/forum/programmirovanie/nuzhna-pomoshch-po-takhometru-na-digispark-e?page=2#comment-324915

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

ну учитывая, что это велосипед - число оборотов мизерное будет

значит и погрешность можно не учитывать, да и использовать можно 2-4-6-8 магнита для повышения точности на низких оборотах

да и даже на 20" колесах на велике маловероятно больше 10 оборотов/с - тоесть 100мс всего....

параллельно геркону поставить конденсатор 100пф (примерно 5-7мс дает) - это избавит от дребезга и этого хватит фиксировать даже с 4 и даже с 6 магнитов за оборот без проблем

и что за рпоблемы с датчиком хола могут быть?! о_О может быть вы просто не правильно магнит повесили?? ведь 441 НЕ униполярный - он работает от ЮЖНОГО оплюса только - если верхногами магнит - он будет глючить и не срабатывать

но можно взять и унипорлярный - которому пофик на полюс.... (я брал 441 только потому, что он самый дешевый из поналичию был)

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

ELITE пишет:

ну учитывая, что это велосипед - число оборотов мизерное будет

ещё раз повторяю - ОДИН оборот, считаем скорость: длина_обода/время_оборота. О_О

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

кстати можно схитрить и взять ВАЗовский датчик хола - он с встроенным магнитом уже  - и поставить его на тормозной диск, нарезав в нем зубчики нужное число (принцип работы как у оптипары получается, только не свет, а магнитное поле проходит/не проходит

 

Logik
Offline
Зарегистрирован: 05.08.2014

Для повышение точности надо не по одному обороту считать. Точность ход внутреннего таймера кварцем определяется. Обычно там все сильно лучше чем описали.

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

Клапауций 298 пишет:

ELITE пишет:

ну учитывая, что это велосипед - число оборотов мизерное будет

ещё раз повторяю - ОДИН оборот, считаем скорость: длина_обода/время_оборота. О_О

1 оборот в секунду для 20" колеса = 7км/ч примерно

для 24" уже 10км/ч... значит на скорости ниже этой он будет врать, или делать обновление раз в 2-4-10 секунд - но это дерганые цифры.... 

если делать более-менее плавно - то хотябы 4-5 раз в секунду надо считать скорость

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

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

ELITE пишет:

1 оборот в секунду для 20" колеса = 7км/ч примерно

верно.

ELITE пишет:

для 24" уже 10км/ч... значит на скорости ниже этой он будет врать, или делать обновление раз в 2-4-10 секунд - но это дерганые цифры.... 

внимательно конспектирую... ещё раз - с какой точно скорости начинает врать?

если катить велосипед со скоростью 0.5км/ч, то на сколько соврёт?

 

 

Logik
Offline
Зарегистрирован: 05.08.2014

ELITE пишет:

1 оборот в секунду для 20" колеса = 7км/ч примерно

для 24" уже 10км/ч... значит на скорости ниже этой он будет врать

Не выдумывайте проблем, где их нет.  Как раз на низкой скорости у вас  относительная погрешность наименшая, менее процента. И врать соответственно будет в сотых долях км/ч.

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

Logik пишет:

Для повышение точности надо не по одному обороту считать. Точность ход внутреннего таймера кварцем определяется. Обычно там все сильно лучше чем описали.

для повышения точности до какого знака после запятой? О_О

Logik
Offline
Зарегистрирован: 05.08.2014

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

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

Logik пишет:

2 знакоместа разумно использовать нужно.

ок.

а брать более одного оборота, что нам это даст?

на данном этапе меня интересует источник ошибки рассчёта скорости - как так: на более, чем одном обороте ошибка не накапливается, а уменьшается в n-оборотов раз? или как?

*пока я увидел реальный источник ошибки - это миллис() на МК с непрецизионным кварцем. но это решается поправочным коэффициентом, а не увеличением времени измерения.

Logik
Offline
Зарегистрирован: 05.08.2014

угу. относительная в n раз. Курс метрологии читайте. Реальных источников ошибки много, кварц тут мене всего как раз (там и у хреновенького 10^-8), а вот дискретность измерения времени на миллис 1мсек. значить относительная погрешность времени ( и скорости по одному обороту тоже) для интервала 1сек будет порядка тысячной, а для интервала 0,1сек - порядка сотой. По 10 оборотах относительная погрешность снова будет в тысячных. На самом деле вопрос сложней, характер погрешности,  какое распределение вероятности и пр надо учитывать. Но для начала так.

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

чем ниже скорость (ниже число оборотов) - тем дольше измерение её

чем дольше измерение - тем больше погрешность в каждый момент времени между измерениями

если у вас 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 раз/с

 

 

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

Logik пишет:

угу. относительная в n раз. Курс метрологии читайте. Реальных источников ошибки много, кварц тут мене всего как раз (там и у хреновенького 10^-8), а вот дискретность измерения времени на миллис 1мсек. значить относительная погрешность времени ( и скорости по одному обороту тоже) для интервала 1сек будет порядка тысячной, а для интервала 0,1сек - порядка сотой. По 10 оборотах относительная погрешность снова будет в тысячных. На самом деле вопрос сложней, характер погрешности,  какое распределение вероятности и пр надо учитывать. Но для начала так.

юзать микросекунды Я запретил вероятностным метрологам?

на сколько порядков уменьшится дискретность измерения времени одного оборота колеса?

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

ELITE пишет:

а вывод на экран с частотой 5 раз/с

вывод на экран каждый ОДИН оборот колеса. О_О

Logik
Offline
Зарегистрирован: 05.08.2014

ELITE пишет:

дальше у вас замер идет 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км/час что уже заметно в младшем разряде.

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

ELITE пишет:

чем дольше измерение - тем больше погрешность в каждый момент времени между измерениями

я всегда подозревал, что в стоячем автомобиле спидометр безбожно врёт, но умело скрывает. О_О

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

чо вы спорите, у человека университетское "образование"

evgta
Offline
Зарегистрирован: 02.09.2016

Нафига человеку измерять скорость в с разрядностью выше чем 1 оборот колеса? велокомпутеры считают один оборот колеса и никто не жалуется.

Да и ТС куда-то уже потерялся

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

evgta пишет:

Нафига человеку измерять скорость в с разрядностью выше чем 1 оборот колеса? велокомпутеры считают один оборот колеса и никто не жалуется.

читай вероятностную метролохию дискретности измерений.

к примеру - у стоячего автомобиля скорость может быть любая.

невозможно узнать - колёса сука не крутятся. О_О

evgta
Offline
Зарегистрирован: 02.09.2016

зато можно принять сто если небыл, например, сделан оборот за 5 секунд, то скорость равна 0

Клапауций 298
Клапауций 298 аватар
Offline
Зарегистрирован: 25.01.2018

evgta пишет:

например, сделан оборот за 5 секунд, то скорость равна 0

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

Logik
Offline
Зарегистрирован: 05.08.2014

evgta пишет:

зато можно принять сто если небыл, например, сделан оборот за 5 секунд, то скорость равна 0

Точней, если от предыдущего срабатывания датчика прошло более допустим 5 сек, то скорость 0.

Экран
Offline
Зарегистрирован: 20.12.2017

Я понял, в чём была ошибка в коде - вот в этой строчке:

dlina4 = (dlina/100)*kofficient;

Надо было умножать длино окружности колеса не на общее количество секунд с момента прошлого обнуления, а на количество оборотов колеса

dlina4 = (dlina/100)*gerkon;

 

Экран
Offline
Зарегистрирован: 20.12.2017

Нет, всё равно не работает. Что-то не так именно в коде, в вычислениях, геркон тут не причём, и с ним можно это организовать. Но вот что не так в коде, всё же логично: сначала получаем количество секунд с последнего обнуления, затем вычисляем пройденный за это время путь, затем делим этот путь на количество секунд, таким образом узнаем скорость в метрах в секунду, а затем переводим в километры в час. Что тут не так, я не пойму?

Logik
Offline
Зарегистрирован: 05.08.2014

Выводите промежуточные значеня. Так локализуете где именно не так. Отладка нужна любому свежему коду.