Бесплатная отправка SMS из Arduino без GSM модуля

68fbc66f860c4bacb93f11f88d479992Понадобилось мне слать SMS из ардуинины себе на телефон. Да так, что бы без заморочек с GSM, сим картами и оплатой. Под катом то, что из этого вышло.Раз GSM не подходит, то слать придется через интернет. В закромах имелся сверх дешевый Wi-Fi модуль ESP8266. Про его предварительную настройку можно почитать в этой отличной статье ссылка.Перво-наперво полез гуглить различные интернет-сервисы для отправки SMS. Сервисов оказалось много, но вот подходящего среди них не оказалось. Либо 10 SMS в день, либо хотят денег. Да и капчи ардуинине не по зубам. Но тут совершенно случайно наткнулся на на интересный сервис своего мобильного оператора (MTS BY) — всего за 1$ можно подключить услугу приема email в виде SMS ссылка. Что же, полностью бесплатно не получилось, и после оплаты я получил почтовый адрес вида 375XXYYYYYYY@sms.mts.by (где XX и YYYYYYY — код сети и номер). То есть все свелось к банальной отправке email из arduino.Но не тут-то было. Оказывается в последнее время все уважающие себя почтовые сервера отказываются принимать почту по 25 порту и без шифрования. А с другими связываться не хотелось, как и привязываться к своему домашнему серверу. Нагуглил вот такой сервис ссылка. В базовом бесплатном варианте дают 6к писем в месяц, что для моего домашнего использования хватает с головой. После регистрации идем в настройки и видим адрес smtp сервера, порт, логин и сгенерированный нам пароль.Быстро накатал скетч, отправляю email 375XXYYYYYYY@sms.mts.by и… Облом. Отправляю на обычную почту — приходит. Пытался так и эдак переделывать заголовок — все равно письма исчезают в безднах серверов МТС, явно попадая в котел спам фильтра.Значит нужно «отмыть» почту. В качестве сервиса отмывки выбрал (тихо ненавидимый мною за рекламу) mail.ru. Для отмывки в настройках почты, в разделе «Фильтры и пересылка», создал новое правило: Настройки 2a5b417cb5ae4441a6747cd98fac9cc8 После создания фильтра его понадобилось активировать введя код, пришедший в виде email-SMS на телефон.Вот и момент триумфа — отправляю email из ардуинины, и через минуту телефон раздается радостным сигналом оповещения, при этом пугая проходящего рядом кота.Далее скучные технические подробности.В качестве платы взял Arduino Mega 2560, так как в нем целых три дополнительных последовательных порта (хотя можно и обычный UNO, только дебажить будет сложнее).ESP8266 подключен: GND → GND, VCC и CH_PD → +3.3V, RX → TX3, TX → RX3. Скорость ESP8266 настроена на 115200 бод.Для общения с smtp сервером нужно закодировать свои логин и пароль в Base64.Можно воспользоваться консолью Linux: openssl enc -base64 <<< 'email@gmail.com'openssl enc -base64 <<< 'password'Или же каким-либо онлайн сервисом, например ссылка.Ну и собственно код скетча. После включения отправляется СМС и код уходит в вечный цикл. Дополнительные библиотеки не использовал.

Код #define SSID «wi-fi_login» // ваш SSID #define PASS «wi-fi_password» // ваш пароль Wi-Fi

#define SMTPServer «s02.atomsmtp.com» //smtp сервер #define SMTPPort »2525» // smtp порт #define MailLogin «smtp_example@gmail.com» // логин для smtp #define MailLoginBase64 «dWd1LCBrb25lNG5vCg==» //логин для smtp в Base64 #define MailPasswordBase64 «aHJlbiB0YW0K» // пароль для smtp в Base64 #define MailRelay «example@mail.ru» // промежуточная почта для «отмывания» email #define PhoneNumber »375290000000» // номер телефона #define Message «Hello from Arduino!» //сообщение

#define SERIAL_RX_BUFFER_SIZE 256 #define SERIAL_TX_BUFFER_SIZE 256

