Arduino:Примеры/GSMExamplesTestGPRS

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Тест GPRS при помощи GPS Shield[1]

Этот скетч тестирует GPRS-связь на модуле GSM Shield. Он пытается подключиться к странице arduino.cc.

Чтобы использовать GPRS на GPS Shield, вам нужно знать APN (Access Point Name, т.е. имя точки доступа), логин и пароль. Информацию об этом (включая самые последние обновления) можно узнать у своего оператора связи. На этой странице можно найти настройки для различных операторов, но учтите, что она может быть устаревшей.

Необходимое оборудование

  • Плата Arduino;
  • Модуль Arduino + Telefonica GSM/GPRS Shield;
  • SIM-карта с возможностью передачи данных;

Цепь

Модуль Arduino GSM Shield, установленный поверх Arduino Uno

Код

Для начала импортируем библиотеку GSM.

#include <GSM.h>

Функционал SIM-карты может быть заблокирован PIN-кодом. В этом случае его нужно определить в качестве константы, для чего мы воспользуемся директивой #define. Если у вашей SIM-карты PIN-кода нет, значит оставляем это место пустым.

#define PINNUMBER ""

Создаем экземпляры классов GSM, GPRS и GSMClient.

GSMClient client;
GPRS gprsAccess;
GSM gsmAccess;

Создаем пару статусных сообщений, которые в случае необходимости будем отправлять на Serial Monitor.

String oktext = "OK";
String errortext = "ERROR";

Создаем несколько переменных, которые будут содержать информацию о сервере, пути и прокси, к которому вы собираетесь подключиться.

char url[] = "arduino.cc";
char path[] = "/";
char urlproxy[] = "http://arduino.cc";

Создаем переменную, в которой будет храниться ответ от сервера, а также еще одну переменную, информирующую о том, будете ли вы использовать прокси или нет.

String response = "";
boolean use_proxy = false;

В секции setup() инициализируем последовательную передачу данных.

void setup(){
  Serial.begin(9600); 
}

Теперь создадим пользовательскую функцию, которая будет обрабатывать входящие данные, идущие через последовательный порт. Аргументом у этой функции будет массив типа char.

int readSerial(char result[])
{

Создаем переменную, которая будет работать счетчиком. Если через последовательный порт будет прибывать информация, мы будем считывать ее в char-массив. Если среди входящих данных попадется символ новой строки, удаляем этот массив и возвращаемся к главному циклу программы.

int i = 0;
  while(1)
  {
    while (Serial.available() > 0)
    {
      char inChar = Serial.read();
      if (inChar == '\n')
      {
        result[i] = '\0';
        return 0;
      }
      if(inChar!='\r')
      {
        result[i] = inChar;
        i++;
      }
    }
  }
}

В секции loop() устанавливаем «флаг» для прокси в положение false.

