Логирование данных с нескольких датчиков температуры

STam
Offline
Зарегистрирован: 18.04.2021

Доброго дня. Нуждаюсь в совете как это реализуется и какой код должен быть. Изначально тестирую на двух датчиков DS18B20. Целью проекта снимать показания по адресу с 20 датчиков. На цифровой вход двух выходов подключить под 10штук и вести логирование на SD карту. Arduino Uno + SD модуль + rtc ds1307. Посмотрев реализацию в интернете написал сей код (какой есть)) )

Но значения у меня не выводятся, уже запутался в этом. И время не записывается в файл. Нужна ваша помощь

#include <RTClib.h> 
#include <SPI.h>
#include <SD.h>                                       
#include <OneWire.h>                                  
#include <DallasTemperature.h>

#define chipSelect 10                                 
#define ONE_WIRE_BUS 2                                
OneWire oneWire(ONE_WIRE_BUS);                        
DallasTemperature sensors(&oneWire);

uint8_t sensor1[8] = { 0x28, 0xFF, 0xDD, 0xC5, 0x68, 0x60, 0x19, 0x99 };
uint8_t sensor2[8] = { 0x28, 0xFF, 0x97, 0xC4, 0x68, 0x60, 0xCB, 0xA9 };

File myFile;  
RTC_DS1307 rtc;     

void setup() {
     Serial.begin(9600);       
     sensors.begin();

  while(!Serial); 
    if(! rtc.begin()) {
      Serial.println("Couldn't find RTC");
      while (1); 
    }
    else {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }
    if(! rtc.isrunning()) {
      Serial.println("RTC is NOT running!");
    }

  Serial.print("Initializing SD card...");

  if(!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  myFile=SD.open("DATA.txt", FILE_WRITE);
  if (myFile) {
    Serial.println("File opened ok");
    myFile.println("Date,Time,Temperature ºC");
  }
  myFile.close();
}

void loggingTime() {
  DateTime now = rtc.now();
  myFile = SD.open("DATA.txt", FILE_WRITE);
  if (myFile) {
    myFile.print(now.year(), DEC);
    myFile.print('/');
    myFile.print(now.month(), DEC);
    myFile.print('/');
    myFile.print(now.day(), DEC);
    myFile.print(',');
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    myFile.print(now.minute(), DEC);
    myFile.print(':');
    myFile.print(now.second(), DEC);
    myFile.print(",");
  }
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.println(now.day(), DEC);
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.println(now.second(), DEC);
  myFile.close();
  delay(1000);  
}

void loggingTemperature() {

  
sensors.requestTemperatures();                
  delay(500);
 sensors.requestTemperatures(); 
  delay(1000);

  Serial.print("Sensor 1: ");
  Serial.print("Sensor 2: ");

   
  Serial.println(" *C");
  //Serial.print(f);
  //Serial.println(" *F\t"); 
  
  myFile = SD.open("DATA.txt", FILE_WRITE);
  if (myFile) {
    Serial.println("open with success");
    myFile.print("Sensor 1: ");
        myFile.print("Sensor 2: ");
    myFile.println(",");
  }
  myFile.close();
}

void loop() {
  loggingTime();
  loggingTemperature();
  delay(1000);
}

 

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

По отдельности что-то работает? Зачем всё сразу наваливать? Где лог монитора порта?

STam
Offline
Зарегистрирован: 18.04.2021

Сейчас проблема только в RTC, не синхронизируется с пк. Код подправил, взял из примеров, все заработало. Осталось только проверить на всех 20 датчиков и на большом временном промежутке. Лог порта убрал. А здесь есть ребята которые помогают в программировании кода? Ессесно за вознаграждение 

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

STam пишет:
А здесь есть ребята которые помогают в программировании кода? Ессесно за вознаграждение
Есть, но Вы неправильно выбрали раздел форума. Они тусуются в разделе "Ищу исполнителя"

STam
Offline
Зарегистрирован: 18.04.2021

Понял, спасибо

STam
Offline
Зарегистрирован: 18.04.2021

Доброго дня. Реализовал всю конструкцию, получилось 20 датчиков на одной линии и запись идет на sd карту. Есть только одна проблема, запись данных идет не более 10 часов. Дальше данные не пишутся, если только не перезапустить arduino. Никто не сталкивался с таким? 

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

С каким - таким?

STam
Offline
Зарегистрирован: 18.04.2021

С тем что спустя определенное время данные перестают писаться на сд карту ииии все) 

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

