В котором телефон с номеронабирателем получает электронику для работы в мобильных сетях и может работать, как было задумано.
Это описание проекта из трёх частей, которое я должен был написать в качестве торжественного завершения самого проекта, но поскольку я слишком оттянул этот момент, я решил описать весь проект целиком в виде одного связного изложения.
Если кто помнит, я очень сердитый человек. Я легко распаляюсь, говоря по телефону, но сейчас не существует хорошего способа выразить своё раздражение. Я скучаю по старому времени, когда можно было с силой шарахнуть телефонной трубкой по аппарату, чтобы сбросить напряжение – но мобильные телефоны такой возможности не дают. И я задался целью создать мобильный телефон с номеронабирателем.
Так и родился iRotary
Проект iRotary
Красотуля
Начал я с покупки олдскульного настоящего телефона с поворотным номеронабирателем – как раз такого, какой я использовал ещё ребёнком. Выбрал я славный оранжевый цвет, чтобы красота iRotary не уступала амбициозности проекта.
Фото сделано с того самого телефона в первый день покупки, с кабелями и всем остальным. Именно так здорово он выглядит и сегодня, хотя у него на 50% меньше проводов – что хорошо в случае мобильных телефонов.
Весь проект обошёлся мне в $150 на запчасти и в $2000 за время разработки – он занял два полных дня на сборку, и растянулся на несколько месяцев всяких действий, ожидания запчастей, использования запчастей, ожидания следующих запчастей и т.п. Первый шаг, конечно, заключался в извлечении всего ненужного и заменой на всё нужное.
Шаг 1: первый, вах!
Представьте, каково заявиться с таким в клубешник!
Лучший кандидат в интерфейсы со старым номеронабирателем, конечно же, Arduino. Он же будет отвечать и за работу с GSM. Он идеален для чтения импульсов номеронабирателя и преобразования их в целое число, которое затем можно использовать для набирания номера.
Коммуникации без проблем обрабатываются GSM-шилдом. Это периферийное устройство, подсоединяющееся к Arduino (на улицах мы зовём его «шилдом»). Его очень просто программировать, к нему идёт библиотека с большинством нужных функций – чтение SMS, отправка и приём звонков, отправка DTMF, и проч.
Следующим шагом было написание кода для преобразования набора в числа. Набиратель работает так: после принудительного вращения он начинает вращаться обратно, оно задевает переключатель по разу для каждого набираемого номера. Это значит, что если вы наберёте три, переключатель отправит три сигнала, так как мимо него пройдут три номера. Чтобы определить набранное число, нужно просто подсчитать, сколько раз переключатель был открыт и закрыт.
Это было легко сделать следующим кодом, который просто инкрементирует переменную каждый раз, когда напряжение с переключателя меняется с low до high:
void readPulses() {
char pinPulse = digitalRead(PIN_PULSE);
if (pinPulse == HIGH && edge == 0) {
pulses++;
edge = 1;
} else if (pinPulse == LOW && edge == 1) {
edge = 0;
}
}
Всё, что нужно сделать дальше – собрать цифры и сделать звонок, когда количество цифр достигнет 10. В Греции все номера десятизначные, за исключением номеров секса по телефону, код для которых я добавлю позже.
Добавление цифр к строке по очереди – процесс простой, делается следующим кодом.
void readDialing() {
char digit;
bool finalDigit = false;
char pinDialing = digitalRead(PIN_DIALING);
if (pinDialing == 1 && dialing == 0) {
digit = getDigit();
if (digit != -1) {
number += (int)digit;
showNumber(number);
if (number.length() == NUMBER_LENGTH) {
dialNumber(number);
}
}
}
dialing = pinDialing;
}
Он ещё не отправлял звонок, поскольку шилд ещё не был подключен – это был уже следующий шаг. Вот прототип за работой:
Он хорошо заработал прямо сразу, даже со старым, полуразвалившимся аппаратом, который я нашёл для прототипирования. Номеронабиратель – удивительно точная штука, и он должен таким быть, иначе вы могли бы попасть не туда, и не узнать об этом, пока вам не ответил бы какой-нибудь чувак, а вы звоните своей девушке, и вы решите, что она вам изменяет, и закатите скандал, а на самом деле это просто переключатель барахлит. Именно поэтому количество разводов резко упало после ввода цифровых тональных номеронабирателей. Кроме этого, снизилось насилие по отношению к людям с большим количеством нулей в номерах.
Шаг 2: кто не рискует, тот не GSM-ит
Следующий шаг после успешного распознавания номеров – добавить возможность совершать звонки по мобильной связи. Я соединил шилд с Arduino и добавил нужный для звонков код:
void dialNumber(String number) {
call.Call(numArray);
}
Захватывающе.
Хотя это так просто, это было очень здорово, потому что большая часть функциональности мобильного телефона (набор номера и звонки) была готова. Вот как это работает:
На этом шаге я встретил несколько сложностей. Первая – где разместить Arduino с шилдом в телефоне, поскольку там практически не было места из-за компонентов телефона. Для решения этой почти неразрешимой задачи пришлось пойти на компромисс: я удалил звонок, который всё равно нельзя было запитать от батарейки (ему нужно 50 В), чем уменьшил аутентичность аппарата. Зачем нужен телефон с номеронабирателем, если он не может произвести знакомый звук дззззззззззззззззынь?
И пришло вдохновение! Решение было простым: пусть телефон будет работать в тихом режиме, будет вежливым, чтобы не беспокоить других людей, но в остальном – прекрасным.
Решив одним махом две проблемы, я почувствовал, как моя радость растёт. Ещё одна проблема заключалась в том, что нужно было каким-то образом подключить вход и выход шилда к трубке. Тут отговорки не помогут, так как ни один уважающий себя телефон не будет глухим и немым, поэтому я сначала задумал купить мелкие микрофон и динамик, и засунуть их в трубку. И почти уже заказал, когда вдруг решил: а попробую-ка я сначала существующие микрофон и динамик.
Я быстренько поскакал к кульману и набросал сложнейшую схему, состоящую из огромного количества компонентов: трёх проводов и двух коннекторов. Собрав всё вместе, я вставил коннекторы во входы и выходы шилда и сделал звонок.
— Привет! – сказал мой голос.
— Привет! – радостно ответил я.
— Я тебя слышу! – сказал я себе.
— И я тебя! – прозвучал ответ.
Тест завершился оглушительным успехом. Существующие компоненты не только подходили к шилду, но и производили аутентичный шуршащий звук и обратную связь, о которых я успел забыть.
Разница между мобильным и таким телефоном в том, что первому не нужно проигрывать ваш голос обратно через динамик. Поэтому вам кажется, что ваш голос тише, чем есть (поскольку вы затыкаете ухо динамиком), и вы больше кричите – как если бы вы пытались слушать музыку в наушниках, одновременно разговаривая с кем-либо.
А по старому телефону вы можете слышать свой голос при разговоре, что приятно, и что не требует от вас кричать на вашего собеседника. Это приятный эффект, которого мы лишились.
Вот тизер конечного продукта:
Звуки звонка ненастоящие, но это же Голливуд.
Шаг 3: шагаем дальше
Когда аудио, распознавание номера и GSM заработали, настало время подключить остальные управления – рычаг, кнопку и странную светодиодную штуку, индикатор загрузки.
Лучше всего делать это через события. Arduino так не работает, потому что вам постоянно нужно спрашивать «не нажата ли кнопка?» много тысяч раз в секунду, но архитектуру событий легко подделать, использовав немножечко кода.
Я хотел, чтобы поднятие трубки с рычага отвечало на звонок, если телефон звонил, а размещение трубки обратно на рычаге прерывало текущий звонок. Также я хотел, чтобы все сигналы управления игнорировались, когда трубка была на рычаге.
Этого легко достичь с машиной состояний. Это значит, что существует переменная, содержащая текущее состояние телефона – в покое, разговор, звонит, набирает и т.д. И если происходят какие-то события (нажатие кнопки), могут просто проверять, в каком состоянии находится телефон, и либо выполнить действие, либо не выполнить.
События
Распознавать события можно так же, как номера. Мы проверим, меняется ли состояние кнопки, и запустим событие, только если засечём изменение (а иначе мы бы запускали событие тысячи раз, когда спрашивали «нажата ли кнопка», и Arduino отвечал бы «да» тысячи раз в секунду).
#define PIN_BUTTON_HALF 6
char buttonHalfEdge = 0;
void checkButtonHalfPressed() {
if (digitalRead(PIN_BUTTON_HALF) == LOW) {
if (buttonHalfEdge == 0) {
buttonHalfPressed();
}
buttonHalfEdge = 1;
} else {
if (buttonHalfEdge == 1) {
buttonHalfReleased();
}
buttonHalfEdge = 0;
}
}
У этой кнопки два состояния, полу-нажатая и целиком нажатая (или полу-отжатая и целиком отжатая, если спросить пессимиста). Код определяет оба состояния, и другие события обрабатываются примерно так же.
За работой системы можно посмотреть в следующем видео, где компоненты находятся в корпусе, но его всё ещё нужно втыкать в USB для питания.
Красота!
Шаг 4: питание от аккумулятора
USB-коннектор для зарядки аккумулятора
Конечно, что это был бы за мобильный телефон, если бы он не был мобилен? Это был бы не мобильный телефон! Так что два варианта для ношения телефона – это небольшой 5-вольтовый аккумулятор и схема для USB-зарядки, или очень, очень длинный кабель. Поскольку медь сегодня стоит дороже золота, а я сделан не из денег, я выбрал первый вариант.
Для него нужны три компонента:
- Аккумулятор (с держателем, без которого он не работает). Очевидно, он будет питать телефон, и не очевидно, будет скрыт с глаз внутри корпуса.
- Схема зарядки, один конец которой будет соединён с аккумулятором, а другой – с USB-коннектором типа «мама». Можно будет заряжать батарею обычной USB-зарядкой.
- Некий регулятор (не помню точного названия). Будет соединён с батареей, и будет лишать её энергии, прямо как криптонит для аккумуляторов. Аккумуляторы не выдают то напряжение, которое обещают, а вместо этого выдают все меньше и меньше по мере разрядки, и этот компонент позволит Arduino получить честные 5В, пока аккумулятор не сдохнет полностью.
Регулятор и зарядка в сборе
Ещё раз повторим, что аккумулятор и регулятор соединены с зарядкой. У зарядки есть USB-порт (и я использовал удлинитель, чтобы провести его туда, где был телефонный кабель), который будет использоваться для зарядки. Регулятор все разрулит и выдаст нужное напряжение нужным компонентам, так что вы можете включать и выключать телефон во время работы, и напряжение не будет падать.
Также можно заряжать включённый телефон, что удобно. Не знаю, на сколько хватит батареи, я не использовал её больше, чем несколько часов, но возможно, на пару дней –ведь вы не сможете писать своим друзьям с телефона (надо подсоединять пишущую машинку). Я попробую это протестировать когда-нибудь, но пока что просто заявлю, что батарейка живёт месяцами, а говорить можно неделями, и он тогда будет лучше продаваться, или хотя бы быстрее наберёт нужную сумму на кикстартере.
Шаг 5: шага 5 нет.
Внутренности в сборе
И проект был завершён! После протяжки проводов и впихивания вещей в такие места, для которых они не были предназначены, можно закрыть корпус, в котором всё хорошо укладывается – если только его не трясти.
Можно примерно разобрать расположение компонентов. Arduino справа вверху, под ним находится шилд (можно видеть торчащую антенну), голубой USB-кабель питания идёт к регулятору, соединённому с батареей и зарядником, идущим к разъёму типа «мама» слева вверху. Можно видеть кабели для микрофона и динамика (из правого верхнего угла в левый).
Схемы на коричневой плате снизу – это оригинальные схемы телефона. Они не используются, но удалять их было бы тяжело, и, возможно, без них не работал бы рычаг (прозрачный кусок пластика слева), что было бы неприемлемо.
И вот, как обещал, финальный рекламный ролик, во всей его финальной красоте. Что за прелесть! Обязательно разошлите его всем друзьям, даже тем, с которыми давно не общались. Что может быть важнее, чем вновь пообщаться со старыми друзьями благодаря безумному интернет-проекту какого-то чувака из Греции? Конечно, ничего!
Если вам прямо чешется сделать свой собственный мобильный телефон с номеронабирателем, и вы раздумываете над написанием всего с нуля, над проведением бессонных ночей над реверс-инжинирингом моих кусочков кода, у меня для вас хорошие новости. Я опубликовал весь код в онлайне, потому что ну вот такой я человек.
github.com/skorokithakis/iRotary
Расскажите мне, как сильно этот потрясающий проект изменил вашу жизнь в комментариях к оригинальной статье или в твиттере! Чмоки!
Автор: SLY_G