Arduino:Примеры/GSMExamplesMakeVoiceCall

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

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


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

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

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

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

Цепь

GSMShield ArduinoUno.png

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

Код

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

1 #include <GSM.h>

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

1 #define PINNUMBER ""

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

1 GSM gsmAccess; 
2 GSMVoiceCall vcs;

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

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

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

1 void setup(){
2 
3   Serial.begin(9600); 
4   Serial.println("Make Voice Call");

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

1 boolean notConnected = true;

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

 1 while(notConnected)
 2   {
 3     if(gsmAccess.begin(PINNUMBER)==GSM_READY)
 4       notConnected = false;
 5     else
 6     {
 7       Serial.println("Not connected");
 8       delay(1000);
 9     }
10   }

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

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

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

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

 1 void loop()
 2 {
 3   while (Serial.available() > 0)
 4   {
 5     char inChar = Serial.read();
 6 <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
 7 
 8 Если в буфере есть символ новой строки, проверяем, не содержит ли вписанный телефонный номер более '''20 цифр''' (теоретически, вы никогда не сможете набрать номер, где цифр будет больше '''20-ти''').
 9 
10 <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS" enclose="div">
11 if (inChar == '\n')
12     {
13       if (remoteNumber.length() < 20)
14       {

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

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

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

1 remoteNumber.toCharArray(charbuffer, 20);

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

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

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

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

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

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

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

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

1 else
2     {
3       if(inChar!='\r')
4         remoteNumber += inChar;
5     }
6   } 
7 }

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

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

  1 /*
  2 Голосовой звонок при помощи Arduino
  3 
  4 Этот скетч для Arduino GSM Shield позволяет делать голосовой звонок 
  5 на удаленный телефонный номер, который вы вводите через Serial Monitor.
  6 Когда все будет настроено, откройте Serial Monitor и, увидев сообщение READY, впишите телефонный номер. 
  7 Убедитесь, что Serial Monitor настроен таким образом,
  8 чтобы при нажатии на клавишу ввода отсылался только символ новой строки.
  9 
 10 Цепь:
 11 * GSM Shield
 12 * Подключенные к Shield динамик и микрофон. 
 13 Без них ни отправлять, ни получать голосовые сообщения будет нельзя.
 14 
 15 Создан в марте 2012 Хавьером Зорзано (Javier Zorzano).
 16 
 17 Этот код не защищен авторским правом.
 18 */
 19 
 20 // Библиотеки:
 21 #include <GSM.h>
 22 
 23 // PIN-код:
 24 #define PINNUMBER ""
 25 
 26 // Создаем экземпляры классов GSM и GSMVoiceCall:
 27 GSM gsmAccess; // включая параметр «true» для активации отладки
 28 GSMVoiceCall vcs;
 29 
 30 String remoteNumber = "";  // номер, по которому вы будете звонить
 31 char charbuffer[20];
 32 
 33 void setup()
 34 {
 35 
 36   // Инициализируем последовательную передачу данных и ждем открытия порта:
 37   Serial.begin(9600);
 38   while (!Serial) {
 39     ; // ждем подключения последовательного порта (нужно только для Leonardo)
 40   }
 41 
 42   Serial.println("Make Voice Call");  //  "Делаем голосовой звонок"
 43 
 44   // Состояние соединения:
 45   boolean notConnected = true;
 46 
 47   // Запускаем GSM Shield.
 48   // Если у вашей SIM-карты есть PIN, делаем его параметром функции gsmAccess.begin():
 49   while (notConnected)
 50   {
 51     if (gsmAccess.begin(PINNUMBER) == GSM_READY)
 52       notConnected = false;
 53     else
 54     {
 55       Serial.println("Not connected");  //  "Подключиться не удалось"
 56       delay(1000);
 57     }
 58   }
 59 
 60   Serial.println("GSM initialized.");  //  "GSM инициализирован."
 61   Serial.println("Enter phone number to call.");  //  "Введите телефонный номер, на который будем звонить."
 62 
 63 }
 64 void loop()
 65 {
 66 
 67   // Добавляем в строку любые входящие символы:
 68   while (Serial.available() > 0)
 69   {
 70     char inChar = Serial.read();
 71     // Если это символ новой строки, значит, делаем звонок:
 72     if (inChar == '\n')
 73     {
 74       // Убедитесь, что телефонный номер не слишком длинен:
 75       if (remoteNumber.length() < 20)
 76       {
 77         // Дайте пользователю знать, что вы звоните:
 78         Serial.print("Calling to : ");  //  "Звоним на: "
 79         Serial.println(remoteNumber);
 80         Serial.println();
 81 
 82         // Звоним на указанный номер:
 83         remoteNumber.toCharArray(charbuffer, 20);
 84 
 85 
 86         // Проверяем, сняли ли на том конце трубку:
 87         if (vcs.voiceCall(charbuffer))
 88         {
 89           Serial.println("Call Established. Enter line to end");  //  "Связь установлена. Введите символ новой строки, чтобы закончить"
 90           // Ждем получения символа новой строки:
 91           while (Serial.read() != '\n' && (vcs.getvoiceCallStatus() == TALKING));
 92           // и вешаем «трубку»:
 93           vcs.hangCall();
 94         }
 95         Serial.println("Call Finished");  //  "Звонок окончен"
 96         remoteNumber = "";
 97         Serial.println("Enter phone number to call.");  //  "Введите телефонный номер, на который хотите позвонить."
 98       }
 99       else
100       {
101         Serial.println("That's too long for a phone number. I'm forgetting it");  //  "Слишком длинный номер. Такие у меня в голове не помещаются"
102         remoteNumber = "";
103       }
104     }
105     else
106     {
107       // Чтобы отправить сообщение, добавьте к нему последний символ:
108       if (inChar != '\r')
109         remoteNumber += inChar;
110     }
111   }
112 }

См.также

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

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