Цель — добавить Bluetooth в штатный магнитофон, сохранив возможность управления им с руля и со штатных кнопок магнитолы. Для реализации пришлось сначала научиться вычислять код магнитолы и разобраться с протоколом работы кнопок руля (хотя в итоге это не понадобилось).
Делать решил как все — на модуле XS3868. На драйве есть куча отчетов по его интеграции, но все они меня не устроили, так как либо вообще никак не добавляли управление к модулю, либо делали это через внешний пульт. К тому же при этих переделках всегда приходилось оставлять модулю лентопротяжного механизма, так как без него мафон не работал. Поэтому принял решение делать правильно — выкидывать лентопротяжный механизм и делать его эмуляцию.
Итак, приступим. Лентопротяг подключен двумя шлейфами — 8-ми проводной шлейф с питанием и управлением и шлейф со звуковой головки. Звуковой шлейф нам не нужен, а на шлейф управления посмотрим внимательнее. На нём присутствуют:
— сигнал CRST — служит для перезагрузки контроллера лентопротяга
— +5В
— сигнал CRQ (линия прерывания, которое выставляет лентопротяг, когда хочет что-то сказать главному контроллеру)
— сигналы шины I2C — SCL и SDA — по ним проходит всё управление
— +12В
— земля
— сигнал наличия кассеты, соединенный с микриком (загадка для меня — почему не отдали это функцию на откуп лентопротяжки, а вынесли наружу)
Шаг номер 1. Изучение протокола.
Шаг скучный и кропотливый, но необходимый. Берём логический анализатор, цепляемся к сигнальным ногам, жмём кнопки на мафоне и записываем проходящие сигналы. Желающим поковыряться с протоколом самостоятельно — вот исходники, которые я записал, и использовал для дальнейшего анализа. Их можно загрузить в прогу для логического анализатора (даже не имея анализатора) и прикинуть что где и как работает.
Результаты анализа приводить не буду — это слишком долго и нудно, но пару моментов отмечу:
-после включения магнитофона лентопротяг должен отчитаться в течении полутора секунд о своём состоянии. Если этого не происходит — вылезает ошибка.
-в лентопротяг приходят только самые базовый команды типа "мотай вперед/назад", "играй", "включись/выключись", "выплюни кассету". Я рассчитывал на то, что где-то там гуляют данные, передаваемые на дисплей, но увы. Если кому интересно, то вот файлик, в который я выписал проанализированные данные с ЛА.
Шаг номер 2. Прототип.
Прикрутил проводами XS3868 к ардуине и надёжно замотал изолентой — и весь прототип. Схему не рисовал. Управление сделал дёрганьем ног на XS3868. Тут обнаружилась неприятная особенность — на импульсы короче 200мс модуль не реагирует, а мне это кажется очень долгим переключением. Вторая неприятная особенность — из-за особенностей Arduino он при перезагрузке почти 2 секунды проводит в загрузчике, что не позволяет прицепить полноценно RESET, так как магнитофон вываливается в ошибку раньше, чем загружается контроллер. В итоге на прототипе пришлось ситуацию ресета обрабатывать отдельно и адскими костылями.
По результатам эксплуатации прототипа выяснилось следующее:
-сильный цифровой шум очень напрягает, и натыкивание разделяющих резисторов/конденсаторов/индуктивностей проблему не решает
-хочется сбрасывать/принимать вызов по кнопкам на руле (next — принять вызов, back — сбросить/завершить)
Исходя из этого переходим к следующему шагу:
Шаг номер 3. Финальный вариант.
Рисуем схему и плату в Eagle. Взял ту же Atmega328P исключительно чтобы быстро перейти с Ардуинки, минимально переписывая код. Ключевой момент — полная изоляция блутуса. Питание развязано через трансформаторный DC-DC преобразователь, сигнальные линии развязаны оптронами.
Платка получилась простой, запаивается за час. Сам текстолит заказывал в seeedstudio, вот файлы для заказа
Пайка ручная.
Софт получился простой, как угол дома. Изначально я думал считывать информацию о состоянии из Bluetooth-модуля для корректного ответа на звонок, но выяснил, что ему можно просто отдать пачку команд (предыдущий трек/отклонить вызов/завершить вызов), и он всё сделает правильно, исходя из своего текущего состояния. Поэтому нижний оптрон можно не запаивать — он не используется. Зашиваю софт я через китайский клон USBASP, используя Avrdude. Собственно линуксоидам и маководам достаточно написать make flash — и всё зальётся, под виндой геморроя немного больше.
Главный нюанс в софте — это переключение треков. Дело в том, что мафон вырубает предусилитель, как только отдаёт команду лентопротягу на переключение трека. Хак, которым я это обошел — через несколько миллисекунд после получения команды на переключение трека вскидываю прерывание, и сообщаю магнитофону, что у меня закончилась плёнка, и я перевернул кассету и начал её играть. Магнитофон соглашается, и примерно через 100мс предусилитель включается обратно :)
Ну и видосик напоследок:
В результате всё работает как задумано, кроме микрофона — провод ещё не протянул. Треки переключаются по обоим парам кнопок на мафоне и по кнопкам на руле, по ним же сбрасывается/отвечается звонок. Единственный момент — после нажатия на switch side/eject секунд через 10-20 выскочит tape error и потребуется перезагрузка мафона. Ибо непонятно как в случае эмуляции выброса кассеты "затолкать" её обратно.
Уровень шума получился примерно такой же, как и на CD-ченджере — белый шум, который слышно только при переключении треков на громкости >90%.
К сожалению, есть паразитный писк через несколько секунд после отключения аудио (многократно описано в других источниках). Это немного напрягает, и я, пожалуй, нагружу выходной тракт блутуса на резисторы в пару десятков килоом чтобы его снизить, к тому же сейчас уровень громкости блутуса чуть выше, чем на CD или радио.
Задавайте вопросы, я мог что-то упустить, так как проект длится уже несколько месяцев. Всем добра и ровных дорог :)