Здравствуйте! Для изучения программирования и arduino я пытаюсь сделать “устройство” которое бы совмещало data logger, экран с отображением информации о времени и температуре, а так же веб-сервер. На данный момент я смог собрать код, который выводит на экран информацию, а так же записывает данные на sd карту каждую минуту.
Читая различные инструкции и мнения на форуме я обнаружил, что скорее всего мой код слишком часто считывает показания датчиков ds18b20, а так же отрисовывает экран.
Эту “проблему” я попытался решить с помощью функции millis() и таймеров и это явно не лучшее решение, но таков путь познания. После имплементации заметил. что на экране секунды часов “замерают” каждый 500ms :буквально на момент Возможно еще есть какие то проблемы, которые я не вижу ввиду отсутствия опыта программирования .
На форуме нашел рекомендации, что необходимо отрисовывать только ту часть экарана, что изменилась, но комментатор не удосужился предоставить пример, либо ссылок на пример, поэтому решил задать вопрос сообществу arduino.ru:
Как правильно отрисовывать экран при использовании библиотеки u8glib, чтобы экономить ресурсы мк
Заодно прошу дать дельные замечания по моему “коду”.
Спасибо!
P.S. Может часты тоже не надо опрашивать со скоростью работы МК ? Если я правильно понял, то все, что в loop() и без таймеров либо условий, “опрашивается” так быстро на сколько это возможно.
#include <U8glib.h>
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>
#include <SD.h>
#define PERIOD 500
#define PERIOD2 250
uint32_t timer = 0;
/*
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
*/
const int chipSelect = 4; //SD card pin. CS pin of your data logger shield
File LogFile; //Name of the file
// Data wire is plugged into pin X on the Arduino
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
//uint8_t sensor1[8] = { 0x28, 0xED, 0x2E, 0x3C, 0x05, 0x00, 0x00, 0x48 };
//uint8_t sensor2[8] = { 0x28, 0xB7, 0x1B, 0x3D, 0x05, 0x00, 0x00, 0x70 };
U8GLIB_ST7920_128X64 u8g(22, 23, 24, U8G_PIN_NONE); // настройка пинов
tmElements_t tm;
const char *monthName[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
void draw() {
if (millis() - timer >= PERIOD2) {
// ваше действие
u8g.setRot180();
u8g.setFont(u8g_font_unifont);
// u8g.drawStr(15, 12, "SOMEtEXT");
//u8g.setPrintPos( 10, 12); u8g.print(tm.Hour);
if (tm.Second / 10 == 1) {
u8g.setPrintPos(10, 12);
u8g.print(tm.Hour / 10);
} else {
u8g.setPrintPos(10, 12);
u8g.print(tm.Hour / 10);
}
if (tm.Second % 10 == 1) {
u8g.setPrintPos(19, 12);
u8g.print(tm.Hour % 10);
} else {
u8g.setPrintPos(19, 12);
u8g.print(tm.Hour % 10);
}
//u8g.setPrintPos( 30, 12); u8g.print(tm.Minute);
if (tm.Second / 10 == 1) {
u8g.setPrintPos(30, 12);
u8g.print(tm.Minute / 10);
} else {
u8g.setPrintPos(30, 12);
u8g.print(tm.Minute / 10);
}
if (tm.Second % 10 == 1) {
u8g.setPrintPos(39, 12);
u8g.print(tm.Minute % 10);
} else {
u8g.setPrintPos(39, 12);
u8g.print(tm.Minute % 10);
}
//u8g.setPrintPos( 50, 12); u8g.print(tm.Second);
if (tm.Second / 10 == 1) {
u8g.setPrintPos(50, 12);
u8g.print(tm.Second / 10);
} else {
u8g.setPrintPos(50, 12);
u8g.print(tm.Second / 10);
}
if (tm.Second % 10 == 1) {
u8g.setPrintPos(59, 12);
u8g.print(tm.Second % 10);
} else {
u8g.setPrintPos(59, 12);
u8g.print(tm.Second % 10);
}
u8g.drawLine(0, 15, 128, 15);
u8g.setFont(u8g_font_6x12);
u8g.setPrintPos(10, 25);
u8g.print(sensors.getTempCByIndex(0));
u8g.drawStr(1, 25, "C");
u8g.setPrintPos(50, 25);
u8g.print(sensors.getTempCByIndex(1));
u8g.setColorIndex(1);
u8g.drawBox(0, 35, 128, 20);
u8g.setFont(u8g_font_unifont);
u8g.setColorIndex(0);
u8g.drawStr(35, 50, "ARDUINO");
u8g.setColorIndex(1);
u8g.setFont(u8g_font_unifont);
u8g.drawStr(45, 64, "HELLO");
do {
timer += PERIOD;
if (timer < PERIOD) break; // переполнение uint32_t
} while (timer < millis() - PERIOD); // защита от пропуска шага
}
}
void setup() {
sensors.begin();
sensors.setResolution(9);
bool parse = false;
bool config = false;
// get the date and time the compiler was run
/* if (getDate(__DATE__) && getTime(__TIME__)) {
parse = true;
// and configure the RTC with this info
if (RTC.write(tm)) {
config = true;
}
} */
Serial.begin(9600);
while (!Serial)
; // wait for Arduino Serial Monitor
delay(200);
if (parse && config) {
Serial.print("DS1307 configured Time=");
Serial.print(__TIME__);
Serial.print(", Date=");
Serial.println(__DATE__);
} else if (parse) {
Serial.println("DS1307 Communication Error :-{");
Serial.println("Please check your circuitry");
} else {
Serial.print("Could not parse info from the compiler, Time=\"");
Serial.print(__TIME__);
Serial.print("\", Date=\"");
Serial.print(__DATE__);
Serial.println("\"");
}
Serial.println("DS1307RTC Read Test");
Serial.println("-------------------");
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.");
LogFile = SD.open("LogFile.csv", FILE_WRITE); //Open and write once, just for headers
LogFile.println(" Date/Time;Temp1;Temp2"); //Print headers(not saved yet)
LogFile.close(); //Print saved
}
void loop() {
if (millis() - timer >= PERIOD) {
// ваше действие
sensors.requestTemperatures();
do {
timer += PERIOD;
if (timer < PERIOD) break; // переполнение uint32_t
} while (timer < millis() - PERIOD); // защита от пропуска шага
}
//tmElements_t tm;
u8g.firstPage();
do {
draw();
} while (u8g.nextPage());
// tmElements_t tm;
// sensors.requestTemperatures();
RTC.read(tm);
if (tm.Second == 00) {
LogFile = SD.open("LogFile.csv", FILE_WRITE);
Serial.println("open file to write");
LogFile.print(tmYearToCalendar(tm.Year));
LogFile.print("/");
LogFile.print(tm.Month);
LogFile.print("/");
LogFile.print(tm.Day);
LogFile.print(" ");
LogFile.print(tm.Hour);
LogFile.print(":");
LogFile.print(tm.Minute);
LogFile.print(":");
LogFile.print(tm.Second);
LogFile.print(";");
LogFile.print(sensors.getTempCByIndex(0));
LogFile.print(";");
LogFile.print(sensors.getTempCByIndex(1));
LogFile.println();
LogFile.close();
Serial.println("close file to write");
Serial.println();
}
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
// Serial.print(" Requesting temperatures...");
// Send the command to get temperatures
// Serial.println("DONE");
// Serial.print("Temperature is: ");
// Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"?
// You can have more than one IC on the same bus.
// 0 refers to the first IC on the wire
// Serial.print(" Requesting temperatures...");
// Send the command to get temperatures
// Serial.println("DONE");
// Serial.print("Temperature is: ");
// Serial.print(sensors.getTempCByIndex(1));
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write('0');
}
Serial.print(number);
}
bool getTime(const char *str) {
int Hour, Min, Sec;
if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
tm.Hour = Hour;
tm.Minute = Min;
tm.Second = Sec;
return true;
}
bool getDate(const char *str) {
char Month[12];
int Day, Year;
uint8_t monthIndex;
if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
for (monthIndex = 0; monthIndex < 12; monthIndex++) {
if (strcmp(Month, monthName[monthIndex]) == 0) break;
}
if (monthIndex >= 12) return false;
tm.Day = Day;
tm.Month = monthIndex + 1;
tm.Year = CalendarYrToTm(Year);
return true;
}