Мишкофон
- Платформы: Iskra Neo
- Языки программирования: Arduino (C++)
- Тэги: Детский телефон, мягкая игрушка, радионяня, общение с ребёнком.
Что это?
С помощью этого «мишкофона» можно болтать со своим ребёнком и рассказывать ему сказки, не отходя от рабочего места. Да, есть вариант научить чадо пользоваться смартфоном. Но в смартфоне нет ничего волшебного. А плюшевый медведь, говорящий папиным голосом, — самое, что ни на есть настоящее волшебство. При чём сделанное своими руками.
Что нам понадобится?
- SIM-карта
- Миниатюрный активный динамик
- Микрофон
- Мягкая игрушка
Как собрать?
- Для начала вставьте сим-карту в GPRS Shield и установите его на платформу Iskra Neo.
- Подключите внешнюю антенну через SMA-разъём.
- На платах 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. На их место воткните два провода «мама-мама». - Присоедините к Troyka Shield контактные колодки и установите получившуюся конструкцию на GPRS Shield. Соединяем с помощью проводов «мама-мама» контакты
ST
иPK
GPRS Shield’a с пинами5
и6
платы Iskra Neo соответственно. - Используя два 3-проводных шлейфа подключите Troyka-гироскоп к Troyka Shield следующим образом:
- Контакты питания:
- Земля (G) — чёрный провод. Соединить с пином
GND
Troyka Shield. - Питание (V) — красный провод. Соединить с пином
VCC
Troyka Shield. - Не используется.
- Контакты шины I²C:
- Сигнальный (D) — чёрный провод. Подключить к
2
пину Troyka Shield. - Сигнальный (С) — красный провод. Подключить к
3
пину Troyka Shield. - Не используется.
- Используйте 3-проводной шлейф, чтобы подключить Troyka-светодиод к цифровому пину
13
на Troyka Shield. - Теперь подключите динамик и микрофон в соответствующие разъёмы GPRS Shield.
- Вставьте шесть NiMH аккумуляторов в батарейный отсек 3×2 AA. Через штекер питания 2,1 мм с клеммником подключите его к плате Iskra Neo.По итогу должна получиться следующая схема:
- Теперь вам нужно упаковать устройство в плюшевого зверя. Для этого переверните игрушку спиной к себе, сделайте аккуратный надрез по шву и разместите всю электронику внутри. Проще сразу взять игрушку с молнией на спине, как у нас, иначе замаетесь штопать, и получите в итоге монстра Франкинштейна вместо милой зверушки.
Алгоритм
- Сразу после подачи питания считываем данные с гироскопа.
- Если данные больше заданного порога в течении 5 секунд, звоним на указанный в коде номер.
- Каждую секунду проверяем — не пришёл ли входящий звонок.
- Если входящий номер совпадает с номером в коде, берём трубку. Другие номера игнорируем.
- Повторяем весь цикл.
Исходный код
- gsmbear.ino
// подключаем библиотеку для работы I²C #include <Wire.h> // подключаем библиотеку для работы с модулями IMU #include <TroykaIMU.h> // подключаем библиотеку для работы с GPRS устройством #include <GPRS_Shield_Arduino.h> // подключаем библиотеку для эмуляции Serial порта // она нужна для работы библиотеки GPRS_Shield_Arduino #include <SoftwareSerial.h> #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); } }
Демонстрация работы устройства
Что дальше?
Придумайте историю, о том, как волшебным образом работает связь через медведя или расскажите про невидимые волны, которые передают ваш голос на большие расстояния.
Если воткнуть в медведя датчик шума и настроить SMS-оповещения, при превышении определённого порога, сможете звонить каждый раз, как только малыш начнёт капризничать. WOW-эффект обеспечен.