Как сделать чтобы даталоггер создавал файл каждый час?

valera140582
Offline
Зарегистрирован: 01.07.2016

Я сделал даталоггер для регистрации аналоговых  процессов на SD карту. Помогите чтобы даталоггер создавал файл каждый час. А то файлы получаются большими. С разу скажу что опыт у меня небольшой по программированию ардуино. Использую leonardo pro micro.

Вот код:

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

// Простой логгер для Arduino аналоговые пины


#define LOG_INTERVAL  100 // мельницы между записи (уменьшить, чтобы взять больше/быстрее данные)
#define SYNC_INTERVAL 1000 // мельницы между звонков flush() - запись данных на карту
uint32_t syncTime = 0; // момент последней синхронизации()

#define ECHO_TO_SERIAL   1 // Эхо данные для последовательного порта
#define WAIT_TO_START    0 // Ждать серийного ввода в Setup()

// цифровой штыри, которые подключаются к Светодиодам
#define redLEDpin 0
#define greenLEDpin 1


RTC_DS1307 RTC; // определить часы реального времени объект

// за экран регистрации данных, мы используем цифровой вывод 10 для SD в CS онлайн
const int chipSelect = 7;

// файл журнала
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while(1);
}
//-------------------------------------------------------------------------------------------
void setup(void)
{
  Serial.begin(9600);
  Serial.println();

// использовать отладочные светодиоды
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
  
#if WAIT_TO_START
  Serial.println("Type any character to start"); //Введите любой символ, чтобы начать
  while (!Serial.available());
#endif //WAIT_TO_START

//-------------------------------------------------------------------------------------------
// initialize the SD card
  Serial.print("Initializing SD card...");
  pinMode(7, OUTPUT);
  
// смотрите, если на карте присутствует и может быть инициализирован:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present"); //Карта не удалась, или нет
  }
  Serial.println("card initialized.");
  
// создать новый файл
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // только открыть новый файл если он не существует
      logfile = SD.open(filename, FILE_WRITE); 
      break;  // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file"); //не мог создать файл
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);
  
//-------------------------------------------------------------------------------------------
// подключение к RTC
  Wire.begin();  
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }

  logfile.println("миллисекунда, дата и время, канал1, канал2, канал3, канал4, ,канал5, канал6, канал7, канал8, Temp");    
#if ECHO_TO_SERIAL
  Serial.println("миллисекунда, дата и время, канал1, канал2, канал3, канал4, ,канал5, канал6, канал7, канал8, Temp");
#endif //ECHO_TO_SERIAL

}

void loop(void)
{

//------------------------------------------------------  
  DateTime now;

  // задержки в течение времени, мы хотим, чтобы между чтениями
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
  
  digitalWrite(greenLEDpin, HIGH);

//-------------------------------------------------------------------------------------------
  String dataString = "";

  // читать три датчика и присоединить к строке:
  for (int analogPin = 0; analogPin < 4;  analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 7) {
      dataString += ",";
    }  
  }
  //-------------------------------------------------------------------------------------------
  String dataString2 = "";

  // читать три датчика и присоединить к строке:
  for (int analogPin1 = 6; analogPin1 < 10;  analogPin1++) {
    int sensor2 = analogRead(analogPin1);
    dataString2 += String(sensor2);
     //if (analogPin1 < 7)
     {
      dataString2 += ",";
     }  
  }
//-------------------------------------------------------------------------------------------  
  // журнал миллисекунд с момента начала
