Arduino:Примеры/GSMExamplesMakeVoiceCall

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

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


Голосовой звонок[1]

Этот скетч при помощи платы Arduino и модуля GSM Shield позволяет делать звонок на удаленный телефонный номер, введенный через Serial Monitor. Чтобы слышать человека на том конце связи и иметь возможность отправлять свой голос, вам надо будет подключить к Shield динамик и микрофон.

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

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

Цепь

Изображение Arduino GSM Shield поверх Arduino Uno

Код

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

#include <GSM.h>

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

#define PINNUMBER ""

Создаем экземпляры классов, которые будем использовать. В данном примере вам понадобятся GSM и GSMVoiceCall.

GSM gsmAccess; 
GSMVoiceCall vcs;

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

String remoteNumber = "";
char charbuffer[20];

В секции setup() инициализируем последовательную передачу данных на компьютер. Она будет использоваться для передачи телефонного номера на Arduino. Запустив коммуникацию, отправляем на Serial Monitor сообщение, информирующее о начале работы скетча.

void setup(){

  Serial.begin(9600); 
  Serial.println("Make Voice Call");

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

boolean notConnected = true;

Подключаемся к сети, вызывая функцию gsmAccess.begin(). В качестве аргумента в ней будет PIN-код SIM-карты. Ставим эту функцию в секции while(), чтобы постоянно проверять статус соединения. Когда модем подключится, gsmAccess.begin() вернет значение GSM_READY. Используем его, как сигнал для того, чтобы присвоить переменной notConnected значение true или false. В противном случае на Serial Monitor появится сообщение о том, что подключиться не удалось.

while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }

Заканчиваем секцию setup()выводом сообщения на Serial Monitor о том, что настройка связи прошла успешно, а также с предлагаем пользователю ввести телефонный номер.

Serial.println("GSM initialized.");
  Serial.println("Enter phone number to call.");
}

Код в секции loop() принимает от Serial Monitor входящие байты и делает голосовой звонок.

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

void loop()
{
  while (Serial.available() > 0)
  {
    char inChar = Serial.read();
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">

Если в буфере есть символ новой строки, проверяем, не содержит ли вписанный телефонный номер более '''20 цифр''' (теоретически, вы никогда не сможете набрать номер, где цифр будет больше '''20-ти''').

<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
if (inChar == '\n')
    {
      if (remoteNumber.length() < 20)
      {

Выводим номер, по которому собираемся звонить, на Serial Monitor.

Serial.print("Calling to : ");
        Serial.println(remoteNumber);
        Serial.println();

Телефонный номер будет храниться в строке под названием remoteNumber. Для функции voiceCall() требуется массив char, поэтому копируем эту строку в массив под названием charbuffer.

remoteNumber.toCharArray(charbuffer, 20);

Чтобы послать вызов, воспользуемся функцией vcs.voiceCall(), «скормив» ей номер, до которого хотим дозвониться. Проверяем статус соединения при помощи функции getvoiceCallStatus().

Чтобы активировать функцию hangCall() – и тем самым прервать звонок – отправляем символ новой строки.

if(vcs.voiceCall(charbuffer))
        {
          Serial.println("Call Established. Enter line to end");
          while(Serial.read()!='\n' && (vcs.getvoiceCallStatus()==TALKING));          
          vcs.hangCall();
        }

Завершив звонок, очищаем переменную, в которой хранится телефонный номер.

Serial.println("Call Finished");
        remoteNumber="";
        Serial.println("Enter phone number to call.");
      }

Если номер, введенный в Serial Monitor, содержит больше 20 цифр, очищаем строку remoteNumber и начинаем снова.

else
      {
        Serial.println("That's too long for a phone number. I'm forgetting it"); 
        remoteNumber = "";
      }
    }

Если при считывании информации с Serial Monitor оказывается, что среди входящих символов нет символа новой строки или возврата строки, добавляем его к строке remoteNumber и закрываем секцию loop().

else
    {
      if(inChar!='\r')
        remoteNumber += inChar;
    }
  } 
}

