Спидометр на Arduino

Denchik200401
Offline
Зарегистрирован: 17.07.2016

а светодиод это для индиации считает он хоть что - нибудь, в окончательном варианте этого не будет

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Denchik200401 пишет:

я хочу посчитать время между 1 и 2 замыканием геркона

Ок, определились. У нас есть геркон, и надо посчитать время между двумя его замыканиями, так? Тогда примерно так, навскидку:

enum {IDLE, FIRST_CHECK, SECOND_CHECK};
byte state;
unsigned long t1,t2;

void setup()
{
	state = IDLE;
}

void loop()
{
	bool isHighLevel = digitalRead(buttonPin);
	if(isHighLevel)
	{
		// геркон замкнут
		switch(state)
		{
			case IDLE:
				// замкнут в первый раз
				state = FIRST_CHECK;
			break;
			
			case SECOND_CHECK:
				// замкнут второй раз, можно выводить разницу
				t2 = millis();
				Serial.println(t2 - t1);
				state = IDLE; // сбрасываем состояние автомата
			break;
		}
		
	}
	else
	{
		// геркон не замкнут
		switch(state)
		{
			case FIRST_CHECK: // был замкнут, стал незамкнут, надо сохранить время начала отсчёта интервала между двумя замыканиями
				state = SECOND_CHECK;
				t1 = millis();
			break;
		}
	}
}

Не проверял, надеюсь, мысль понятна.

Denchik200401
Offline
Зарегистрирован: 17.07.2016

А геркон на gnd или на +5 надо подключать?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Denchik200401 пишет:

А геркон на gnd или на +5 надо подключать?

Да как хотите, только логику работы с сигналом поменяйте на нужную, и всё. Если у вас при срабатывании геркона на пин идёт +5В - то логика та, что я написал. Если же наоборот - надо поменять одно условие, и всё - в строке 13 поставить ! перед isHighLevel.

Denchik200401
Offline
Зарегистрирован: 17.07.2016

https://yadi.sk/i/F8pOfNxstUaeZ вот так вот мелькает, это при том что геркон не замкнут

ВН
Offline
Зарегистрирован: 25.02.2016

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

Ну тут один  товарищ не прочитал почему-то заголовка темы =) вот и лепит вумный, но совершенно бесполезные применительно к реальной задаче код.  

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ВН пишет:

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

Ну тут один  товарищ не прочитал почему-то заголовка темы =) вот и лепит вумный, но совершенно бесполезные применительно к реальной задаче код.  

Тебя и тут разрывает? Вижу, вижу, как твоя истеричная натура мечется и плачет - "ну где бы ещё его поддеть, где?". Если бы ты не был таким упоротым, то понял бы, на что именно я отвечаю. Для тебя, укурыша, поделюсь:

Цитата:

я хочу посчитать время между 1 и 2 замыканием геркона

ВН
Offline
Зарегистрирован: 25.02.2016

Да просто ловлю на гротеске, намеренно выпячивая и повторяя твои недавние опусы, ты еще не въехал? 

ну понятно, я не тормоз... я медленный газ =)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ВН пишет:

Да просто ловлю на гротеске, намеренно выпячивая и повторяя твои недавние опусы, ты еще не въехал? 

ну понятно, я не тормоз... я медленный газ =)

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

ВН
Offline
Зарегистрирован: 25.02.2016

Я тут недавно одному перцу тоже пытался объяснить. панымаешь ли, что мол отвечал по сути алгоритма, а не синтаксиса .... так хошь отправлю почитать че он там мне понаписал? 

Ты у его еще  спроси, у его претензии к сути поправок алгоритма есть, али не. а то он вместо сути всякую пургу несет.

 

зы. все. я дебаты на эту тему закрыл. Прошу прощения за оффтоп у ТС

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ВН пишет:

Я тут недавно одному перцу тоже пытался объяснить. панымаешь ли, что мол отвечал по сути алгоритма, а не синтаксиса .... так хошь отправлю почитать че он там мне понаписал? 

Ты у его еще  спроси, у его претензии к сути поправок алгоритма есть, али не. а то он вместо сути всякую пургу несет.

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

Ты это - слезай с таблеток, тебе уже хватит.

a5021
Offline
Зарегистрирован: 07.07.2013

Denchik200401 пишет:
Вот в этом коде проблема с millis()

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

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

Denchik200401
Offline
Зарегистрирован: 17.07.2016

А ничего, что от вашего кода такой же результат?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
Denchik200401
Offline
Зарегистрирован: 17.07.2016

