Arduino:Примеры/GSMExamplesReceiveVoiceCall

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

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Прием голосового звонка[1]

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

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

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

Цепь

GSMShield ArduinoUno.png

Arduino GSM Shield, установленная поверх Arduino Uno

Код

Во-первых, импортируем библиотеку GSM.

#include <GSM.h>

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

#define PINNUMBER ""

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

GSM gsmAccess;
GSMVoiceCall vcs;

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

char numtel[20];

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

void setup(){
  Serial.begin(9600); 
  Serial.println("Receive Voice Call");

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

boolean notConnected = true;

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

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

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

vcs.hangCall();

Заканчиваем setup() выводом двух сообщений на Serial Monitor – о том, что GSM инициализирован, а скетч ждет звонка.

Serial.println("GSM initialized.");
  Serial.println("Awaiting call.");
}

В секции loop() воспользуемся оператором switch для управления тем, по какому сценарию может пойти работа программы. Для того, чтобы определить статус скетча, вызовем функцию getvoiceCallStatus().

void loop()
{
  switch (vcs.getvoiceCallStatus()) 
  {

Если функция getvoiceCallStatus() возвращает значение IDLE_CALL, то дальше ничего не происходит.

case IDLE_CALL:

      break;

Если getvoiceCallStatus() возвращает значение RECEIVINGCALL, это значит, что вам кто-то звонит. Воспользуемся функцией retrieveCallingNumber() для того, чтобы записать входящий номер в созданный вами массив numtel, а затем выводим его на Serial Monitor.

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

case RECEIVINGCALL:

      Serial.println("RECEIVING CALL");

      vcs.retrieveCallingNumber(numtel, 20);

      Serial.print("Number:");
      Serial.println(numtel);

      vcs.answerCall();         
      break;

Когда вы ответите на звонок, функция getvoiceCallStatus() вернет значение TALKING. В то же время скетч будет ждать символа новой строки, чтобы запустить функцию hangCall() и тем самым прервать звонок.

Закрываем оператор switch.

case TALKING:

      Serial.println("TALKING. Enter line to interrupt.");
      while(Serial.read()!='\n')
        delay(100);
      vcs.hangCall();
      Serial.println("HANG. Waiting Call.");      
      break;
  }

И небольшая задержка перед тем, как начинать новый заход через цикл.

delay(1000);
}

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

/*
Прием голосового звонка

Этот скетч для Arduino GSM Shield получает голосовые звонки,
отображает входящий номер, ждет несколько секунд и вежливо кладет трубку.

Цепь:
* Arduino GSM Shield
*  Микрофон и динамик, подключенные к Shield.
Если их не будет, ни передавать свой голос, ни слышать чужой вы не сможете. 

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

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

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

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

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


char numtel[20];           // буфер для хранения входящего номера

void setup()
{
  // Инициализируем последовательную передачу данных:
  Serial.begin(9600);
  Serial.println("Receive 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);
    }
  }

  // Эта функция помогает удостовериться,
  // что модем готов к принятию входящих звонков:
  vcs.hangCall();

  Serial.println("Waiting Call");  //  "Ожидание звонка"
}

void loop()
{
  // Проверяем статус голосового звонка:
  switch (vcs.getvoiceCallStatus()) 
  {
    case IDLE_CALL: // ничего не происходит

      break;

    case CALLING: // этого сценария никогда не возникнет, потому что звонок делаем не мы

      Serial.println("CALLING");  //  "Звонок"
      break;

    case RECEIVINGCALL: // Да! Кто-то нам звонит

      Serial.println("RECEIVING CALL");  //  "Прием звонка"

      // «Изымаем» входящий телефонный номер:
      vcs.retrieveCallingNumber(numtel, 20);

      // Выводим этот номер на Serial Monitor:
      Serial.print("Number:");  //  "Номер:"
      Serial.println(numtel);

      // Отвечаем на звонок, устанавливаем соединение:
      vcs.answerCall();         
      break;

    case TALKING:  // в этом сценарии связь уже установлена, а скетч ждет, когда она будет прервана:

      Serial.println("TALKING. Enter line to interrupt.");  //  "Идет разговор. Нажмите на клавишу ввода, чтобы прервать звонок."
      while(Serial.read()!='\n')
        delay(100);
      vcs.hangCall();
      Serial.println("HANG. Waiting Call."); //  "Звонок окончен. Ожидание нового звонка"
      break;
  }
  delay(1000);
}

См.также

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

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