uint32_t m = millis();
logfile.print(m);           // milliseconds since start
logfile.print(", ");    
#if ECHO_TO_SERIAL
Serial.print(m);         // milliseconds since start
Serial.print(", ");  
#endif

  // выборка по времени
  now = RTC.now();
  logfile.print(now.day(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.year(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
  logfile.print(", ");    
  logfile.print(dataString);
  logfile.print(", ");    
  logfile.print(dataString2);
  logfile.print(", ");  

#if ECHO_TO_SERIAL
  Serial.print(now.day(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.year(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print(", ");   
  Serial.print(dataString);
  Serial.print(", ");   
  Serial.print(dataString2);
  Serial.print(", ");

#endif //ECHO_TO_SERIAL


logfile.println();
#if ECHO_TO_SERIAL
Serial.println();
#endif // ECHO_TO_SERIAL
//-------------------------------------------------------------------------------------------
  digitalWrite(greenLEDpin, LOW);

// Теперь мы записать данные на диск! Не синхронизируются слишком часто - требует 2048 байт ввода-вывода в SD-карта
// который использует кучу энергии и занимает время
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();
  
// мигать светодиод, чтобы показать нам синхронизацию данных с карты и обновления жир!
  digitalWrite(redLEDpin, HIGH);
  logfile.flush();
  digitalWrite(redLEDpin, LOW);
  
} 

 

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

Просто открывать файл с нужными флагами, смотрите описание функции SD.open. Есть флаги - создавать, если нету. Есть флаги - открыть и усечь. Разные флаги есть, достаточно только чуть-чуть поискать.

kraus
Offline
Зарегистрирован: 07.07.2019


 

Очень прошу не пинать ногами - я только-только начинаю на ардуинке. Дома надо срочно воткнуть логгер по давлению и по температуре горячей воды. Скетч сделал, пишет..., но есть одно НО! - пишет всё в один файл. Карта 16 гигов (уж какая есть) - даже не представляю на сколько её хватит записать логи... может на неделю??? И страшно открывать текстовый файл размером 16 гигов - интересно сколько это займёт времени?...

Очень прошу: подскажите пожалуйста как сделать чтобы логи писались в файлы ну хотя бы по 10 мегабайт, или по временичасов по 8.... как лучше-то?

Тут вотнаписано:

DIYMan пишет:

Просто открывать файл с нужными флагами, смотрите описание функции SD.open. Есть флаги - создавать, если нету. Есть флаги - открыть и усечь. Разные флаги есть, достаточно только чуть-чуть поискать.

А я не понял какие флаги? всё перерыл - нет нихрена в библиотеках и в их описании.

/ регистратор давления и температуры с шагом в минуту

#include <SD.h>                                 // Подключаем библиотеку SD
#include <SPI.h>                                // Подключаем библиотеку SPI
#include <DS3231.h>                             // Подключаем библиотеку DS3231

b707
Онлайн
Зарегистрирован: 26.05.2017

У тебя там в кооде есть RTC часы - тогда проще всего делать по времени. Скажем, если реальное время == 6 часов 0 минут 0 секунд - закрываешь старый файл, открываешь новый. Так логи будут сменяться раз в сутки. Если насоздаешь таких условий еще и для 12 часов, 18 и 00 - получишь смену файла каждые 6 часов...

kraus
Offline
Зарегистрирован: 07.07.2019

Я боюсь мозгов не хватит скетч написать по времени. Влез в это дело только неделю назад от необходимости. Языка вообще не знаю. А то что скетч такой - так объединил из трёх. неделю мучился методом тыка. Может поможете чем? Направьте хоть.... где операнды искать и как их увязывать..и куда вставлять.

Ещё хотел скетч упростить, но ничерта не получилось. Ну и хрен с ним работает и ладно. А вот с флэшкой - боюсь комп открывать будет доооооолго. Потому и хочу на файлы порубить. А как - не знаю.

Сначала запись лога будет каждые 1 минуту, месяцев через 3-4-5  наверное через 5 минут. 

Задолбали жкошники с теплосетью. Как комиссия приходит - дают еормальное давление и температуру, как уходит комиссия - так либо вообще вода не идёт, либо тооооненькой струйкой и температура 41 градус. Вот комиссия наверное и говорит что я их задолбал по пустякам вызывать, мол брешу я о том что воды нет горячей.

b707
Онлайн
Зарегистрирован: 26.05.2017
DateTime now = rtc.now();
if ( ( now.hour() == 6) && (now.minute() == 30) && (now.second() == 45)) {
// закрыть старый файл и открыть новый
}

 

kraus
Offline
Зарегистрирован: 07.07.2019

b707 пишет:

У тебя там в кооде есть RTC часы - тогда проще всего делать по времени. Скажем, если реальное время == 6 часов 0 минут 0 секунд - закрываешь старый файл, открываешь новый. Так логи будут сменяться раз в сутки. Если насоздаешь таких условий еще и для 12 часов, 18 и 00 - получишь смену файла каждые 6 часов...

А как код такой написать??У меня же по скетчу получается что файл открывается каждую секунду и записывает показания, после чего закрывается и опять открывается для записи... 

kraus
Offline
Зарегистрирован: 07.07.2019

b707 пишет:

DateTime now = rtc.now();
if ( ( now.hour() == 6) && (now.minute() == 30) && (now.second() == 45)) {
// закрыть старый файл и открыть новый
}

 

Так новый както ещё обзывать надо, а то перезаписывать старый будет..

b707
Онлайн
Зарегистрирован: 26.05.2017

kraus пишет:

Так новый както ещё обзывать надо, а то перезаписывать старый будет..

конечно. Ну это уже второй вопрос

kraus
Offline
Зарегистрирован: 07.07.2019

Нашёл в интернете 

// создать новый файл
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // только открыть новый файл если он не существует
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }

а как работает до конца не пойму... тут ведь только 100 файлов может создаться, а какого размера не сказано. Ещё видел на английском ктото спрашивал и есму сказали что новая строчка нужна типа "filename[8] =" а чему равно - он сразу понял - а я тупой.... А у меня может 100, а может 100000 файлов будет......... как тогда?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Был бы у тебя Zabbix на компе поднят - решил бы всё за полчаса... Даже графики бы получил.

b707
Онлайн
Зарегистрирован: 26.05.2017

sadman41 пишет:

Был бы у тебя Zabbix на компе поднят - решил бы всё за полчаса... Даже графики бы получил.

надо будет что-нибудь почитать про Заббикс...

kraus
Offline
Зарегистрирован: 07.07.2019

Ну нет такой проги.... 

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

filename[6] = i/10 + '0';
 

filename[7] = i%10 + '0';      

что вот эти строки делают.... особенно вторая.

b707
Онлайн
Зарегистрирован: 26.05.2017

kraus пишет:

Ну нет такой проги.... 

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

filename[6] = i/10 + '0';
 

filename[7] = i%10 + '0';      

что вот эти строки делают.... особенно вторая.

блин, есть же интернет? что мешает посмотреть описание оператора "%" ????

kraus
Offline
Зарегистрирован: 07.07.2019

Тормознул..  а + '0' это зачем? И почему у них индексы 6 и 7, а не 7и8, ведь 00 в названии файла являются 7 и 8 позициями. "LOGGER00.CSV"

 

Получается надо типа filename[8] = i + '0';  так чтоли? или filename[8] = i%10 + '10';... или filename[8] = i/1 + '10';

 

Да непонятно нихрена... как ноль плюсуется к этому делу? Получается если i=1, то i/10=0,1+"0", а 0 то как пюсуется? сдвигает влево? (т.е. было ,1 стало 1), но тогда одновременно во второй строке получается: i%10+'0'  - 1+'0 = 10 и получается что новые файлы нумеруются: 0,11,52'...... ничего не понял...

sadman41
Онлайн
Зарегистрирован: 19.10.2016

1) Кампутер считает не с "раз", а с "ноль". То, что для вас - первый элемент массива, то для него - нулевой.
2) '0' - это не ноль, а символ нуля. При вычислениях вместо него подставляется ASCII-код символа "нуль".
3) Какой символ следует за '0' через две позиции ('0'+2)? 

(подсказка - ищите в гуголе таблицу ASCII)

sadman41
Онлайн
Зарегистрирован: 19.10.2016

b707 пишет:

sadman41 пишет:

Был бы у тебя Zabbix на компе поднят - решил бы всё за полчаса... Даже графики бы получил.

надо будет что-нибудь почитать про Заббикс...

Ну, в данном случае даже он не нужен. Любой инструмент, который умеет с STDIO читать или коннектится на TCP порт, кидать туда запрос, получать цифирь текстом. Далее - хоть в DB ложи, хоть в null спускай.

kraus
Offline
Зарегистрирован: 07.07.2019

Нашёл таблицу... будь она неладна.... https://www.industrialnets.ru/files/misc/ascii.pdf - двум - 2 соответствует 02....     10 - 0А   ... и как считать.....???????? Это в гексе, а чар - вообще песня. про цмд говорить не буду...

kraus
Offline
Зарегистрирован: 07.07.2019

[/quote]

Ну, в данном случае даже он не нужен. Любой инструмент, который умеет с STDIO читать или коннектится на TCP порт, кидать туда запрос, получать цифирь текстом. Далее - хоть в DB ложи, хоть в null спускай.

[/quote]

Не ругайтесь...

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Чего ж неладна сразу? Char - это то, что рисуется на экране. DEC - числовой код этого изображения (ASCII-код).

То, что мы видим, как картинку нуля - '0', кампутер видит, как 48.

kraus
Offline
Зарегистрирован: 07.07.2019

Т.е. i/10+"0" будет равно( при i=2 ) 0,2+48 =48,2? так чтоли? 

b707
Онлайн
Зарегистрирован: 26.05.2017

kraus - имхо, быстренько решить свою задачу, ни во что не вникая - у вас не выйдет. Разве что только кто сжалится и напишет весь код за вас. А сами без знания хотя бы основ программирования вы ничего не сделаете. У вас на каждой строчке программы десять вопросов будет - что такое '0' или зачем тут  '%'? :)

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

