Найти в Дзене
Чиним тачку

Тюнинг гонга BMW / Retrofit chime (часть 3)

В прошлой части я написал что эксперимент не удался и голый модуль не работает так как нам необходимо. Для корректной работы гонга требуется контроллер, который будет обрабатывать входящие сигналы.

Прикупил Arduino Nano. Написал прошивку. Программа запоминает входящие сигналы и проигрывает их в соответствии с запрограммированным приоритетом.

Т.е даже если сейчас звучит более приоритетный сигнал, то как только он закончится, проиграются другие сигналы, которые постоянно отлавливаются и добавляются в очередь.

Код программы я выложу снизу. Если кто захочет повторить, мне не жалко. Но скажу сразу, что при подключении к автомобилю возникли ложные срабатывания, которые я исправил опытным путем, а подробности устройства автомобильных сигналов решил не раскрывать.

Принимаю заказы WhatsApp +79191898286

Если вам необходим такой гонг, то по стоимости напишите мне на ватсаб. Доставку можно оформлять через Avito, Почтомат или BoxBerry. Учтите, что только себестоимость такого устройства будет в районе 2500 (сам гонг + микросхемы + флеш карта), да и работа творческая.

Устройство обрабатывает и проигрывает 5 сигналов. Корректная работоспособность парктроника пока что не гарантируется. Требуется доработка обработки этого сигнала. У меня в машине парктроника нет. Экспериментировать не на чем.

При желании вы можете прокинуть провод сигнала включения заднего хода и получить приятный, не громкий звук при реверсивном движении предупреждающий что воткнули заднюю, а не переднюю передачу.

Данный образец я собрал как тестовый для отладки. К тому же в процессе сборки приходилось думать как лучше расположить модули в крайне малом пространстве. Следующие гонги буду собирать еще более качественно.

Например канифоль я не стал отмывать, так как в процессе сборки приходилось постоянно припаивать и отпаивать провода. Питание я задублировал, что позволяет использовать разные фишки, например только большую или только маленькую.

-2
-3
-4

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

-5

USB гнездо вывел сбоку корпуса, что позволяет перепрограммировать устройство без разбора корпуса. Также, через USB работает питание устройства, что позволяет его проверить на столе.

-6
-7
-8

SD карту можно также заменить без разбора корпуса. Простым нажатием извлекаем и меняем звуки по желанию. Сделал видео где видно как работают все звуки, но оно удалилось. Остался только отрывок который можно посмотреть на ютуб.

Тюнинг гонг BMW Retrofit Chime (Gong)
Gong Sounds.zip

Просили выложить звуки, выкладываю их в архиве. Кстати, пришлось многократно подбирать громкость звуков, чтобы на готовом устройстве они звучали приятно и одинаково, а не орали.

-9

🔗 https://pay.mysbertips.ru/83928782

#include <DFMiniMp3.h>
#include <DfMp3Types.h>
#include <Mp3ChipBase.h>
#include <Mp3ChipIncongruousNoAck.h>
#include <Mp3ChipMH2024K16SS.h>
#include <Mp3ChipOriginal.h>
#include <SoftwareSerial.h>

const uint8_t PIN_TON1 = 2;
const uint8_t PIN_TON2 = 3;
const uint8_t PIN_TON3 = 4;
const uint8_t PIN_TON4 = 5;
const uint8_t PIN_TON5 = 6;

boolean ton1_required = false;
boolean ton2_required = false;
boolean ton3_required = false;
boolean ton4_required = false;
boolean ton5_required = false;

class Mp3Notify;

SoftwareSerial mySerial(10, 11); // RX, TX

typedef DFMiniMp3<SoftwareSerial, Mp3Notify> DfMp3;

DfMp3 player(mySerial);

boolean isPlaying = false;

class Mp3Notify
{
public:
static void PrintlnSourceAction(DfMp3_PlaySources source, const char* action)
{
}

static void OnError([[maybe_unused]] DfMp3& mp3, uint16_t errorCode)
{
}

static void OnPlayFinished([[maybe_unused]] DfMp3& mp3, [[maybe_unused]]
DfMp3_PlaySources source, uint16_t track)
{
isPlaying = false;
}

static void OnPlaySourceOnline([[maybe_unused]] DfMp3& mp3,
DfMp3_PlaySources source)
{
}

static void OnPlaySourceInserted([[maybe_unused]] DfMp3& mp3,
DfMp3_PlaySources source)
{
}

static void OnPlaySourceRemoved([[maybe_unused]] DfMp3& mp3,
DfMp3_PlaySources source)
{
}
};

void setup() {
initPins();
initPlayer();
}

void initPins() {
pinMode(PIN_TON1, INPUT_PULLUP);
pinMode(PIN_TON2, INPUT_PULLUP);
pinMode(PIN_TON3, INPUT_PULLUP);
pinMode(PIN_TON4, INPUT_PULLUP);
pinMode(PIN_TON5, INPUT_PULLUP);
}

void initPlayer()
{
Serial.begin(9600);
mySerial.begin(9600);
player.begin();
// player.reset();
player.setVolume(30);
}

void loop()
{
boolean ton1_state = readState(PIN_TON1);
boolean ton2_state = readState(PIN_TON2);
boolean ton3_state = readState(PIN_TON3);
boolean ton4_state = readState(PIN_TON4);
boolean ton5_state = readState(PIN_TON5);

if (ton1_state) ton1_required = true;
if (ton2_state) ton2_required = true;
if (ton3_state) ton3_required = true;
if (ton4_state) ton4_required = true;
if (ton5_state) ton5_required = true;
if (!isPlaying) playQueue();
wait(10);
}

boolean readState(uint8_t pin) {
if (digitalRead(pin)) return false;
return true;
}

void playQueue()
{
// Priority T3 > Т4 > T2 > T1 > T5
if (ton3_required) {
ton3_required = false;
playTon(3);
}

else if (ton4_required) {
ton4_required = false;
playTon(4);
}

else if (ton2_required) {
ton2_required = false;
playTon(2);
}

else if (ton1_required) {
ton1_required = false;
playTon(1);
}

else if (ton5_required) {
ton5_required = false;
playTon(5);
}
}

void playTon(uint16_t ton) {
isPlaying = true;
player.playMp3FolderTrack(ton);
if (ton != 4) delay(300);
}

void wait(uint16_t ms)
{
uint32_t start = millis();
while ((millis() - start) < ms) {
player.loop();
delay(1);
}
}