Да сколько угодно таких случаев. Вот у моего товарища был кот, который трогал провода на макетке,  пока хозяин отсутствовал.

STam
Offline
Зарегистрирован: 18.04.2021

А если отбросить случаи когда самолет пролетел чайник закипел? 

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

Так вот отбросьте эти случаи и приведите объективные данные, обнаруженные в результате исследования. 

Например: с одним датчиком не вешается, с десятью - вешается через трое суток, с двадцатью - через 10 часов.

 

STam
Offline
Зарегистрирован: 18.04.2021

Датчики допускается программно отключать или только физически? Еще на питание думаю, везде пишут лучше его на цифровой вход ставить. Не тестировал, поставил на заметку.  Из исследований делал только время измерений (1мин, 5мин, 30 мин) и замена портов - без изменений. Данные перестают записываться через 8-10 часов

И еще вопрос - если закрыть на это все глаза и поставить костыль ввиде таймера на сброс арудино или программно перезапуск(если есть, не в курсе еще) можно же назвать временным выходом? Собственно почему бы и нет, хоть и колхоз.

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

В коде хрень

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

К проблеме не относится, но: по какой схеме питание DS? Какой номинал кондера?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

хоть один плюс от логирования на SD карту, а не в базу данных есть?

STam
Offline
Зарегистрирован: 18.04.2021

ua6em пишет:

хоть один плюс от логирования на SD карту, а не в базу данных есть?

Не совсем понял что за база данных? На SD как самый распространенный вариант, в идеале на сервер конечно.

Rumata пишет:

К проблеме не относится, но: по какой схеме питание DS? Какой номинал кондера?

Вечером доберусь до пк, напишу и нарисую все. С кодом подумаю что там.

 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

ua6em пишет:

хоть один плюс от логирования на SD карту, а не в базу данных есть?

Интернет не нужен?

b707
Offline
Зарегистрирован: 26.05.2017

STam, в сообщении #1 последняя версия кода? - если да, то там нет чтения температуры с датчиков вовсе, поэтому и выводить на экран и в лог просто нечего

STam
Offline
Зарегистрирован: 18.04.2021

b707 пишет:

STam, в сообщении #1 последняя версия кода? - если да, то там нет чтения температуры с датчиков вовсе, поэтому и выводить на экран и в лог просто нечего

Нет, это пробник первый. Вечером скину свою версию кода. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Rumata пишет:

ua6em пишет:

хоть один плюс от логирования на SD карту, а не в базу данных есть?

Интернет не нужен?

мне нет... можно жеж и в локальную базу лить...
мне непонятно, как далее с этой SD работают, девайс тушат что ли...

у меня так
Число записей в таблице - 117973
Данные по температуре за последние 120 минут!

STam
Offline
Зарегистрирован: 18.04.2021

Стандартное подключение которое было использовано. Число датчиков 23, все соединения пропаяны включая все контакты на самой arduino включая RTC и SD Module.  Питание подается через штекер с блока питания +5В. 

Сам код который используется.

/*
DS18B20    OUT D2, +5V VCC, GND
DS1307     SDA A4, SCL A5, VCC +5V, GND
SD CARD    CS D10, SCK D13, MISO D12, MOSI D11, +5V VCC, GND
 */

#include <RTClib.h>
#include <Wire.h>                
#include <OneWire.h>                        
#include <DallasTemperature.h>
#include <SPI.h>
#include <SD.h>                             

#define ONE_WIRE_BUS_PIN 2                 

OneWire oneWire(ONE_WIRE_BUS_PIN);         
DallasTemperature sensors(&oneWire);       

RTC_DS1307 RTC;                            

const int chipSelect = 10;                 

File Logfile;                            