kraus пишет:

Т.е. i/10+"0" будет равно( при i=2 ) 0,2+48 =48,2? так чтоли? 

Всё так. Теперь вспоминаем (или узнаём) что char - целочисленный и в него попадают только целые части числа. 

Но Вам пока непонятно зачем это, потому что Вы рассматриваете пример в отрыве от алгоритма в целом. Узнайте, что делает оператор % и найдите результат вычисления при i = 12 для:


filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
kraus
Offline
Зарегистрирован: 07.07.2019

Да мне просто срочно нужен логгер.И не программер я.. И узнавать всё, компилировать времени нет уже.

"Т.е. i/10+"0" будет равно( при i=2 ) 0,2+48 =48,2? так чтоли? " тогда такое же число будет и при 3, 4, 5, 6, 7, 8, 9. i будет меняться а выражение так и останется 48.

b707
Онлайн
Зарегистрирован: 26.05.2017

kraus пишет:

мне просто срочно нужен логгер

Садман, я пошел. мне срочно нужно

kraus
Offline
Зарегистрирован: 07.07.2019
char filename[] = "datalog000.CSV"; // Первоначальное название
for (uint8_t i = 0; i < 1000; i++) {
  
  }
}

Так чтоли?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

kraus пишет:

Да мне просто срочно нужен логгер.И не программер я.. И узнавать всё, компилировать времени нет уже.

