я хочу посчитать время между 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;
}
}
}
Да как хотите, только логику работы с сигналом поменяйте на нужную, и всё. Если у вас при срабатывании геркона на пин идёт +5В - то логика та, что я написал. Если же наоборот - надо поменять одно условие, и всё - в строке 13 поставить ! перед isHighLevel.
дело в том, что такая простая программа не годится для колеса, т.к. оборотов много и все они несколько отличаются по времени, а данные выкидываются на каждый оборот, поэтому показанию будут мельтешить на экране.
Ну тут один товарищ не прочитал почему-то заголовка темы =) вот и лепит вумный, но совершенно бесполезные применительно к реальной задаче код.
дело в том, что такая простая программа не годится для колеса, т.к. оборотов много и все они несколько отличаются по времени, а данные выкидываются на каждый оборот, поэтому показанию будут мельтешить на экране.
Ну тут один товарищ не прочитал почему-то заголовка темы =) вот и лепит вумный, но совершенно бесполезные применительно к реальной задаче код.
Тебя и тут разрывает? Вижу, вижу, как твоя истеричная натура мечется и плачет - "ну где бы ещё его поддеть, где?". Если бы ты не был таким упоротым, то понял бы, на что именно я отвечаю. Для тебя, укурыша, поделюсь:
Цитата:
я хочу посчитать время между 1 и 2 замыканием геркона
Да просто ловлю на гротеске, намеренно выпячивая и повторяя твои недавние опусы, ты еще не въехал?
ну понятно, я не тормоз... я медленный газ =)
Ну то есть опять ты сел в лужу, и опять пытаешься сохранить личико, Гюльчатай? Я не удивлён. Тебе ясно было написано, на какой поставленный вопрос я писал ответ. Претензии к этому есть? Нет? Ну и ладушки - иди дальше глуши белую, разрушай нейроны, они тебе ни к чему.
Я тут недавно одному перцу тоже пытался объяснить. панымаешь ли, что мол отвечал по сути алгоритма, а не синтаксиса .... так хошь отправлю почитать че он там мне понаписал?
Ты у его еще спроси, у его претензии к сути поправок алгоритма есть, али не. а то он вместо сути всякую пургу несет.
зы. все. я дебаты на эту тему закрыл. Прошу прощения за оффтоп у ТС
Я тут недавно одному перцу тоже пытался объяснить. панымаешь ли, что мол отвечал по сути алгоритма, а не синтаксиса .... так хошь отправлю почитать че он там мне понаписал?
Ты у его еще спроси, у его претензии к сути поправок алгоритма есть, али не. а то он вместо сути всякую пургу несет.
Нет, ну ты реально укуренный что-ли? По сути синтаксиса я тут ничего не отвечал, это, что называется, раз. Два - по сути алгоритма ты и там сел в лужу, ибо там никакого алгоритма работы с временем не было.
Я просил вас показать код с герконом. Вы показываете код с какой-то кнопкой. Причем, от предложенного мной варианта там нет ни одной строчки, зато есть куча ваших ошибок, одна на другой.
Как прикажете помогать вам, если мое подробное описание, что и как должно делаться, пример кода, который худо-бедно должен работать, вы просто выкинули не вникая?
И я ничего не выкидывал не вникая, я как только не пытался запустить ваш код, но он все равно неработал
Надо не запускать чужой код, а постараться понять, как тот или иной кусок кода работает, его логику ;) Тогда просветление и придёт. А просто копируя куски кода, неважно чьи - вы не добавите себе ни капли понимания, как оно всё работает.
Логику работы я понял, но понять почему после деления на 3600000 получается 0 я не могу
Потому что получается такое значение float, которое очень близко к нулю, и при выводе получается 0. Это в том случае, когда разница между Time2 и Time1 - мизерная.
Отлично, я рад за него. Осталось понять, какую цифру "он" выдаёт каждый раз как разницу между Time2 и Time1 - и дело будет в шоколаде. Чуете, к чему веду? Если цифра маааааааааааааахонькая, то результат её деления на большоооооооооое число будет оооооочень близко к нулю, и вы это увидите как 0 из-за округления при выводе в порт.
Например, 1/3600000 = 2,7777777777777777777777777777778e-7 - видите, какое маленькое число?
В том и дело, тут нужно максимально все упрощать, иначе он просто не поймет. Не поймет не потому, что глупый, а потому, что в силу возраста объем знаний еще не велик. Поэтому просьба ко всем, кто здесь пишет -- упрощайте все, насколько это возможно. В данном случае, даже сильное упрощение не является чем-то осудительным.
Denchik200401, вы пробовали менять тип переменных float на double ?
Вобщем, именно эта строка и являлась ляпом. Если выражение записывается, как
float rTime = (Time2 - Time1) / 3600000;
то вычисление производится в целочисленной арифметике и потом приводится к типу float. Понятно, что в целочисленных вычислениях какое-нибудь 600 / 3600000 всегда будет равно нулю.
если константу записать с десятичной точкой 3600000.0, то все встает на свои места и вычисляется правильно.
Однако, конкретно этот виртуальный велосипед едет неправдоподобно быстро. :)
Спасибо, сейчас попробую, а по поводу скорости какой нибудь шоссейный с не амортизации оной вилкой на 28 колёсах на 28 скорости может столько и поедет, но это уже отступление...
Ну да, признаю: сам совершил ошибку, за которую уже кого-то критиковал - отождествление Arduino и AVR.
Сейчас просмотрел тему и не обнаружил, чтобы ТС где-то писал, что у него нечто отличное от AVR. Обычно Due выплывает как-то раньше конца второй страницы.
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 работает
а светодиод это для индиации считает он хоть что - нибудь, в окончательном варианте этого не будет
я хочу посчитать время между 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; } } }Не проверял, надеюсь, мысль понятна.
А геркон на gnd или на +5 надо подключать?
А геркон на gnd или на +5 надо подключать?
Да как хотите, только логику работы с сигналом поменяйте на нужную, и всё. Если у вас при срабатывании геркона на пин идёт +5В - то логика та, что я написал. Если же наоборот - надо поменять одно условие, и всё - в строке 13 поставить ! перед isHighLevel.
https://yadi.sk/i/F8pOfNxstUaeZ вот так вот мелькает, это при том что геркон не замкнут
дело в том, что такая простая программа не годится для колеса, т.к. оборотов много и все они несколько отличаются по времени, а данные выкидываются на каждый оборот, поэтому показанию будут мельтешить на экране.
Ну тут один товарищ не прочитал почему-то заголовка темы =) вот и лепит вумный, но совершенно бесполезные применительно к реальной задаче код.
дело в том, что такая простая программа не годится для колеса, т.к. оборотов много и все они несколько отличаются по времени, а данные выкидываются на каждый оборот, поэтому показанию будут мельтешить на экране.
Ну тут один товарищ не прочитал почему-то заголовка темы =) вот и лепит вумный, но совершенно бесполезные применительно к реальной задаче код.
Тебя и тут разрывает? Вижу, вижу, как твоя истеричная натура мечется и плачет - "ну где бы ещё его поддеть, где?". Если бы ты не был таким упоротым, то понял бы, на что именно я отвечаю. Для тебя, укурыша, поделюсь:
я хочу посчитать время между 1 и 2 замыканием геркона
Да просто ловлю на гротеске, намеренно выпячивая и повторяя твои недавние опусы, ты еще не въехал?
ну понятно, я не тормоз... я медленный газ =)
Да просто ловлю на гротеске, намеренно выпячивая и повторяя твои недавние опусы, ты еще не въехал?
ну понятно, я не тормоз... я медленный газ =)
Ну то есть опять ты сел в лужу, и опять пытаешься сохранить личико, Гюльчатай? Я не удивлён. Тебе ясно было написано, на какой поставленный вопрос я писал ответ. Претензии к этому есть? Нет? Ну и ладушки - иди дальше глуши белую, разрушай нейроны, они тебе ни к чему.
Я тут недавно одному перцу тоже пытался объяснить. панымаешь ли, что мол отвечал по сути алгоритма, а не синтаксиса .... так хошь отправлю почитать че он там мне понаписал?
Ты у его еще спроси, у его претензии к сути поправок алгоритма есть, али не. а то он вместо сути всякую пургу несет.
зы. все. я дебаты на эту тему закрыл. Прошу прощения за оффтоп у ТС
Я тут недавно одному перцу тоже пытался объяснить. панымаешь ли, что мол отвечал по сути алгоритма, а не синтаксиса .... так хошь отправлю почитать че он там мне понаписал?
Ты у его еще спроси, у его претензии к сути поправок алгоритма есть, али не. а то он вместо сути всякую пургу несет.
Нет, ну ты реально укуренный что-ли? По сути синтаксиса я тут ничего не отвечал, это, что называется, раз. Два - по сути алгоритма ты и там сел в лужу, ибо там никакого алгоритма работы с временем не было.
Ты это - слезай с таблеток, тебе уже хватит.
Я просил вас показать код с герконом. Вы показываете код с какой-то кнопкой. Причем, от предложенного мной варианта там нет ни одной строчки, зато есть куча ваших ошибок, одна на другой.
Как прикажете помогать вам, если мое подробное описание, что и как должно делаться, пример кода, который худо-бедно должен работать, вы просто выкинули не вникая?
А ничего, что от вашего кода такой же результат?
http://wiki.amperka.ru/projects:pov-speedometr
В вашем коде ,а5021, Time1 и Time2 возвращают значения, а rTime возвращает 0
И я ничего не выкидывал не вникая, я как только не пытался запустить ваш код, но он все равно неработал
И я ничего не выкидывал не вникая, я как только не пытался запустить ваш код, но он все равно неработал
Надо не запускать чужой код, а постараться понять, как тот или иной кусок кода работает, его логику ;) Тогда просветление и придёт. А просто копируя куски кода, неважно чьи - вы не добавите себе ни капли понимания, как оно всё работает.
Логику работы я понял, но понять почему после деления на 3600000 получается 0 я не могу
Логику работы я понял, но понять почему после деления на 3600000 получается 0 я не могу
Потому что получается такое значение float, которое очень близко к нулю, и при выводе получается 0. Это в том случае, когда разница между Time2 и Time1 - мизерная.
Если вместо float поставить unsigned long, получается тоже самое
Если вместо float поставить unsigned long, получается тоже самое
Выводили в порт разницу между двумя переменными (Time2 и Time1)? Чего показывает?
Может происходить потеря значимости из-за недостаточной разрядности переменных типа float. Попробуйте вместо float использовать double.
Разницу выводит
Выводит 0.000.00
Вы не слишком "частите" магнитом возле геркона? Не хочу вникать в код, но не может быть так, что программа делает рассчёты для дребезга контактов?
Разницу выводит
Какая разница-то, господи? 1, 2, 10, 1234?
Он подрят цифр 5 выдал
Он подрят цифр 5 выдал
Отлично, я рад за него. Осталось понять, какую цифру "он" выдаёт каждый раз как разницу между Time2 и Time1 - и дело будет в шоколаде. Чуете, к чему веду? Если цифра маааааааааааааахонькая, то результат её деления на большоооооооооое число будет оооооочень близко к нулю, и вы это увидите как 0 из-за округления при выводе в порт.
Например, 1/3600000 = 2,7777777777777777777777777777778e-7 - видите, какое маленькое число?
Вы в своем уме? Двенадцатилетнему ребенку предлагать оценить величину числа по его экспоненциальной записи.
Вы в своем уме? Двенадцатилетнему ребенку предлагать оценить величину числа по его экспоненциальной записи.
Ох, я и забыл, что ему 12 лет :(
В том и дело, тут нужно максимально все упрощать, иначе он просто не поймет. Не поймет не потому, что глупый, а потому, что в силу возраста объем знаний еще не велик. Поэтому просьба ко всем, кто здесь пишет -- упрощайте все, насколько это возможно. В данном случае, даже сильное упрощение не является чем-то осудительным.
Denchik200401, вы пробовали менять тип переменных float на double ?
Да, пробовал, результат, как всегда 0
Придется мне видно лезть в протеус.
Наверное
Наверное
Попробуйте ради интереса делить не на 3600000, а просто на 36 - что покажет в мониторе порта?
Вы в своем уме? Двенадцатилетнему ребенку предлагать оценить величину числа по его экспоненциальной записи.
кто пустил мальчика на математический форум?
кто-нибудь, сообщите в службу защиты мальчиков от математики!
Этот мальчик, к вашему сведению, отличник по математике.
(Time2 - Time1) / 36; = 1.00
Также может равнться 3.00 9.00 и т.д.
А Вы у нас кандидат математических наук?
А Вы у нас кандидат математических наук?
я у вас тут радиомонтажник с полным средним образованием.
(Time2 - Time1) / 36; = 1.00
Вобщем, именно эта строка и являлась ляпом. Если выражение записывается, как
то вычисление производится в целочисленной арифметике и потом приводится к типу float. Понятно, что в целочисленных вычислениях какое-нибудь 600 / 3600000 всегда будет равно нулю.
если константу записать с десятичной точкой 3600000.0, то все встает на свои места и вычисляется правильно.
Однако, конкретно этот виртуальный велосипед едет неправдоподобно быстро. :)
Спасибо, сейчас попробую, а по поводу скорости какой нибудь шоссейный с не амортизации оной вилкой на 28 колёсах на 28 скорости может столько и поедет, но это уже отступление...
Может происходить потеря значимости из-за недостаточной разрядности переменных типа float. Попробуйте вместо float использовать double.
В Ардуино double как таковой нет. Вместо нее подставляется float.
это уже не так важно, потому что все заработало, но все таки компилятор double воспринимает, а значит фактически она там есть
По сути, в ардуине есть все, что есть в GNU C/C++. И double в том числе.
Ну да, признаю: сам совершил ошибку, за которую уже кого-то критиковал - отождествление Arduino и AVR.
Сейчас просмотрел тему и не обнаружил, чтобы ТС где-то писал, что у него нечто отличное от AVR. Обычно Due выплывает как-то раньше конца второй страницы.
...тема еще жива?
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 работает