Ardiuno IDE 1.8.2 Arduino Nano 328p 16 MHz Есть полный скетч: Спойлер: скетч Код (C++): // Include the libraries we need //#include <OneWire.h> #include <DallasTemperature.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2); //#include "DHT.h" #include "RTClib.h" #include <SPI.h> #include <SD.h> const int chipSelect = 4; #define ONE_WIRE_BUS 9 //подключение DS18B20 в будущем #define RELE 7 #define BUZZER 6 #define UPTR 5 //темпер выключения реле 9 #define DOWNTR 3 //темпер включения реле 2 #define TBUZZ 0 //темпер включения реле 0 град #define DHTPIN 10 //контакт датчика float tempCH, tempC; int h; boolean vkl; byte simvol[8] = {B11100,B10100,B11100,B00000,B00000,B00000,B00000,B00000,}; //DHT dht(DHTPIN, DHT11); DS1307 rtc; char daysOfTheWeek[7][9] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"}; unsigned long time1,time2,time3; //String namefile; OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress insideThermometer; void lcdZeroPaddedPrint(long i, byte len, bool decimal = false) { if (i < 0) { // negate value i = i * -1; lcd.print("-"); } switch (len) { case 6: lcd.print(i / 100000); i %= 100000; case 5: lcd.print(i / 10000); i %= 10000; case 4: lcd.print(i / 1000); i %= 1000; case 3: lcd.print(i / 100); i %= 100; case 2: lcd.print(i / 10); i %= 10; if (decimal) lcd.print("."); default: lcd.print(i); } } unsigned long deltamills(unsigned long t_old, unsigned long t_new) { unsigned long delta; if ( t_old <= t_new ) { delta = t_new - t_old; } else { delta = (4294967295 - t_old) + t_new; } return delta; } void setup(void) { vkl=false; lcd.init(); lcd.backlight();// Включаем подсветку дисплея pinMode(RELE, OUTPUT); pinMode(BUZZER, OUTPUT); Serial.begin(9600); // dht.begin(); sensors.begin(); Serial.print(sensors.getDeviceCount(), DEC); Serial.print("Parasite power is: "); if (sensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF"); if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); printAddress(insideThermometer); sensors.setResolution(insideThermometer, 9); Serial.print(sensors.getResolution(insideThermometer), DEC); rtc.begin(); if (! rtc.isrunning()) { lcd.clear(); lcd.setCursor(0,0); lcd.print("RTC NO!"); rtc.adjust(DateTime(__DATE__, __TIME__)); //тянем время в ПК } time2=millis(); Serial.print("Initializing SD card..."); // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); // don't do anything more: return; } Serial.println("card initialized."); } void loop(void) { DateTime now = rtc.now(); char buf[100]; char buf2[100]; //strncpy(buf,"DD.MM.YYYY hh:mm:ss",100); strncpy(buf,"hh:mm:ss DD-MM",100); strncpy(buf2,"DD.MM.YYYY hh:mm:ss",100); if (deltamills(time1,millis())>1000) { time1=millis(); lcd.setCursor(0,0); lcd.print(now.format(buf)); lcd.setCursor(9,0); lcd.setCursor(14,0); lcd.print(daysOfTheWeek[now.dayOfWeek()]); lcd.print(" "); lcd.createChar(1, simvol); lcd.setCursor(12, 0); lcd.setCursor(0, 1); lcdZeroPaddedPrint(tempC*10, 3, true); lcd.print("\1 "); lcd.print(h); lcd.print("% "); lcd.print(DOWNTR); lcd.print("-"); lcd.print(UPTR); if (vkl) lcd.print(" E"); else lcd.print(" D"); } if (deltamills(time3,millis())>2000) { time3=millis(); Serial.print(now.format(buf2)); Serial.print(" "); sensors.requestTemperatures(); // Send the command to get temperatures tempC = sensors.getTempC(insideThermometer); Serial.print("DST: "); Serial.print(tempC); Serial.println(" "); // h = round(dht.readHumidity()); // tempCH = dht.readTemperature(); // Serial.print("В ");Serial.print(h); Serial.print(" T ");Serial.println(tempCH); // if (isnan(h) || isnan(tempCH)) { // return; // } } if (millis() > 5000) { if (tempC <= DOWNTR) {digitalWrite(RELE, HIGH); vkl=true;} else if (tempC >= UPTR) {digitalWrite(RELE, LOW); vkl=false;} if (tempC <= TBUZZ) {digitalWrite(BUZZER, HIGH);} else if (tempC > TBUZZ) {digitalWrite(BUZZER, LOW);} } if (deltamills(time2,millis())>10000) { time2=millis(); String dataString = ""; dataString += String(now.format(buf2)); dataString += " DST: "; dataString += String(tempC); File dataFile = SD.open("log2.txt", FILE_WRITE); if (dataFile) { dataFile.println(dataString); dataFile.close(); // print to the serial port too: Serial.println("WRITE: "); Serial.println(dataString); } // if the file isn't open, pop up an error: else { Serial.println("error opening datalog.txt"); Serial.println(dataString); } } } //DS18B20 void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16) Serial.print("0"); Serial.print(deviceAddress[i], HEX); } Serial.println(" "); } Все работает, за исключением участка: Код (C++): String dataString = ""; dataString += String(now.format(buf2)); dataString += " DST: "; dataString += String(tempC); File dataFile = SD.open("log2.txt", FILE_WRITE); if (dataFile) { dataFile.println(dataString); dataFile.close(); // print to the serial port too: Serial.println("WRITE: "); Serial.println(dataString); dataString формировал и просто как dataString = String(now.format(buf2)) + " DST: " + String(tempC); Но значения в строку не переводит. Либо часть значений переводит в строку. Формат типа: Код (C++): String dataString = ""; dataString += "DST: "; dataString += String(tempC); нормально работает. в логе вижу: Код (C++): 1Parasite power is: OFF 28757E4592020289 9Initializing SD card...card initialized. 06.10.2019 15:54:45 DST: 15.50 06.10.2019 15:54:47 DST: 15.50 06.10.2019 15:54:49 DST: 15.50 06.10.2019 15:54:51 DST: 15.50 06.10.2019 15:54:53 DST: 15.50 WRITE: DST: 06.10.2019 15:54:55 DST: 15.50 06.10.2019 15:54:57 DST: 15.50 06.10.2019 15:54:59 DST: 15.50 06.10.2019 15:55:01 DST: 15.50 06.10.2019 15:55:03 DST: 15.50 WRITE: DST: 06.10.2019 15:55:05 DST: 15.50 06.10.2019 15:55:07 DST: 15.50 Дату добавлял также частями, типа год + месяц + день и т.д.... и только год показывает, вместо остальных значений - ничего... Тестовые скетчи для SD карты отрабатывают отлично, на основе одного из них и сделан этот код. Ничего не понимаю. Подскажите куда копать? Или чего я не учитываю?
Код переполнен всякими чудесатостями. Особенно доставляет функция deltamills - мало того, что нафиг не нужна, так она ещё и врёт безбожно. Что касается проблемы с формированием строки, поставь печать текущего значения dataString после каждой строки, начиная с "String dataString ="";" и заканчивая "File dataFile = ...". Увидишь, что происходит. Заодно убери пока печать из под "if (deltamills(time3, millis()) > 2000)" или сделай. чтобы эти печати отличались, а то у тебя хрен поймёшь что печатается.
Если есть иной путь не тормозя выполнение программы выполнять действия с определенным промежутком времени - прошу подсказать. Функция не моя, взял с рабочей программы одной. Сделал, да и делал ранее... Иногда что-то убирая на печать, получаю что начинает выводить и записывать температуру.. И год выводит и записывает, если дату по частям собирать и год самый первый в формировании строки ' dataString += String(now.year(), DEC); ' следующие строки уже пустотой выводит... Походу слишком я память засрал... То выводит, то не выводит... *** Да... Одну функцию прибил, стало отрабатывать... Реально видимо засрал память... буду дальше вырезать некритичные участки... И прошу подсказать, чем можно более оптимально заменить deltamills ?
Ничем. Она просто не нужна, её нужно выбросить и заменить обычным вычитанием старого значения из нового. Обычное вычитание, кстати, работает правильно (не врёт на 1 как Ваша функция). Так вставьте контроль памяти. String же пытается выделить память каждый раз. Это можно проверить, но Вы нигде не проверяете. Вообще, неясно, зачем нужен String c его динамическими запросами, почему не обойтись массивом символов. Также неясно, зачем нужны такие огромные buf2 и buf? Мало того, что они всего по 15 байтов (а выделено 100), так они ещё и одинаковые. Зачем?
Благодарю за развернутый ответ! Функции брал из готовых иных скетчей и пока не заморачивался с оптимизацией, что где-то выделено больше памяти, чем нужно. Спасибо!