// Assign the addresses of your  temp sensors.
DeviceAddress Probe01 = { 0x28, 0x4C, 0xE2, 0x75, 0xD0, 0x01, 0x3C, 0xA6 }; //Гильза
DeviceAddress Probe02 = { 0x28, 0xFF, 0x97, 0xC4, 0x68, 0x60, 0xCB, 0xA9 }; //5см
DeviceAddress Probe03 = { 0x28, 0xFF, 0x12, 0xCA, 0x68, 0x60, 0x08, 0x8D }; //10см
DeviceAddress Probe04 = { 0x28, 0xFF, 0x2B, 0xBF, 0x68, 0x60, 0x18, 0x4E }; //15см
DeviceAddress Probe05 = { 0x28, 0xFF, 0x0E, 0xC3, 0x68, 0x60, 0x2E, 0xBD }; //20см
DeviceAddress Probe06 = { 0x28, 0xFF, 0xE8, 0xC5, 0x68, 0x60, 0x0E, 0xD1 }; //25см
DeviceAddress Probe07 = { 0x28, 0xFF, 0x42, 0xD6, 0x68, 0x60, 0x69, 0x09 }; //30см
DeviceAddress Probe08 = { 0x28, 0xFF, 0x94, 0xC2, 0x68, 0x60, 0x34, 0xDB }; //35см
DeviceAddress Probe09 = { 0x28, 0xFF, 0xBD, 0xCA, 0x68, 0x60, 0x3D, 0x50 }; //40см
DeviceAddress Probe10 = { 0x28, 0xFF, 0xAB, 0xE9, 0x68, 0x60, 0x86, 0x5A }; //45см
DeviceAddress Probe11 = { 0x28, 0xFF, 0xBE, 0x39, 0x68, 0x60, 0x45, 0xDD }; //50см
DeviceAddress Probe12 = { 0x28, 0xFF, 0xB2, 0xC7, 0x68, 0x60, 0xF6, 0x48 }; //55см
DeviceAddress Probe13 = { 0x28, 0xFF, 0x5B, 0xCC, 0x68, 0x60, 0x1D, 0x3C }; //60см
DeviceAddress Probe14 = { 0x28, 0xFF, 0xB2, 0xC1, 0x68, 0x60, 0x66, 0x50 }; //65см
DeviceAddress Probe15 = { 0x28, 0xFF, 0x08, 0xD6, 0x68, 0x60, 0x83, 0xCA }; //70см
DeviceAddress Probe16 = { 0x28, 0xFF, 0x6D, 0xCC, 0x68, 0x60, 0x65, 0x1E }; //75см
DeviceAddress Probe17 = { 0x28, 0xFF, 0xDE, 0xCA, 0x68, 0x60, 0x07, 0xCF }; //80см
DeviceAddress Probe18 = { 0x28, 0xFF, 0xD5, 0x39, 0x68, 0x60, 0x4E, 0x9C }; //85см
DeviceAddress Probe19 = { 0x28, 0xFF, 0xF8, 0xC9, 0x68, 0x60, 0x55, 0x44 }; //90см
DeviceAddress Probe20 = { 0x28, 0xFF, 0xA3, 0xC2, 0x68, 0x60, 0x69, 0x28 }; //95см
DeviceAddress Probe21 = { 0x28, 0xFF, 0x98, 0xCC, 0x68, 0x60, 0xD8, 0xA5 }; //100см
DeviceAddress Probe22 = { 0x28, 0x8D, 0xE8, 0xC9, 0x0A, 0x00, 0x00, 0x9A }; //105см
DeviceAddress Probe23 = { 0x28, 0xFF, 0xDD, 0xC5, 0x68, 0x60, 0x19, 0x99 }; //110см




void setup()
{ 
SD.begin(chipSelect);            
sensors.begin();

RTC.begin();
    if (! RTC.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));  //  Sync Time from PC
  }
  
  // set the resolution to 9 bit (Can be 9 to 12 bits .. lower is faster)
  sensors.setResolution(Probe01, 12);
  sensors.setResolution(Probe02, 12);
  sensors.setResolution(Probe03, 12);
  sensors.setResolution(Probe04, 12);
  sensors.setResolution(Probe05, 12);
  sensors.setResolution(Probe06, 12);
  sensors.setResolution(Probe07, 12);
  sensors.setResolution(Probe08, 12);
  sensors.setResolution(Probe09, 12);
  sensors.setResolution(Probe10, 12);
  sensors.setResolution(Probe11, 12);
  sensors.setResolution(Probe12, 12);
  sensors.setResolution(Probe13, 12);
  sensors.setResolution(Probe14, 12);
  sensors.setResolution(Probe15, 12);
  sensors.setResolution(Probe16, 12);
  sensors.setResolution(Probe17, 12);
  sensors.setResolution(Probe18, 12);
  sensors.setResolution(Probe19, 12);
  sensors.setResolution(Probe20, 12);
  sensors.setResolution(Probe21, 12);
  sensors.setResolution(Probe22, 12);
  sensors.setResolution(Probe23, 12);
                  
