Arduino:Примеры/GSMExamplesReceiveVoiceCall: различия между версиями

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
м (Замена текста — «<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">» на «<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">»)
 
Нет описания правки
Строка 24: Строка 24:
Во-первых, импортируем библиотеку '''GSM'''.
Во-первых, импортируем библиотеку '''GSM'''.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
#include <GSM.h>
#include <GSM.h>
</syntaxhighlight>
</syntaxhighlight>
Строка 30: Строка 30:
Функционал '''SIM'''-карты может быть заблокирован '''PIN'''-кодом. В таком случае нам потребуется директива #define, с помощью которой мы определим этот '''PIN'''-код как константу. Если у вашей '''SIM'''-карты '''PIN'''-кода нет, то можете оставить это место пустым.
Функционал '''SIM'''-карты может быть заблокирован '''PIN'''-кодом. В таком случае нам потребуется директива #define, с помощью которой мы определим этот '''PIN'''-код как константу. Если у вашей '''SIM'''-карты '''PIN'''-кода нет, то можете оставить это место пустым.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
#define PINNUMBER ""
#define PINNUMBER ""
</syntaxhighlight>
</syntaxhighlight>
Строка 36: Строка 36:
Создаем экземпляры классов '''GSM''' и '''GSMVoiceCall'''.
Создаем экземпляры классов '''GSM''' и '''GSMVoiceCall'''.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
GSM gsmAccess;
GSM gsmAccess;
GSMVoiceCall vcs;
GSMVoiceCall vcs;
Строка 43: Строка 43:
Создаем массив типа char, в котором будем хранить входящий номер.
Создаем массив типа char, в котором будем хранить входящий номер.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
char numtel[20];
char numtel[20];
</syntaxhighlight>
</syntaxhighlight>
Строка 49: Строка 49:
В секции setup() инициализируем последовательную передачу данных на компьютер. Открыв соединение, отправляем сообщение, информирующее о начале работы скетча.
В секции setup() инициализируем последовательную передачу данных на компьютер. Открыв соединение, отправляем сообщение, информирующее о начале работы скетча.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
void setup(){
void setup(){
   Serial.begin(9600);  
   Serial.begin(9600);  
Строка 57: Строка 57:
Создаем локальную переменную для отслеживания статуса соединения. Благодаря этому скетч не запустится до тех пор, пока '''SIM'''-карта не подключится к сети.  
Создаем локальную переменную для отслеживания статуса соединения. Благодаря этому скетч не запустится до тех пор, пока '''SIM'''-карта не подключится к сети.  


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
boolean notConnected = true;
boolean notConnected = true;
</syntaxhighlight>
</syntaxhighlight>
Строка 63: Строка 63:
Подключаемся к сети, вызывая функцию gsmAccess.begin(), в которой '''PIN'''-код '''SIM'''-карты будет в качестве аргумента. Поместив его в блоке while(), мы сможем постоянно проверять статус соединения. Когда модем подключится, функция gsmAccess() вернет значение '''GSM_READY'''. Воспользуемся им, как сигналом для того, чтобы задать для переменной notConnected значение true или false. Если подключиться не удалось, сообщаем об этом на '''Serial Monitor'''.
Подключаемся к сети, вызывая функцию gsmAccess.begin(), в которой '''PIN'''-код '''SIM'''-карты будет в качестве аргумента. Поместив его в блоке while(), мы сможем постоянно проверять статус соединения. Когда модем подключится, функция gsmAccess() вернет значение '''GSM_READY'''. Воспользуемся им, как сигналом для того, чтобы задать для переменной notConnected значение true или false. Если подключиться не удалось, сообщаем об этом на '''Serial Monitor'''.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
while(notConnected)
while(notConnected)
   {
   {
Строка 78: Строка 78:
Чтобы удостовериться, что модем готов принимать входящие звонки, воспользуемся функцией hangCall().
Чтобы удостовериться, что модем готов принимать входящие звонки, воспользуемся функцией hangCall().


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
vcs.hangCall();
vcs.hangCall();
</syntaxhighlight>
</syntaxhighlight>
Строка 84: Строка 84:
Заканчиваем setup() выводом двух сообщений на '''Serial Monitor''' – о том, что '''GSM''' инициализирован, а скетч ждет звонка.
Заканчиваем setup() выводом двух сообщений на '''Serial Monitor''' – о том, что '''GSM''' инициализирован, а скетч ждет звонка.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
Serial.println("GSM initialized.");
Serial.println("GSM initialized.");
   Serial.println("Awaiting call.");
   Serial.println("Awaiting call.");
Строка 92: Строка 92:
В секции loop() воспользуемся оператором switch для управления тем, по какому сценарию может пойти работа программы. Для того, чтобы определить статус скетча, вызовем функцию getvoiceCallStatus().
В секции loop() воспользуемся оператором switch для управления тем, по какому сценарию может пойти работа программы. Для того, чтобы определить статус скетча, вызовем функцию getvoiceCallStatus().


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
void loop()
void loop()
{
{
Строка 101: Строка 101:
Если функция getvoiceCallStatus() возвращает значение '''IDLE_CALL''', то дальше ничего не происходит.
Если функция getvoiceCallStatus() возвращает значение '''IDLE_CALL''', то дальше ничего не происходит.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
case IDLE_CALL:
case IDLE_CALL:


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


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
case RECEIVINGCALL:
case RECEIVINGCALL:


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


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
case TALKING:
case TALKING:


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


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
delay(1000);
delay(1000);
}
}
Строка 150: Строка 150:
Загрузив код, откройте '''Serial Monitor'''. Убедитесь, что '''Serial Monitor''' настроен таким образом, что при нажатии на кнопку ввода отправляет только символ новой строки.
Загрузив код, откройте '''Serial Monitor'''. Убедитесь, что '''Serial Monitor''' настроен таким образом, что при нажатии на кнопку ввода отправляет только символ новой строки.


<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS">
/*
/*
Прием голосового звонка
Прием голосового звонка

Версия от 12:32, 20 мая 2023

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


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

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

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

  • Плата Arduino;
  • Модуль Arduino + Telefonica GSM/GPRS Shield;
  • Микрофон и динамик, подсоединенные к GSM 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;

Создаем массив типа 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()

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