И что вы предлагаете нам сделать - срочно всё бросить и писать его за вас? Погуглите - не исключено, что уже все кем-то написано.

kraus
Offline
Зарегистрирован: 07.07.2019

Если читали, то просил помочь тем что написать, т.к. мне не осилить, а надо срочно. Но спасибо вам за потраченное на меня время, хотя за это время можно было бы написать столь короткий код раз 20, а не заставлять меня форсированно обучаться (что я и так , но потихоньку делаю). Я не лентяй, просто времени нет уже до конца всё познавать. За неделю я не научусь же.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Ваш пост в разделе "Программирование". Тут обучают. Фабрика исполнения заказов в другом месте.

b707
Онлайн
Зарегистрирован: 26.05.2017

kraus пишет:

Если читали, то просил помочь тем что написать, т.к. мне не осилить, а надо срочно. Но спасибо вам за потраченное на меня время, хотя за это время можно было бы написать столь короткий код раз 20

Сюда каждый день заходит несколько человек, ожидающих, что вот сейчас им выдадут готовый код. Каждый из местных завсегдатаев в свое время поддавался на такие просьбы и писал кому готовые программы. Но это. знаете ли, быстро надоедает - поэтому на форуме существует правило - код за новичков мы не пишем. Мы можем помочь  в чем-то разобраться, показать путь решения. обьяснить, как обойти проблемы. Но делать за вас тут никто не будет.

Обо всем этом, кстати, написано в правилах форума.

SLKH
Offline
Зарегистрирован: 17.08.2015

b707 пишет:

Обо всем этом, кстати, написано в правилах форума.

мне некогда читать ваши правила, мне срочно нужен логгер.

bwn
Offline
Зарегистрирован: 25.08.2014

kraus пишет:

Задолбали жкошники с теплосетью. Как комиссия приходит - дают еормальное давление и температуру, как уходит комиссия - так либо вообще вода не идёт, либо тооооненькой струйкой и температура 41 градус. Вот комиссия наверное и говорит что я их задолбал по пустякам вызывать, мол брешу я о том что воды нет горячей.

Да комиссии на ваши самоделки будет глубоко фиолетово, во внимание могут приниматься показания поверенного, зарегистрированного и правильно установленного прибора (с соответствующей ценой). На все остальные даже смотреть не будут, ни комиссия, ни суд.  Я не очень понял, о чем идет речь, о ГВС или отплении? Если ГВС и стоят счетчики, а напор по холодной нормальный, то поставьте эл.бойлер литров на 100 и забейте на свою жилконтору. ИМХО.