Logfile=SD.open("Logfile.csv",FILE_WRITE);              // Open and write once, just for headers
Logfile.println(" Date Time Temp1 Temp2 Temp3 Temp4 Temp5 Temp6 Temp7 Temp8 Temp9 Temp10 Temp11 Temp12 Temp13 Temp14 Temp15 Temp16 Temp17 Temp18 Temp19 Temp20 Temp21 Temp22 Temp23");    // Print headers(not saved yet)
Logfile.close();                                        // Print saved
}

//----------Temp Variable------------//
void printTemperature(DeviceAddress deviceAddress)
{
   float tempC = sensors.getTempC(deviceAddress);
   
   Logfile.print(tempC);
  /*  Logfile.print(" C"); */
   Logfile.print(" ");
}

void loop()
{

 DateTime now = RTC.now();        // Clock call
 now = RTC.now();                 

if(now.minute()==30 && now.second()==00){    
 
 Logfile=SD.open("Logfile.csv",FILE_WRITE);  // Print date and time    

Logfile.println();
Logfile.print(now.year(), DEC);
Logfile.print("/");
Logfile.print(now.month(), DEC);
Logfile.print("/");
Logfile.print(now.day(), DEC);
Logfile.print(" ");
Logfile.print(now.hour(), DEC);
Logfile.print(":");
Logfile.print(now.minute(), DEC);
Logfile.print(":");
Logfile.print(now.second(), DEC);
Logfile.print("  ");              //Space beween date/time and temp1
Logfile.close();                  //Save date and time

sensors.requestTemperatures(); // Command all devices on bus to read temperature 
Logfile=SD.open("Logfile.csv",FILE_WRITE); 
  
 Logfile.print(" ");             //Print temp1
 printTemperature(Probe01);
 Logfile.print(" ");             //Print temp2
 printTemperature(Probe02);
 Logfile.print(" ");             //Print temp3
 printTemperature(Probe03);
 Logfile.print(" ");             //Print temp4
 printTemperature(Probe04);
 Logfile.print(" ");             //Print temp5
 printTemperature(Probe05);
 Logfile.print(" ");             //Print temp6
 printTemperature(Probe06);
 Logfile.print(" ");             //Print temp7
 printTemperature(Probe07);
 Logfile.print(" ");             //Print temp8
 printTemperature(Probe08);
 Logfile.print(" ");             //Print temp9
 printTemperature(Probe09);
 Logfile.print(" ");             //Print temp10
 printTemperature(Probe10);
 Logfile.print(" ");             //Print temp11
 printTemperature(Probe11);
 Logfile.print(" ");             //Print temp12
 printTemperature(Probe12);
 Logfile.print(" ");             //Print temp13
 printTemperature(Probe13);
 Logfile.print(" ");             //Print temp14
 printTemperature(Probe14);
 Logfile.print(" ");             //Print temp15
 printTemperature(Probe15);
 Logfile.print(" ");             //Print temp16
 printTemperature(Probe16);
 Logfile.print(" ");             //Print temp17
 printTemperature(Probe17);
 Logfile.print(" ");             //Print temp18
 printTemperature(Probe18);
 Logfile.print(" ");             //Print temp19
 printTemperature(Probe19);
 Logfile.print(" ");             //Print temp20
 printTemperature(Probe20);
 Logfile.print(" ");             //Print temp21
 printTemperature(Probe21);
 Logfile.print(" ");             //Print temp22
 printTemperature(Probe22);
 Logfile.print(" ");             //Print temp23
 printTemperature(Probe23);
 Logfile.close();                //Print saved
 }
 
delay(1000);                        //One data per second
}

 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Про массивы и циклы, стало быть, не слышали))

111 и 112 как то так себе

114: а если ровно в 30:00 контроллер будет чем то другим занятЪ, например отбывать блокирующий while из библиотеки Далласа?

STam
Offline
Зарегистрирован: 18.04.2021

