Отправка 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
}
Прошу сильно не пинать, так как я новичок!
Объясните мне, с какого перепугу Вас нельзя пинать? Потому, что Вы новичок? А кого прикажете пинать? Заслуженных ветеранов? У Вас с логикой всё нормально? Как раз новичков и надо пороть, чтобы ума набирались.
Третий день ломаю голову
А сюда чего пришли? Поломайте месяца три, проблема и решится, так хоть Вам польза будет.
Чтобы не усложнять ситуацию .... пока что максимум, чего смог добится - это отправки какого-то одного показателя
Чтобы не усложнять ситуацию, объясню Вам, что человек, который не может отправить две переменные в сообщении, в принципе, ни за какие коврижки, не способен написать код, который Вы привели. Код это не Ваш. А потому, всё, "чего Вы смогли добиться" - это стырить готовый код (вот здесь, возможно) и ни хрена в нём не понять.
Поэтому, давайте поступим так. Берите книжку. Хоть вот эту - она написана проще некуда - для совсем уж альтернативно одарённых. Изучайте, разбирайтесь. Потом напишите свой код отправки Ваших переменных и, если с ним будут проблемы, приходите, Вам помогут (я сам с удовольствием помогу).
А изменять для Вас чужой код, который Вы не только не писали, но даже и не понимаете - увольте. Сильно нужно - топайте в раздел "Ищу исполнителя" и заказывайте за деньги.
А я разве говорил, что код мой? Именно там, где Вы сказали я его и взял, теперь пытаюсь упростить под свои нужды, пока безуспешно. За книжку спасибо, почитаем!
А я разве говорил, что код мой?
Конечно. "чего смог добится" по мне это означает, что Вы добились, а не автор кода, которого Вы даже не поняли.