// подключение библиотек
#include <Wire.h>
#include "WiFi.h"
#include <stdlib.h>
#include <SPI.h>
//#include <Adafruit_GFX.h>
#include <EncButton.h>
#include <GyverOLED.h>
//#include <NTPClient.h>
//#include <WiFiUdp.h>
#include <GyverBME280.h>
#define DT 18
#define CLK 5
#define SW 19
#define SDA 21
#define SCL 22
#define relay4_pin 33
#define relay3_pin 25
#define relay2_pin 14
#define relay1_pin 27
#define relay0_pin 15
#define PIN_PHOTO_SENSOR 13
#define PCF8591 (0x90 >> 1) // I2C bus address
#define ADC0 0x00 // control bytes for reading individual ADCs
#define ADC1 0x01
#define ADC2 0x02
#define ADC3 0x03
// создание объекта OLED, адрес I2C - 0x3C
GyverOLED<SSD1306_128x64, OLED_BUFFER> display;
// Создание обьекта датчика bme
GyverBME280 bme;
// Создание объекта энкодера
EncButton enc(CLK, DT, SW);
//const char* ssid = "Waflya";
//const char* password = "!ontario@@";
//WiFiUDP ntpUDP;
//NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL);
int8_t n = 0;
int8_t _t, temp; //значения температуры
uint8_t _h, hum; //значения влажности
uint8_t _l, lum; //освещенность
uint8_t _s, somo; //влажность почвы
bool timhum = 0;
bool timlum = 0;
bool timsoi = 0;
TaskHandle_t Task0;
StaticQueue_t _dataSendQueueBuffer;
struct Data
{
int8_t t; //значения температуры
uint8_t h; //значения влажности
uint8_t l; //освещенность
uint8_t s; //влажность почвы
};
uint8_t _dataSendQueueStorage[10 * sizeof(Data)];
QueueHandle_t _dataSendQueue = xQueueCreateStatic(10, sizeof(Data), &(_dataSendQueueStorage[0]), &_dataSendQueueBuffer);
void core0(void *p)
{
byte value0, value1, value2, value3;
Wire.begin();
for(;;)
{
// Скорость шины I2C повыше
Wire.setClock(150000L);
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(ADC0); // control byte - read ADC0
Wire.endTransmission(); // end tranmission
Wire.requestFrom(PCF8591, 2);
value0=Wire.read();
value0=Wire.read();
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(ADC1); // control byte - read ADC1
Wire.endTransmission(); // end tranmission
Wire.requestFrom(PCF8591, 2);
value1=Wire.read();
value1=Wire.read();
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(ADC2); // control byte - read ADC2
Wire.endTransmission(); // end tranmission
Wire.requestFrom(PCF8591, 2);
value2=Wire.read();
value2=Wire.read();
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(ADC3); // control byte - read ADC3
Wire.endTransmission(); // end tranmission
Wire.requestFrom(PCF8591, 2);
value3=Wire.read();
value3=Wire.read();
// Скорость шины I2C повыше
Wire.setClock(400000L);
//Serial.print(value0); Serial.print(" ");
//Serial.print(value1); Serial.print(" ");
//Serial.print(value2); Serial.print(" ");
//Serial.print(value3); Serial.print(" ");
Serial.println();
Data a;
int light;
light = analogRead(PIN_PHOTO_SENSOR);
a.l = map(light, 0, 4096, 0, 100);
a.t = bme.readTemperature();
a.h = bme.readHumidity();
a.s = map(value3, 200, 90, 0, 100);
xQueueSend(_dataSendQueue, &a, pdMS_TO_TICKS(1000));
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
//display
void displayDrawString(const char* str, int x, int y) {
display.setCursorXY(x, y);
display.print(str);
}
void displayDrawString(String str, int x, int y) {
display.setCursorXY(x, y);
display.print(str);
}
void displayDrawStringInt(const char* str, int a, int x, int y) {
display.setCursorXY(x, y);
display.print(str);
char buffer1[3];
itoa(a, buffer1, 10);
display.setCursorXY(x + 90, y);
display.print(buffer1);
}
void displayDrawInt(int a, int x, int y) {
display.setCursorXY(x, y);
char buffer1[3];
itoa(a, buffer1, 10);
display.setCursorXY(x, y);
display.print(buffer1);
}
#if 0
// Wifi
void WiFiStationConnected(WiFiEvent_t event, WiFiEventInfo_t info) {
displayDrawString("connected", 0, 0);
// что-то делаем, например, снова вычисляем mac-адрес
for (int i = 0; i < 6; i++) {
//Serial.printf("%02X", info.sta_disconnected.mac[i]);
if (i < 5)Serial.print(":");
}
Serial.println("\n------------");
}
void WiFiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
displayDrawString("disconnected", 0, 0);
// что-то делаем, например, снова вычисляем mac-адрес
for (int i = 0; i < 6; i++) {
//Serial.printf("%02X", info.sta_disconnected.mac[i]);
if (i < 5)Serial.print(":");
}
Serial.println("\n------------");
}
#endif
//Menu
void WriteData() {
displayDrawStringInt("Вл. воздухав: ", hum, 0, 16);
displayDrawStringInt("Темп. воздуха: ", temp, 0, 28);
displayDrawStringInt("Освещенность: ", lum, 0, 40);
displayDrawStringInt("Вл. почвы: ", somo, 0, 52);
}
void WriteMenu()
{
if (n == 0) displayDrawString("Меню", 1, 0);
else if (n == 1) displayDrawString("Влажность воздуха", 1, 0);
else if (n == 2) displayDrawString("Температура воздуха", 1, 0);
else if (n == 3) displayDrawString("Освещенность", 1, 0);
else if (n == 4) displayDrawString("Влажность почвы", 1, 0);
}
void DrawSettings(int a)
{
display.clear();
WriteMenu();
displayDrawString("Таймер/знач:", 0, 16);
if (timhum)
{
displayDrawString("таймер", 90, 16);
}
else
{
displayDrawString("знач", 90, 16);
}
displayDrawString("Значение:", 0, 28);
if (timhum)
{
displayDrawString("таймер", 90, 28);
}
else
{
displayDrawInt(a, 90, 28);
}
}
int WriteSettings(int a)
{
bool ir = 0;
bool ir1 = 0;
int vibor = 0;
DrawSettings(a);
if (enc.click()) { ir = 1; }
while (ir)
{
enc.tick();
DrawSettings(a);
displayDrawString("Выход", 0, 40);
switch (enc.action())
{
case EB_PRESS:
break;
case EB_CLICK:
if (vibor == 1)
{
ir1 = 1;
while (ir1 == 1)
{
enc.tick();
switch (enc.action())
{
case EB_PRESS:
break;
case EB_CLICKS:
if (enc.getClicks() == 2) { ir1 = 0; }
break;
case EB_HOLD:
break;
case EB_TURN:
a -= enc.dir();
break;
}
DrawSettings(a);
display.update();
}
}
else if (vibor == 2)
{
ir = 0;
}
break;
case EB_HOLD:
break;
case EB_TURN:
vibor -= enc.dir();
break;
}
if (vibor > 2) vibor = 0;
else if (vibor < 0) vibor = 2;
if (vibor == 0)
{
display.line(88, 26, 128, 26);
}
else if (vibor == 1)
{
display.line(88, 38, 128, 38);
}
else if (vibor == 2)
{
display.line(0, 50, 128, 50);
}
display.update();
}
return a;
}
//relay
void CheckRelay()
{
if (hum >= _h) { digitalWrite(relay2_pin, HIGH); digitalWrite(relay0_pin, HIGH); }
else { digitalWrite(relay2_pin, LOW); }
if (temp <= _t) { digitalWrite(relay3_pin, HIGH); digitalWrite(relay0_pin, HIGH); }
else { digitalWrite(relay3_pin, LOW); }
if (lum <= _l) { digitalWrite(relay1_pin, HIGH); digitalWrite(relay0_pin, HIGH); }
else { digitalWrite(relay1_pin, LOW); }
if (somo <= _s) { digitalWrite(relay4_pin, HIGH); digitalWrite(relay0_pin, HIGH); }
else { digitalWrite(relay4_pin, LOW); }
if (hum < _h && temp> _t && lum > _l && somo > _s) { digitalWrite(relay0_pin, LOW); }
}
void setup() {
// Пороговые значение для активации реле
_h = 40;
_t = 30;
_l = 25;
// Если доп. настройки не нужны - инициализируем датчик
bme.begin();
//настройки энкодера
enc.setBtnLevel(LOW);
enc.setClickTimeout(500);
//enc.setDencTimeout(50);
enc.setHoldTimeout(600);
enc.setStepTimeout(200);
enc.setEncReverse(0);
enc.setFastTimeout(30);
// сбросить счётчик энкодера
enc.counter = 0;
Serial.begin(9600);
pinMode(PIN_PHOTO_SENSOR, INPUT);
// инициализация OLED
display.init();
// Скорость шины I2C повыше
Wire.setClock(400000L);
// установка шрифта и размера
display.setScale(1);
xTaskCreatePinnedToCore(core0, "Task0", 10000, NULL, 1, &Task0, 0);
#if 0
WiFi.begin(ssid, password);
Serial.print("ESP Board MAC Address: ");
Serial.println(WiFi.macAddress());
while (WiFi.status() != WL_CONNECTED)
{
display.clear();
delay(500);
displayDrawString("Please connect to internet.", 0, 0);
display.display();
}
Serial.print("ESP Board MAC Address: ");
Serial.println(WiFi.macAddress());
display.clear();
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
timeClient.begin();
WiFi.softAP(ssid, password);
WiFi.softAP(ssid); // без пароля
Serial.println();
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP());
//WiFi.onEvent(WiFiStationConnected, SYSTEM_EVENT_AP_STACONNECTED);
//WiFi.onEvent(WiFiStationDisconnected, SYSTEM_EVENT_AP_STADISCONNECTED);
#endif
// Настройка пинов для реле
pinMode(relay1_pin, OUTPUT);
pinMode(relay2_pin, OUTPUT);
pinMode(relay3_pin, OUTPUT);
pinMode(relay4_pin, OUTPUT);
pinMode(relay0_pin, OUTPUT);
digitalWrite(relay1_pin, LOW);
digitalWrite(relay2_pin, LOW);
digitalWrite(relay3_pin, LOW);
digitalWrite(relay4_pin, LOW);
}
void loop() {
// очистить дисплей
display.clear();
if (enc.tick())
{
switch (enc.action())
{
case EB_PRESS:
break;
case EB_HOLD:
break;
case EB_TURN:
n -= enc.dir();
break;
}
if (n > 4) n = 0;
else if (n < 0) n = 4;
}
WriteMenu();
if (n == 0) WriteData();
else if (n == 1) _h = WriteSettings(_h);
else if (n == 2) _t = WriteSettings(_t);
else if (n == 3) _l = WriteSettings(_l);
else if (n == 4) _s = WriteSettings(_s);
Data b;
// Если в очереди есть данные, считываем
if (xQueueReceive(_dataSendQueue, &b, 0) == pdTRUE)
{
lum = b.l;
somo = b.s;
temp = b.t;
hum = b.h;
}
CheckRelay();
// вывести изображение из буфера на экран
display.update();
}