Регистратор данных весьма полезная в садо-огородных делах штука , со своим универсальным можно сказать 7 лет в любви и дружбе живу
Основная его начинка спрятана в корпусе , а все требуемые в данном случае датчики подсоединяются к внешним разъемам , в теории десятка полтора одновременно датчиков могу подсоединить , но чаще 2-3-4 одновременно требуются
ну вот к примеру одна из обработок данных логгера в экселе
Это в одну из майских ночей сравнивал температуру на улице и в парнике
Ладно , хорош лирики , что же нам потребуется для создания Регистратора Данных , окромя самой ардуины это модуль часов реального времени
я такой обычно использую на DS3231 и AT24C32
И само собою кошелек , куда складывать информацию будем , то бишь модуль карты памяти :
Перед началом работ часы снаряжаем элементом 2032 , затем в модуль часов загружаем текущую дату , время , тут пример вам в помощь :
Потом ищем любую свободную microSD-карту минимального объема , формально модуль до 2гб видит , но у меня и 8ка прекрасно работает , возможно всего на эти 2гб , но нам и несколько мб не исписать вовек
Карту перед работой форматируем в системе FAT , не важно каком
Ну а дальше простейшая сборка , только чтобы убедится что все фурычит :
Живьем это будет так выглядеть :
Ну и заливаем программу (скетч) :
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>// библиотека и под DS3231
#include <SPI.h>// библиотека под SPI протокол
#include <SD.h>// библиотека работы с картой
String s;
File myFile;
void setup() {
setSyncProvider(RTC.get); // функция для того чтобы получить время от RTC
//pinMode(10, OUTPUT);//якобы надо заявить что SS работает как выход , фигня , и так все дышит
SD.begin(4) ;//Проверяем готовность SD модуля
// Проверяем, существует ли на карте файл data.csv, если существует, то удаляем его.
if(SD.exists("data.csv")) {
//SD.remove("data.csv");//не стал удалять файл , на случай сбоя питания продолжит писать в прежний
}
}
void loop()
{
if (timeStatus() == timeSet) {
digitalClockDisplay();
}
}
void digitalClockDisplay(){
// Открываем файл data.csv для записи
myFile = SD.open("data.csv", FILE_WRITE);//а говорили что WRITE удаляет прежний файл , брехня
// Если удалось открыть файл для записи, то записываем данные
if (myFile) {
String ss = String(day())+"-"+String(month())+"-"+String(year());//календарь
myFile.print(ss);
myFile.print(";");
String s = String(hour())+":"+String(minute())+":"+String(second());//часы
myFile.print(s);
myFile.println(";");
myFile.close();// закрываем файл
}
delay (1000);
}
Постарался все лишние сопли для упрощения из кода убрать
Тут разве что стоит обратить внимание на эту строку :
//SD.remove("data.csv");
Она переведена у меня в разряд комментариев , если ее активировать , то регистратор при каждой подаче питания будет удалять прежний файл и начинать писать за ново
В принципе у меня так это и работает сейчас в действующем изделии , но при этом всегда есть риск что вы запустили логгер на ночь или вообще на несколько суток , а в какой-то момент будет отключение сети и в этом случае все предыдущие данные пропадут при повторной подачи питания
По этой причине я и исключил эту строку из кода , если такая ситуация вам не опасна по причине не долгих измерений или наличия бесперебойного питания на борту , то конечно же лучше активировать эту строку , это избавит вас от необходимости удалять старые файлы с карты вручную
Я у себя сейчас внеся изменения в код на рабочем девайсе вынужден был на флешке такой пустой файл-напоминалку создать :
Ладно , пришло время испытать что мы там собрали , загружаем программу , даем некоторое время сборке поработать , потом на некоторое время обесточиваем схему , а после подключаем вновь , даем чуток поработать и уже окончательно отключаем чтобы извлечь флешку и запустить ее на компе :
ну вот что и требовалось получить
Регистратор пишет до момента снятия питания , идет вынужденный простой , а после без удаления старой записи вновь продолжают поступать данные
Но пока собственно у нас никаких данных в карту не пишется окромя даты , времени
Ну теперь для примера добавим какой ни то датчик в схему , к примеру модуль температуры и влажности GXHT30
Ну раз появились датчики , то придется и дисплей вешать для контроля , чтоб знать что пишется в память , так же пустое табло вам напомнит о том что карту памяти вы забыли вернуть в модуль , пока сборка не увидит карты памяти к опросу датчиков она не перейдет
Получается такая сборка :
В код программы вносим изменения :
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal_I2C.h>//библиотека под LCD
LiquidCrystal_I2C lcd(0x27,20,4);
#include "Adafruit_SHT31.h"// библиотека под эту серию датчиков влажности
Adafruit_SHT31 sht31 = Adafruit_SHT31();
String s;
File myFile;
void setup() {
lcd.init();// Инициализация lcd дисплея
lcd.backlight();// Включение подсветки дисплея
sht31.begin(0x44);//инициализация датчика GXHT30 44 адресу
setSyncProvider(RTC.get); // функция для того чтобы получить время от RTC
//pinMode(10, OUTPUT);//якобы надо заявить что SS работает как выход , фигня , и так все дышит
SD.begin(4) ;//Проверяем готовность SD модуля
// Проверяем, существует ли на карте файл data.csv, если существует, то удаляем его.
if(SD.exists("data.csv")) {
//SD.remove("data.csv");//не стал удалять файл , на случай сбоя питания продолжит писать в прежний
}
}
void loop()
{
if (timeStatus() == timeSet) {
digitalClockDisplay();
}
}
void digitalClockDisplay(){
// Открываем файл data.csv для записи
myFile = SD.open("data.csv", FILE_WRITE);//а говорили что WRITE удаляет прежний файл , брехня
// Если удалось открыть файл для записи, то записываем данные
if (myFile) {
String ss = String(day())+"-"+String(month())+"-"+String(year());//календарь
myFile.print(ss);
myFile.print(";");
String s = String(hour())+":"+String(minute())+":"+String(second());//часы
myFile.print(s);
myFile.print(";");
float h = sht31.readHumidity();
float t = sht31.readTemperature();
lcd.setCursor(0, 0);
lcd.print("Humidity");
lcd.setCursor(12, 0);
lcd.print(" "); //протир 8 знакомест перед выводом значения
lcd.setCursor(12, 0);
lcd.print(h); //вывод значения датчика
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("Temperature");
lcd.setCursor(12, 1);
lcd.print(" "); //протир 8 знакомест перед выводом значения
lcd.setCursor(12, 1);
lcd.print(t); //вывод значения датчика
lcd.print("c");
myFile.print(h);
myFile.print(";");
myFile.println(t);
myFile.close();// закрываем файл
}
delay (2000);//период опроса 2сек.
}
Ну все , код исправили , загрузились , тестируем :
ну что датчик нормально встал , дает цыфири
Конечно же когда датчиков много подключено , уже лишних надписей не выведешь на экран , значение бы со всех датчиков уместить
Так же в какой-то момент делаем паузу в питании , хотя этот момент что проверять , до этого уже тестили
ну и вот теперь мы получили привязанные ко времени данные влажности и температуру
Пауза на момент обесточивания присутствует
По такому же принципу можно любые требуемые датчики подключить , на сколько фантазии хватит
Опрос самих датчиков сам по себе занимает некое время что стоит учитывать при выставлении задержки delay в последней строке скетча
Но если опрос делать раз в минуту скажем , то уже секунда другая потерянная на опрос всех датчиков будет и не особо заметна
Ну как-то так выходит
- Читать далее...
- 0 комментариев
- 157 просмотров
Перейти к содержанию