first commit

This commit is contained in:
root
2026-04-03 16:08:04 +00:00
commit 41e93f74f7
10 changed files with 6704 additions and 0 deletions

5
.gitignore vendored Executable file
View File

@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
.vscode/extensions.json vendored Executable file
View File

@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"clangd.arguments": [
"--compile-commands-dir=/root/PlatformIO/Projects/Kuriatnik",
"--query-driver=/root/.platformio/packages/toolchain-*/bin/*,/root/.platformio/packages/tool-*/bin/*"
]
}

0
README.md Normal file
View File

6144
compile_commands.json Normal file

File diff suppressed because it is too large Load Diff

37
include/README Executable file
View File

@@ -0,0 +1,37 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the convention is to give header files names that end with `.h'.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Executable file
View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into the executable file.
The source code of each library should be placed in a separate directory
("lib/your_library_name/[Code]").
For example, see the structure of the following example libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Example contents of `src/main.c` using Foo and Bar:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
The PlatformIO Library Dependency Finder will find automatically dependent
libraries by scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

22
platformio.ini Executable file
View File

@@ -0,0 +1,22 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:d1_mini_lite]
platform = espressif8266
board = d1_mini_lite
framework = arduino
lib_deps =
RobTillaart/PCF8574
knolleary/pubsubclient
enjoyneering/LiquidCrystal_I2C
paulstoffregen/OneWire
https://github.com/toannv17/DHT-Sensors-Non-Blocking.git
adafruit/RTClib

423
src/main.cpp Executable file
View File

@@ -0,0 +1,423 @@
#include <Arduino.h>
#include <ESP8266WiFi.h> //библиотека wifi для ESP8266 ("стандартная")
#include <PubSubClient.h> //библиотека MQTT : версия для PubSubClient от knolleary ("стандартная")
#include <Wire.h> //библиотека wire ("стандартная")
#include <LiquidCrystal_I2C.h> //библиотека дисплея с поддержкой i2c ("стандартная")
//#include "WiFiTerm.h" //библиотека wifiTerm (https://github.com/bricoleau/WiFiTerm)
#include <OneWire.h> //библиотека OneWire ("стандартная")
#include <DHT_Async.h>
#include <PCF8574.h> //библиотека pcf8574 https://github.com/RobTillaart/PCF8574/tree/master
#include <RTClib.h>
#include <ESP8266HTTPUpdateServer.h>
/**************************************************************************
* Настройки проекта
*************************************************************************/
// Параметры подключения к WiFi
const char* WIFI_SSID = "MelnikiHome";
const char* WIFI_PASS = "ZyVhw8pZ";
unsigned long pr_Wifi = (long)10 * 60 * 1000; // Промежуток между проверками wifi
unsigned long prt_Wifi; // Таймер проверок wifi
// События WiFi
WiFiEventHandler wifiConnectHandler;
WiFiEventHandler wifiDisconnectHandler;
// Инициализация серверов обновления и wifiterminal
ESP8266WebServer server(80);
ESP8266HTTPUpdateServer httpUpdater;
// Параметры подключения к MQTT брокеру
// Примечание: использовать статический mqttClientId оптимальнее с точки зрения фрагментации кучи, только не забывайте изменять его на разных устройствах
const char* mqttServer = "192.168.109.106";
const int mqttPort = 1883;
const char* mqttClientId = "Kurytnik";
const char* mqttUser = "mqtt";
const char* mqttPass = "m_623850";
//Переменные для инициализации mqtt
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
// Топик LWT, одновременно это топик статуса устройства:
// - в рабочем состоянии в этом топике будет сообщение "online"
// - когда устройство по какой-либо причине отключится от сервера, сервер примерно через 60 секунд опубликует LWT "offline"
const char* mqttTopicDeviceStatus = "demo/status";
const char* mqttDeviceStatusOn = "online";
const char* mqttDeviceStatusOff = "offline";
const int mqttDeviceStatusQos = 1;
const bool mqttDeviceStatusRetained = true;
//Переменные температурного датчика DS18b20
byte data_ds[12]; //для температуры
byte addr_ds[8]; //для адреса датчика
OneWire ds(D3); //пин подключения D3
#define UPDATE_TIME_ds 1000 //константа для опроса датчика минимум 750
unsigned long LastUpdateTime_ds = 0; //переменная времени
int init_ds;
//Переменные температурного датчика DHT11
#define DHT_SENSOR_TYPE DHT_TYPE_11
DHT_Async dht_sensor(D4, DHT_SENSOR_TYPE);
//Переменные для замера освещенности
unsigned long LastUpdateTime_br; //переменная времени для замера освещенности
const int photoPin = A0; // Аналоговый вход с фоторезистором
//Переменные для контроля времени
RTC_DS1307 rtc;
//Переменные кнопок и реле
int btnKey[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
long btnTime[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int btnState[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int RelayState[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
//Переменные для i2C
uint8_t ADDR_KBRD = 0x24;
uint8_t ADDR_RELAY = 0x3A;
uint8_t ADDR_TIME = 0x57;
uint8_t ADDR_LCD = 0x27;
PCF8574 pcf_kbrd(ADDR_KBRD);
PCF8574 pcf_relay(ADDR_RELAY);
//Переменные основного модуля
int tm = 300; // таймер между отправками данных
const int led = 5; // диод на плате
float humidity;
float temp_kur = 1000;
float temp_pkur = 1000;
float bright = 1000;
//=============================================
// Объявление процедур и функций
//=============================================
void initWiFi();
void onWifiConnect(const WiFiEventStationModeGotIP& event);
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event);
/**************************************************************************
* Инициализация
*************************************************************************/
void setup() {
Serial.begin(115200);
//Register event handlers
wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);
//подключаем wifi
initWiFi();
LastUpdateTime_ds = millis();
LastUpdateTime_br = LastUpdateTime_ds;
pinMode(photoPin, INPUT);
Wire.begin();
pcf_kbrd.begin();
pcf_relay.begin();
httpUpdater.setup(&server);
server.begin();
//term.begin(server);
}
/**************************************************************************
* Работа с WiFi
*************************************************************************/
// Проверка подключения к WiFi точке доступа
bool wifiConnected() {
// Если подключение активно, то просто выходим и возвращаем true
if (WiFi.status() != WL_CONNECTED) {
// проверяем возможность запустить wifi по времени
if ((long)millis() - prt_Wifi > pr_Wifi) {
initWiFi(); //подключаем wifi
}
if (WiFi.status() != WL_CONNECTED) {
return false;
}
};
return true;
}
// Инициируем соединение
void initWiFi() {
Serial.print("Connecting to WiFi AP ");
Serial.print(WIFI_SSID);
Serial.print(" ");
// Настраиваем WiFi
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
prt_Wifi = millis();
}
//При соединении
void onWifiConnect(const WiFiEventStationModeGotIP& event) {
Serial.println("Connected to Wi-Fi sucessfully.");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
//При обрыве
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
Serial.println("Disconnected from Wi-Fi, trying to connect...");
WiFi.disconnect();
WiFi.begin(WIFI_SSID, WIFI_PASS);
prt_Wifi = millis();
}
//=============================================
// Работа с MQTT
//=============================================
// Подключение к MQTT брокеру :: версия для PubSubClient от knolleary ("стандартная")
bool mqttConnected() {
if (!mqttClient.connected()) {
Serial.print("Connecting to MQTT broker: ");
// Настраиваем MQTT клиент
mqttClient.setServer(mqttServer, mqttPort);
// Пробуем подключиться с LWT сообщением "offline"
if (mqttClient.connect(mqttClientId, mqttUser, mqttPass,
mqttTopicDeviceStatus, mqttDeviceStatusQos, mqttDeviceStatusRetained, mqttDeviceStatusOff)) {
Serial.println("ok");
// Публикуем статус устройства в тот же топик, что и LWT, но с содержимым "online"
mqttClient.publish(mqttTopicDeviceStatus, mqttDeviceStatusOn, mqttDeviceStatusRetained);
} else {
Serial.print("failed, error code: ");
Serial.print(mqttClient.state());
Serial.println("!");
};
return mqttClient.connected();
};
return true;
}
//=============================================
// Работа с 18b20
//=============================================
//Инициализация DS18b20
void DS18B20_init() {
init_ds++;
if (!ds.search(addr_ds)) {
//no more sensors on chain, reset search
ds.reset_search();
return;
}
if (addr_ds[0] != 0x10 && addr_ds[0] != 0x28) {
Serial.print("Device is not recognized");
return;
}
ds.reset();
ds.select(addr_ds);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
}
//Получение температуры
float DS18B20() {
if (addr_ds[0] != 0x10 && addr_ds[0] != 0x28) {
Serial.print("Device is not recognized");
return -1000;
}
LastUpdateTime_ds = millis();
init_ds = 0;
byte present = ds.reset();
ds.select(addr_ds);
ds.write(0xBE); // Read Scratchpad
for (int i = 0; i < 9; i++) { // we need 9 bytes
data_ds[i] = ds.read();
}
ds.reset_search();
float raw = ((data_ds[1] << 8) | data_ds[0]); //=======Пересчитываем в температуру
float celsius = raw / 16.0;
return celsius;
}
//=============================================
// Работа с DHT11
//=============================================
/*
* Poll for a measurement, keeping the state machine alive. Returns
* true if a measurement is available.
*/
static bool measure_environment(float* temperature, float* humidity) {
static unsigned long measurement_timestamp = millis();
/* Measure once every four seconds. */
if (millis() - measurement_timestamp > 4000ul) {
if (dht_sensor.measure(temperature, humidity)) {
measurement_timestamp = millis();
return (true);
}
}
return (false);
}
//=============================================
// Работа с wifiTerminal
//=============================================
void SendTerminal(String lineString) {
// if (term.available())
// {
// term.print(lineString);
// }
Serial.print(lineString);
}
//=============================================
// Опрос кнопок
//=============================================
void ReadBtn() {
for (int Pin_i = 0; Pin_i < 8; Pin_i++) {
int reading = pcf_kbrd.read(Pin_i);
if (reading != btnKey[Pin_i]) {
// reset the debouncing timer
btnTime[Pin_i] = millis();
btnKey[Pin_i] = reading;
}
if ((millis() - btnTime[Pin_i]) > 50) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != btnState[Pin_i]) {
btnState[Pin_i] = reading;
SendTerminal(String("BTN ") + Pin_i + " lay ");
if (Pin_i > 3)
{
RelayState[Pin_i] != RelayState[Pin_i];
SendTerminal(String("PIN ") + Pin_i + " set " + RelayState[Pin_i]);
}
else
{
switch (Pin_i)
{
case 0:
// setBtn0();
break;
case 1:
// setBtn1();
break;
case 2:
// setBtn2();
break;
case 3:
// setBtn3();
break;
}
}
}
}
}
}
//=============================================
// Основной модуль
//=============================================
void loop() {
//Проверяем wifi - в случае отсутствия связи в течении 30 минут - пытаемся переподключить
if (wifiConnected()) {
if (mqttConnected()) {
// Основной цикл клиента MQTT
mqttClient.loop();
};
server.handleClient();
//term.handleClient();
}
if ((long)millis() - LastUpdateTime_ds < UPDATE_TIME_ds && init_ds == 0) {
DS18B20_init();
}
if ((long)millis() - LastUpdateTime_ds > UPDATE_TIME_ds) {
temp_pkur = DS18B20();
}
if (measure_environment(&temp_kur, &humidity)) {
}
if ((long)millis() - LastUpdateTime_br > UPDATE_TIME_ds * 10) {
bright = analogRead(photoPin);
}
ReadBtn();
}

11
test/README Executable file
View File

@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html