====== Мишкофон ====== {{ :projects:gsmbear:gsmbear_overview.jpg?nolink&700 |}} * Платформы: Iskra Neo * Языки программирования: Arduino (C++) * Тэги: Детский телефон, мягкая игрушка, радионяня, общение с ребёнком. ===== Что это? ===== С помощью этого «мишкофона» можно болтать со своим ребёнком и рассказывать ему сказки, не отходя от рабочего места. Да, есть вариант научить чадо пользоваться смартфоном. Но в смартфоне нет ничего волшебного. А плюшевый медведь, говорящий папиным голосом, — самое, что ни на есть настоящее волшебство. При чём сделанное своими руками. ===== Что нам понадобится? ===== {{ :projects:gsmbear:gsmbear_parts.jpg?nolink&700 |}} - [[amp>product/iskra-neo?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | Iskra Neo]] - [[amp>product/arduino-gprs-shield?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | GPRS Shield]] - [[amp>product/arduino-troyka-shield?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | Troyka Shield]] - [[amp>product/troyka-gyro?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | Гироскоп (Troyka-модуль)]] - [[amp>product/troyka-led-module?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | Светодиод «Пиранья» Красный (Troyka-модуль)]] - [[amp>product/21mm-screw-jack?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | Штекер питания 2,1 мм с клеммником]] - [[amp>product/stackable-pin-headers-with-icsp?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | Контактные колодки Arduino]] - [[amp>product/battery-holder-3x2-aa?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | Батарейный отсек 3×2 AA]] - 6×[[amp>product/nimh-aa-cell?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | NiMH-аккумулятор]] - [[amp>product/wire-ff?utm_source=proj&utm_campaign=gsmbeer&utm_medium=wiki | Соединительные провода «мама-мама»]] - SIM-карта - Миниатюрный активный динамик - Микрофон - Мягкая игрушка ===== Как собрать? ===== - Для начала вставьте сим-карту в GPRS Shield и установите его на платформу Iskra Neo.{{ :projects:gsmbear:gsmbear_build1.jpg?nolink&700 |}} - Подключите внешнюю антенну через SMA-разъём.{{ :projects:gsmbear:gsmbear_build2.jpg?nolink&700 |}} - На платах Arduino с микроконтроллером ATmega32U4 (Iskra Neo, Arduino Leonardo, Arduino ETH, Arduino Micro и Arduino Yún) пины ''2'' и ''3'' используются для протокола I²C. В GPRS Shield контакты ''PK'' и ''ST'' также по умолчанию находятся на пинах ''2'' и ''3''. Чтобы избежать конфликта с I²C-гироскопом перебросим контакты ''PK'' и ''ST'' GPRS Shield’a на пины ''6'' и ''5''. Для этого снимите джамперы с контактов ''ST'' и ''PK'' GPRS Shield’a. На их место воткните два провода «мама-мама».{{ :projects:gsmbear:gsmbear_build3.jpg?nolink&700 |}} - Присоедините к Troyka Shield контактные колодки и установите получившуюся конструкцию на GPRS Shield. Соединяем с помощью проводов «мама-мама» контакты ''ST'' и ''PK'' GPRS Shield’a с пинами ''5'' и ''6'' платы Iskra Neo соответственно.{{ :projects:gsmbear:gsmbear_build4.jpg?nolink&700 |}} - Используя два 3-проводных шлейфа подключите Troyka-гироскоп к Troyka Shield следующим образом: * **Контакты питания:** - Земля (G) — чёрный провод. Соединить с пином ''GND'' Troyka Shield. - Питание (V) — красный провод. Соединить с пином ''VCC'' Troyka Shield. - Не используется. * **Контакты шины I²C:** - Сигнальный (D) — чёрный провод. Подключить к ''2'' пину Troyka Shield. - Сигнальный (С) — красный провод. Подключить к ''3'' пину Troyka Shield. - Не используется.{{ :projects:gsmbear:gsmbear_gyro_scheme.png?nolink&282 |}} - Используйте 3-проводной шлейф, чтобы подключить Troyka-светодиод к цифровому пину ''13'' на Troyka Shield.{{ :projects:gsmbear:gsmbear_build6.jpg?nolink&700 |}} - Теперь подключите динамик и микрофон в соответствующие разъёмы GPRS Shield.{{ :projects:gsmbear:gsmbear_build7.jpg?nolink&700 |}} - Вставьте шесть NiMH аккумуляторов в батарейный отсек 3×2 AA. Через штекер питания 2,1 мм с клеммником подключите его к плате Iskra Neo.{{ :projects:gsmbear:gsmbear_build8.jpg?nolink&700 |}}По итогу должна получиться следующая схема:{{ :projects:gsmbear:gsmbear_scheme.png?nolink& |}} - Теперь вам нужно упаковать устройство в плюшевого зверя. Для этого переверните игрушку спиной к себе, сделайте аккуратный надрез по шву и разместите всю электронику внутри. Проще сразу взять игрушку с молнией на спине, как у нас, иначе замаетесь штопать, и получите в итоге монстра Франкинштейна вместо милой зверушки.{{ :projects:gsmbear:gsmbear_build9.jpg?nolink&700 |}} ===== Алгоритм ===== * Сразу после подачи питания считываем данные с гироскопа. * Если данные больше заданного порога в течении 5 секунд, звоним на указанный в коде номер. * Каждую секунду проверяем — не пришёл ли входящий звонок. * Если входящий номер совпадает с номером в коде, берём трубку. Другие номера игнорируем. * Повторяем весь цикл. ===== Исходный код ===== // подключаем библиотеку для работы I²C #include // подключаем библиотеку для работы с модулями IMU #include // подключаем библиотеку для работы с GPRS устройством #include // подключаем библиотеку для эмуляции Serial порта // она нужна для работы библиотеки GPRS_Shield_Arduino #include #define GPRS_BUFFER_LENGTH 46 #define TELEPHONE_NUM_LENGTH 12 // порог скорости вращения гироскопа #define ROTATE_SPEED_TRESHOLD 10 // время задержки, после которой будет совершён исходящий вызов #define OUTCOMING_CALL_TIMEOUT 5000 // порог после которого будем звонить #define OUTCOMING_CALL_TRESHOLD 500 // индикаторный светодиод расположен на 13 пине #define INDICATOR_PIN 13 char fathersNumber[] = "+74993221317"; char incomingPhoneNumber[GPRS_BUFFER_LENGTH]; // создаём объект класса GPRS, передаём ему // номера пинов PK, ST и скорость 9600 бод GPRS gprs(6, 5, 9600); // создаём объект для работы с гироскопом Gyroscope gyro; unsigned long waitTime = 0; unsigned long rotateTime = 0; int rotateCounter = 0; void setup() { //настраиваем пин 13 в режим выхода, pinMode(INDICATOR_PIN, OUTPUT); // подаём на пин 13 «низкий уровень» digitalWrite(INDICATOR_PIN, LOW); // включаем GPRS Shield gprs.powerUpDown(); while (!gprs.init()) { // завелся ли GPRS Shield? digitalWrite(INDICATOR_PIN, !digitalRead(INDICATOR_PIN)); // если связи нет, ждём 1 секунду // процесс повторяется в цикле, // пока не появится ответ от GPRS устройства delay(1000); } digitalWrite(INDICATOR_PIN, LOW); // запускаем гироскоп gyro.begin(); } void loop() { // если функция возвращает true if (gyroCall()) { // звоним на заданный в коде номер gprs.callUp(fathersNumber); // индикация звонка calling(); } // каждую секунду ожидаем входящий звонок if (millis() - waitTime > 1000) { incomingCall(); // запоминаем текущее время waitTime = millis(); } } void incomingCall() { // ожидаем звонка if (gprs.ifcallNow()) { // если поступает входящий звонок, // подаём на пин 13 «высокий уровень», чтобы // зажечь светодиод на 13 пине digitalWrite(INDICATOR_PIN, HIGH); // считываем номер входящего звонка gprs.isCallActive(incomingPhoneNumber); if (!strncmp(incomingPhoneNumber, fathersNumber, TELEPHONE_NUM_LENGTH)) { // если звонит папа // по истечении 3 секунд берём трубку delay(3000); gprs.answer(); // индикация звонка calling(); } else { // если нет, кладём трубку gprs.callEnd(); } } } bool gyroCall() { // считываем абсолютную скорость вращения гироскопа по трём осям float bearRotate = abs(gyro.readDegPerSecX()) + abs(gyro.readDegPerSecY()) + abs(gyro.readDegPerSecZ()); // если это не случайные помехи if (bearRotate > ROTATE_SPEED_TRESHOLD) { // запоминаем текущее время rotateTime = millis(); // увеличиваем счётчик вращения ++rotateCounter; // увеличиваем яркость светодиода analogWrite(INDICATOR_PIN, map(rotateCounter, 0, OUTCOMING_CALL_TRESHOLD, 0, 255)); } else if (millis() - rotateTime > OUTCOMING_CALL_TIMEOUT) { // если же скорость вращение была ниже порога в течении 5 секунд // гасим светодиод digitalWrite(INDICATOR_PIN, LOW); // обнуляем счётчик вращения rotateCounter = 0; } // возвращаем результат // превысил ли счётчик вращения порог срабатывания исходящего звонка return (rotateCounter > OUTCOMING_CALL_TRESHOLD); } void calling() { while (!gprs.ifcallEnd()) { // моргаем и ждём пока абонент не положит трубку digitalWrite(INDICATOR_PIN, HIGH); delay(50); digitalWrite(INDICATOR_PIN, LOW); delay(200); digitalWrite(INDICATOR_PIN, HIGH); delay(50); digitalWrite(INDICATOR_PIN, LOW); } } ===== Демонстрация работы устройства ===== {{youtube>HrOUeHlAUAE?large}} ===== Что дальше? ===== Придумайте историю, о том, как волшебным образом работает связь через медведя или расскажите про невидимые волны, которые передают ваш голос на большие расстояния. Если воткнуть в медведя [[amp>product/troyka-sound-loudness-sensor?utm_source=proj&utm_campaign=gsmbear&utm_medium=wiki | датчик шума]] и настроить SMS-оповещения, при превышении определённого порога, сможете звонить каждый раз, как только малыш начнёт капризничать. WOW-эффект обеспечен.