Вот, держите))
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <LoRa.h>
#define MAX485_DE 4
#define MAX485_RE 5
#define RX_PIN 2
#define TX_PIN 3
#define ss 6 // Chip Select (CS) на D6
#define rst 7 // Сброс на D7
#define dio0 8 // DIO0 (IRQ) на D8
ModbusMaster node;
SoftwareSerial rs485Serial(RX_PIN, TX_PIN);
const uint16_t concentration_address = 0x00;
const uint16_t threshold1_address = 0x02;
const uint16_t threshold2_address = 0x04;
const int bufferSize = 12; // Изменено на 12 строк
String dataBuffer[bufferSize]; // Буфер для данных
int currentIndex = 0; // Индекс для записи в буфер
// Настройки LoRa
const long frequency = 433E6; // Частота LoRa
const int txPower = 10; // Мощность передачи (от 2 до 10 dBm БОЛЬШЕ 10 НЕЛЬЗЯ! ЗАПРЕЩЕНО)
const int spreadingFactor = 12; // Спрединг фактор (от 6 до 12)
const long signalBandwidth = 125E3; // Ширина сигнала
void displayData(uint16_t registers[], uint16_t threshold1, uint16_t threshold2, int deviceID) {
if (registers == nullptr) {
return;
}
uint8_t byte1 = (registers[0] >> 8) & 0xFF;
uint8_t byte2 = registers[0] & 0xFF;
uint8_t byte3 = (registers[1] >> 8) & 0xFF;
uint8_t byte4 = registers[1] & 0xFF;
bool sign_bit = (byte1 >> 7) & 0x01;
uint8_t comma_position = byte1 & 0x07;
int32_t integer_part = (int32_t)byte2 * 10000L + (int32_t)byte3 * 10L + (byte4 >> 4);
int32_t decimal_part = (byte4 & 0x0F) * 100;
double value = integer_part + decimal_part / 10000.0;
value = sign_bit ? -value : value;
double divisor = pow(10.0, comma_position);
value /= divisor;
value = round(value * 100.0) / 100.0;
// Преобразование порогов в HEX формат
String threshold1Hex = String(threshold1, HEX);
String threshold2Hex = String(threshold2, HEX);
String lastTwoDigitsThreshold1 = threshold1Hex.substring(threshold1Hex.length() - 2);
String lastTwoDigitsThreshold2 = threshold2Hex.substring(threshold2Hex.length() - 2);
// Форматирование данных для буфера с добавлением идентификатора устройства
String dataLine = String(deviceID) + " " + String(value, 2) + " " + lastTwoDigitsThreshold1 + " " + lastTwoDigitsThreshold2 + "\n";
// Сохранение в буфер
if (currentIndex < bufferSize) {
dataBuffer[currentIndex++] = dataLine;
Serial.println("Запись данных в буфер: " + dataLine); // Вывод в консоль
}
// Если буфер заполнен, передаем данные по LoRa
if (currentIndex == bufferSize) {
sendDataBuffer();
currentIndex = 0; // Сброс индекса
}
}
void sendDataBuffer() {
Serial.println("Передача пакета данных..."); // Сообщение о начале передачи
LoRa.beginPacket();
for (int i = 0; i < bufferSize; i++) {
LoRa.print(dataBuffer[i]); // Передача строки
}
LoRa.endPacket();
Serial.println("Передача выполнена!"); // Сообщение о завершении передачи
}
void readDevice(int deviceID) {
node.begin(deviceID, rs485Serial);
uint8_t result;
uint16_t data[2];
uint16_t threshold1 = 0;
uint16_t threshold2 = 0;
// Чтение концентрации
result = node.readHoldingRegisters(concentration_address, 2);
if (result == node.ku8MBSuccess) {
data[0] = node.getResponseBuffer(0);
data[1] = node.getResponseBuffer(1);
} else {
Serial.print("Устройство ");
Serial.print(deviceID);
Serial.print(" - Ошибка чтения концентрации. Код ошибки: ");
Serial.println(result, HEX);
return;
}
delay(500);
// Чтение первого порога
result = node.readHoldingRegisters(threshold1_address, 1);
if (result == node.ku8MBSuccess) {
threshold1 = node.getResponseBuffer(0);
} else {
Serial.print("Устройство ");
Serial.print(deviceID);
Serial.print(" - Ошибка чтения первого порога. Код ошибки: ");
Serial.println(result, HEX);
}
delay(500);
// Чтение второго порога
result = node.readHoldingRegisters(threshold2_address, 1);
if (result == node.ku8MBSuccess) {
threshold2 = node.getResponseBuffer(0);
} else {
Serial.print("Устройство ");
Serial.print(deviceID);
Serial.print(" - Ошибка чтения второго порога. Код ошибки: ");
Serial.println(result, HEX);
}
// Вывод всех данных в одну строку с указанием ID устройства
displayData(data, threshold1, threshold2, deviceID);
}
void preTransmission() {
digitalWrite(MAX485_RE, HIGH);
digitalWrite(MAX485_DE, HIGH);
}
void postTransmission() {
digitalWrite(MAX485_RE, LOW);
digitalWrite(MAX485_DE, LOW);
}
void setup() {
Serial.begin(9600);
rs485Serial.begin(9600);
pinMode(MAX485_DE, OUTPUT);
pinMode(MAX485_RE, OUTPUT);
digitalWrite(MAX485_RE, LOW);
digitalWrite(MAX485_DE, LOW);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
// Настройка LoRa
LoRa.setPins(ss, rst, dio0);
while (!LoRa.begin(frequency)) {
Serial.print(".");
delay(500);
}
LoRa.setSpreadingFactor(spreadingFactor);
LoRa.setSignalBandwidth(signalBandwidth);
LoRa.setTxPower(txPower);
Serial.println("LoRa Initializing OK!");
}
void loop() {
readDevice(1); // Чтение данных с устройства 1
delay(500);
readDevice(2); // Чтение данных с устройства 2
delay(10000); // Задержка 10 секунд перед следующим циклом
}
#include <SPI.h>
#include <LoRa.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
// Piny dlya podklyucheniya LoRa
#define ss 5 // Chip Select dlya LoRa
#define rst 14 // Reset dlya LoRa
#define dio0 2 // DIO0 dlya LoRa
// Piny dlya displeya
#define TFT_CS 15 // Chip Select dlya displeya
#define TFT_RST 4 // Reset dlya displeya
#define TFT_DC 16 // Data/Command dlya displeya
// Sozdanie obyekta dlya raboty s displeyem
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// Nastroyki Wi-Fi
const char* ssid = "TP-Link_B692"; // Imya Wi-Fi
const char* password = "qwerty12345"; // Parol' Wi-Fi
// Fiksirovannyy IP-adres dlya ESP32
IPAddress local_IP(192, 168, 12, 132); // Fiksirovannyy IP dlya ESP32
IPAddress gateway(192, 168, 12, 1); // Shlyuz (obyichno eto IP marshrutizatora)
IPAddress subnet(255, 255, 255, 0); // Podset'
const char* serverUrl = "http://192.168.12.8:5000/data"; // URL dlya otpravki dannykh
void setup() {
Serial.begin(9600);
while (!Serial);
// Initsializatsiya displeya
tft.initR(INITR_BLACKTAB);
tft.setRotation(1); // Povorot displeya v gorizontальное polozhenie
tft.fillScreen(ST77XX_BLACK); // Zalivka ekrana chernym tsvetom
tft.setTextColor(ST77XX_WHITE); // Ustanovka tsveta teksta
tft.setTextSize(1); // Umenshenie razmera teksta
// Ustanavlivaem staticheskiy IP
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("Ne udalos' ustanovit' staticheskiy IP.");
}
// Podklyuchenie k Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Podklyucheniye k Wi-Fi...");
}
Serial.println("Podklyucheno k Wi-Fi!");
// Initsializatsiya LoRa
LoRa.setPins(ss, rst, dio0);
if (!LoRa.begin(433E6)) {
Serial.println("LoRa ne initsializirovalsya. Prover'te podklyucheniye.");
while (1);
}
// Nastroyki LoRa
LoRa.setSpreadingFactor(12); // Ustanavlivaem SF7
LoRa.setSignalBandwidth(125E3); // Standartnaya shirina polosy 125 kHz
LoRa.setTxPower(10); // Ustanavlivaem moshchnost' na 1 dBm (~10 mW)
Serial.println("LoRa Receiver gotov!");
}
void loop() {
int packetSize = LoRa.parsePacket();
if (packetSize) {
String message = "";
while (LoRa.available()) {
message += (char)LoRa.read();
}
// Polucheniye urovnya RSSI
int rssi = LoRa.packetRssi(); // Polucheniye RSSI
// Vyvodim poluchennoye soobshcheniye
Serial.println(message);
// Pokazaniya soobshcheniy na displee
displayMessage(message, rssi);
// Sokhranyaem dannye na servere
sendDataToServer(message);
}
}
void displayMessage(String message, int rssi) {
tft.fillScreen(ST77XX_BLACK); // Ochrashchayem ekran
tft.setCursor(10, 10); // Ustanavlivaem kursor
tft.print("Polucheno soobshcheniye: rssi ");
tft.print(rssi);
tft.println(" dBm"); // Vyvodim RSSI
tft.println(message); // Vyvodim poluchennoye soobshcheniye
}
void sendDataToServer(String message) {
// Razdelyaem soobshcheniye na stroki
int lineStart = 0;
int lineEnd;
while ((lineEnd = message.indexOf('\n', lineStart)) != -1) {
String line = message.substring(lineStart, lineEnd);
lineStart = lineEnd + 1; // Ukazyvayem nachalo sleduyushchey stroki
// Razdelyaem stroku na chasti
int sensorID;
float concentration, threshold1, threshold2;
// Razdelyaem soobshcheniye na chasti
sscanf(line.c_str(), "%d %f %f %f", &sensorID, &concentration, &threshold1, &threshold2);
// Podgotovka HTTP-zaprosa
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String postData = String(sensorID) + "," + String(concentration) + "," + String(threshold1) + "," + String(threshold2);
http.begin(serverUrl);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpResponseCode = http.POST("data=" + postData);
if (httpResponseCode > 0) {
Serial.printf("Dannye otpravleny dlya datchika %d. Kod otveta: %d\n", sensorID, httpResponseCode);
} else {
Serial.printf("Oshibka pri otpravke dannykh: %s\n", http.errorToString(httpResponseCode).c_str());
}
http.end();
} else {
Serial.println("WiFi ne podklyuchen");
}
}
}