Циклический счетчик на RTC

rcew
Offline
Зарегистрирован: 23.06.2019

Здравствуйте.

Помогите решить проблему скорее всего относящуюся к математическим вычислениям на ардуино.

Что имеем: RTC + Arduino

Что требуется: выполнение кода каждые 10 секунд.

Как реализовано: получаем данные времени с RTC и каждые 10 (секунд или минут) выполняем требуемую операцию

// подключаем RTC3231
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS3231);          // подключаем RTC модуль на базе чипа DS3231, используется аппаратная шина I2C

// Задаем интервал записи данных на карту SD (см в коде)
byte interval = 10; // интервал записи данных на карту SD

byte currentTime = 0;
int previousTime = 0;

   
   byte hourGlobalClock        = 0; // часы
   byte minuteGlobalClock      = 0; // минуты
   byte secondGlobalClock      = 0; // секунды
void setup() {
  // put your setup code here, to run once:
  time.begin(); // функция инициирует модуль: проверяет регистры модуля, запускает генератор модуля и т.д.
}

void loop() {
      time.gettime(); // см документацию к библиотеке модуля #include <iarduino_RTC.h>
      hourGlobalClock   = time.Hours;   // часы
      minuteGlobalClock = time.minutes; // минуты
      secondGlobalClock = time.seconds; // секунды
 
  // задаем интервал записи на карту каждые 10 секунд
  currentTime = secondGlobalClock; // выбираем, что считаем (секунды)
      if (currentTime == 0) { // 
          previousTime = (60 - previousTime) * -1;
      }
  if ((currentTime - previousTime) >= interval) {
      previousTime = currentTime;

 // здесь выполняем запись на SD
  }
}

Проблема в следующем: в момент перехода времени 59 -> 00 происходит многократная запись данных на SD

Данной строкой пытаюсь решить проблему, когда после перехода времени 59 -> 00 последнее значение previousTime > currentTime и вычисление (currentTime - previousTime) >= interval загоняет программу в ступор.

      if (currentTime == 0) { // 
          previousTime = (60 - previousTime) * -1;
      } 

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

  if ((currentTime - previousTime) >= interval) {
      previousTime = currentTime;

 // здесь выполняем запись на SD
  }

Но в момент достижения переменной currentTime значения 0,  отрицательное число previousTime  принимает значение 0, вместо того, чтобы быть заданным согласно 

previousTime = (60 - previousTime) * -1;
Вопрос в том, как заставить переменную previousTime  не менять своего значения?
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

rcew,ну здесь могу сказать одно. Попробуйте входить в дом через дверь, а не лезть через форточку. Конечно некоторым это удается, но очень не удобно.

b707
Offline
Зарегистрирован: 26.05.2017
if (currentTime < previousTime ) { 
   (currentTime +=60;
} 

а на самом деле в этом коде не нужен RTC вовсе

sadman41
Offline
Зарегистрирован: 19.10.2016

Завести флажок needToSave, контролировать интервалами с помощью счетчика, например по N сек. Через N/2 сек поднять флажок, через N сек. счётчик сбросить на 0 и считать с начала. Записать данные, если флажок поднят и счётчик секунд < N/2. Флажок сбросить после записи. Повторять процесс до износа контроллера.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы можете словами, по-русски объяснить что именно делается в строках №№ 27-32? Подробно, но именно словами, а не "переменными".

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:
Вы можете словами, по-русски объяснить что именно делается в строках №№ 27-32?

Это же и есть они, математические вычисления, с которыми проблема.

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

sadman41 пишет:
Это же и есть они, математические вычисления, с которыми проблема.
С математическими вычислениями проблем нет. Проблемы у ТС с пониманием. Пока у ТС понимания не будет, то пиши не пиши все будет так же.

rcew
Offline
Зарегистрирован: 23.06.2019

qwone,

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

Я могу это сделать на millis(), но захотелось на RTC

Главный вопрос в том, почему объявленное значение previousTime  в 29 строке в 31 строке становится равным 0

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

rcew пишет:

qwone,

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

Я могу это сделать на millis(), но захотелось на RTC

Главный вопрос в том, почему объявленное значение previousTime  в 29 строке в 31 строке становится равным 0

тот же millis() но уже колличество секунд от полночи. Есть еще время Unix .На нем работа компьютеров и интернета основана. А вы все по форточкам лазите. https://habr.com/ru/post/123461/

rcew
Offline
Зарегистрирован: 23.06.2019

27 строка

получаю текущее значение времени из RTC

31 - 32 строки

считаю разницу во времени между текущим и временем последней записи и сравниваю с заданным интервалом, при выполнении условия, пишу данные на карту

28-29 строки

устраняю косяк, возникающий в 31 - 32 , когда при вычислении (currentTime - previousTime) >= interval

currentTime < previousTime, а это возникает в момент перехода значения currentTime  59 -> 0. Тк значение это минут(секунд) и идет по кругу. И в какой-то момент времени становится вот так  (currentTime - previousTime) >= interval  = (2 - 56) >= 10

Для этого в момент, когда currentTime == 0 в строке 29 получаю разницу 60-previousTime, которую нужно сложить с тем, что насчитается с момента, когда currentTime счановится 0 и идет далее.

С тем, чтобы в какой-то момент получить значениее (2 - (-8)) >= 10

Так вот через монитор порта видно, что previousTime принимает отрицательное значение пока currentTime не стал равен 0, те 59 и менее. В момент, когда currentTime = 0, значение previousTime сбрасывается на 0

Пс я гуманитарий и ковыряю ардуино для интереса

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

rcew пишет:
Пс я гуманитарий и ковыряю ардуино для интереса
Музыкант что ли. Литературой запрещено пользоваться. Ну ладно сказал бы что он технарь. Ему техника ближе чем программирование. Но программирование это уже давно гуманитарное ремесло, потому что оно делается для взамодействия с людьми.

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

rcew пишет:

Что имеем: RTC + Arduino

Что требуется: выполнение кода каждые 10 секунд.

Задам простой вопрос: нахрена козе RTC? Если по условиям задачи вполне достаточно обыкновенного millis?

uint32_t last = 0;

void setup()
{
}

void loop()
{
	if(millis() - last >= 10000ul)
	{
		doTheJob();
		last = millis();
	}
}

И не надо лохматить бабушку ;)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

rcew пишет:

Помогите решить проблему 

Что имеем: RTC + Arduino

Что требуется: выполнение кода каждые 10 секунд.

Решаем. Тока, выкинем RTC, за ненадобностью

#include <TimerList.h>

extern TTimerList TimerList;

THandle h10SecTimer = INVALID_HANDLE;

void tmr10Sec(void){
// Выполняем здесь всё что хочешь раз в 10 секунд
// Или, что лучше, взведем флаг и в loop() выполним
}

void setup() {

h10SecTimer = TimerList(10000, tmr10Sec); // взводим таймер на 10 секунд

}

Функция tmr10Sec() будет вызываца строго 1 раз в 10 секунд.

Проблема решена. 

rcew
Offline
Зарегистрирован: 23.06.2019

b707 пишет:

if (currentTime < previousTime ) { 
   (currentTime +=60;
} 

а на самом деле в этом коде не нужен RTC вовсе

 

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

По поводу RTC

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

Спасибо всем за участие.

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

rcew пишет:
Но тут до меня дошло, что случись что с RTC(батарейка села, контакта нет и тд), данные на SD я писать не смогу.
О как, гуманитариям но специфике положено головой думать, а не лезть в железо.