Загрузив код, открываем Serial Monitor. Увидев сообщение «Enter phone number to call» (т.е. «Введите телефонный номер, на который хотите позвонить»), впишите нужный телефонный номер и нажмите клавишу ввода.

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

/*
Голосовой звонок при помощи Arduino

Этот скетч для Arduino GSM Shield позволяет делать голосовой звонок 
на удаленный телефонный номер, который вы вводите через Serial Monitor.
Когда все будет настроено, откройте Serial Monitor и, увидев сообщение READY, впишите телефонный номер. 
Убедитесь, что Serial Monitor настроен таким образом,
чтобы при нажатии на клавишу ввода отсылался только символ новой строки.

Цепь:
* GSM Shield
* Подключенные к Shield динамик и микрофон. 
Без них ни отправлять, ни получать голосовые сообщения будет нельзя.

Создан в марте 2012 Хавьером Зорзано (Javier Zorzano).

Этот код не защищен авторским правом.
*/

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

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

// Создаем экземпляры классов GSM и GSMVoiceCall:
GSM gsmAccess; // включая параметр «true» для активации отладки
GSMVoiceCall vcs;

String remoteNumber = "";  // номер, по которому вы будете звонить
char charbuffer[20];

void setup()
{

  // Инициализируем последовательную передачу данных и ждем открытия порта:
  Serial.begin(9600);
  while (!Serial) {
    ; // ждем подключения последовательного порта (нужно только для Leonardo)
  }

  Serial.println("Make Voice Call");  //  "Делаем голосовой звонок"

  // Состояние соединения:
  boolean notConnected = true;

  // Запускаем GSM Shield.
  // Если у вашей SIM-карты есть PIN, делаем его параметром функции gsmAccess.begin():
  while (notConnected)
  {
    if (gsmAccess.begin(PINNUMBER) == GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("Not connected");  //  "Подключиться не удалось"
      delay(1000);
    }
  }

  Serial.println("GSM initialized.");  //  "GSM инициализирован."
  Serial.println("Enter phone number to call.");  //  "Введите телефонный номер, на который будем звонить."

}
void loop()
{

  // Добавляем в строку любые входящие символы:
  while (Serial.available() > 0)
  {
    char inChar = Serial.read();
    // Если это символ новой строки, значит, делаем звонок:
    if (inChar == '\n')
    {
      // Убедитесь, что телефонный номер не слишком длинен:
      if (remoteNumber.length() < 20)
      {
        // Дайте пользователю знать, что вы звоните:
        Serial.print("Calling to : ");  //  "Звоним на: "
        Serial.println(remoteNumber);
        Serial.println();

        // Звоним на указанный номер:
        remoteNumber.toCharArray(charbuffer, 20);


        // Проверяем, сняли ли на том конце трубку:
        if (vcs.voiceCall(charbuffer))
        {
          Serial.println("Call Established. Enter line to end");  //  "Связь установлена. Введите символ новой строки, чтобы закончить"
          // Ждем получения символа новой строки:
          while (Serial.read() != '\n' && (vcs.getvoiceCallStatus() == TALKING));
          // и вешаем «трубку»:
          vcs.hangCall();
        }
        Serial.println("Call Finished");  //  "Звонок окончен"
        remoteNumber = "";
        Serial.println("Enter phone number to call.");  //  "Введите телефонный номер, на который хотите позвонить."
      }
      else
      {
        Serial.println("That's too long for a phone number. I'm forgetting it");  //  "Слишком длинный номер. Такие у меня в голове не помещаются"
        remoteNumber = "";
      }
    }
    else
    {
      // Чтобы отправить сообщение, добавьте к нему последний символ:
      if (inChar != '\r')
        remoteNumber += inChar;
    }
  }
}

См.также

  1. GSM Constructor
  2. GSM.begin()
  3. GSM.shutdown()
  4. GSMVoiceCall Constructor
  5. getVoiceCallStatus()
  6. ready()
  7. voiceCall()
  8. answerCall()
  9. hangCall()
  10. retrieveCallingNumber()

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