Уроци по програмиране на Arduino
Блог за техническа поддръжка на моите разработки
Главно меню
Урок 22 Проект за спортен хронометър.
Помислете за функциите на работа с времето. Нека разработим спортен хронометър, базиран на платката Arduino.
За работа с времето в системата Arduino има 4 стандартни функции:
Нека разгледаме подробно тези функции.
отлагане на анулиране (неподписано дълго време)
Функцията спира програмата на пауза за времето, определено в ms.
забавяне (500); // пауза за 0,5 сек
Вече сме използвали тази функция в предишни уроци. Използва се в програми за отстраняване на грешки. В практическите програми функцията се използва рядко.
Факт е, че спира програмата. Програмата не прави нищо за определен период от време. Не е достъпен лукс, валиден само в режими за отстраняване на грешки.
Освен това функцията не ви позволява да създавате цикли с дадено време. Например времето на следващия цикъл няма да бъде точно 100ms.
Времето за цикъл е равно на сумата от: времето от 100 ms, времето за изпълнение на програмния блок и времето за прескачане до началото на цикъла while(). Времето за програмен блок може да варира в зависимост от алгоритъма за изпълнение на програмата. Времето за преход към началото на цикъла също не е точно определено. В резултат на това времето на цикъла може да се определи само приблизително.
За да организирате цикли с дадено време, по-добре е да използвате прекъсване на таймера (урок 10). Необходимо е само да се разбере, че този метод осигурява стабилно време на цикъла, но може да се различава леко от определеното. Например библиотеката MsTimer2 указва времето в ms. Реалното време може да се различава с 1-2 µs. В някои приложения, като часовници, грешкатаще се натрупат и ще доведат до неприемлива грешка.
микросекунди закъснение за анулиране (вълшебно време)
Функцията спира програмата на пауза за времето, посочено в µs.
забавяне Микросекунди (50); // пауза за 50 µs
Аналог на функцията delay(), само че осигурява по-кратки спирания на програмата. Той е напълно приемлив за използване в практически програми по две причини.
- Кратките периоди от време са трудни за прилагане с други методи.
- Спирането на програмата дори за няколко десетки микросекунди няма да доведе до катастрофални последици.
неподписани дълги милисекунди (празно)
Функцията връща времето в ms от началото на текущата програма. Стойността на времето препълва след 1193 часа, приблизително 50 дни.
tm = millis(); // четене на времето в tm
Всъщност това е функция за четене на системното време на Arduino. Времето се изчислява в паралелен процес и не зависи от алгоритмите за изпълнение на програмата, спиранията, включително функцията delay() и др. За да измерите интервали от време, трябва да прочетете системното време в началото и края на интервала и да направите разликата между тези стойности. По-долу е примерна програма за работа с времеви интервали.
Деактивирането на прекъсванията с функцията noInterrupts() за дълго време може да наруши системния часовник.
Точността на функцията millis().
Точността на отчитането на времето от функцията millis () се определя от точността и стабилността на честотата на кварцовия резонатор на платката Arduino. Дори при евтини резонатори честотната грешка не надвишава 30 ppm. Заедно с температурната нестабилност, при нормални условия това е 50 ppm, което съответства на ± 0,00005%. Така общата абсолютна грешка на системното време Arduino ще бъде:
- 0,18 сек за 1 час;
- 4.32 сек за ден;
- 129,6 сек за месец;
- 26 минути за една година.
Вероятно доста приемлива точност за създаване на хронометри и дори часовници.
неподписани дълги микроси(празно)
Функцията връща времето в µs от началото на текущата програма. Стойността се препълва след приблизително 70 минути.
tm = micros(); // четене на времето в tm
На платки Arduino с тактова честота 16 MHz разделителната способност на стойността на функцията micros() е 4 µs. За платки с честота 8 MHz - 8 ms.
Спортен хронометър, базиран на платка Arduino.
Изпълняваме доста прост проект - хронометър. Вероятно практическото приложение на такова устройство е ограничено. Хронометър с мрежово захранване има право да съществува само в стационарни устройства. В табла за спортни състезания, в системи за интелектуални игри и др. Но след като разберете програмата, можете лесно да настроите хронометъра за вашите задачи или да създадете напълно различно устройство.
Хронометърът се управлява с два бутона:
След натискане на бутона START/STOP, хронометърът започва да отчита времето. Повторното натискане на този бутон спира броенето. Следващото натискане продължава обратното броене от спряната стойност. Така хронометърът може да се използва за отчитане на "чистото" време на спортни състезания.
За да нулирате стойността на времето, натиснете бутона RESET.
Часът се показва на четирицифрен седемсегментен дисплей в следните формати.
Форматът на изходните данни се променя автоматично в зависимост от стойността на времето. Минутите, секундите и дробната част са разделени на индикатора с десетични точки. Натискане на бутонипридружен от звукови сигнали.
Спортен хронометър, базиран на платката Arduino UNO R3.
Според вече добре познатите ни схеми се свързваме към платката Arduino:
- 4-цифрен седемсегментен LED индикатор GNQ-3641BUE;
- два бутона;
- звуков пиезо излъчвател.
Всички тези компоненти може да са различни. Ако проектирате хронометър за спортно табло, тогава индикаторите трябва да са големи. Можете дори да ги сглобите от отделни светодиоди. Можете да видите как да свържете индикатори към дъската в урок 19.
Ако бутоните за управление на хронометъра са физически разположени на значително разстояние от таблото, тогава е по-добре да ги свържете според веригата на алармата срещу крадец, урок 17. Или поне свържете входовете на бутоните с + 5 V мощност през 1 kΩ резистори.
Но за отстраняване на грешки и тестване на програмата горната схема е достатъчна. Сглобих го на бредборд.
Програма за спортен хронометър на Arduino.
Скицата на програмата може да бъде изтеглена от тази връзка за изтегляне. Не забравяйте да инсталирате библиотеките от предишните уроци: MsTimer2.h (урок 10), Led4Digits.h (урок 20) и Button.h (урок 9).
Програмната скица за хронометъра изглежда така.
#define SOUND_PIN 18 // звукоизлъчващ щифт 18 (A4)
// индикатор тип 1; заключения на разряди 5,4,3,2; сегментни изходи 6,7,8,9,10,11,12,13 Led4Digits disp(1, 5,4,3,2, 6,7,8,9,10,11,12,13);
Бутон buttonReset(16, 10); // Бутон RESET, щифт 16 (A2) Бутон StartStop(17, 10); // Бутон START/STOP, щифт 17 (A3)
bytemode=0; // режим, 0 - СТОП, 1 - MC контрол unsigned long msTime=0; // интервално време, милисекунди byte minTime=0; // интервално време, минути byte decMinTime=0; //интервално време, десетки минути unsigned long prevTime; // предишна времева стойност unsigned long currentTime; // текуща времева стойност byte soundCount=0; // брояч на звуково време
void setup() MsTimer2::set(2, timerInterrupt); // 2ms таймер прекъсва MsTimer2::start(); // разрешаване на прекъсване pinMode(SOUND_PIN, OUTPUT); // изход на аудио емитер >
// ----------------------- превключване на режим START/STOP if ( buttonStartStop.flagClick == true ) buttonStartStop.flagClick= false; // функция за нулиране // инверсия на режима if ( mode == 0) mode= 1; // START soundCount= 250; // стартиране на звука 250*2ms > иначе < // СПРИ режим= 0; soundCount= 50; // спира звука 50*2ms > >
// ----------------------- Бутон RESET if ( buttonReset.flagClick == true ) buttonReset.flagClick= false; // функция за нулиране msTime=0; minTime=0; decMinTime=0; soundCount= 50; // нулиране на звука 50*2ms >
// ----------------------- време if ( режим == 0 ) // СПРИ prevTime= millis(); > else // ИЗПЪЛНЕНИЕ curentTime= millis(); // прочете текущото време msTime += curentTime - prevTime; // добавяне на време към милисекунди ако ( msTime > 59999 ) // препълнени милисекунди, повече от минута msTime -= 60000; minTime++; // +1 към минути единици if ( minTime > 9 ) // минути единици препълнени minTime -= 10; decMinTime++; // +1 до десетки минути > > предишен час= текущ час; // претоварване на предишно време >