Эксперимент 42. Запись данных в файл. Двухзонный регистратор

Добавим функцию записи данных в файл. Для записи выберем формат файла CSV. CSV (от англ. Comma-Separated Values — значения, разделённые запятыми) — текстовый формат, предназначенный для представления табличных данных. Строка таблицы соответствует строке текста, которая содержит одно или несколько полей, разделенных запятыми.

Одна строка файла будет соответствовать одному измерению температуры. Первым числом будет температура в комнате, а вторым — на улице. Разделителем данных в строке будет символ точки с запятой. Пример записей в файл:

23,2;12,0
24,2;13,0
24,1;13,2

Формат CSV имеет широкое распространение, его можно открыть в Excel или OpenOffice Calc и построить графики. Что мы и сделаем.

Схема эксперимента

Схема эксперимента остается неизменной Рисунок 1. Монтажная схема эксперимента

Эксперимент 42. Запись данных в файл. Двухзонный регистратор

Добавим функцию записи данных в файл. Для записи выберем формат файла CSV. CSV (от англ. Comma-Separated Values — значения, разделённые запятыми) — текстовый формат, предназначенный для представления табличных данных. Строка таблицы соответствует строке текста, которая содержит одно или несколько полей, разделенных запятыми.

Одна строка файла будет соответствовать одному измерению температуры. Первым числом будет температура в комнате, а вторым — на улице. Разделителем данных в строке будет символ точки с запятой. Пример записей в файл:

23,2;12,0
24,2;13,0
24,1;13,2

Формат CSV имеет широкое распространение, его можно открыть в Excel или OpenOffice Calc и построить графики. Что мы и сделаем.

Схема эксперимента

Схема эксперимента остается неизменной Рисунок 1. Монтажная схема эксперимента

Программный код эксперимента

Exp42.ino
  1. #include <OneWire.h>
  2. #include <DallasTemperature.h>
  3. #include <LCDI2C_Multilingual.h>
  4. #include <LittleFS.h>
  5.  
  6. #define ACD_PIN A0
  7. #define BUS_PIN 12
  8. #define DEFAULT_I2C_ADDR 0x3F // Или 0x27 в зависимости от твоей платы IoT
  9.  
  10. const int Bcoef = 3950;
  11. const int R1 = 10000;
  12. const int Rtnom = 10000;
  13. const float T0 = 273.15;
  14.  
  15. OneWire oneWire(BUS_PIN);
  16. DallasTemperature sensors(&oneWire);
  17. LCDI2C_Generic lcd(DEFAULT_I2C_ADDR, 16, 2);
  18.  
  19. void setup() {
  20. Serial.begin(9600);
  21. Serial.println();
  22. sensors.begin();
  23. lcd.init();
  24. lcd.setBacklight(0);
  25.  
  26. LittleFS.format();
  27. LittleFS.begin();
  28.  
  29. Serial.print("Writing data to file");
  30.  
  31. for(int i = 0; i < 30; i++) {
  32. int value = analogRead(ACD_PIN);
  33. float R2 = (-R1 * value) / (value - 1023);
  34. float temp_outodor = 1 / (log(R2 / Rtnom) / Bcoef + 1/(25 + T0)) - T0;
  35.  
  36. sensors.requestTemperatures();
  37. float temp_inroom = sensors.getTempCByIndex(0);
  38.  
  39. lcd.clear();
  40. lcd.print("Outodor: ");
  41. lcd.println(temp_outodor, 1);
  42. lcd.print("In room: ");
  43. lcd.print(temp_inroom, 1);
  44.  
  45. String s = String(temp_outodor, 1) + ";" + String(temp_inroom, 1) + "\n";
  46. s.replace('.', ',');
  47.  
  48. File f = LittleFS.open("/temp_data.csv", "a");
  49. f.print(s);
  50. f.close();
  51.  
  52. Serial.print(".");
  53. delay(2000);
  54. }
  55.  
  56. Serial.println();
  57. Serial.println("Reading data from file");
  58.  
  59. File f = LittleFS.open("/temp_data.csv", "r");
  60. while(f.available()) Serial.write(f.read());
  61. f.close();
  62. }
  63.  
  64. void loop() {
  65. }

По сравнений с прошлой программой мы перенесли код работы с датчиками из бесконечного цикла в конечный, добавили код для работы с файлом и подготовки данных для записи в него. Рассмотрим эти части подробнее.

Создаем строку из чисел для записи в файл. Строка состоит из температуры в комнате, символа разделителя данных ;, температуры на улице и символа перехода на новую строку \n. Без \n всё записывалось бы в одну строку.

  1. String s = String(temp_outodor, 1) + ";" + String(temp_inroom, 1) + "\n";

Arduino использует точку как десятичный разделитель. Однако русские версии программ, вроде Excel и OpenOffice Calc используют запятую. Поэтому, чтобы в дальнейшем работать с файлом в этих программах, нам нужно заменить точку на запятую:

  1. s.replace('.', ',');

Далее идет работа с файлом. Открываем файл. Дескриптор открытого файла оказывается в переменной f.

  1. File f = LittleFS.open("/temp_data.csv", "a");

Файл открывается с помощью оператора open() в качестве параметров ему передается имя файла и опции, описывающие что мы собираемся делать с файлом. Здесь может быть указано r для чтения, w для записи файла и a для дополнения файла. Мы используем a, в таком случае при открытии файл не будет очищен, а будет дополняться новыми записями в конце. Если файл не существует, то при открытии с помощью w или a файл будет автоматически создан.

Записываем в файл строку:

  1. f.print(s);

После записи закрываем файл:

  1. f.close();

Далее открываем файл уже в режиме чтения - r, в цикле while печатаем строки файла в последовательный порт пока файл не закончиться, и закрываем файл.

  1. File f = LittleFS.open("/temp_data.csv", "r");
  2. while(f.available()) Serial.write(f.read());
  3. f.close();

Запустим программу и дождемся ее выполнения. Это займет 1 минуту, после чего записанные в файл данные будут выведены в последовательный порт.

К сожалению при использовании Arduino IDE отсутствует удобный способ скачать созданный файл на компьютер. Поэтому предлагаем создать с помощью блокнота текстовый файл, скопировать в него выведенные в последовательный порт данные и сохранить файл с расширением .csv.

Читать такие данные достаточно неудобно, поэтому откроем их с помощью Excel:

Excel автоматически распознал формат CSV и занес данные с «комнатного» датчика в столбец A, и данные с «уличного» датчика в столбец B. Построим графики температуры: Вставка График

Датчик DS18B20 измерял у нас температуру в комнате, а термистор мы через некоторое время после начала эксперимента погрузили в стакан с теплой водой. Температура термистора резко возросла. Вода в стакане постепенно остывала, что мы хорошо видим на графике.