Arduino_Nano+SIM800L

akkinak
Offline
Зарегистрирован: 24.09.2012

Приветствую!

Изучаю работу с 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 пустая строка, а ответ от модуля "ОК" есть

 

b707
Offline
Зарегистрирован: 26.05.2017

про служебные символы ASCII что-нибудь слышали?

На картинке терминала отлично видно, что в ответ приходит не "OK", а что-то типа  "OK\n", поэтому условие в строке 28 не срабатывает.

Вообще, проверять приходящие с модема символы на точное равенство условием ответ == "ОК" - плохая идея. используйте лучше индекс

akkinak
Offline
Зарегистрирован: 24.09.2012

а 45 строка в функции набора команд убирает \r\n(там только \r, но я добавлял \n, но

все равно не получается)

b707
Offline
Зарегистрирован: 26.05.2017

akkinak пишет:

а 45 строка в функции набора команд убирает \r\n

нет, не убирает. Эта функция работает только в том случае, если у вас ответ НАЧИНАЕТСЯ с посланной команды. А конечные \r\n она не вырезает.

Да и вообще, нафига заниматься вырезанием ненужных символов. лучше ищите нужные...

akkinak
Offline
Зарегистрирован: 24.09.2012

а у меня Echo Mode не выключен , получается что ответ начинается з посланой команды.

скажите пожалуйста, что делает эта строчка:

_resp = _resp.substring(_resp.indexOf("\r\n", cmd.length()) + 2);

что-то никак не пойму

 

b707
Offline
Зарегистрирован: 26.05.2017

akkinak пишет:

а у меня 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/

akkinak
Offline
Зарегистрирован: 24.09.2012

если в условии вместо "==" поставить "indexOf", то работает.

еще спрошу, есть глобальная переменная для хранение результата ответа модуля _response, и есть локальная переменная _resp тоже для хранения результата ответа модуля внутри функций. Функции возвращают переменную _resp, А в условии setup фигурирует _response. Зачем две переменные для хранения результата ответа модуля? Может нужна только _response?

b707
Offline
Зарегистрирован: 26.05.2017

akkinak пишет:

еще спрошу, есть глобальная переменная для хранение результата ответа модуля _response, и есть локальная переменная _resp тоже для хранения результата ответа модуля внутри функций. Функции возвращают переменную _resp, А в условии setup фигурирует _response. Зачем две переменные для хранения результата ответа модуля? Может нужна только _response?

с точки зрения хорошего стиля программирования правильнее будет _response тоже сделать локальной внутри setup().

А точки зрения эффективености. честно говоря, не знаю