Проблема с GPRS shield

Тема в разделе "Arduino & Shields", создана пользователем ZZZenon, 26 сен 2015.

  1. ZZZenon

    ZZZenon Нуб

    Совсем недавно начал изучать ардуино, поэтому, если вопрос глупый, заранее прошу прощения.
    Собственно на ардуино леонардо поставил gprs shield от амперки.
    Начал писать код для беспроводной GSM сигнализации.
    Передающий блок настроил. Все нормально работает.
    Принимающий блок (на котором и стоит GPRS шилд) тоже запрограмировал вот таким кодом:
    Код (C++):
    // Подключаем библиотеки
    #include <VirtualWire.h>
    #include <Wire.h>

    // библиотека для работы с GPRS устройством
    #include <GPRS_Shield_Arduino.h>
    // библиотека для эмуляции Serial порта
    // она нужна для работы библиотеки GPRS_Shield_Arduino
    #include <SoftwareSerial.h>

    // длина сообщения
    #define MESSAGE_LENGTH 160
    // текст сообщения о включении сигнализации
    #define MESSAGE_ON  "ALARM ON"
    // текст сообщения о выключении сигнализации
    #define MESSAGE_OFF  "ALARM OFF"
    // текст сообщения об ошибке распознавания команды
    #define MESSAGE_ERROR  "Error...unknown command!"

    // номер сообщения в памяти сим-карты
    int messageIndex = 0;

    // текст сообщения
    char message[MESSAGE_LENGTH];
    // номер, с которого пришло сообщение
    char phone[16];
    // дата отправки сообщения
    char datetime[24];

    bool stateRelay = false;

    // номер на который будем отправлять сообщение
    #define PHONE_NUMBER  "+7918"

    //тексты имен приемников
    #define FIRST_UNIT_NAME "FIRST_unit"

    #define GSM_START_MESSAGE "GSM_ON"
    #define SENSORS_START_MESSAGE "SENSORS_ON"

    //тексты сообщений тревоги
    #define FIRST_UNIT_MESSAGE_FireALARM "FireALARM"
    #define FIRST_UNIT_MESSAGE_MOTION "MOTION_detected"

    // создаём объект класса GPRS и передаём ему скорость 9600 бод
    // с помощью него будем давать команды GPRS шилду
    GPRS gprs(9600);

    //Пин приемника
    const int receive_pin = 11;
    //


    int i;

    boolean alarmState = 0; //флаг работающей сигнализации
    boolean Hacked = 0; // стандартные коды: 1- включение, 2- выключение, 3- тревога

    //---------------------------------------------------------
    void setup()
    {
      // открываем последовательный порт для мониторинга действий в программе
      Serial.begin(9600);
      while (!Serial) {
        // ждём пока не откроется монитор последовательного порта
        // для того, чтобы отследить все события в программе
      }
      // включаем GPRS-шилд
      gprs.powerUpDown();
      // проверяем, есть ли связь с GPRS-устройством
      while (!gprs.init()) {
        // если связи нет, ждём 1 секунду
        // и выводим сообщение об ошибке;
        // процесс повторяется пв цикле,
        // пока не появится ответ от GPRS-устройства
        delay(1000);
        Serial.print("Init error\r\n");
      }
      // вывод об удачной инициализации GPRS Shield
      Serial.println("GPRS init success");

      vw_set_rx_pin(receive_pin);
      vw_set_ptt_inverted(true); // Required for DR3100
      //Скорость приема бит в секунду
      vw_setup(2000);
      // запускаем приемник
      vw_rx_start();       // Start the receiver PLL running

      // сообщаем о написании и отправке СМС по указанному номеру
      Serial.println("Start to send message ...");
      // отправляем сообщение по указанному номеру с заданным текстом
      // gprs.sendSMS(PHONE_NUMBER, GSM_START_MESSAGE);
      // delay(1000);
      // gprs.sendSMS(PHONE_NUMBER,SENSORS_START_MESSAGE);

    }
    //--------------------------------------------------------
    void loop ()
    {

      // проверяем наличие непрочитанных сообщений
      // и находим их номер в памяти сим-карты
      messageIndex = gprs.isSMSunread();
      if (messageIndex > 0) {
        // если есть хотя бы одно непрочитанное сообщение,
        // читаем его
        gprs.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);

        // Удаляем прочитанное сообщение из памяти Сим-карты
        gprs.deleteSMS(messageIndex);

        // выводим номер, с которого пришло смс
        Serial.print("From number: ");
        Serial.println(phone);

        // выводим дату, когда пришло смс
        Serial.print("Datetime: ");
        Serial.println(datetime);

        // выводим текст сообщения
        Serial.print("Recieved Message: ");
        Serial.println(message);



        if (strcmp(message, "0460 on") == 0) {
          // если сообщение — с текстом «0460 On»,
          // выводим сообщение в Serial
          // и включаем сигнализацию
          Serial.println("OK! ALARM On");

          stateRelay = true;
          alarmState = 1; // включаем статус сигнализации
          // на номер, с которого пришёл запрос,
          // отправляем смс с текстом о включении сигнализации
          gprs.sendSMS(PHONE_NUMBER, MESSAGE_ON);
          // переходим к циклу с включенной сигнализацией
          guardON();
        } else if (strcmp(message, "0460 off") == 0) {
          // если пришло сообщение с текстом «0460 Off»,
          // выводим сообщение в Serial
          // и размыкаем реле
          Serial.println("OK! ALARM Off");
          alarmState = 0; // выключаем статус сигнализации
          stateRelay = false;
          // на номер, с которого пришёл запрос
          // отправляем смс с текстом о выключении питания
          gprs.sendSMS(PHONE_NUMBER, MESSAGE_OFF);
          // переходим к циклу с выключенной сигнализацией
          guardOFF();
        } else if (strcmp(message, "0460 state") == 0) {
          // если пришло сообщение с текстом «State»,
          // отправляем сообщение с состоянием сигнализации
          if (stateRelay == true) {
            Serial.println("State: ALARM On");
            gprs.sendSMS(PHONE_NUMBER, MESSAGE_ON);
          } else {
            Serial.println("State: ALARM Off");
            gprs.sendSMS(PHONE_NUMBER, MESSAGE_OFF);
          }
        } else {
          // если сообщение содержит неизвестный текст,
          // отправляем сообщение с текстом об ошибке
          Serial.println("Error... unknown command!");
          gprs.sendSMS(PHONE_NUMBER, MESSAGE_ERROR);
          goto redirect;
        }

      }
      else {
    redirect:
        switch (alarmState) {
          case 0:
            guardOFF();
       
          case 1:
            guardON();
         
        }
      }

    }

    void guardOFF()
    {
      uint8_t buf[VW_MAX_MESSAGE_LEN];
      uint8_t buflen = VW_MAX_MESSAGE_LEN;
      if (vw_get_message(buf, &buflen)) { // Если принято сообщение

        if (buf[0] == 'z' && buf[2] == 'c' && buf[4] == 'F') { // жарко на СВОЕМ 1 датчике
          Serial.print("FIRST_unit ");
          Serial.print("FireALARM");
          Serial.println(" NO SMS");
          delay(5000);
          loop();
        }
        else if (buf[0] == 'z' && buf[2] == 'c' && buf[4] == 'M') { // движение на СВОЕМ 1 датчике
          Serial.print("FIRST_unit ");
          Serial.print("MOTION_detected");
          Serial.println(" NO SMS");
          delay(5000);
          loop();
        }

        // если не жарко и нет движения, начинаем разбор
        // Если сообщение адресовано нам и оно с первого датчика, продолжаем

        else if (buf[0] == 'z' && buf[2] == 'c' && buf[2] != 'F' || 'M')    {

          // Числовой параметр начинается с индекса 4
          i = 4;
          int number = 0;
          // Посколько передача идет посимвольно, то нужно преобразовать набор символов в число
          while (buf[i] != '.')
          {
            number *= 10;
            number += buf[i] - '0';
            i++;
          }

          char Temperature1 = buf[4];
          char Temperature2 = buf[5];
          char Humidity1 = buf[7];
          char Humidity2 = buf[8];

          Serial.println("FIRST_unit = OK");
          Serial.print("Temperature = ");
          Serial.print(Temperature1);
          Serial.print(Temperature2);
          Serial.println(" Cels");
          Serial.print("Humidity = ");
          Serial.print(Humidity1);
          Serial.print(Humidity2);
          Serial.println(" %");
          Serial.println(" ");
          Serial.println(" ");
          Serial.println(" ");
        }
      }
      else {
        loop();
      }
    }


    void guardON()
    { uint8_t buf[VW_MAX_MESSAGE_LEN];
      uint8_t buflen = VW_MAX_MESSAGE_LEN;

      if (vw_get_message(buf, &buflen)) { // Если принято сообщение

        if (buf[0] == 'z' && buf[2] == 'c' && buf[4] == 'F') { // жарко на СВОЕМ 1 датчике
          Serial.print("FIRST_unit ");
          Serial.println("FireALARM");
          gprs.sendSMS(PHONE_NUMBER, FIRST_UNIT_MESSAGE_FireALARM);
          delay(5000);
          loop();
        }
        else if (buf[0] == 'z' && buf[2] == 'c' && buf[4] == 'M') { // движение на СВОЕМ 1 датчике
          Serial.print("FIRST_unit ");
          Serial.println("MOTION_detected");
          gprs.sendSMS(PHONE_NUMBER, FIRST_UNIT_MESSAGE_MOTION);
          delay(5000);
          loop();
        }

        // если не жарко и нет движения, начинаем разбор
        // Если сообщение адресовано нам и оно с первого датчика, продолжаем
        else if (buf[0] == 'z' && buf[2] == 'c' && buf[4] != 'F' || 'M')    {

          // Числовой параметр начинается с индекса 4
          i = 4;
          int number = 0;
          // Посколько передача идет посимвольно, то нужно преобразовать набор символов в число
          while (buf[i] != '.')
          {
            number *= 10;
            number += buf[i] - '0';
            i++;
          }

          char Temperature1 = buf[4];
          char Temperature2 = buf[5];
          char Humidity1 = buf[7];
          char Humidity2 = buf[8];

          Serial.println("FIRST_unit = OK");
          Serial.print("Temperature = ");
          Serial.print(Temperature1);
          Serial.print(Temperature2);
          Serial.println(" Cels");
          Serial.print("Humidity = ");
          Serial.print(Humidity1);
          Serial.print(Humidity2);
          Serial.println(" %");
          Serial.println(" ");
          Serial.println(" ");
          Serial.println(" ");
          loop();
        }
      }
    }
    По идее, приемник после запуска должен ждать входящего командного смс, а если такового нет, то обрабатывать данные с от 433MHZ передатчика по установленным программой условиям.
    Проблема в том, что шилд стартует, на смс реагирует, НО данные с 433MHZ передатчика не поступают

    Что характерно, с установленным GPRS шилдом через D1-D13, A0-A5 пины ВООБЩЕ данные не идут.

    Вот, не пойму это шилд накрылся или все таки у меня руки из неправильного места растут?
    Кстати, этому шилду доп питание нужно или нет? Просто для китайских шилдов - в обязательном порядке, а для этого в описании ничего не сказано
     
    Последнее редактирование: 26 сен 2015
  2. ZZZenon

    ZZZenon Нуб

    Ну, и, на всякий случай, код передатчика (возможно в нем проблема)
    Код (C++):

    //Подключаем библиотеки
    #include <VirtualWire.h>
    #include "DHT.h"
    //Определяем пин светодиода
    const int led_pin = 13;
    //Определяем пин передатчика
    const int transmit_pin = 5;
    //Пин и тип датчика температуры
    #define DHTPIN A1
    #define DHTTYPE DHT11
    DHT dht(DHTPIN, DHTTYPE);
    // объявляем массив
    char dataString [12];
    //Время калибровки датчика движения (10-60 сек. по даташиту)
    int calibrationTime = 10;
    int motionwarningtime = 3;
    //the time when the sensor outputs a low impulse
    long unsigned int lowIn;
    //the amount of milliseconds the sensor has to be low
    //before we assume all motion has stopped
    long unsigned int pause = 5000;
    boolean lockLow = true;
    boolean takeLowTime;
    int pirPin = 7;    //вход подключения датчика движения
    //----------------------------------------------------------------
    void setup()
    {
      Serial.begin(9600);
      vw_set_tx_pin(transmit_pin);
      vw_set_ptt_inverted(true);
      // скорость передачи бит в секунду
      vw_setup(2000);
      pinMode(led_pin, OUTPUT);
      pinMode(pirPin, INPUT);
      digitalWrite(pirPin, LOW);
      //запуск датчика температуры
      dht.begin();
      //дадим датчикам время на калибровку
      Serial.print("Calibrating sensors ");
      for (int i = 0; i < calibrationTime; i++) {
        Serial.print(".");
        delay(1000);
      }
      Serial.println(" done");
      Serial.println("SENSORS ACTIVE");
      delay(50);
    }

    //---------------------------------------------------------------
    void loop() {
      char symbol = 'c'; // служебный символ определения конкретного передатчика

      if (digitalRead(pirPin) == HIGH) {

        if (lockLow) {
          //makes sure we wait for a transition to LOW before any further output is made:
          for (int m = 0; m < motionwarningtime; m++) { // сообщение передается 3 раза для гарантии приема
          lockLow = false;
          Serial.println("---");
          Serial.print("motion detected at ");
          Serial.print(millis() / 1000);
          Serial.println(" sec");

          String strMsg = "z "; //код доступа к приемнику
          strMsg += symbol;
          strMsg += " ";
          strMsg += "M"; // код обнаружения движения (4й номер в строке)
          strMsg += " ";
          char msg[255];

          strMsg.toCharArray(msg, 255);

          Serial.println(msg);

          // Включаем светодиод
          digitalWrite(led_pin, HIGH);

          // Передаем данные
          vw_send((uint8_t *)msg, strlen(msg));
          vw_wait_tx(); // Ждем пока передача будет окончена
          // Выключаем светодиод
          digitalWrite(led_pin, LOW);
          //отдыхаем 2 сек.
          delay(2000);
              }
              delay(5000);
        }
        takeLowTime = true;
      }

      if (digitalRead(pirPin) == LOW) {

        if (takeLowTime) {
          lowIn = millis();          //save the time of the transition from high to LOW
          takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
        //if the sensor is low for more than the given pause,
        //we assume that no more motion is going to happen
        if (!lockLow && millis() - lowIn > pause) {
          //makes sure this block of code is only executed again after
          //a new motion sequence has been detected
          lockLow = true;
          Serial.print("motion ended at ");      //output
          Serial.print((millis() - pause) / 1000);
          Serial.println(" sec");
          delay(50);
          goto Temperature;
        }
      }
    Temperature:
      // опрашиваем датчик температуры и влажности
      int h = dht.readHumidity();
      int t = dht.readTemperature();


      if (t >= 41) { // если превышен температурный порог

        String strMsg = "z ";
        strMsg += symbol;
        strMsg += " ";
        strMsg += "F"; // код превышения температурного порога (4й номер в строке)
        strMsg += " ";
        char msg[255];

        strMsg.toCharArray(msg, 255);

        Serial.println(msg);

        // Включаем светодиод
        digitalWrite(led_pin, HIGH);

        // Передаем данные
        vw_send((uint8_t *)msg, strlen(msg));
        vw_wait_tx(); // Ждем пока передача будет окончена
        // Выключаем светодиод
        digitalWrite(led_pin, LOW);
        //отдыхаем 5 сек.
        delay(5000);
        return;
      }

      else {
        //Формируем буфер

        String strMsg = "z ";
        strMsg += symbol;
        strMsg += " ";
        strMsg += t;
        strMsg += ";";
        strMsg += h;
        strMsg += ".";

        char msg[255];

        strMsg.toCharArray(msg, 255);

        Serial.println(msg);

        // Включаем светодиод
        digitalWrite(led_pin, HIGH);

        // Передаем данные
        vw_send((uint8_t *)msg, strlen(msg));
        vw_wait_tx(); // Ждем пока передача будет окончена
        // Выключаем светодиод
        digitalWrite(led_pin, LOW);
        //отдыхаем 5 сек.
        delay(5000);
      }
    }
     
     
  3. ZZZenon

    ZZZenon Нуб

    В порядке эксперимента GPRS шилд подсоединил к ардуино проводами (только теми, которые ему нужны).
    433Mhz приемник подсоединил в 11й пин непосредственно ардуино, питание 5V дал ему отдельно.
    Все так же: датчик с присоединенным шилдом все равно не работает (без шилда - все нормально).
    Вот, вообще не пойму, в чем может быть проблема. будто шилд что-то запирает в самой ардуино.
     
  4. ZZZenon

    ZZZenon Нуб

    Хм. Продолжаю локализовывать проблему.
    Оказалось, что через "неактивированный", но физически подключенный к ардуино шилд приемник спокойно работает.
    Под "неактивированным" я имею ввиду невключенные в скетч библиотеки <GPRS_Shield_Arduino.h>
    и <SoftwareSerial.h> (на самом шилде индикаторы ON и AIR в этот момент не горят).
    Стоит только активировать шилд, так сразу через его пины что-либо подключить становится невозможно.

    Теперь вообще непонятно, в чем проблема.
     
  5. ZZZenon

    ZZZenon Нуб

    Проблема решилась самым элементарным образом. Как оказалось, шилду просто не хватало питания.
    Подключил и по ЮСБ, и по АС - заработало.

    Магазину амперки - отдельное %#@%#@#%@!!, т.к. в описании шилда НИГДЕ не написано, что ему может не хватать питания. Поправьте что ли описание в викиамперке.
     
    Последнее редактирование: 27 сен 2015
  6. Привет, на всякий случай всем.
    "Подключил и по ЮСБ, и по АС - заработало." Это излишне, автоматически выбирается тот способ питания, который дает наибольшую мощность ,точнее силу тока. В вашем случае, достаточно было, имхо, выбрать просто противоположный вариант и этого должно было бы быть достаточно.
    Если этот театр одного актера :)) еще актуален, то я апну темку.
    Я тоже типа нуб, и сейчас пока в стадии только идеи, а мысль такая - подружить Мега2560, датчики температуры и влажности, а также уровня воды с УЖЕ имеющейся вполне себе автономной китайской GSM-сигнализацией, которая воспринимает беспроводные датчики 433 Мгц. Задача ,как я понимаю, ограничится приобретением исключительно передатчика в виде совместимого с Мегой шилда, который, образно говоря, будет прикидываться в целом очередным беспроводным датчиком для сиги. И надеяться ,что сигнал с него будет корректно восприниматься приемником собственно сигнализации. Т.е. задачи программирования отправки СМС, звонка вовсе не стоит. Нужен только скетч на обработку сигналов с проводных датчиков Т и влажности и передачи их показаний через передатчик в основной блок сиги.
    Вопрос собственно пока три.
    1)Помимо предложенного в этой теме скетча ,который вроде бы тоже может подходить для моей задачи (датчик будет типа SHT20 или DHT-22), может дадите линки на также работающие ,проверенные примеры?
    2) посоветуйте подходящий и/или проверенный в бою модуль(шилд) передатчика 433 МГц из ассортимента Ali.
    3) Если бы мне все-таки нужно было делать свой собственный GSM-модуль (а вдруг аппетит разыграется), то какой из своего опыта посоветуете приобретать -А6, А7, SIM900 или какой-то иной? Но так, чтобы питание было 5В и воспринимал сим-карты стандартного, а не микро размера, ну или гарантированно поддерживал как 3G/4G, так и старые 2G симки и вообще российских операторов.
     
    Последнее редактирование: 1 янв 2019
  7. Daniil

    Daniil Гуру

    Нет. Посмотрите схему, кто там определяет параметры источника?
    я думаю лучше новую тему создать, если у вас будут вопросы.
     
  8. Модер не будет возражать, если я продублирую свой текст в новой теме уже как ТС?