void setup () { delay (2000); Serial3.begin (115200); Serial3.setTimeout (5000); Serial.begin (115200); // для отладки Serial.println («Init»); Serial3.println («AT+RST»); // сброс и проверка, что модуль готов if (WiteString («Ready», 5000)) { while (Serial3.available ()) { Serial3.read ();} Serial.println («WiFi — Module is ready»); }else{ Serial.println («Module dosn’t respond.»); while (1); } delay (100);

Serial3.println (» AT+CIPMODE=0»); WiteString («OK»); while (Serial3.available ()) { Serial3.read ();}

Serial3.println («AT+CIPMUX=1»); WiteString («OK»); while (Serial3.available ()) { Serial3.read ();}

// try to connect to wifi boolean connected = false; for (int i=0; i<5;i++) { if(connectWiFi()) { connected = true; break; } } if (!connected) { while(1); } } void loop() { String cmd = "AT+CIPSTART=0,\"TCP\",\""; cmd += String(SMTPServer); cmd += "\"," + String(SMTPPort); Serial3.println(cmd);

if (WiteString («Linked», 5000)) { while (Serial3.available ()) { Serial3.read ();} Serial.println («Link»); } else { Serial.println («Link fail»); while (1); }

if (WiteString («OK», 2000)) { while (Serial3.available ()) { Serial3.read ();} } else { while (1); } Send («HELO 1.2.3.4», true); Send («AUTH LOGIN», true); Send (MailLoginBase64, true); Send (MailPasswordBase64, true); Send («MAIL FROM: <" + String(MailLogin) + ">», true); Send («RCPT TO: <" + String(MailRelay) + ">», true); Send («DATA», true); Send («Subject: SMS», false); Send («To:\» + String (PhoneNumber) + »\» <" + String(PhoneNumber) + "@sms.mts.by>», false); Send («From: <" + String(MailLogin) + ">», false); Send (», false); Send (Message, false); Send (».», true); Send («QUIT», true);

while (1) {}; } boolean connectWiFi () { Serial3.println («AT+CWMODE=1»); while (! Serial3.available ()) { delay (10);} while (Serial3.available ()) {Serial3.read ();} String cmd=«AT+CWJAP=\»; cmd+=SSID; cmd+=»\»,\»; cmd+=PASS; cmd+=»\»; Serial3.println (cmd);

if (WiteString («OK», 8000)){ Serial.println («Connected to WiFi.»); return true; }else{ Serial.println («Can not connect to the WiFi.»); return false; } }

bool Send (String S, bool wite) { Serial3.print («AT+CIPSEND=0,»); Serial3.println (S.length ()+2); while (! Serial3.available ()) { delay (10);} if (Serial3.find (»>»)){ }else{ Serial3.println («AT+CIPCLOSE=0»); delay (1000); return false; } Serial3.print (S + »\r\n»);//добаяляем перевод строки if (WiteString («OK», 15000)) { if (wite) { WiteString (»+IPD», 15000); while (Serial3.available ()) { Serial3.read ();}} return true;} else { return false;} }

void WiteString (String S) { int L = S.length (); String T = String (» »); while (1) { if (Serial3.available ()) { char c = Serial3.read (); T = T + String©; if (T.length () > L) T = T.substring (1); if (S.charAt (0) == T.charAt (0)) if (S.compareTo (T) == 0) return; } else { delay (1); } } }

bool WiteString (String S, int Time) { int L = S.length (); String T = String (» »); while (Time>0) { if (Serial3.available ()) { char c = Serial3.read (); T = T + String©; if (T.length () > L) T = T.substring (1); if (S.charAt (0) == T.charAt (0)) if (S.compareTo (T) == 0) return true; } else { delay (1); Time--; } } return false; }

String WiteString (int Time) { String T = String (»); while (Time>0) { if (Serial3.available ()) { char c = Serial3.read (); T = T + String©; } else { delay (1); Time--; } } return T; }

© Habrahabr.ru