В вашем коде ,а5021, Time1 и Time2 возвращают значения, а rTime возвращает 0

Denchik200401
Offline
Зарегистрирован: 17.07.2016

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

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Denchik200401 пишет:

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

Надо не запускать чужой код, а постараться понять, как тот или иной кусок кода работает, его логику ;) Тогда просветление и придёт. А просто копируя куски кода, неважно чьи - вы не добавите себе ни капли понимания, как оно всё работает.

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Логику работы я понял, но понять почему после деления на 3600000 получается 0 я не могу

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Denchik200401 пишет:

Логику работы я понял, но понять почему после деления на 3600000 получается 0 я не могу

Потому что получается такое значение float, которое очень близко к нулю, и при выводе получается 0. Это в том случае, когда разница между Time2 и Time1 - мизерная.

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Если вместо float поставить unsigned long, получается тоже самое

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Denchik200401 пишет:

Если вместо float поставить unsigned long, получается тоже самое

Выводили в порт разницу между двумя переменными (Time2 и Time1)? Чего показывает?

a5021
Offline
Зарегистрирован: 07.07.2013

Denchik200401 пишет:
Логику работы я понял, но понять почему после деления на 3600000 получается 0 я не могу

Может происходить потеря значимости из-за недостаточной разрядности переменных типа float. Попробуйте вместо float использовать double.

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Разницу выводит

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Выводит 0.000.00

gena
Offline
Зарегистрирован: 04.11.2012

  Вы не слишком "частите" магнитом возле геркона? Не хочу вникать в код, но не может быть так, что программа делает рассчёты для дребезга контактов?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Denchik200401 пишет:

Разницу выводит

Какая разница-то, господи? 1, 2, 10, 1234?

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Он подрят цифр 5 выдал

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Denchik200401 пишет:

Он подрят цифр 5 выдал

Отлично, я рад за него. Осталось понять, какую цифру "он" выдаёт каждый раз как разницу между Time2 и Time1 - и дело будет в шоколаде. Чуете, к чему веду? Если цифра маааааааааааааахонькая, то результат её деления на большоооооооооое число будет оооооочень близко к нулю, и вы это увидите как 0 из-за округления при выводе в порт.

Например, 1/3600000 = 2,7777777777777777777777777777778e-7 - видите, какое маленькое число?

a5021
Offline
Зарегистрирован: 07.07.2013

Вы в своем уме? Двенадцатилетнему ребенку предлагать оценить величину числа по его экспоненциальной записи.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

a5021 пишет:

Вы в своем уме? Двенадцатилетнему ребенку предлагать оценить величину числа по его экспоненциальной записи.

Ох, я и забыл, что ему 12 лет :(

a5021
Offline
Зарегистрирован: 07.07.2013

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

Denchik200401, вы пробовали менять тип переменных float на double ?

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Да, пробовал, результат, как всегда 0

a5021
Offline
Зарегистрирован: 07.07.2013

Придется мне видно лезть в протеус.

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Наверное

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Denchik200401 пишет:

Наверное

Попробуйте ради интереса делить не на 3600000, а просто на 36 - что покажет в мониторе порта?

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

a5021 пишет:

Вы в своем уме? Двенадцатилетнему ребенку предлагать оценить величину числа по его экспоненциальной записи.

кто пустил мальчика на математический форум?

кто-нибудь, сообщите в службу защиты мальчиков от математики!

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Этот мальчик, к вашему сведению, отличник по математике.

Denchik200401
Offline
Зарегистрирован: 17.07.2016

(Time2 - Time1) / 36; = 1.00

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Также может равнться 3.00 9.00 и т.д.

Denchik200401
Offline
Зарегистрирован: 17.07.2016

А Вы у нас кандидат математических наук?

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

Denchik200401 пишет:

А Вы у нас кандидат математических наук?

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

a5021
Offline
Зарегистрирован: 07.07.2013

Denchik200401 пишет:

(Time2 - Time1) / 36; = 1.00

Вобщем, именно эта строка и являлась ляпом. Если выражение записывается, как

float rTime = (Time2 - Time1) / 3600000;

то вычисление производится в целочисленной арифметике и потом приводится к типу float. Понятно, что в целочисленных вычислениях какое-нибудь 600 / 3600000 всегда будет равно нулю.

если константу записать с десятичной точкой 3600000.0, то все встает на свои места и вычисляется правильно.

Однако, конкретно этот виртуальный велосипед едет неправдоподобно быстро. :)

Denchik200401
Offline
Зарегистрирован: 17.07.2016

