Отправка 6 переменных в одном СМС с помощью SIM800L
- Войдите на сайт для отправки комментариев
Всем привет! Прошу сильно не пинать, так как я новичок! Третий день ломаю голову и не могу решить проблему: имеется Arduino Uno с подключенными датчиками (температуры и влажности воздуха, освещения, влажности почвы, температуры почвы, открытой форточки) и модулем SIM800L. Необходимо сделать так, чтобы при получении модулем СМС с цифрой "1" включалось реле на несколько секунд для полива, а при получении СМС с цифрой "2" модуль отправлял в ответ СМС, в котором бы высылались 6 переменных с показаниями, снимаемыми с датчиков (температура, влажность и т.д.).
Чтобы не усложнять ситуацию, пока тренируюсь на датчике DHT22, пробуя отправить в СМС всего две переменных. Но, пока что максимум, чего смог добится - это отправки какого-то одного показателя, а вот как вывести сразу два (температура и влажность)?
#include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу SoftwareSerial SIM800(8, 9); // RX, TX #include "DHT.h" //dht22 #define DHTPIN 2 //dht22 #define DHTTYPE DHT22 //dht22 DHT dht(DHTPIN, DHTTYPE); //dht22 int pins = 5; // Пин с подключенным реле String _response = ""; // Переменная для хранения ответа модуля long lastUpdate = millis(); // Время последнего обновления long updatePeriod = 60000; // Проверять каждую минуту String phones = "+7920269****"; // Белый список телефонов void setup() { dht.begin(); //dht pinMode(pins, OUTPUT); // Настраиваем пины в OUTPUT digitalWrite(pins, HIGH); // Изначально реле выключено Serial.begin(9600); // Скорость обмена данными с компьютером SIM800.begin(9600); // Скорость обмена данными с модемом Serial.println("Start!"); sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память // Команды настройки модема при каждом запуске sendATCommand("AT+CMGF=1;&W", true); // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)! lastUpdate = millis(); // Обнуляем таймер } String sendATCommand(String cmd, bool waiting) { String _resp = ""; // Переменная для хранения результата Serial.println(cmd); // Дублируем команду в монитор порта SIM800.println(cmd); // Отправляем команду модулю if (waiting) { // Если необходимо дождаться ответа... _resp = waitResponse(); // ... ждем, когда будет передан ответ // Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду _resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2); } Serial.println(_resp); // Дублируем ответ в монитор порта } return _resp; // Возвращаем результат. Пусто, если проблема } String waitResponse() { // Функция ожидания ответа и возврата полученного результата String _resp = ""; // Переменная для хранения результата long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... if (SIM800.available()) { // Если есть, что считывать... _resp = SIM800.readString(); // ... считываем и запоминаем } else { // Если пришел таймаут, то... Serial.println("Timeout..."); // ... оповещаем об этом и... } return _resp; // ... возвращаем результат. Пусто, если проблема } bool hasmsg = false; // Флаг наличия сообщений к удалению void loop() { float h = dht.readHumidity(); //DHT float t = dht.readTemperature(); //DHT Serial.print("Humidity: "); //DHT // выводим данные температуры и влажности в Serial Serial.print(h);//DHT Serial.print(" %\t");//DHT Serial.print("Temperature: "); //DHT Serial.print(t);//DHT Serial.println(" *C");//DHT if (lastUpdate + updatePeriod < millis() ) { // Пора проверить наличие новых сообщений do { _response = sendATCommand("AT+CMGL=\"REC UNREAD\",1", true);// Отправляем запрос чтения непрочитанных сообщений if (_response.indexOf("+CMGL: ") > -1) { // Если есть хоть одно, получаем его индекс int msgIndex = _response.substring(_response.indexOf("+CMGL: ") + 7, _response.indexOf("\"REC UNREAD\"", _response.indexOf("+CMGL: "))).toInt(); char i = 0; // Объявляем счетчик попыток do { i++; // Увеличиваем счетчик _response = sendATCommand("AT+CMGR=" + (String)msgIndex + ",1", true); // Пробуем получить текст SMS по индексу _response.trim(); // Убираем пробелы в начале/конце if (_response.endsWith("OK")) { // Если ответ заканчивается на "ОК" if (!hasmsg) hasmsg = true; // Ставим флаг наличия сообщений для удаления sendATCommand("AT+CMGR=" + (String)msgIndex, true); // Делаем сообщение прочитанным sendATCommand("\n", true); // Перестраховка - вывод новой строки parseSMS(_response); // Отправляем текст сообщения на обработку break; // Выход из do{} } else { // Если сообщение не заканчивается на OK Serial.println ("Error answer"); // Какая-то ошибка sendATCommand("\n", true); // Отправляем новую строку и повторяем попытку } } while (i < 10); break; } else { lastUpdate = millis(); // Обнуляем таймер if (hasmsg) { sendATCommand("AT+CMGDA=\"DEL READ\"", true); // Удаляем все прочитанные сообщения hasmsg = false; } break; } } while (1); } if (SIM800.available()) { // Если модем, что-то отправил... _response = waitResponse(); // Получаем ответ от модема для анализа _response.trim(); // Убираем лишние пробелы в начале и конце Serial.println(_response); // Если нужно выводим в монитор порта if (_response.indexOf("+CMTI:") > -1) { // Пришло сообщение об отправке SMS lastUpdate = millis() - updatePeriod; // Теперь нет необходимости обрабатываеть SMS здесь, достаточно просто // сбросить счетчик автопроверки и в следующем цикле все будет обработано } } if (Serial.available()) { // Ожидаем команды по Serial... SIM800.write(Serial.read()); // ...и отправляем полученную команду модему }; } void parseSMS(String msg) { // Парсим SMS String msgheader = ""; String msgbody = ""; String msgphone = ""; msg = msg.substring(msg.indexOf("+CMGR: ")); msgheader = msg.substring(0, msg.indexOf("\r")); // Выдергиваем телефон msgbody = msg.substring(msgheader.length() + 1); // правил + 1. Было ( msgbody = msg.substring(msgheader.length() + 2);) msgbody = msgbody.substring(0, msgbody.lastIndexOf("OK")); // Выдергиваем текст SMS msgbody.trim(); int firstIndex = msgheader.indexOf("\",\"") + 3; int secondIndex = msgheader.indexOf("\",\"", firstIndex); msgphone = msgheader.substring(firstIndex, secondIndex); Serial.println("Phone: " + msgphone); // Выводим номер телефона Serial.println("Message: " + msgbody); // Выводим текст SMS if (msgphone.length() > 6 && phones.indexOf(msgphone) > -1) { // Если телефон в белом списке, то... setLedState(msgbody, msgphone); // ...выполняем команду } else { Serial.println("Unknown phonenumber"); } } void setLedState (String result, String phone) { bool correct = false; // Для оптимизации кода, переменная корректности команды String msgToSend = ""; if (result.length() == 1) { int ledIndex = ((String)result[0]).toInt(); // Получаем первую цифру команды if (ledIndex == 1 ) // Если все нормально, исполняем команду { float t = dht.readTemperature(); //DHT int SMSTEMP = t; //DHT //digitalWrite(pins, LOW); // Включаем реле Serial.println("Otpravka SMS Temp"); delay(3000); // Ждем 3 секунды sendSMS("+7920269****", String (SMSTEMP)); correct = true; // Флаг корректности команды } if (ledIndex == 2 ) // Если все нормально, исполняем команду { digitalWrite(pins, LOW); // Включаем реле Serial.println("POLIV 2!"); delay(3000); // Ждем 3 секунды digitalWrite(pins, HIGH); // Выключаем реле Serial.println("POLIV 2 OKONCHEN"); sendSMS("+7920269****", "POLIV 2 OKONCHEN"); delay(5000); correct = true; // Флаг корректности команды } } if (!correct) { msgToSend = "Incorrect command: " + result; // Статус исполнения } Serial.println(msgToSend); // Выводим результат в терминал } void sendSMS(String phone, String message) { sendATCommand("AT+CMGS=\"" + phone + "\"", true); // Переходим в режим ввода текстового сообщения sendATCommand(message + "\r\n" + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z }
Прошу сильно не пинать, так как я новичок!
Объясните мне, с какого перепугу Вас нельзя пинать? Потому, что Вы новичок? А кого прикажете пинать? Заслуженных ветеранов? У Вас с логикой всё нормально? Как раз новичков и надо пороть, чтобы ума набирались.
Третий день ломаю голову
А сюда чего пришли? Поломайте месяца три, проблема и решится, так хоть Вам польза будет.
Чтобы не усложнять ситуацию .... пока что максимум, чего смог добится - это отправки какого-то одного показателя
Чтобы не усложнять ситуацию, объясню Вам, что человек, который не может отправить две переменные в сообщении, в принципе, ни за какие коврижки, не способен написать код, который Вы привели. Код это не Ваш. А потому, всё, "чего Вы смогли добиться" - это стырить готовый код (вот здесь, возможно) и ни хрена в нём не понять.
Поэтому, давайте поступим так. Берите книжку. Хоть вот эту - она написана проще некуда - для совсем уж альтернативно одарённых. Изучайте, разбирайтесь. Потом напишите свой код отправки Ваших переменных и, если с ним будут проблемы, приходите, Вам помогут (я сам с удовольствием помогу).
А изменять для Вас чужой код, который Вы не только не писали, но даже и не понимаете - увольте. Сильно нужно - топайте в раздел "Ищу исполнителя" и заказывайте за деньги.
А я разве говорил, что код мой? Именно там, где Вы сказали я его и взял, теперь пытаюсь упростить под свои нужды, пока безуспешно. За книжку спасибо, почитаем!
А я разве говорил, что код мой?
Конечно. "чего смог добится" по мне это означает, что Вы добились, а не автор кода, которого Вы даже не поняли.