void loop()
{
  use_proxy = false;

Запускаем соединение с сетью GSM, «скармливая» функции gsmAccess.begin() аргумент в виде PIN-кода SIM-карты.

Serial.print("Connecting GSM network...");
  if(gsmAccess.begin(PINNUMBER)!=GSM_READY)
  {
    Serial.println(errortext);
    while(true);
  }
  Serial.println(oktext);

Создаем массив типа char, в котором будем держать APN. Далее используем созданную нами функцию readSerial() для считывания байтов, входящих через последовательный порт.

char apn[50];
  Serial.print("Enter your APN: ");
  readSerial(apn);
  Serial.println(apn);

Создаем массив типа char, в котором будем держать логин к APN. Далее используем созданную нами функцию readSerial() для считывания байтов, входящих через последовательный порт.

char login[50];
  Serial.print("Now, enter your login: ");
  readSerial(login);
  Serial.println(login);

Создаем массив типа char, в котором будем держать пароль к APN. Затем используем созданную нами функцию readSerial() для считывания байтов, входящих через последовательный порт.

char password[20];
  Serial.print("Finally, enter your password: ");
  readSerial(password);

Подключаемся к GPRS при помощи функции gprs.attachGPRS(). В качестве аргументов ей требуются как раз введенные вами ранее APN, логин и пароль. Когда модем подключит себя к GPRS, функция gsmAccess() вернет значение GSM_READY.

Serial.println("Attaching to GPRS with your APN...");
  if(gprsAccess.attachGPRS(apn, login, password)!=GPRS_READY)
  {
    Serial.println(errortext);
  }
  else{

    Serial.println(oktext);

Создаем массив типа char, где будет храниться любая необходимая нам информация о прокси. Далее используем созданную нами функцию readSerial() для считывания байтов, входящих через последовательный порт.

char proxy[100];
    Serial.print("If your carrier uses a proxy, enter it, if not press enter: ");
    readSerial(proxy);
    Serial.println(proxy);

Если прокси определился, запрашиваем номер порта и выставляем «флаг» прокси на true.

int pport;
    if(proxy[0] != '\0'){
      // read proxy port introduced by user
      char proxyport[10];
      Serial.print("Enter the proxy port: ");
      readSerial(proxyport);
      // cast proxy port introduced to integer
      pport = (int) proxyport;
      use_proxy = true;
      Serial.println(proxyport);
    }

Создаем переменную, которая будет указывать, подключились вы к серверу или нет. Подключаемся к серверу при помощи функции client.connect(). То, каким образом вы создаете соединение, будет зависеть от того, используете вы прокси или нет.

Serial.print("Connecting and sending GET request to arduino.cc...");
    int res_connect;

    if(use_proxy)
      res_connect = client.connect(proxy, pport);
    else
      res_connect = client.connect(url, 80);

Если подключились, делаем запрос HTTP GET при помощи функции client.print().

if (res_connect)
    {
      client.print("GET ");

      if(use_proxy)
        client.print(urlproxy);
      else
        client.print(path);

      client.println(" HTTP/1.0");
      client.println();
      Serial.println(oktext);
    }

Если подключиться не получилось, сообщаем об ошибке.

else
    {
      Serial.println(errortext);
    }

При помощи функции client.available() проверяем, пришли от сервера какие-нибудь байты или нет. Если да, считываем их в строку response, а затем «заливаем» в char-массив. Проверяем массив подстрокой «200 OK», которая указывает на корректный ответ от arduino.cc.

Serial.print("Receiving response...");

    boolean test = true;
    while(test)
    {
      if (client.available())
      {
        char c = client.read();
        response += c;

        char responsechar[response.length()+1];
        response.toCharArray(responsechar, response.length()+1);

        if(strstr(responsechar, "200 OK") != NULL){
          Serial.println(oktext);
          Serial.println("TEST COMPLETE!");
          test = false;
        }
      }

Если сервер отключился, останавливаем работу клиента и закрываем блок loop().

if (!client.connected())
      {
        Serial.println();
        Serial.println("disconnecting.");
        client.stop();
        test = false;
      }
    }
  }
}

Итак, чтобы увидеть статус соединения, загрузите код и откройте Serial Monitor.

/*

Этот тест запрашивает данные об APN, а затем при помощи GPRS
пытается подключиться к arduino.cc.

Цепь:
* GSM Shield, подключенный к Arduino

Создан 18 июня 2012 Дэвидом дель Пералем (David del Peral).
*/

// Библиотеки:
#include <GSM.h>

// PIN-код:
#define PINNUMBER ""

// Создаем экземпляры классов:
GSM gsmAccess;        // доступ к GSM (включая параметр «true» для активации отладки)
GPRS gprsAccess;  // доступ к GPRS
GSMClient client;  // клиентский сервис для соединения по TCP

// Сообщения для ответа через Serial Monitor:
String oktext = "OK";  
String errortext = "ERROR";  //  "Ошибка"

// URL и путь (например, arduino.cc)
char url[] = "arduino.cc";
char urlproxy[] = "http://arduino.cc";
char path[] = "/";

// Переменная для хранения принятого ответа:
String response = "";

// Используем прокси:
boolean use_proxy = false;

void setup()
{
    // Инициализируем последовательную передачу данных:
  Serial.begin(9600);
}