Спасибо, сейчас попробую, а по поводу скорости какой нибудь шоссейный с не амортизации оной вилкой на 28 колёсах на 28 скорости может столько и поедет, но это уже отступление...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

a5021 пишет:

Denchik200401 пишет:
Логику работы я понял, но понять почему после деления на 3600000 получается 0 я не могу

Может происходить потеря значимости из-за недостаточной разрядности переменных типа float. Попробуйте вместо float использовать double.

В Ардуино double как таковой нет. Вместо нее подставляется float.

Denchik200401
Offline
Зарегистрирован: 17.07.2016

это уже не так важно, потому что все заработало, но все таки компилятор double воспринимает, а значит фактически она там есть

a5021
Offline
Зарегистрирован: 07.07.2013

andriano пишет:
В Ардуино double как таковой нет. Вместо нее подставляется float.

По сути, в ардуине есть все, что есть в GNU C/C++. И double в том числе.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ну да, признаю: сам совершил ошибку, за которую уже кого-то критиковал - отождествление Arduino и AVR.

Сейчас просмотрел тему и не обнаружил, чтобы ТС где-то писал, что у него нечто отличное от AVR. Обычно Due выплывает как-то раньше конца второй страницы.

NikKulik
Offline
Зарегистрирован: 06.03.2018

...тема еще жива?

NikKulik
Offline
Зарегистрирован: 06.03.2018

a5021 пишет:

Denchik200401 пишет:
можно было и повежливее я всё-таки ребёнок!

2004.01 -- это дата рождения? Если так, то прости нас всех. На форуме не видно, кому сколько лет.

Обод колеса (шины) имеет длину. Ее можно измерить рулеткой или "сантиметром", которым пользуются любители домашнего шитья. Предположим, что имеется некий  небольшой велосипед, где длина окружности колеса равняется одому метру. Дальше мы закпрепляем геркон неподвижно на вилке, а магнит на спицах или ободе. В этом случае, при движении велосипеда, магнит будет замыкать контакты геркона один раз за оборот колеса.  Замыкание контактов будет происходить всякий раз, когда велосипед пройдет один метр (длина обода). Если же измерить время, которое проходит между замыканиями геркона, то мы получим вторую величину, необходимую для вычисления скорости. Предположим, что едущий велосипед замыкает геркон через каждые 600 миллисекунд или 0.6 секунды. Разделив длину окружности на время между замыканиями геркона, получим скорость: 1 метр / 0.6 секунды = 1.67 м/с. Скорость обычно считают в км/ч, т.ч. полученное значение нужно умножить на 3600 (секунд в часе) и разделить на 1000 (метров в километре). Скорость нашего воображаемого велосипеда таким образом составит 6 км/ч.

int reedSwitch = 10; // пин, куда присоединен геркон
float cLen = 1.0;    // длина обода в метрах

void setup() {
  pinMode(reedSwitch, INPUT_PULLUP); // режим входа с подтяжкой к плюсу
  Serial.begin(9600); // включаем вывод в последовательный порт
}

void loop() {
  while (digitalRead(reedSwitch) == HIGH); // ждем, пок геркон не будет замкнут
  uint32_t Time1 = millis(); // запоминаем время
  for (;;) {  // крутим "вечный" цикл
    delay(50); // ждем, пока магнит проедет мимо геркона
    while (digitalRead(reedSwitch) == HIGH); // опять ждем замыкания
    uint32_t Time2 = millis(); // берем текущее время
    float rTime = (Time2 - Time1) / 3600000;  // находим время полного оборота колеса в долях часа
    float bikeSpeed = (cLen / 1000) / rTime; // вычисляем скорость в км/ч
    Serial.print("Скорость равна: ");
    Serial.print(bikeSpeed);
    Serial.println(" км/ч.");
    Time1 = Time2; // запоминаем время для след. вычисления
  }
}

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

 

Вы используете экран OLED млм 5510?
Сталкнулся с тойже проблемой. Делал и через Таймеры, но воз и ныне там.

Диагностика показала, что как только Вы отключаете вывод на дисплей - все сразу работате!

Такое впечатление что таймер это фигня и ей не нужен приоритет прерывание, а вот Олед дисплей по шине i2C это самое главное.

Я так понял что шина у дисплея оченьт медленная и "ХАВАЕТ" время не давая правильно считать импульсы по прерыванию.

попробуйте все вывести в порт, а вывод дисплея заремить...

а пока переделываю схему на 7сегментник.
и да millis и им подобные это фигня - оно не работате! Timer1 работает