Помогите оптимизировать код. Логирование данных
- Войдите на сайт для отправки комментариев
Втр, 27/02/2018 - 20:16
Доброго времени суток.
Помогите оптимизировать скетч, до добавления функции записи на SD все работает.
Я новичок, собирал скетч из разных источников, сам в программировании не очень. Надо что бы в файл записывалась дата, время и показания с трех датчиков.
Так все работает:
#include <Wire.h>
#include <DS1307.h> // Подключаем библиотеку для работы с модулем DS3231
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 // номер пина к которому подключен DS18B20
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DS1307 rtc(SDA, SCL); //часовой модуль подключен к пинам Arduino: Vcc к +5V, GND к 3емле, SDA к A3, SCL к A2
char buffer[25];
char buffer1[25];
#include <OLED_I2C.h>
OLED myOLED(A2, A3, 8); // Подключение дисплея, 4pin - SDA , 5pin - SCL
extern uint8_t SmallFont[]; // Базовый шрифт без поддержки русскийх символов.
int x = 0;
void setup()
{
sensors.begin();
myOLED.begin();
rtc.halt(false);
}
void loop(){
// Выводим на экран показания температуры
sensors.requestTemperatures();
myOLED.clrScr(); // очищаем экран
myOLED.setFont(SmallFont);
myOLED.print("TEMPERATURA", CENTER, 55); // вывод текста
myOLED.setFont(SmallFont);
myOLED.print(String(sensors.getTempCByIndex(0) , 1), 15, 20); // Отображение значения температуры, с точностью до десятых
myOLED.print(String(sensors.getTempCByIndex(1) , 1), 55, 20); // Отображение значения температуры, с точностью до десятых
myOLED.print(String(sensors.getTempCByIndex(2) , 1), 95, 20); // Отображение значения температуры, с точностью до десятых
myOLED.print("in", 20, 30); // Отображение значения температуры, с точностью до десятых
myOLED.print("out", 60, 30); // Отображение значения температуры, с точностью до десятых
myOLED.print("st", 100, 30); // Отображение значения температуры, с точностью до десятых
// Получение показаний с DS1307
String stringOne = rtc.getTimeStr();
myOLED.print(stringOne.substring(0,5), 98, 0);
myOLED.print(rtc.getDateStr(), 0, 0);
myOLED.update();
delay(2000); // Пауза 2 секунды
}
Добавил запись на SD и не хватка памяти и не понял как записать данные температуры:
#include <Wire.h>
#include <DS1307.h> // Подключаем библиотеку для работы с модулем DS3231
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SD.h> // Подключаем библиотеку для работы с SD картой
#define chipSelect 10 // Указываем пин подключения CS вывода модуля SD
#define ONE_WIRE_BUS 2 // номер пина к которому подключен DS18B20
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DS1307 rtc(SDA, SCL); //часовой модуль подключен к пинам Arduino: Vcc к +5V, GND к 3емле, SDA к A3, SCL к A2
#include <OLED_I2C.h>
OLED myOLED(A2, A3, 8); // Подключение дисплея, 4pin - SDA , 5pin - SCL
extern uint8_t SmallFont[]; // Базовый шрифт без поддержки русскийх символов.
int x = 0;
void setup()
{
SD.begin(chipSelect); // Инициализируем начало работы с SD-модулем, указывая пин подключения вывода CS
sensors.begin();
myOLED.begin();
rtc.halt(false);
}
void loop(){
File dataFile = SD.open("log.txt", FILE_WRITE); // Открываем файл для записи логов
if (dataFile) { // Если удалось открыть файл
dataFile.println(logString()); // Записываем строку логов в файл
dataFile.close(); // Закрываем файл
} else // Если не удалось открыть файл
myOLED.print("ErrorSD", CENTER, 40); // Выводим сообщение об ошибке
delay(9500); // Задержка в 59 с половиной сек.
}
String logString() { // Функция для генерации логов
// Выводим на экран показания температуры
sensors.requestTemperatures();
myOLED.clrScr(); // очищаем экран
myOLED.print("TEMPERATURA", CENTER, 55); // вывод текста
//myOLED.setFont(SmallFont);
myOLED.print(String(sensors.getTempCByIndex(0) , 1), 15, 20); // Отображение значения температуры, с точностью до десятых
myOLED.print(String(sensors.getTempCByIndex(1) , 1), 55, 20); // Отображение значения температуры, с точностью до десятых
myOLED.print(String(sensors.getTempCByIndex(2) , 1), 95, 20); // Отображение значения температуры, с точностью до десятых
myOLED.print("in", 20, 30); // Отображение значения температуры, с точностью до десятых
myOLED.print("out", 60, 30); // Отображение значения температуры, с точностью до десятых
myOLED.print("st", 100, 30); // Отображение значения температуры, с точностью до десятых
// Получение показаний с DS1307
String stringOne = rtc.getTimeStr();
myOLED.print(stringOne.substring(0,5), 98, 0);
myOLED.print(rtc.getDateStr(), 0, 0);
myOLED.update();
//
String dataString = rtc.getTimeStr(); // Помещаем дату и температуру в новую строку логов
delay(2000); // Пауза 2 секунды
}
Вот еще один код, тут все работает, но не подключен экран.
#include <SD.h> // Подключаем библиотеку для работы с SD картой #include <DS3231.h> // Подключаем библиотеку для работы с модулем DS3231 #include <OneWire.h> // Подключаем библиотеку для взаимодействия с устройствами, работающими на шине и по протоколу 1-Wire #include <DallasTemperature.h> // Подключаем библиотеку с функциями для работы с DS18B20 (запросы, считывание и преобразование возвращаемых данных) #define chipSelect 10 // Указываем пин подключения CS вывода модуля SD #define oneWireBus 2 // Указываем пин подключения data-вывода датчика DS18B20 //#define term_power 5 // Указываем пин подключения питания датчика DS18B20 void setup() { Serial.begin(9600); // Инициализируем вывод данных на монитор серийного порта SD.begin(chipSelect); // Инициализируем начало работы с SD-модулем, указывая пин подключения вывода CS // pinMode(term_power, OUTPUT); // Определяем пин подключения питания датчика температуры DS18B20 } void loop() { File dataFile = SD.open("log.txt", FILE_WRITE); // Открываем файл для записи логов if (dataFile) { // Если удалось открыть файл dataFile.println(logString()); // Записываем строку логов в файл dataFile.close(); // Закрываем файл } else // Если не удалось открыть файл Serial.println("Can't open file"); // Выводим сообщение об ошибке delay(9500); // Задержка в 59 с половиной сек. } String logString() { // Функция для генерации логов // Получение показаний с DS18B20 OneWire oneWire(oneWireBus); // Сообщаем библиотеке об устройстве, работающем по протоколу 1-Wire(DS18B20) DallasTemperature sensors(&oneWire); // Связываем функции библиотеки DallasTemperature с DS18B20 sensors.begin(); // Запускаем библиотеку измерения температуры // digitalWrite(term_power, HIGH); // Включаем питание датчика температуры DS18B20 sensors.requestTemperatures(); // Запрос на измерение температуры (1-й ошибочный) delay(500); // Задержка перед поторным измерением sensors.requestTemperatures(); // Запрос на измерение температуры (повторный) int t0 = round(float(sensors.getTempCByIndex(0))); // Получаем значение температуры int t1 = round(float(sensors.getTempCByIndex(1))); // Получаем значение температуры int t2 = round(float(sensors.getTempCByIndex(2))); // Получаем значение температуры // digitalWrite(term_power, LOW); // Отключаем питание датчика температуры DS18B20 // // Получение показаний с DS3231 DS3231 clock; // Связываем объект clock с библиотекой DS3231 clock.begin(); // Инициализируем модуль RTC DS3231 RTCDateTime DateTime; // Определяем переменную DateTime, как описанную структурой RTCDateTime (структура описана в библиотеке DS3231.h) DateTime = clock.getDateTime(); // Заполняем DateTime значениями, полученными при запросе текущего времени // String dataString = leadNull(DateTime.day) + "." + leadNull(DateTime.month) + "." + String(DateTime.year) + " " + leadNull(DateTime.hour) + ":" + leadNull(DateTime.minute) + ":" + leadNull(DateTime.second) + "|" + String(round(clock.readTemperature())) + "|" + String(t0) + "|" + String(t1) + "|" + String(t2); // Помещаем дату и температуру в новую строку логов Serial.println(dataString); // Выводим строку логов на монитор серийного порта return(dataString); // Возвращаем полученные значения в место вызова функции } String leadNull(int value) { // Функция добавления ведущего нуля if (value < 10) // Если значение меньше десяти return ("0" + String(value)); // Добавляем ноль в начало значения и возвращаем его else // Иначе return String(value); // Возвращяем значение, предварительно преобразовав его в строковый формат }Много памяти не хватает?
Примерно так
А первый и третий скетчи сколько занимают?
Первый
Третий
Ну судя по всему памяти должно хватить, надо просто второй скетч правильно написать. Функция logString не та, что в третьем скетче и вывод на дисплей из loop переехал в logString зачем-то.
В целом у меня третий скетч работает и все хорошо, кроме наглядности, сейчас залил первый и получил результат как на фото.
Если можно, помогите к третьему варианту прикрутить дисплей с выводом примерно как в первом варианте. Простите если путано получается излагать мысли...
Функция logString не та, что в третьем скетче и вывод на дисплей из loop переехал в logString зачем-то.
совершенно верно, пробовал разные варианты, пока ничего путного не выходит
Сперва удалить из третьего строки 28-30
Из первого в третий копируем строки:
6-7 и 12-13 до setup
17-18 в setup
23-24 в начало loop
25-38 в loop перед delay
ещё строки из третьего 41 до setup
42-43 в setup
paradox3007, для вывода на экран Вы пользуетесь библиотекой, использующей экранный буфер. Сам буфер занимает 1к из имеющихся ы контроллере 2к. При этом, судя по фото, Вы выводите на экран только текст. Возьмите библиотеку без экранного буфера и все у Вас поместится.
paradox3007, для вывода на экран Вы пользуетесь библиотекой, использующей экранный буфер. Сам буфер занимает 1к из имеющихся ы контроллере 2к. При этом, судя по фото, Вы выводите на экран только текст. Возьмите библиотеку без экранного буфера и все у Вас поместится.
я использую библиотеку OLED_I2C, какую библиотеку можно использовать?
paradox3007, допили сначала с этим, посмотри сколько получается.
paradox3007, допили сначала с этим, посмотри сколько получается.
точно так как сказал не получилось, посыпались ошибки, после устранения стало так:
Ну вот тебе ссылка
Там есть про без буферные библиотеки.
Ну вот тебе ссылка
Там есть про без буферные библиотеки.
Спасибо. Насколько я понял только OzOled но не понял с синтаксисом
На всякий случай продублирую ссылку на свою библиотеку, хотя она и есть в указанной выше теме:
http://arduino.ru/forum/proekty/asoled-kompaktnaya-biblioteka-dlya-oled-...
На всякий случай продублирую ссылку на свою библиотеку, хотя она и есть в указанной выше теме:
http://arduino.ru/forum/proekty/asoled-kompaktnaya-biblioteka-dlya-oled-displeya-128kh64-s-kirillitsei-utf-8
А не затруднит ли Вас помочь мне внедрить вашу библиотеку в скетч №3 что бы вывод был как на фото выше?
я пока очень далет от этого, но пытаюсь разбираться на примерах
я когда нибудь обязательно научусь =)
1. Пример использования библиотеки есть внутри.
2. Библиотека содержит очень ограниченный набор функций, так что запутаться сложно.
3. Назначение всех функций откомментировано.
1. Пример использования библиотеки есть внутри.
2. Библиотека содержит очень ограниченный набор функций, так что запутаться сложно.
3. Назначение всех функций откомментировано.
подключил библиотеку, экран выводит тест командой
LD.printString_12x16(F(" NORM TEST "), 0, 0);
Поскажите, какой командой вывести показания с датчиков и дату/время. не смог найти, т.к. LD.printString_12x16 выводит только текст...
А LD.printNumber((long)n0, 0, 0); ?
Example к библиотеке можно посмотреть.
1. Пример использования библиотеки есть внутри.
2. Библиотека содержит очень ограниченный набор функций, так что запутаться сложно.
3. Назначение всех функций откомментировано.
Доброй ночи.
Подскажите пожалуйста, как вывести дату и время используя вашу библиотеку. часы ds1307 библиотека такая же, но можно и другую подключить.
Не могу понять как реализовать это. с выводом температуры с датчиков разобрался
Стопор на каком месте происходит, что именно не получается?
получается фигня какая то.
LD.printString_6x8("", 0, 0); LD.printNumber((long)DateTime.day, 0, 0, 0); LD.printString_6x8(".", 15, 0); LD.printNumber((long)DateTime.month, 0, 30, 0); LD.printString_6x8(".", 40, 0); LD.printNumber((long)DateTime.year, 0, 45, 0);но должен же быть способ проще, что бы сразу вставлялась дата целиком и время
Как начсет фотки того, что пишется на экране и, что выводится в serial?
получается фигня какая то.
LD.printString_6x8("", 0, 0); LD.printNumber((long)DateTime.day, 0, 0, 0); LD.printString_6x8(".", 15, 0); LD.printNumber((long)DateTime.month, 0, 30, 0); LD.printString_6x8(".", 40, 0); LD.printNumber((long)DateTime.year, 0, 45, 0);но должен же быть способ проще, что бы сразу вставлялась дата целиком и время
Кто кому должен?
Лично я не помню, чтобы кому-то задолжал.
Библиотека должна уметь выводить С-строку. Все остальное - факультатив.
Вам нужно - Вы и пишите.
получается фигня какая то.
LD.printString_6x8("", 0, 0); LD.printNumber((long)DateTime.day, 0, 0, 0); LD.printString_6x8(".", 15, 0); LD.printNumber((long)DateTime.month, 0, 30, 0); LD.printString_6x8(".", 40, 0); LD.printNumber((long)DateTime.year, 0, 45, 0);но должен же быть способ проще, что бы сразу вставлялась дата целиком и время
Не знаю, чем Вас не устраивает такой способ вывода, но если Вы хотите "проще" (в кавычках потому, что внутри всё то же самое будет) и самому ничего не писать, возьмите библиотеку для часов, которая сразу возвращает дату строкой. Такие есть.
№54 Убавить один датчик я думаю сам дагодаешься.
получается фигня какая то.
LD.printString_6x8("", 0, 0); LD.printNumber((long)DateTime.day, 0, 0, 0); LD.printString_6x8(".", 15, 0); LD.printNumber((long)DateTime.month, 0, 30, 0); LD.printString_6x8(".", 40, 0); LD.printNumber((long)DateTime.year, 0, 45, 0);но должен же быть способ проще, что бы сразу вставлялась дата целиком и время
Кто кому должен?
Лично я не помню, чтобы кому-то задолжал.
Библиотека должна уметь выводить С-строку. Все остальное - факультатив.
Вам нужно - Вы и пишите.
Добрый день. Видимо Вы что то не так поняли, к Вам у меня только благодарность за библиотеку!
получается фигня какая то.
LD.printString_6x8("", 0, 0); LD.printNumber((long)DateTime.day, 0, 0, 0); LD.printString_6x8(".", 15, 0); LD.printNumber((long)DateTime.month, 0, 30, 0); LD.printString_6x8(".", 40, 0); LD.printNumber((long)DateTime.year, 0, 45, 0);но должен же быть способ проще, что бы сразу вставлялась дата целиком и время
Не знаю, чем Вас не устраивает такой способ вывода, но если Вы хотите "проще" (в кавычках потому, что внутри всё то же самое будет) и самому ничего не писать, возьмите библиотеку для часов, которая сразу возвращает дату строкой. Такие есть.
в первом скетче что размещен в этой теме есть вот такие строчки:
Это выводит дату и время на экран так как показанно на фотов 7 посте.
Сейчас это не работает =(
но это не такая большая проблема.
Всем спасибо за отклик.
Как начсет фотки того, что пишется на экране и, что выводится в serial?
вывод на экран
вывод в сериал порт и запись на флешку
Есть правда еще вопрос, может кто подскажет.
в одном скетче вывод температуры выводится до десятых
в другом до целых
предполагаю что за это отвечает единица после sensors.getTempCByIndex(0) но после дабавления ее выводятся только единицы вместо температуры
вопрос, как сделать что бы температура выводилась до десятых а лучше до сотых в данном коде:
paradox3007, у Вас round() округляет до целых. После этого десятым уже взятья неоткуда.
А выводить сотые - бессмысленно, т.к. для этого нужны датчики из совершенно другого ценового диапазона.
paradox3007, у Вас round() округляет до целых. После этого десятым уже взятья неоткуда.
А выводить сотые - бессмысленно, т.к. для этого нужны датчики из совершенно другого ценового диапазона.
Спасибо, буду пробовать исключать эту переменную из кода
Пробуйте.
Только это не переменная а функция.