Arduino_Nano+SIM800L
- Войдите на сайт для отправки комментариев
Чт, 17/06/2021 - 13:44
Приветствую!
Изучаю работу с SIM800L, , для начала работу с АТ-командами.
На примере этого скетча:
#include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу
SoftwareSerial SIM800(11, 10); // RX, TX
// Макроопределения выводов микроконтроллера
#define PIN_LED_RED A2 // Красный цвет RGB-светодиода
#define PIN_LED_GREEN A1 // Зелёный цвет RGB-светодиода
#define PIN_LED_BLUE A0 // Голубой цвет RGB-светодиода
String _response = ""; // Переменная для хранения ответа модуля
void setup() {
Serial.begin(9600); // Скорость обмена данными с компьютером
SIM800.begin(9600); // Скорость обмена данными с модемом
Serial.println("Start!");
pinMode(PIN_LED_RED, OUTPUT); digitalWrite(PIN_LED_RED, LOW);
pinMode(PIN_LED_GREEN, OUTPUT); digitalWrite(PIN_LED_GREEN, LOW);
pinMode(PIN_LED_BLUE, OUTPUT); digitalWrite(PIN_LED_BLUE, LOW);
//sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными
// Команды настройки модема при каждом запуске
_response = sendATCommand("AT+CLIP=1", true); // Включаем АОН
_response = sendATCommand("AT+DDET=1", true); // Включаем DTMF
_response = sendATCommand("AT", true); // Проверка общего статуса
if( _response == "OK") {
digitalWrite(PIN_LED_GREEN, HIGH);
}
else {
digitalWrite(PIN_LED_RED, HIGH);
}
}
//Функции
String sendATCommand(String cmd, bool waiting) { // Функция посылки AT-команды модулю SIM800L
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; // ... возвращаем результат. Пусто, если проблема
}
void loop() {
if (SIM800.available()) {
Serial.write(SIM800.read());
}
if (Serial.available()) {
SIM800.write(Serial.read());
}
}
после загрузки в ардуино загорается красный светодиод. а по идее
должен зеленый. Почему? Команды с терминала работают.
Вивод в терминал после загрузки скетча

Получается что в глобальной переменной _response пустая строка, а ответ от модуля "ОК" есть
про служебные символы ASCII что-нибудь слышали?
На картинке терминала отлично видно, что в ответ приходит не "OK", а что-то типа "OK\n", поэтому условие в строке 28 не срабатывает.
Вообще, проверять приходящие с модема символы на точное равенство условием ответ == "ОК" - плохая идея. используйте лучше индекс
а 45 строка в функции набора команд убирает \r\n(там только \r, но я добавлял \n, но
все равно не получается)
а 45 строка в функции набора команд убирает \r\n
нет, не убирает. Эта функция работает только в том случае, если у вас ответ НАЧИНАЕТСЯ с посланной команды. А конечные \r\n она не вырезает.
Да и вообще, нафига заниматься вырезанием ненужных символов. лучше ищите нужные...
а у меня Echo Mode не выключен , получается что ответ начинается з посланой команды.
скажите пожалуйста, что делает эта строчка:
_resp = _resp.substring(_resp.indexOf("\r\n", cmd.length()) + 2);что-то никак не пойму
а у меня Echo Mode не выключен , получается что ответ начинается з посланой команды.
вы не поняли, тут без разницы, начинается у вас ответ с команды или нет - в любом случае эта строчка концевые \r\n не убирает.
_resp = _resp.substring(_resp.indexOf("\r\n", cmd.length()) + 2);что-то никак не пойму
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/substring/
если в условии вместо "==" поставить "indexOf", то работает.
еще спрошу, есть глобальная переменная для хранение результата ответа модуля _response, и есть локальная переменная _resp тоже для хранения результата ответа модуля внутри функций. Функции возвращают переменную _resp, А в условии setup фигурирует _response. Зачем две переменные для хранения результата ответа модуля? Может нужна только _response?
еще спрошу, есть глобальная переменная для хранение результата ответа модуля _response, и есть локальная переменная _resp тоже для хранения результата ответа модуля внутри функций. Функции возвращают переменную _resp, А в условии setup фигурирует _response. Зачем две переменные для хранения результата ответа модуля? Может нужна только _response?
с точки зрения хорошего стиля программирования правильнее будет _response тоже сделать локальной внутри setup().
А точки зрения эффективености. честно говоря, не знаю