Кнопка остановки/запуска секундомера и сброс
я пытаюсь сделать секундомер с кнопкой стоп/старт и кнопкой сброса
Я сделал это
#include "RTClib.h"
//Настройка часов реального времени, DS3231
RTC_DS3231 rtc;
const byte SQWinput = 2; // Должно быть внешнее прерывание
volatile uint32_t MillisecondsAtStartOfSecond = 0;
unsigned long secondss=0 ;
unsigned long minutess=0 ;
unsigned long hourss =0;
unsigned long ms;
boolean passed_second=true;
boolean start=true;
const byte ledPin = 13;
const byte startButton = 7;
const byte resetButton = 3;
// Создаем еще один объект Bounce
const char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// Вывод SQW, установленный в режим 1 Гц, имеет спадающий фронт в начале каждой секунды.
void SQWFallingISR()
{
MillisecondsAtStartOfSecond = millis();
}
void setup ()
{
Serial.begin(9600); // Установить серийный монитор на 115200
delay(200);
pinMode(7, INPUT);
digitalWrite(7, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
if (! rtc.begin())
{
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
if (rtc.lostPower())
{
Serial.println("RTC lost power, let's set the time!");
// Когда необходимо установить время на новом устройстве или после сбоя питания,
// следующая строка устанавливает RTC на дату & время составления этого скетча
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Эта строка устанавливает RTC с явной датой & время, например, установить
// 21 января 2014 года в 3 часа ночи вы бы позвонили:
// rtc.adjust(DateTime(2022, 4, 03, 21, 14, 0));
}
// Настройте контакт SQW на DS3231 для вывода прямоугольного сигнала с частотой 1 Гц
rtc.writeSqwPinMode(DS3231_SquareWave1Hz);
// Получаем MillisecondsAtStartOfSecond по заднему фронту SQW.
attachInterrupt(digitalPinToInterrupt(SQWinput), SQWFallingISR, FALLING);
}
void loop ()
{
DateTime now = rtc.now();
ms = millis();
noInterrupts();
// Сколько времени прошло с начала второго?
ms -= MillisecondsAtStartOfSecond;
interrupts();
if(digitalRead(7) != HIGH) //КНОПКА ПУСК
{ displayTime (now, ms);
Serial.println("stopwatch ");
Serial.print(hourss);
Serial.print(':');
Serial.print(minutess);
Serial.print(':');
Serial.print(secondss);
Serial.print(':');
Serial.println(ms);
}
if(digitalRead(3) != HIGH) //КНОПКА СБРОСА
{
Serial.println("stopwatch ");
Serial.print(0);
Serial.print(':');
Serial.print(0);
Serial.print(':');
Serial.print(0);
Serial.print(':');
Serial.println(0);
ms=0;
}
// displayTime (сейчас, мс);
/*Serial.println("stopwatch ");
Serial.print(hourss);
Serial.print(':');
Serial.print(minutess);
Serial.print(':');
Serial.print(secondss);
Serial.print(':');
Serial.println(ms);
Serial.println("*********************************");
Serial.println("Clock & Date ");*/
}
void displayTime(DateTime &now, unsigned long ms)
{
ms = ms % 1000; // Игнорировать полные секунды
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
if (now.minute() < 10)
Serial.print('0');
Serial.print(now.minute(), DEC);
Serial.print(':');
if (now.second() < 10)
Serial.print('0');
Serial.print(now.second(), DEC);
// Serial.println();
Serial.print(':');
if (ms < 100)
Serial.print('0');
if (ms < 10)
Serial.print('0');
Serial.print(ms, DEC);
Serial.println();
Serial.println("*********************************");
if(ms>998) {
secondss++;
}
if(secondss>59) {
secondss=0;
minutess++;
}
if(minutess>59) {
minutess=0;
hourss++;}
}
но он не работает должным образом
время не увеличивается после того, как мс достигает 999
в чем причина?
@Amr Ahmed, 👍-1
Обсуждение1 ответ
Этот код довольно запутанный, так как вы используете как millis()
, так и
RTC как источник времени.
Ваша проблема может исходить отсюда:
ms -= MillisecondsAtStartOfSecond;
Если внутренние часы вашего Arduino немного сбиваются, может случиться так, что
секунда RTC составляет всего 999 миллисекунд от millis()
. Если это произойдет,
тогда ms
никогда не достигнет 999, а вместо этого пойдет прямо с 998
до 0.
Или, может быть, здесь:
ms = ms % 1000; // Игнорировать полные секунды
// ...
if (ms > 998) {
secondss++;
}
Если ваш скетч занят (возможно, он обменивается данными с RTC), он может
не запускать этот код точно в миллисекунду 999. И 999 - единственный
значение ms
, которое может увеличить secondss
.
Для секундомера данные RTC на самом деле не нужны. Вы можете реализовать
он полностью основан на millis()
, и это упростило бы ситуацию:
bool stop_watch_running;
uint32_t stop_watch_last_update;
uint16_t stop_watch_ms;
uint8_t stop_watch_s;
uint8_t stop_watch_min;
uint8_t stop_watch_h;
void stop_watch_reset() {
stop_watch_running = false;
stop_watch_ms = 0;
stop_watch_s = 0;
stop_watch_min = 0;
stop_watch_h = 0;
}
void stop_watch_start() {
stop_watch_last_update = millis();
stop_watch_running = true;
}
// Периодически вызывайте это.
void stop_watch_update() {
if (!stop_watch_running)
return;
uint32_t now = millis();
stop_watch_ms += now - stop_watch_last_update;
stop_watch_last_update = now;
while (stop_watch_ms >= 1000) {
stop_watch_ms -= 1000;
stop_watch_s++;
if (stop_watch_s >= 60) {
stop_watch_s = 0;
stop_watch_min++;
if (stop_watch_min >= 60) {
stop_watch_min = 0;
stop_watch_h++;
}
}
}
}
void stop_watch_stop() {
stop_watch_update();
stop_watch_running = false;
}
Если вы немного разбираетесь в классах C++, вы можете превратить это в
class и замените префикс stop_watch_
на StopWatch::
.
привет Эдгар Большое спасибо за ваш код RTC используется для получения сигнала прямоугольной формы., @Amr Ahmed
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- Измерить количество циклов и время цифрового входа
- Проблема прерывания библиотеки MPU6050 Arduino Jeff Rowberg
- генерировать два сдвинутых по фазе ШИМ-импульса, запускаемых внешним сигналом с частотным разделением, с помощью Arduino uno?
- Включение прерывания Timer1 CompareA мгновенно вызывает прерывание?
- Таймер Arduino в режиме ctc 4 против 14
Что вы подразумеваете под «_это не работает должным образом_»? Какое поведение вы видите? Чем оно отличается от ожидаемого вами поведения?, @Edgar Bonet
время не увеличивается после того, как мс достигает 999, @Amr Ahmed
объявите
now
вsetup()
...DateTime now;
.... затем используйтеnow = rtc.now();
вloop()
, @jsotola