
Код:
#include <SoftwareSerial.h>
#include <TextFinder.h>
#include <Wire.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include "DS1307.h"
//Массив, содержащий время компиляции
char compileTime[] = __TIME__;
//Массив, содержащий дату компиляции
//char compileDate[] = __DATE__;
DS1307 clock;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//Создание пользовательского значка градуса
byte gradus[8] = {
B00111, B00101, B00111, B00000, B00000, B00000, B00000, B00000};
// ESP8266 -- Arduino
// ESP TX - 10 (Arduino SoftwareSerial RX)
// ESP RX - 11 (Arduino SoftwareSerial TX)
SoftwareSerial dbgSerial(10, 11);
TextFinder finder(Serial);
// для SoftSerial скорость порта в 115200 является большой и не гарантирует стабильную работу
const int COM_BAUD = 9600;
void setup() {
clock.begin();
lcd.begin (16, 2);
lcd.createChar(1, gradus);
//Получаем часы, минуты, секунды
byte hour = getInt(compileTime, 0);
byte minute = getInt(compileTime, 3);
byte second = getInt(compileTime, 6);
//Импровизированный хэш времени
//Содержит в себе количество секунд с начала дня
unsigned int hash = hour * 60 * 60 + minute * 60 + second;
//Проверяем несовпадение нового хэша с хэшем в EEPROM
if (EEPROMReadInt(0) != hash) {
//Сохраняем новый хэш
EEPROMWriteInt(0, hash);
//Готовим для записи в RTC часы, минуты, секунды, год, месяц, день
clock.fillByHMS(hour, minute, second); //Вставляем часы, минуты, секунды
//clock.fillByYMD(year, month, day); //Вставляем год, месяц, день
// clock.fillDayOfWeek(String(week[weekday(month, day, year)]).toInt()); //Вставляем день недели
//Записываем эти данные во внутреннюю память часов.
//С этого момента они начинают считать нужное для нас время
clock.setTime();
}
dbgSerial.begin(COM_BAUD);
Serial.begin(COM_BAUD);
dbgSerial.println("Setup done");
}
void loop() {
//Получение времени
clock.getTime();
int clo = clock.hour;
// Если больше заданного значения времени (часов), то выключится подсветка дисплея
if (clo > 22 || clo < 7 )
{
lcd.noBacklight();
}
else
{
lcd.backlight();
}
Serial.println("AT");
if (Serial.find("OK"))
{
dbgSerial.println("MODULE IS WORKING");
}
lcd.setCursor(14, 0);
lcd.print(clock.minute / 10);
lcd.print(clock.minute % 10);
Serial.println("AT+CIPSTART=\"TCP\",\"162.243.58.21\",80");
delay(1000);
if (Serial.find("OK"))
{
dbgSerial.println("Connected");
}
Serial.println("AT+CIPSEND=54");
delay(1000);
if (Serial.find(">"))
{
dbgSerial.println("Enter data");
}
Serial.println("GET /data/2.5/weather?q=irkutsk&mode=xml&units=metric");
if (finder.find("temperature value=") )
{
int temperature = finder.getValue();
dbgSerial.print("Temp C: ");
dbgSerial.println(temperature);
lcd.setCursor(0, 0);
lcd.print("T=");
lcd.print(" ");
lcd.setCursor(2, 0);
lcd.print(temperature);
lcd.write(1);
lcd.print("C");
}
if (finder.find("humidity value=") )
{
int humy = finder.getValue();
dbgSerial.print("Humidity: ");
dbgSerial.println(humy);
lcd.setCursor(8, 0);
lcd.print("H=");
lcd.print(" ");
lcd.setCursor(10, 0);
lcd.print(humy);
lcd.print("%");
}
if (finder.find("pressure value=") )
{
int pres = finder.getValue();
dbgSerial.print("Pressure: ");
dbgSerial.println(pres);
lcd.setCursor(0, 1);
lcd.print("P=");
lcd.print(pres);
lcd.print("mm");
}
if (finder.find("speed value=") )
{
int speedv = finder.getValue();
dbgSerial.print("Wind speed: ");
dbgSerial.println(speedv);
lcd.setCursor(8, 1);
lcd.print("W=");
lcd.print(" ");
lcd.setCursor(10, 1);
lcd.print(speedv);
lcd.print("km/h");
}
if (finder.find("lastupdate value=") )
{
int lastupdate = finder.getValue();
dbgSerial.print("Last update: ");
dbgSerial.println(lastupdate);
}
delay(600000);
/*if ( Serial.available() )
dbgSerial.write( Serial.read() );
if ( dbgSerial.available() )
Serial.write( dbgSerial.read() );
*/
}
//Запись двухбайтового числа в память
void EEPROMWriteInt(int address, int value)
{
EEPROM.write(address, lowByte(value));
EEPROM.write(address + 1, highByte(value));
}
//Чтение числа из памяти
unsigned int EEPROMReadInt(int address)
{
byte lowByte = EEPROM.read(address);
byte highByte = EEPROM.read(address + 1);
return (highByte << 8) | lowByte;
}
//Вычисление времени
char getInt(const char* string, int startIndex) {
return int(string[startIndex] - '0') * 10 + int(string[startIndex + 1]) - '0';
}
/*
//Вычисление года
int get4DigitInt(const char* string, int startIndex) {
return (string[startIndex ] - '0') * 1000 + (string[startIndex + 1] - '0') * 100 + (string[startIndex + 2] - '0') * 10 + (string[startIndex + 3] - '0');
}
//Вычисление дня недели
int weekday(int month, int day, int year)
{
int ix, tx, vx;
switch (month) {
case 2 :
case 6 :
vx = 0;
break;
case 8 :
vx = 4;
break;
case 10 :
vx = 8;
break;
case 9 :
case 12 :
vx = 12;
break;
case 3 :
case 11 :
vx = 16;
break;
case 1 :
case 5 :
vx = 20;
break;
case 4 :
case 7 :
vx = 24;
break;
}
if (year > 1900) // 1900 was not a leap year
year -= 1900;
ix = ((year - 21) % 28) + vx + (month > 2); // take care of February
tx = (ix + (ix / 4)) % 7 + day; // take care of leap year
return (tx % 7);
}
*/