Новичок по всем пунктам)  Направление понял про for*, почитаю как делается. А что не так со временем? 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

STam пишет:

А что не так со временем? 

Ничего страшного, если бы не delay(1000) в каждом проходе loop(). Кстати, зачем он там? С учетом этого, условие может и не выполниться при неудачном стечении обстоятельств. Особенно, учитывая тот факт, что чтение данных из RTC тоже не супер-быстрая процедура.

И еще момент, не связанный с кодом. Каждый датчик по ДШ жрет от 1 до 1,5 мА, а у вас их 23. Не многовато тока на одну ногу? Особенно с учетом того, что они все хором вам рапортуют. Я уже не говорю об электролите, который просится на питание шины

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Еще заметил: 63 и 65 как то не складываются у меня в один пазл

И еще не понял, зачем в одном проходе цикла постоянно дергать файл open/close? Нельзя все сразу записать? 

Гриша
Offline
Зарегистрирован: 27.04.2014

Rumata пишет:

STam пишет:

А что не так со временем? 

Ничего страшного, если бы не delay(1000) в каждом проходе loop().

ИМХО странно что вообще что-то пишется при таком строгом условии и такими таймингами... мне когда считать лень я использую флаг события...

скажем в 30:00 что-то делаю и флаг опускаю, а в 35:00 флаг поднимаю...

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Гриша пишет:

ИМХО странно что вообще что-то пишется при таком строгом условии и такими таймингами... 

Скорее всего, в этом и есть причина. Какое то время все работает нормально, пока rtc.now() выполняется в начале 59-й секунды. Но начало цикла с каждым проходом сдвигается на несколько миллис и в какой то момент чтение RTC возвращает близкое к 29:59:999. И тут кажется, что все накрылось тазом, ибо после этого сразу наступает 30:01. 

b707
Offline
Зарегистрирован: 26.05.2017

если дело в таймингах - из этого следует что в следующий час оно снова может сработать.

ТС. когда ваша программа через 10 часов перестает писать логи - вы пробовали оставить работать ее дальше? Может на 11 часу она снова будет писать?

 

А вообще весь код - просто кровь из глаз. Яркое подтверждение правила - если новичку в первом же проекте нужно 20 датчиков - это исключительно от дурости... ой. простите. я хотел сказать от неопытности :)

Upper
Offline
Зарегистрирован: 23.06.2020

b707 пишет:

 - это исключительно от дурости... ой. простите. я хотел сказать от неопытности :)

Если хотели так сказать, то зачем написали по другому?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

не уймусь - обрабатывать данные физически как собираетесь?

STam
Offline
Зарегистрирован: 18.04.2021

b707 пишет:

А вообще весь код - просто кровь из глаз. Яркое подтверждение правила - если новичку в первом же проекте нужно 20 датчиков - это исключительно от дурости... ой. простите. я хотел сказать от неопытности :)

Исхожу от целей, мне для исследований надо 20 датчиков.

 

b707 пишет:

если дело в таймингах - из этого следует что в следующий час оно снова может сработать.

ТС. когда ваша программа через 10 часов перестает писать логи - вы пробовали оставить работать ее дальше? Может на 11 часу она снова будет писать?

Нет, дальше не пишет. Проверил на временном отрезке 48 часов. 

ua6em пишет:

не уймусь - обрабатывать данные физически как собираетесь?

Да вроде тут нет проблем, тот же Origin. 

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

Берёшь несколько светодиодов, заставляешь их моргать каждый луп, каждый момент записи и пр. Включаешь и ждёшь 10 часов. Перестали моргать все - система зависла, только тот, что "запись" - в условие не попадаешь, моргают все, но данных на карте нет - проблема в районе SD.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Похоже перегревается КРЕН в ардуинке (пальцем через полчаса потрогайте). Питание нормально организуйте и всё заработает.

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

mykaida пишет:

Похоже перегревается КРЕН в ардуинке (пальцем через полчаса потрогайте). Питание нормально организуйте и всё заработает.

Там вроде греться то не от чего. Пустой луп гоняетсо. Надо бы по человечески весь код переписать и там уже смотреть. Уверен, проблема исчезнет

UPD: Схему подключения питания ДСок не видел, но даже если от ноги, то с такой периодичностью не должно быть проблем.