Arduino Mega и GPRS Shield учимся общаться

Тема в разделе "Arduino & Shields", создана пользователем Фархад, 23 июн 2016.

Метки:
  1. Фархад

    Фархад Нерд

    Добрый день коллеги! На днях купил себе GPRS Shield
    http://wiki.amperka.ru/продукты:gprs-shield
    Сегодня экспериментирую с ней и Mega2560. Попробовал протестить библиотеки GPRS_Shield_Arduino.h и sim900.h. Нашел небольшой косяк в примерах кодов. Пример на передачу СМС был с ошибкой - компилятор ругался на переменную PHONE_NUMBER, что она не char. Переобъявил ее как
    char PHONE_NUMBER= "+7912XXXXXXX"; и смс ушла. Но с приемом ничего не выходит (((
    Вот тот код, что в примере:
    Код (C++):
    // библиотека для работы с GPRS устройством
    #include <GPRS_Shield_Arduino.h>
    // библиотека для эмуляции Serial-порта
    // она нужна для работы библиотеки GPRS_Shield_Arduino
    #include <SoftwareSerial.h>
    // длина сообщения
    #define MESSAGE_LENGTH 160
    // номер сообщения в памяти сим-карты
    int messageIndex = 0;
    // текст сообщения
    char message[MESSAGE_LENGTH];
    // номер, с которого пришло сообщение
    char phone[16];
    // дата отправки сообщения
    char datetime[24];
    // создаём объект класса GPRS. По умолчанию скорость общения с ним 9600 бод
    // с помощью него будем давать команды GPRS шилду
    GPRS gprs;
    void setup()
    {
      // включаем GPRS-шилд
      gprs.powerUpDown();
      // открываем последовательный порт для мониторинга действий в программе
      Serial.begin(9600);
      while (!Serial) {
        // ждём пока не откроется монитор последовательного порта
        // для того, чтобы отследить все события в программе
      }
      // проверяем, есть ли связь с GPRS-устройством
      while (!gprs.init()) {
        // если связи нет, ждём 1 секунду
        // и выводим сообщение об ошибке;
        // процесс повторяется в цикле,
        // пока не появится ответ от GPRS-устройства
        delay(1000);
        Serial.print("Init error\r\n");
      }
      // выводим сообщение об удачной инициализации GPRS Shield
      Serial.println("GPRS init success");
      Serial.println("Please send SMS message to me!");
    }
    void loop()
    {
      // если пришло новое сообщение
      if (gprs.ifSMSNow()) {
        // читаем его
        gprs.readSMS(message, phone, datetime);

        // выводим номер, с которого пришло смс
        Serial.print("From number: ");
        Serial.println(phone);
        // выводим дату, когда пришло смс
        Serial.print("Datetime: ");
        Serial.println(datetime);
        // выводим текст сообщения
        Serial.print("Recieved Message: ");
        Serial.println(message);
      }
    }
    Скомпилировав Мегу как терминал(взяв из примера), чтобы на прямую пообщаться с шилдом - я понял, что и тут не доработка ))) Буфер 64 байта, а некоторые команды - например как чтение смс - шлют данные с шилда более чем 64 символа... Как шилда шлет ответ тогда? кусками? или весь блок сразу, а мы только получаем первые 64 символа? Кто-нибудь разбирал? Как организовать построчное получение данных с шилда?

    Пример терминала:
    Код (C++):
    // буфер PC Serial
    char bufferPC_Serial[64];
    // буфер GPRS Serial
    char bufferGPRS_Serial[64];
    int i = 0;
    int j = 0;
    void setup()
    {
      // включаем GPRS-шилд
      gprs_OnOff();
      // открываем последовательный порт для мониторинга действий в программе
      Serial.begin(9600);
      // открываем последовательный порт
      // для связи с GPRS-устройством со скоростью 9600 бод
      Serial1.begin(9600);
      while (!Serial) {
        // ждём, пока не откроется монитор последовательного порта
        // для того, чтобы отследить все события в программе
      }
      // пока не установится связь с GPRS-устройством, будем крутиться в теле функции
      gprsTest();
    }
    void loop()
    {
      // считываем данные с компьютера и записываем их в GPRS Shield
      serialPCread();

    //!!!!! выполнение приема и передачи на столько быстрое что получается зацикливание передачи данных. Поэтому обязательно тут используем delay. Этого нет в примере. Я прикинул 2 сек на обработку запросов шилдом. Думаю хватит))

    delay(2000);

      // считываем данные с GPRS Shield и выводим их в Serial-порт
      serialGPRSread();
    }
    void serialPCread()
    {
      i = 0;
      // если появились данные с компьютера
      if (Serial.available() > 0) {
        while (Serial.available() > 0) {
          // пока идёт передача данных,
          // записываем каждый байт в символьный массив
          bufferPC_Serial[i++]=(Serial.read());
        }
        // добавляем символ конца строки
        bufferPC_Serial[i] = '\0';
        // записываем данные в GPRS Shield
        Serial1.println(bufferPC_Serial);
        Serial.println("");
        // очищаем буфер PC Serial
        clearBufferPC_Serial();
      }
    }
    void serialGPRSread()
    {
        j = 0;
        // если появились данные с GPRS Shield
        if (Serial1.available() > 0) {
          while (Serial1.available() > 0) {
            // пока идёт передача данных,
            // записываем каждый байт в символьный массив
            bufferGPRS_Serial[j++]=(Serial1.read());
        }
        // добавляем символ конца строки
        bufferGPRS_Serial[j] = '\0';
        // выводим полученные данные с GPRS Shield в Serial-порт
        Serial.write(bufferGPRS_Serial);
        // очищаем буфер GPRS Serial
        clearBufferGPRS_Serial();
      }
    }
    void clearBufferPC_Serial()
    {
      for (int t = 0; t < i; t++) {
        // очищаем буфер,
        // присваивая всем индексам массива значение 0
        bufferPC_Serial[t] = 0;
      }
    }
    void clearBufferGPRS_Serial()
    {
      for (int t = 0; t < j; t++) {
        // очищаем буфер,
        // присваивая всем индексам массива значение 0
        bufferGPRS_Serial[t] = 0;
      }
    }
    void gprsTest()
    {
      // бесконечный цикл
      while (1) {
        // ждём 1 секунду
        delay(1000);
        j = 0;
        // посылаем в GPRS Shield АТ-команду "AT"
        Serial1.println("AT");
        // если появились данные с GPRS Shield
        if (Serial1.available() > 0) {
          while (Serial1.available() > 0) {
            // пока идёт передача данных,
            // записываем каждый байт в символьный массив
            bufferGPRS_Serial[j++] = Serial1.read();
          }
          // добавляем символ конца строки
          bufferGPRS_Serial[j] = '\0';
          // посылаем АТ-команду "AT"; если GPRS Shield исправен,
          // он должен вернуть команду "AT";
          // сравниваем всё что находиться в буфере GPRS Shield
          // со строкой "AT\r\n\r\nOK\r\n"
          if (strcmp(bufferGPRS_Serial, "AT\r\n\r\nOK\r\n") == 0) {
            // если всё верно выводим в Serial порт "State OK"
            // и выходим из бесконечного цикла
            Serial.println("State OK");
            break;
          } else {
            // если строки разные, значит произошла ошибка
            // выводим сообщение об ошибке и продолжаем цикл
            Serial.println("Init ERROR");
          }
        }
        // очищаем буфер GPRS Serial
        clearBufferGPRS_Serial();
      }
    }
    void gprs_OnOff()
    {
      // настраиваем пин №2 в режим выхода
      pinMode(2, OUTPUT);
      // проверяем состояние 3 пина
      if (digitalRead(3) != HIGH) {
        // если на нём «низкий уровень»
        // подаём на пин 2 «высокий уровень»
        digitalWrite(2, HIGH);
        // ждём 3 секунды
        delay(3000);
      }
      // подаём на пин 2 «низкий уровень»
      digitalWrite(2, LOW);
    }
     
  2. stasych

    stasych Нерд

    У меня шилд китайский аналог.
    https://ru.aliexpress.com/item/High...689028159.html?spm=2114.13010608.0.116.TWaKg4
    есть еще такой
    https://ru.aliexpress.com/item/SIM8...467842817.html?spm=2114.13010608.0.134.TWaKg4
    ни тот ни другой не могу запустить хотя бы на отправку смс.

    Код (C++):
    #include <SoftwareSerial.h>

    SoftwareSerial SIM900(0, 1);

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(19200);
      SIM900.begin(19200);    // Cкорость передачи данных модуля
      delay(2500);
     
      SIM900.print("AT+CMGF=1\r");               //AT command to send SMS message
      delay(300);
      SIM900.println("AT + CMGS = \"+79265490895\"");         // recipient's mobile number, in international format
      delay(1000);
      SIM900.println("Message from an Arduino Uno.");        // message to send
      delay(500);
      SIM900.println((char)26);                       // End AT command with a ^Z, ASCII code 26
      delay(100);
      SIM900.println();
    }

    void loop() {

    }
    может подскажешь что не так.
     
  3. Фархад

    Фархад Нерд

    А ардуина какая? (увидел UNO, но суть не меняет)

    Используй шилдку с чипом Sim900, она полнофункциональная.

    У меня мега, и шилда сидит на аппаратном Serial1 порту. Используй свой программный сериал и учти что нога 0 и 1 используется для аппаратного Serial, так что переключи шилду на другие ноги, например 4 и 5 и настройка программного порта следовательно будет на эти ноги вместо (0,1)

    Код (C++):

    //добавь этот код в setup
    Serial1.println("AT+CMGF=1");
    delay(300);
    Serial1.println("AT+IFC=1,1");
    delay(300);
    Serial1.println("AT+CNMI=1,2,2,1,0");
    delay(300);
    // а здесь процедура отправки. Пробелы в команде AT недопустимы
    Serial1.println("AT+CMGS=\"+7912576хххх\"\r");
        delay(300);
    Serial1.println("GPRS Shield is ONLINE");
        delay(300);
    Serial1.println((char)26);
     
     
    Последнее редактирование: 22 сен 2016