void loop()
{
  use_proxy = false;

  // Запускаем GSM Shield.
  // Если у вашей SIM-карты есть PIN-код, указываем его параметром в функции begin():
  Serial.print("Connecting GSM network...");  //  "Подключение к сети GSM..."
  if(gsmAccess.begin(PINNUMBER)!=GSM_READY)
  {
    Serial.println(errortext);
    while(true);
  }
  Serial.println(oktext);

  // Считываем APN, введенный пользователем:
  char apn[50];
  Serial.print("Enter your APN: ");  //  "Введите ваш APN: "
  readSerial(apn);
  Serial.println(apn);

  // Считываем логин к APN, введенный пользователем:
  char login[50];
  Serial.print("Now, enter your login: ");  //  "Теперь введите логин: "
  readSerial(login);
  Serial.println(login);

  // Считываем пароль к APN, введенный пользователем:
  char password[20];
  Serial.print("Finally, enter your password: ");  //  "Наконец, введите пароль: "
  readSerial(password);

  // Подключаемся к GPRS:
  Serial.println("Attaching to GPRS with your APN...");  //  "Подключаемся к GPRS с помощью ваших данных об APN..."
  if(gprsAccess.attachGPRS(apn, login, password)!=GPRS_READY)
  {
    Serial.println(errortext);
  }
  else{

    Serial.println(oktext);

    // Считываем данные о прокси, введенные пользователем:
    char proxy[100];
    Serial.print("If your carrier uses a proxy, enter it, if not press enter: ");  //  "Если ваш оператор использует прокси, введите его, если нет – нажмите Enter"
    readSerial(proxy);
    Serial.println(proxy);

    // Если пользователь указал прокси, запрашиваем у него прокси-порт:
    int pport;
    if(proxy[0] != '\0'){
      // Считываем прокси-порт, введенный пользователем:
      char proxyport[10];
      Serial.print("Enter the proxy port: ");  //  "Введите прокси-порт: "
      readSerial(proxyport);
      // «Заливаем» этот прокси-порт в переменную pport:
      pport = (int) proxyport;
      use_proxy = true;
      Serial.println(proxyport);
    }

    // Подключаемся к arduino.cc и выполняем HTTP-запрос:
    Serial.print("Connecting and sending GET request to arduino.cc...");  //  "Подключение и отправка GET-запроса на arduino.cc..."
    int res_connect;

    // Если используется прокси, подключаемся с его помощью:
    if(use_proxy)
      res_connect = client.connect(proxy, pport);
    else
      res_connect = client.connect(url, 80);

    if (res_connect)
    {
      // Далем запрос типа HTTP 1.0 GET («клиент отправляет запрос»)
      client.print("GET ");

      // Если используется прокси, то путь – URL-ссылка arduino.cc:
      if(use_proxy)
        client.print(urlproxy);
      else
        client.print(path);

      client.println(" HTTP/1.0");
      client.println();
      Serial.println(oktext);
    } 
    else
{
      // Если подключиться к серверу не получилось:
      Serial.println(errortext);
    }
    Serial.print("Receiving response...");  //  "Отправка ответа..."

    boolean test = true;
    while(test)
    {
      // Если от сервера есть входящие байты, считываем их и проверяем:
      if (client.available())
      {
        char c = client.read();
        response += c;

        // «Выливаем» полученный ответ из строки в char-массив:
        char responsechar[response.length()+1];
        response.toCharArray(responsechar, response.length()+1);

        // Если ответ включает подстроку «200 ОК»:
        if(strstr(responsechar, "200 OK") != NULL){
          Serial.println(oktext);
          Serial.println("TEST COMPLETE!");  //  "Тест завершен!"
          test = false;
        }
      }

      // Если сервер отключился, останавливаем работу клиента:
      if (!client.connected())
      {
        Serial.println();
        Serial.println("disconnecting.");  //  "Отключение."
        client.stop();
        test = false;
      }
    }
  }
}

/*
Пользовательская функция для считывания входящих данных
 */
int readSerial(char result[])
{
  int i = 0;
  while(1)
  {
    while (Serial.available() > 0)
    {
      char inChar = Serial.read();
      if (inChar == '\n')
      {
        result[i] = '\0';
        return 0;
      }
      if(inChar!='\r')
      {
        result[i] = inChar;
        i++;
      }
    }
  }
}

См.также

  1. GPRS Constructor
  2. GSMClient Constructor
  3. attachGPRS()

Внешние ссылки