Формирование строки текста тела email сообщения
- Войдите на сайт для отправки комментариев
Ср, 19/12/2018 - 19:45
Есть задача отправлять по емейлу через GPRS показания датчиков температуры и влажности + время
В наличии:
ДАТЧИК ТЕМПЕРАТУРЫ DS18B20
ДАТЧИК ТЕМПЕРАТУРЫ И ВЛАЖНОСТИ DHT22
GSM модуль SIM800L
модуль ЧРВ на базе чипа DS3231
Не могу сформировать строку текста тела сообщения.
С отправкой СМС строка работает и СМС приходит как нужно, с мылом сбоит. Компиляция проходит, а вот после загрузки в Ардуино мыло не отправляется. Если выбросить блок формирования тела сообщения - письмо уходит.
sendATCommand("AT+SMTPBODY=75", true); // количество символов сообщения
String (Time) = time.gettime("d-m-Y, H:i:s");
float h = dht.readHumidity(); // влажность
float t_out = dht.readTemperature(); // температура внешняя
detectTemperature(); // Определяем внешнюю температуру от датчика DS18b20
String (message) = (String (Time) + ";" + "Ves: " + String(scale_dat, 3) + "kg" + ";" + " t out:" + String(t_out, 3) + "*C" + ";" + " Vlagnost:" + String(h, 3) + "%" + ";" + " t in:" + String(temperature2, 3) + "*C");
sendATCommand(message + "\r\n" + (String)((char)26), true); //После получение ответа от модуля DOWNLOAD. вводим текст письма
//Для отправки в конце сообщения отправляем символ SUB ( (char)26 или Cntrl+Z)
sendATCommand("AT+SMTPSEND", true); // отправка email
int detectTemperature()
{
byte data[2];
ds.reset();// Начинаем взаимодействие со сброса всех предыдущих команд и параметров
ds.write(0xCC); // Даем датчику DS18b20 команду пропустить поиск по адресу. В нашем случае только одно устрйоство
ds.write(0x44); // Даем датчику DS18b20 команду измерить температуру.
// Само значение температуры мы еще не получаем - датчик его положит во внутреннюю память
if (millis() - lastUpdateTime > TEMP_UPDATE_TIME)
{
lastUpdateTime = millis();
ds.reset();
ds.write(0xCC);
ds.write(0xBE); // Просим передать нам значение регистров со значением температуры
data[0] = ds.read(); // Читаем младший байт значения температуры
data[1] = ds.read(); // А теперь старший
// Формируем значение
temperature = (data[1] << 8) + data[0]; temperature = temperature >> 4;
// Формируем итоговое значение:
// - сперва "склеиваем" значение,
// - затем умножаем его на коэффициент, соответсвующий разрешающей способности (для 12 бит по умолчанию - это 0,0625)
float temperature2 = ((data[1] << 8) | data[0]) * 0.0625;
// Выводим полученное значение температуры в монитор порта
Serial.println(temperature2);
А где формирование сообщения?
Ну собственно это по идее должно работать так:
Берем данные с датчиков,
и формируем message для Email
String (message) = (String (Time) +";"+" t out:"+ String(t_out, 3) +"*C"+";"+" Vlagnost:"+ String(h, 3) +"%"+";"+" t in:"+ String(temperature2, 3) +"*C");потом передаем через функцию sendATCommand в SIM800.
Код строю на основе кода этого парня http://codius.ru/articles/GSM_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8C_SIM800L_%D1%87%D0%B0%D1%81%D1%82%D1%8C_2
Код Виктора работает идеально. Мне нравится.
С отправкой мыла у меня трабл только в строчке тела сообщения.
Так "по идее"? Или у Вас есть код? Ничего не понял. Если есть, так чего не выложить? Если есть только идеи, так реализуйте.
Ну и зачем нужно было себя так утруждать таким ответом? Нужна всего 1 текстовая строчка, которую нужно сформировать с данных датчиков. Зачем захламлять большим кодом?
Код конечно есть.
#include <SoftwareSerial.h> #include <iarduino_RTC.h> #include <OneWire.h> #include <DHT.h> #include <DHT_U.h> iarduino_RTC time(RTC_DS3231); // Объявляем объект time для модуля на базе чипа DS3231 SoftwareSerial SIM800(8, 9); // RX — 9, TX -8 String _response = ""; // Переменная для хранения ответа модуля OneWire ds(10); // Создаем объект OneWire для шины 1-Wire, с помощью которого будет осуществляться работа с датчиком int temperature = 0; // Глобальная переменная для хранения значение температуры с датчика DS18B20 long lastUpdateTime = 0; // Переменная для хранения времени последнего считывания с датчика const int TEMP_UPDATE_TIME = 2000; // Определяем периодичность проверок #define DHTPIN 2 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); // для весов, датчика температуры ds18b20, датчика температуры DHT22 time.begin(); // Инициируем RTC модуль dht.begin(); Serial.begin(9600); //Скорость сериал порта SIM800.begin(9600); //Скорость порта для связи ARDUINO NANO c SIM800l } void loop() { if (time.minutes == 00 && time.seconds == 0) { sendATCommand("AT+CFUN=1,1", true); // перезагрузка модуля при запуске sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными //Настройки интернет соединения sendATCommand("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", true); // задаем команду выхода в интернет sendATCommand("AT+SAPBR=3,1,\"APN\",\"internet\"", true); // настройки APN Vodafone sendATCommand("AT+SAPBR=1,1", true); // To open a GPRS context. установить GPRS соединение //Настройки для отправки e-mail : //Настройки для отправки e-mail : sendATCommand("AT+EMAILCID=1", true); // Установка CID параметра для email сессии. sendATCommand("AT+EMAILTO=30", true); // Set EMAIL timeout Установка таймаута для SMTP и POP серверов. sendATCommand("AT+EMAILSSL=0", true); sendATCommand("AT+SMTPSRV=\"SMTP.GMAIL.COM\"", true); // Установка адреса и порта SMTP почтового сервера. sendATCommand("AT+SMTPAUTH=1,\"*****@gmail.com\",\"******\"", true); // Аутентификация (e-mail адрес, и пароль от e-mail) sendATCommand("AT+SMTPFROM=\"******@gmail.com\",\"*****\"", true); //от кого письмо (почтовый адрес, имя отправителя) sendATCommand("AT+SMTPSUB=\"Test\"", true); //тема письма sendATCommand("AT+SMTPRCPT=0,0,\"******@gmail.com\",\"*******\"", true); // кому письмо (почтовый адрес, имя получателя) sendATCommand("AT+SMTPBODY=75", true); String (Time) = time.gettime("d-m-Y, H:i:s"); float h = dht.readHumidity(); // влажность float t_out = dht.readTemperature(); // температура внешняя int temperature2 = detectTemperature(); // Определяем внутреннюю температуру от датчика DS18b20 - temperature2 String (message) = (String (Time) + "; + " t out:" + String(t_out, 3) + "*C" + ";" + " Vlagnost:" + String(h, 3) + "%" + ";" + " t in:" + String(temperature2, 3) + "*C"); sendATCommand(message + "\r\n" + (String)((char)26), true); //После получение ответа от модуля DOWNLOAD. вводим текст письма длиной 19 символов. //Для отправки в конце сообщения отправляем символ SUB ( (char)26 или Cntrl+Z) sendATCommand("AT+SMTPSEND", true); // Отправка Email sendATCommand("AT+SAPBR=0,1", true); // разорвать GPRS соединение } } int detectTemperature() { byte data[2]; ds.reset();// Начинаем взаимодействие со сброса всех предыдущих команд и параметров ds.write(0xCC); // Даем датчику DS18b20 команду пропустить поиск по адресу. В нашем случае только одно устрйоство ds.write(0x44); // Даем датчику DS18b20 команду измерить температуру. // Само значение температуры мы еще не получаем - датчик его положит во внутреннюю память if (millis() - lastUpdateTime > TEMP_UPDATE_TIME) { lastUpdateTime = millis(); ds.reset(); ds.write(0xCC); ds.write(0xBE); // Просим передать нам значение регистров со значением температуры data[0] = ds.read(); // Читаем младший байт значения температуры data[1] = ds.read(); // А теперь старший // Формируем значение temperature = (data[1] << 8) + data[0]; temperature = temperature >> 4; // Формируем итоговое значение: // - сперва "склеиваем" значение, // - затем умножаем его на коэффициент, соответсвующий разрешающей способности (для 12 бит по умолчанию - это 0,0625) float temperature2 = ((data[1] << 8) | data[0]) * 0.0625; // Выводим полученное значение температуры в монитор порта //Serial.println(temperature2); } } 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; // ... возвращаем результат. Пусто, если проблема }Ну и зачем нужно было себя так утруждать таким ответом? Нужна всего 1 текстовая строчка, которую нужно сформировать с данных датчиков. Зачем захламлять большим кодом?
Вы решили поуить меня, как Вам помогать?
Я, знаете ли, здесь давно и видел такие вещи, как "чтение аналогового сигнала с пина ресет", "использование для хранения данных переменной, которая обнуляется при каждом проходе loop", запись в память по "неинициализированныму указателю", и т.д., до фига всего.
Вот когда Вы потрахаетесь полндя с тем, что у шибко умного новичка контроллер спонтанно перегружается, пялясь в клочок вполне нормального кода, а через часы траха узнаете, что он просто с ресета читает, вот тогда будете меня учить. А сейчас: я смотрю только полный код и никогда не смотрю куски. Это моё правило - "не хочете, не ешьте".
Вот, выложили полностью, сейчас попробую посмотреть
никого я учить не собирался. наоборот попросил меня научить.
Свою позицию я озвучил - не загромождать. Нужно было сначала сказать зачем весь код, а не "так реализуйте."
Заранее спасибо что посмотрите.
Видимо, Вы пошутили, что
Просто посчитайте кавычки в строке №61 - их там нечётное количество.
В общем, или выкладывайте нормальный код, или решайте свои проблемы самостоятельно.
Нужно было сначала сказать зачем весь код,
Да, нет, нужно было на просьбу выложить код, просто выложить код, а не начинать "Ну и зачем нужно было ...".
Строка 14 - переменная имеет неправильный тип, надо unsigned long. Почему - да потому что у millis() какое возвращаемое значение?
Все строки - во флеш, макросом F().
Строка 107 - объект типа String передаётся по значению, а надо - по ссылке, тогда не будет ненужной работы с оперативкой.
Строка 127 - опять неправильный тип переменной.
Строка 128 - условие будет неправильно работать при пееполнении millis(), т.е. при условии, когда millis() + 10000 - даст переход через 0. Источник трудноуловимых глюков раз в 50 дней :)
ЕвгенийП Компиляция проходит если выбросить 2 строчки тела сообщения.
String (message) = (String (Time) + "; + " t out:" + String(t_out, 3) + "*C" + ";" + " Vlagnost:" + String(h, 3) + "%" + ";" + " t in:" + String(temperature2, 3) + "*C");
вам же уже сказали - число кавычек посчитайте. Неужели и кавычки сами расставить не можете?
ЕвгенийП Компиляция проходит если выбросить 2 строчки тела сообщения.
String (message) = (String (Time) + "; + " t out:" + String(t_out, 3) + "*C" + ";" + " Vlagnost:" + String(h, 3) + "%" + ";" + " t in:" + String(temperature2, 3) + "*C");
Так я Вам и ответил - посчитайте кавычки.
А заодно, ответьте, пожалуйста, что значают глубокомысленные записи типа:
String (message)
String (Time)
Вот, просто скажите,что они по Вашему означают?
Берусь предположить, что Вы вообще, от слова совсем, не знаете как пишутся программы на этом языке и ни одной буквы не понимаете в том. что пытаетесь писать, а делаете это методом тыка, по образу и подобию. Боюсь Вас огорчить, но так не получится.
А обратились Вы сюда не для того,чтобы Вам указали на ошибки, адля того, чтобы написали за Вас. Если так, то не по адресу - здесь есть раздел "Ищу исполнителя".