Обмен данными через последовательный порт
- Войдите на сайт для отправки комментариев
Втр, 12/02/2019 - 12:52
Ещё вчера вечером описал проблему в другой теме, на неё даже ответил DetSimen (судя по подписке на почте), но сейчас там всё подтёрто. Создаю новую тему:
Есть задача отправлять информацию через последовательный порт с Arduino UNO на ESP8266.
Вот кусок кода на передающей стороне (Arduino):
void loop() {
Serial.print("
Ещё вчера вечером описал проблему в другой теме, на неё даже ответил DetSimen (судя по подписке на почте), но сейчас там всё подтёрто. Создаю новую тему:
Есть задача отправлять информацию через последовательный порт с Arduino UNO на ESP8266.
Вот кусок кода на передающей стороне (Arduino):
void loop() { Serial.print("и что не работает? Должен же стопудово работать, если двойную кавычку поставить, потом закрывающую скопку, потом точку с запятой, потом фигурную. И всё.
Не могу понять, почему все мои ссобщения режутся, вот полный текст: http://text.fancy.kz/zxzq
Не могу понять, почему все мои ссобщения режутся, вот полный текст: http://text.fancy.kz/zxzq
Ты чо думаешь, там текста больше?
видимо, в кавычках первым символом идёть ^Z
void loop() { Serial.print("Температура котельной: "); // Serial.print(t); Serial.println(" °C"); Serial.print("Температура воды: "); // Serial.print(TempWater); Serial.println(" °C"); Serial.print("Температура на улице: "); // Serial.print(TempOut); Serial.println(" °C"); Serial.print("Влажность котельной: "); // Serial.print(h); Serial.println(" %"); Serial.print("Качество воздуха: "); // Serial.print(val135); Serial.println(" ед."); Serial.print("Природный газ: "); // Serial.print(val4); Serial.println(" ед."); Serial.print("Датчик протечки: "); // Serial.print(Potop); Serial.println(" ед."); delay (10000); }int ch = 0; String val = ""; if (Serial.available()) { //если в мониторе порта ввели что-то while (Serial.available()) { //сохраняем строку в переменную val ch = Serial.read(); val += char(ch); delay(10); } //передача всех команд, набранных в мониторе порта в бота bot.sendMessage(chat_id, val, ""); val = ""; //очищаем }Там был смайлик "градусник", для наглядности в боте. Не подумал, что он может вызвать какие-то проблемы
а вот это
// Serial.print(t);
ни о чем не?
И другие строчки тоже так, далее по тексту
Я просто вырвал кусок из девайса, который уже работает и залил в тестовую ардуину, чтобы понять как оно вообще функционирует. Ну и закомментил ненужные строки
Пацкаска: Что означает двойной слэш (//) перед Serial?
Я не настолько новичок) У меня дуина передаёт семь строк, а в итоге две с половиной. Это проблема
Передатчик фигачит с максимально возможной скоростью, а на приёмнике зачем-то задержка стоит после каждого символа. Не смущает? Буфер передатчика переполняется и он перестаёт передавать. Попробуйте вызывать flush после каждого println
Ну или прочитай себе вслух вэт это
https://ravesli.com/urok-9-kommentarii-v-s/
и снова приходи, нам расскажешь
Передатчик фигачит с максимально возможной скоростью, а на приёмнике зачем-то задержка стоит после каждого символа. Не смущает? Буфер передатчика переполняется и он перестаёт передавать. Попробуйте вызывать flush после каждого println
Спасибо за ответ. Сейчас открыл монитор порта на передатчике, он передаёт всё как и требуется. На всякий пожарный добавил flush, ничего не поменялось. Убрал задержку на приёмнике, ничего не поменялось(
На всякий пожарный добавил flush, ничего не поменялось. Убрал задержку на приёмнике, ничего не поменялось(
Куда добавил? Как добавил? Показывайте.
Куда добавил? Как добавил? Показывайте.
Сейчас через каждые две строки добавил delay(3000);
void loop() { Serial.print("Температура котельной: "); // Serial.print(t); Serial.println(" °C"); Serial.print("Температура воды: "); // Serial.print(TempWater); Serial.println(" °C"); delay(3000); Serial.print("Температура на улице: "); // Serial.print(TempOut); Serial.println(" °C"); Serial.print("Влажность котельной: "); // Serial.print(h); Serial.println(" %"); delay(3000); Serial.print("Качество воздуха: "); // Serial.print(val135); Serial.println(" ед."); Serial.print("Природный газ: "); // Serial.print(val4); Serial.println(" ед."); delay(3000); Serial.print("Датчик протечки: "); // Serial.print(Potop); Serial.println(" ед."); delay (10000); }Стало приходить всё, но отдельными сообщениями соответственно:
Flush добавлял вот так:
void loop() { Serial.print("Температура котельной: "); // Serial.print(t); Serial.println(" °C"); Serial.flush(); Serial.print("Температура воды: "); // Serial.print(TempWater); Serial.println(" °C"); Serial.flush(); Serial.print("Температура на улице: "); // Serial.print(TempOut); Serial.println(" °C"); Serial.flush(); Serial.print("Влажность котельной: "); // Serial.print(h); Serial.println(" %"); Serial.flush(); Serial.print("Качество воздуха: "); // Serial.print(val135); Serial.println(" ед."); Serial.flush(); Serial.print("Природный газ: "); // Serial.print(val4); Serial.println(" ед."); Serial.flush(); Serial.print("Датчик протечки: "); // Serial.print(Potop); Serial.println(" ед."); Serial.flush(); delay (10000); }Правда я сейчас вычитал, что она буфер-то чистила на версиях до 1. Но что с ней, что без неё в мониторе порта передатчика, повторюсь, всё прекрасно:
а что не так? Все что передеал все принято. В чем вопрос-то?
а что не так? Все что передеал все принято. В чем вопрос-то?
Если Вы про вариант с костыльными делеями по 3 секунды- то это всё-таки не то. Хочется одного целостного сообщения. А то, что в мониторе порта, только лишь выход передатчика.
Если не придумаем более красивой реализации, придётся пользоваться вариантом с делеями
Flush добавлял вот так:
Надо одновременно и добавить flush, и убрать все задержки из приёмника. Вот и покажите как это сделано и что при этом принимается.
В приёмника вообще не должно быть никаких задержек - никогда. Вы же не знаете когда и что будет передаваться.
Если не придумаем более красивой реализации, придётся пользоваться вариантом с делеями
Если не будете делать, что Вам говорят, то будете решать проблему сами :)
Надо одновременно и добавить flush, и убрать все задержки из приёмника. Вот и покажите как это сделано и что при этом принимается.
Я так и делал, но, вот:
Передатчик:
void loop() { Serial.print("Температура котельной: "); // Serial.print(t); Serial.println(" °C"); Serial.flush(); Serial.print("Температура воды: "); // Serial.print(TempWater); Serial.println(" °C"); Serial.flush(); Serial.print("Температура на улице: "); // Serial.print(TempOut); Serial.println(" °C"); Serial.flush(); Serial.print("Влажность котельной: "); // Serial.print(h); Serial.println(" %"); Serial.flush(); Serial.print("Качество воздуха: "); // Serial.print(val135); Serial.println(" ед."); Serial.flush(); Serial.print("Природный газ: "); // Serial.print(val4); Serial.println(" ед."); Serial.flush(); Serial.print("Датчик протечки: "); // Serial.print(Potop); Serial.println(" ед."); Serial.flush(); delay (10000); }Приёмник:
if (Serial.available()) { //если в мониторе порта ввели что-то while (Serial.available()) { //сохраняем строку в переменную val ch = Serial.read(); val += char(ch); //delay(10); } //передача всех команд, набранных в мониторе порта в бота bot.sendMessage(chat_id, val, ""); val = ""; //очищаем }Результат:
По- прежнему отсутсвуют четыре строки
Женя! Я вроде спрашивал, но ответ не помню: у тебя практика преподавания большая?
Это я к тому, что я твою методику наведения на самостоятельное решение не всегда могу понять.
Вот в этом случае, конкретно не могу.
Далее под спойлером, чтобы не портить процесс.
Автор, на твоей совести - не читать!
Это я к тому, что я твою методику наведения на самостоятельное решение не всегда могу понять.
За себя скажу. После чтения определенного объёма глупых вопросов и разбора скетчей-франкенштейнов мозг начинает выдавать такие же безумные конструктивы и отказывается видеть явные и простые ошибки.
Автор, на твоей совести - не читать!
Уж простите, не удержался. И поэтому спешу сообщить, что эту мысль я написал ещё в своём первом сообщении (!):
Думаю, может как-нибудь обозначить конец ввода? Заранее спасибо!
Тоесть я понимаю, что надо сделать так, но не очень понимаю как написать(
Тоесть я понимаю, что надо сделать так, но не очень понимаю как написать(
Ну блин!
Предай, как конец, какой-нибудь дурацкий символ.... например '#' или, как в С положено - '\n'.
И жди его появления, как принял его, не записывай в буфер, а переходи к передаче, вот и всё.
То есть ничего на приемнике не ждешь, понимаешь, что прием может не весь уложиться в один заход в loop().
При каждом заходе в loop() выгребаешь весь буфер приема и ждешь своего символа завершения.
Что тут может быть непонятного????
По- прежнему отсутсвуют четыре строки
А целиком приёмник показать слабо?
у него признака конца сообщения нет,
Это следующий вопрос. Пока пусть хоть просто наладит бридж - "что пришло, то и вышло"
А целиком приёмник показать слабо?
Вот, пожалуйста:
#include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <UniversalTelegramBot.h> char ssid[] = ""; char password[] = ""; #define BOTtoken "" WiFiClientSecure client; UniversalTelegramBot bot(BOTtoken, client); int Bot_mtbs = 500; long Bot_lasttime; bool Start = false; int ch = 0; String val = ""; void handleNewMessages(int numNewMessages) { for (int i = 0; i < numNewMessages; i++) { String chat_id = String(bot.messages[i].chat_id); String text = bot.messages[i].text; String from_name = bot.messages[i].from_name; if (from_name == "") from_name = "Guest"; if (text == "/start") { String welcome = "Welcome to Universal Arduino Telegram Bot library, " + from_name + ".\n"; welcome += "This is serial print bot example.\n"; bot.sendMessage(chat_id, welcome, "Markdown"); } } } void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } } void loop() { String chat_id = ""; if (Serial.available()) { //если в мониторе порта ввели что-то while (Serial.available()) { //сохраняем строку в переменную val ch = Serial.read(); val += char(ch); //delay(10); } //передача всех команд, набранных в мониторе порта в бота bot.sendMessage(chat_id, val, ""); val = ""; //очищаем } if (millis() > Bot_lasttime + Bot_mtbs) { int numNewMessages = bot.getUpdates(bot.last_message_received + 1); while (numNewMessages) { handleNewMessages(numNewMessages); numNewMessages = bot.getUpdates(bot.last_message_received + 1); } Bot_lasttime = millis(); } }Сможете поставить печать переменной val перед строкой 58? Понимаю, что Serial занят, но если сможете, то поймёте проблему.
Кстати (совсем про другое), в строке №63 ошибка, раз в два месяца (при переходе millis через 0) будет сбоить. см. http://arduino.ru/forum/programmirovanie/velikoe-perepolnenie-millis
Сможете поставить печать переменной val перед строкой 58? Понимаю, что Serial занят, но если сможете, то поймёте проблему.
Переделал вот так, подключив передатчик в SoftwareSerial:
#include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <UniversalTelegramBot.h> #include <SoftwareSerial.h> SoftwareSerial mySerial(5, 14); // RX, TX char ssid[] = ""; char password[] = ""; #define BOTtoken "" WiFiClientSecure client; UniversalTelegramBot bot(BOTtoken, client); int Bot_mtbs = 500; long Bot_lasttime; bool Start = false; int ch = 0; String val = ""; void handleNewMessages(int numNewMessages) { for (int i = 0; i < numNewMessages; i++) { String chat_id = String(bot.messages[i].chat_id); String text = bot.messages[i].text; String from_name = bot.messages[i].from_name; if (from_name == "") from_name = "Guest"; if (text == "/start") { String welcome = "Welcome to Universal Arduino Telegram Bot library, " + from_name + ".\n"; welcome += "This is serial print bot example.\n"; bot.sendMessage(chat_id, welcome, "Markdown"); } if (text == "/sensors") { Serial.print("sensors"); } } } void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } mySerial.begin(115200); } void loop() { String chat_id = ""; if (mySerial.available()) { //если в мониторе порта ввели что-то while (mySerial.available()) { //сохраняем строку в переменную val ch = mySerial.read(); val += char(ch); //delay(10); } //передача всех команд, набранных в мониторе порта в бота Serial.println(val); bot.sendMessage(chat_id, val, ""); val = ""; //очищаем } if (millis() > Bot_lasttime + Bot_mtbs) { int numNewMessages = bot.getUpdates(bot.last_message_received + 1); while (numNewMessages) { handleNewMessages(numNewMessages); numNewMessages = bot.getUpdates(bot.last_message_received + 1); } Bot_lasttime = millis(); } }Текста стало ещё меньше:
То же самое, что и отпправляет в бот
Ох....
Ох....
Ну это всё ради вашего совета)
Хорошо, а если убрать пока байду с 72 по 81 строки? Никак не полегчает?
И кстати, софт сериал на таких скоростях не работает. Поставьте 9600 пока (и в передатчике тоже).
Ох....
Ну это всё ради вашего совета)
Прости, тут сейчас Женя рулит, пусть он и отдувается! (Женя! Прости меня, грешного!)
Про твою реплику могу только процитировать старую поговрку:
Дураку и грамота вредна.
В том смысле, что зря я влез... ты совсем не туда ушел, куда надо.
Хорошо, а если убрать пока байду с 72 по 81 строки? Никак не полегчает?
И кстати, софт сериал на таких скоростях не работает. Поставьте 9600 пока (и в передатчике тоже).
Убрал, от неё ни тепло, ни холодно. Поставил 9600, всё тот же обрубок текста
#include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <UniversalTelegramBot.h> #include <SoftwareSerial.h> SoftwareSerial mySerial(5, 14); // RX, TX // Initialize Wifi connection to the router char ssid[] = ""; // your network SSID (name) char password[] = ""; // your network key // Initialize Telegram BOT #define BOTtoken "458450101:-XYqx3V_3qqtX0a1pUTXV-M" // your Bot Token (Get from Botfather) WiFiClientSecure client; UniversalTelegramBot bot(BOTtoken, client); int Bot_mtbs = 500; long Bot_lasttime; bool Start = false; int ch = 0; String val = ""; void handleNewMessages(int numNewMessages) { for (int i = 0; i < numNewMessages; i++) { String chat_id = String(bot.messages[i].chat_id); String text = bot.messages[i].text; String from_name = bot.messages[i].from_name; if (from_name == "") from_name = "Guest"; if (text == "/start") { String welcome = "Welcome to Universal Arduino Telegram Bot library, " + from_name + ".\n"; welcome += "This is serial print bot example.\n"; bot.sendMessage(chat_id, welcome, "Markdown"); } if (text == "/sensors") { Serial.print("sensors"); } } } void setup() { Serial.begin(9600); WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } Serial.println("Test"); mySerial.begin(9600); } void loop() { String chat_id = ""; if (mySerial.available()) { //если в мониторе порта ввели что-то while (mySerial.available()) { //сохраняем строку в переменную val ch = mySerial.read(); val += char(ch); //delay(10); } //передача всех команд, набранных в мониторе порта в бота Serial.println(val); bot.sendMessage(chat_id, val, ""); val = ""; //очищаем } }Что-то я чувствую, сейчас пойду напишу эти три несчастных дэлея, потому что я не особо понимаю, к чему всё это.
Убрал, от неё ни тепло, ни холодно. Поставил 9600, всё тот же обрубок текста
Ну, вот, уже не знаю. Ну, вывод-то из своих экспериментов сделайте! В какой-то момент Вы должны сделать выводы из той информации, что у Вас есть, понимаете. Именно так программы и отлаживают. Неужели, никакой вывод не напрашивается?
void loop() { String chat_id = ""; while (mySerial.available()) { //сохраняем строку в переменную val ch = mySerial.read(); if (ch == '#') break; val += char(ch); //delay(10); } //передача всех команд, набранных в мониторе порта в бота if (ch =='#') { Serial.println(val); bot.sendMessage(chat_id, val, ""); val = ""; //очищаем } }Вместо '#' - тот символ, который ты В ПЕРЕДАТЧИКЕ, МЛЯ, используешь, как конец сообщения.
Спасибо! Сначала выводились такие простыни каждые 3 минуты:
Но потом я снизил скорость, и всё заработало. Возможно, сделай я это раньше, было бы меньше проблем
Возможно, сделай я это раньше, было бы меньше проблем
Надеюсь, Вы о "подумать"? :)
------------------
wdrakula, признаю, что я облажался по уши :(
Надеюсь, Вы о "подумать"? :)
Зачем там думать - нужно было снизить скорость. А ещё прохфессорами назвались...
Возможно, сделай я это раньше, было бы меньше проблем
Надеюсь, Вы о "подумать"? :)
В совокупности)
wdrakula, признаю, что я облажался по уши :(
Женя! Ты о чём? Мне просто показалось, что ты ТС-а ведешь каким-то долгим путём, но "облажаться"??? Не понял тебя....
ТС! В строке 03 напиши
Обязательно это добавь, иначе попадешь на глюк. ;))))
Написал, но чёт не очень понимаю, зачем? Ведь мы в цикле сразу же присваиваем ему Serial.read();
Написал, но чёт не очень понимаю, зачем? Ведь мы в цикле сразу же присваиваем ему Serial.read();
"Не напрягайся, морщины появятся!" ;)
....
Ну сам подумай! Вот нет ничего в буфере, а старое значение в ch осталось и чо? Можно чистить при отправке, или до цикла. Как тебе больше нравиццо!
При отправке экономней на пару спичек.
Почему-то всё равно, даже на скорости 9600 может прийти не всё. Без пауз может прийти чуть-чуть, а с паузами в 3 секунды не приходит вообще ничего. Четыре сообщения на картинке отправляет одна и та же функция:
void smssend(String text) { if (SendSMS == false) { //Считывание информации с сенсоров sensors.requestTemperatures(); float TempWater = sensors.getTempC(WaterT); //темп. воды float TempOut = sensors.getTempC(OutT); //темп. улицы float h = dht.readHumidity(); //влажность комнаты float t = dht.readTemperature(); //темп. комнаты long val135 = 0; //качество воздуха for (int i = 0; i < 100; ++i) { val135 = val135 + analogRead(SENSOR_AQ); } val135 = val135 / 100; long val4 = 0; //природный газ for (int i = 0; i < 100; ++i) { val4 = val4 + analogRead(SENSOR_CH); } val4 = val4 / 100; long Potop = 0; //уровень воды for (int i = 0; i < 100; ++i) { Potop = Potop + analogRead(A3); } Potop = Potop / 100; Serial.println(text); Serial.print("Температура котельной: "); Serial.print(t); Serial.println(" °C"); delay(1500); Serial.print("Температура воды: "); Serial.print(TempWater); Serial.println(" °C"); delay(1500); Serial.print("Температура на улице: "); Serial.print(TempOut); Serial.println(" °C"); delay(1500); Serial.print("Влажность котельной: "); Serial.print(h); Serial.println(" %"); delay(1500); Serial.print("Качество воздуха: "); Serial.print(val135); Serial.println(" ед."); delay(1500); Serial.print("Природный газ: "); Serial.print(val4); Serial.println(" ед."); delay(1500); Serial.print("Датчик протечки: "); Serial.print(Potop); Serial.println(" ед.#"); delay(1500); delay(500); if (text != "Как Вы просили:") { SendSMS = true; } delay(2000); } }Приёмник:
void loop() { String chat_id = ""; ch = 0; while (Serial.available()) { ch = Serial.read(); if (ch == '#') break; val += char(ch); } if (ch == '#') { Serial.println(val); bot.sendMessage(chat_id, val, ""); val = ""; } }спать нужно по ночам. всё завтра.
Женя! Ты о чём? Мне просто показалось, что ты ТС-а ведешь каким-то долгим путём, но "облажаться"??? Не понял тебя....
Как о чём, был уверен, что за пару тройку итераций доведу. Но не довёл.
ЧА что до длинного пути, так если бы у него сначала получилась копировалка длинной портянки, а потом уж ставить признак конца, то он бы понял проблему, а так ...
ТС, хотиите проверить поняли ли Вы проблему? Уберите оттуда while и добейтесь, чтобы без него также хорошо работало.
Нашего ТопикСтартера что-то не видать.... Ну ладно.
Вот вопросы к нему:
1.есть ли резон для того, чтобы все длинные тексты передавать с Уно? Вопрос в том, что на Уно памяти мало, а на ЕСП - неограниченно ;), может стоит передавать только значения?
2. Если пропажа строк сохраняется, то нужно синхронизировать передачу и прием. То есть передатчик кидает что-то, например '?' в приемник и ждет ответа. Получив ответ кидает уже данные, и ждет подтверждения получения.
Это можно выращивать до полноценного протокола обмена, или при ошибке просто повторять всё с начала. Тогда нужно завести запрос первого сообщения, запрос продолжения и запрос окончания. Приемник может отвечать только одним образом. При неответе - передатчик по таймауту вылетает и переходит в начало цикла.
Первый вопрос реализовал, но всё-таки кривовато. Зато работает на 100%. Пока что ни одного сбоя. Вот финальная версия на данный момент:
Передатчик (Уже основной девайс):
//Подключаем библиотеки #include <Wire.h> #include "DHT.h" #include <LiquidCrystal_I2C.h> #include <OneWire.h> #include <DallasTemperature.h> //Прописываем датчики воздуха #define SENSOR_AQ A0 #define SENSOR_CH A1 //Прописываем пороги срабатывания const long mq135ok = 240; //попугаи дыма const long mq4ok = 90; //попугаи природного газа const float tok = 35; //температура котельной const float hok = 95; //влажность котельной const float watermax = 85; //макс. темп. воды const float watermin = 15; //мин темп. воды const long PotopMax = 300; //уровень воды (в попугаях) int ch = 0; boolean SendSMS = false; boolean SendRequest = false; String val = ""; //Прописываем DHT DHT dht(13, DHT22); //Прописываем датчики температуры Dallas OneWire oneWire(11); DallasTemperature sensors(&oneWire); DeviceAddress OutT = { 0x28, 0xFF, 0x26, 0x97, 0x00, 0x16, 0x02, 0xB1 }; // адрес датчика на улице DeviceAddress WaterT = { 0x28, 0xFF, 0xE1, 0xA3, 0x00, 0x16, 0x01, 0x66 }; // адрес датчика воды //Прописываем экран // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE ); // Set the LCD I2C address void setup() { //Инициализация экрана lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines pinMode(1, OUTPUT); digitalWrite(1, LOW); //Вывод приветствия lcd.setCursor(4, 0); //Start at character 4 on line 0 lcd.print("BoilerSecurity"); delay(250); lcd.setCursor(6, 2); lcd.print("Loading"); lcd.setCursor(4, 3); delay(250); lcd.print("Please wait..."); delay(500); //Инициализация пинов pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); pinMode(11, INPUT); pinMode(13, INPUT); SendSMS = false; //Serial Serial.begin(9600); //Инициализация DHT dht.begin(); sensors.begin(); //Инициализация Dallas sensors.setResolution(WaterT, 10); sensors.setResolution(OutT, 10); delay(1750); } void loop() { //Проверяем, есть ли запрос из бота if ((digitalRead(13) == HIGH) & (SendRequest == false)) { SendSMS = false; smssend(String ("Сенсоры:")); SendRequest = true; } else { SendRequest = false; } //Сичтываем показания с датчиков //Температура воды и улицы sensors.requestTemperatures(); float TempWater = sensors.getTempC(WaterT); float TempOut = sensors.getTempC(OutT); //Температура и влажность в котельной float h = dht.readHumidity(); float t = dht.readTemperature(); //Отработка аварии по температурам if ((TempWater <= watermax && TempWater >= watermin) && (t <= tok)) { digitalWrite(10, HIGH); // зажигаем светодиод delay(10); digitalWrite(10, LOW); } else { digitalWrite(10, HIGH); // зажигаем светодиод smssend(String ("Проверь температуру!")); } //Считываем показания датчиков газов //MQ-135 long val135 = 0; for (int i = 0; i < 100; ++i) { val135 = val135 + analogRead(SENSOR_AQ); } val135 = val135 / 100; //MQ4 long val4 = 0; for (int i = 0; i < 100; ++i) { val4 = val4 + analogRead(SENSOR_CH); } val4 = val4 / 100; //Отработка аварии по газам if (val4 <= mq4ok && val135 <= mq135ok) { digitalWrite(7, HIGH); // зажигаем светодиод delay(10); digitalWrite(7, LOW); } else { digitalWrite(7, HIGH); // зажигаем светодиод smssend(String ("Проверь газы!")); } //Считывание датчика уровня воды long Potop = 0; for (int i = 0; i < 100; ++i) { Potop = Potop + analogRead(A3); } Potop = Potop / 100; if (Potop >= PotopMax) { digitalWrite(8, HIGH); // зажигаем светодиод delay(10); digitalWrite(8, LOW); } else { digitalWrite(8, HIGH); // зажигаем светодиод smssend(String ("Проверь уровень воды!")); } //Считвание показаний датчика пламени if (digitalRead(11) == HIGH) { digitalWrite(9, HIGH); // зажигаем светодиод delay(10); digitalWrite(9, LOW); } else { digitalWrite(9, HIGH); // зажигаем светодиод smssend(String ("Обнаружено пламя")); } //Вывод данных на экран //Очистка экрана //lcd.clear(); //ОСТОРОЖНО!!! //Температура и влажность котельной if (isnan(t) || isnan(h)) { lcd.setCursor(3, 0); lcd.print("Failed to read"); lcd.setCursor(6, 1); lcd.print("from DHT"); smssend(String ("Ошибка чтения данных с DHT!")); } else { lcd.setCursor(0, 0); lcd.print("Humidity: "); lcd.setCursor(13, 0); lcd.print(h); lcd.setCursor(19, 0); lcd.print("%"); lcd.setCursor(0, 1); lcd.print("Temperature: "); lcd.setCursor(13, 1); lcd.print(t); lcd.setCursor(19, 1); lcd.print("C"); } lcd.setCursor(0, 2); lcd.print("Water temp: "); lcd.setCursor(12, 2); lcd.print(TempWater); lcd.setCursor(18, 2); lcd.print("C"); lcd.setCursor(0, 3); lcd.print("Out Temp: "); lcd.setCursor(12, 3); lcd.print(TempOut); lcd.setCursor(18, 3); lcd.print("C"); delay(3000); //задержка перед новым опросом датчиков } void smssend(String text) { if (SendSMS == false) { //Считывание информации с сенсоров sensors.requestTemperatures(); float TempWater = sensors.getTempC(WaterT); //темп. воды float TempOut = sensors.getTempC(OutT); //темп. улицы float h = dht.readHumidity(); //влажность комнаты float t = dht.readTemperature(); //темп. комнаты long val135 = 0; //качество воздуха for (int i = 0; i < 100; ++i) { val135 = val135 + analogRead(SENSOR_AQ); } val135 = val135 / 100; long val4 = 0; //природный газ for (int i = 0; i < 100; ++i) { val4 = val4 + analogRead(SENSOR_CH); } val4 = val4 / 100; long Potop = 0; //уровень воды for (int i = 0; i < 100; ++i) { Potop = Potop + analogRead(A3); } Potop = Potop / 100; Serial.print(text); Serial.print("r"); delay (1500); Serial.print(t); Serial.print("k"); delay(1500); Serial.print(TempWater); Serial.print("w"); delay(1500); Serial.print(TempOut); Serial.print("o"); delay(1500); Serial.print(h); Serial.print("h"); delay(1500); if (digitalRead(11) == HIGH) { Serial.print("z"); } else { Serial.print("x"); } Serial.print("f"); delay(1500); Serial.print(val135); Serial.print("q"); delay(1500); Serial.print(val4); Serial.print("g"); delay(1500); Serial.print(Potop); Serial.print("p"); delay(1500); Serial.print("#"); delay(500); if (text != "Сенсоры:") { SendSMS = true; } delay(2000); } }Приёмник:
#include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <UniversalTelegramBot.h> // Initialize Wifi connection to the router char ssid[] = ""; // your network SSID (name) char password[] = ""; // your network key // Initialize Telegram BOT #define BOTtoken ":AAH_fTlgywix-XYqx3V_3qqtX0a1pUTXV-M" // your Bot Token (Get from Botfather) WiFiClientSecure client; UniversalTelegramBot bot(BOTtoken, client); int Bot_mtbs = 500; //Время между сканированием сообщений long Bot_lasttime; //last time messages' scan has been done bool Start = false; //Пин запроса const int Pin = 13; int ch = 0; String val = ""; String TempWater = ""; //темп. воды String TempOut = ""; //темп. улицы String h = ""; //влажность комнаты String t = ""; //темп. комнаты String val135 = ""; //качество воздуха String val4 = ""; //природный газ String Potop = ""; //уровень воды String flame = ""; //датчик пламени String reason = ""; //причина отправки void handleNewMessages(int numNewMessages) { for (int i = 0; i < numNewMessages; i++) { String chat_id = String(bot.messages[i].chat_id); String text = bot.messages[i].text; String from_name = bot.messages[i].from_name; if (from_name == "") from_name = "Guest"; if ((chat_id == "") & (text == "Sensors")) { digitalWrite(Pin, HIGH); delay (5000); digitalWrite(Pin, LOW); bot.sendMessage(chat_id, "Запрос отправлен, ожидайте", "Markdown"); } if (text == "/start") { String welcome = "Приветствую в информационном центре котельной, " + from_name + "!\n"; welcome += "Я выслал тебе кнопку для запроса состояния\n"; String keyboardJson = "[[\"Sensors\"]]"; bot.sendMessageWithReplyKeyboard(chat_id, welcome, "", keyboardJson, true); } } } void setup() { Serial.begin(9600); WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } pinMode(Pin, OUTPUT); delay(10); digitalWrite(Pin, LOW); } void loop() { String chat_id = ""; ch = 0; while (Serial.available()) { ch = Serial.read(); if (ch == 'r') break; if (ch == 'k') break; if (ch == 'w') break; if (ch == 'o') break; if (ch == 'h') break; if (ch == 'f') break; if (ch == 'q') break; if (ch == 'g') break; if (ch == 'p') break; if (ch == '#') break; val += char(ch); } //Причина отправки if (ch == 'r') { reason = val; val = ""; } //Температура котельной if (ch == 'k') { t = val; val = ""; } //температура воды if (ch == 'w') { TempWater = val; val = ""; } //температура на улице if (ch == 'o') { TempOut = val; val = ""; } //влажность котельной if (ch == 'h') { h = val; val = ""; } //пламя if (ch == 'f') { flame = val; if (flame == "z") { flame = "Датчик пламени сработал!"; } if (flame == "x") { flame = "Датчик пламени в покое"; } val = ""; } //качество воздуха if (ch == 'q') { val135 = val; val = ""; } //природный газ if (ch == 'g') { val4 = val; val = ""; } //датчик протечки if (ch == 'p') { Potop = val; val = ""; } //конец передачи if (ch == '#') { String welcome = reason + "\n"; welcome += "Температура котельной: " + t + " °C\n"; welcome += "Температура воды: " + TempWater + " °C\n"; welcome += "Температура на улице: " + TempOut + " °C\n"; welcome += "Влажность котельной: " + h + " %\n"; welcome += flame + " \n"; welcome += "Качество воздуха: " + val135 + " ед.\n"; welcome += "Природный газ: " + val4 + " ед.\n"; welcome += "Датчик протечки: " + Potop + " ед.\n"; bot.sendMessage(chat_id, welcome, "Markdown"); val = ""; } if (millis() > Bot_lasttime + Bot_mtbs) { int numNewMessages = bot.getUpdates(bot.last_message_received + 1); while (numNewMessages) { handleNewMessages(numNewMessages); numNewMessages = bot.getUpdates(bot.last_message_received + 1); } Bot_lasttime = millis(); } }Результат: