DIY ЦАП от Soekris
Зачем
Как и любой человек, я люблю все новое, а уже если это новое в области увлечения и получения удовольствия, то это вдвойне приятно.
Но гораздо более приятно, когда новое можно сделать своими руками. Поэтому послушав и сравнив свой ЦАП на базе ESS9038Q2M с ЦАПом построенным на R2R технологии, несмотря на технические ограничение R2R, и обнаружив совершенно неожиданные плюсы второго, захотелось что-то подобное себе.
В погоне за вкусным звуком своих любимых песен был куплен Soekris 1021 — платка DIY которая по вполне удобоваримой цене, давала тот самый приятный звук, глубокую сцену, и выигрывала у стандартного китайца Topping D50s не по измерениям, а именно по личным впечатлениям от прослушивания. Ссылка на саму плату и ее описание тут: http://www.soekris.dk/dam1021.html
Далее будет описание проекта с небольшими порциями электроники и Ардуино.
Требования к проекту
Для себя определил, что кроме минимального требования самой платы — подключить питание, припаять цифровой вход, и аналоговые выходные коннекторы, захотелось иметь мониторчик, управлялку, возможно даже с дистанционным управлением, ну и прочие мелочи по типу красивых индикаторов.
Поэтому был взят Ардуино НАНО на базе которого и стал строится ЦАП.
В качестве монитора взят стандартный 16×2 тектовый контроллер, а в качестве управлялки использована одна кнопка.
Общая конструкция
Изначально, планировался один блок питания, выдающий ±9 вольт как и требуется схеме Soekris, но так как инвертированную схему с общей землей неудобно использовать для работы с другими уровнями питания, а так же с возникшей проблемой медленного старта Ардуино, которая отставала от практически мгновенного старта схемы ЦАП и не успевала к первому выводу установок которые ЦАП выплевывает по UART, то пришлось заиметь второй трансформатор, который питает отдельными 12 вольтами саму Ардуино, и дает 24В для управляющего питания на реле, которые и включают ЦАП при подачи 5 вольт с пина Ардуино на транзисторный ключ.
Общая схема питания выглядит примерно так (я не специалист в рисовалке и EAGLE не имеет картинок ни схемы монитора ни Ардуино, ни даже использованных типов реле, поэтому не судите строго — схема дает представление об идее и подключениях).
Первый БП имеет в составе два LM317 для стабилизации выходных 9В с обеих обмоток с радиаторами, и дополнительные фильтрующие конденсаторы на 47 мФ, а второй не задается такой целью, так как получает нужные 12 и 24 вольта с обмоток второго трансформатора. Более того ни управление реле ни Ардуино, не нуждаются в стабилизированном питании.
Немного описания
Soekris доступный по ссылке представляет собой немного нестандартное решение для входа с USB при этом полностью соответствует моему личному представлению о правильной организации системы асинхронной передачи данных.
А именно — в нем реализован входной буфер FIFO который помогает избежать затыков, рассинхронизации клоков, и прочих стандартных болезней на входе в ЦАП по USB.
Кроме того, все управление осуществляется через обычный интерфейс COM порта, что дает легкую возможность управлять системой через Ардуино Serial.
Поэтому у Ардуино задействован стандартный железный Tx/Rx транспорт, для монитора используется обычная стандартная система через I2C, управление обычной кнопкой с софтварным PULL_UP.
Реализован отложенный старт, и включение ЦАП осуществляется отдельным цифровым выходом подключенным к базе транзистора, виден на схеме, с помощью которого открывается проход на землю 24В требуемых двумя реле для включения и подачи питания на ЦАП.
В стандартном режиме на мониторе отображен вход, используемый поток (PCM/DSD, 44K / 192K и т.д. и текущий фильтр 1 из 4 выбранных). Долгое нажатие включает поочередно режим смены фильтра, режим смены входа и может по кругу вернуться в стандартный режим. При отсутствии действия на кнопке в течении 30 секунд возврат обратно автоматический.
Короткое нажатие переводит экран в режим стареньких индикаторов, имитация которых реализована с использованием второго выхода с ЦАП (там два аналоговых выхода для использования чистого выхода или буфера с ОП усилков). Я использую для прослушивания чистый выход ЦАП без операционников, а буферный выход заведен на две ардуиновские аналоговые ноги, состояние которых оценивается и выводится простеньким алгоритмом в виде аналоговых уровневых индикаторов.
Код
Код можно найти тут https://github.com/Gromush/adac на гитхабе.
Скетч поделен на файлы по тематике и легко модифицируется под любое изменение. Все константы зашиты в defs.h, в C формате, тем самым не надо бегать и искать где, что валяется.
Писать описания кода — дело неблагодарное, поэтому только суть.
Все константы для восстановления настроек пользователя лежат в EEPROM
Вся настройка в setup ()
void setup() {
sprintf(VersionString, "FW: %s", VERSION_STRING);
saved.bytes.filter = EEPROM.read(SAVED_ADDR_FILTER);
saved.bytes.input = EEPROM.read(SAVED_ADDR_INPUT);
SetupLed();
SetMainPwrOn();
InitLCD();
ButtonInit();
LCD_Print(0,0, "Starting...", true);
LCD_Print(0,1, VersionString,false);
LCD_PritLogo(12,0);
analogReference(DEFAULT);
analogWrite(BRIGHTNESS,BRIGHTNESS_VAL);
InitSerial();
GetGConfig()->inputType = UNINIT_VAL;
GetGConfig()->mode = MODE_NORMAL;
//DAC ON
pinMode(DAC_PWR_ENABLE,OUTPUT);
digitalWrite(DAC_PWR_ENABLE, HIGH);
SetPwrRdyOn();
WaitSerialChar(INFINIT);
GetDACDataSerial();
if (saved.bytes.filter == 0xFF)
{
saved.bytes.filter = GetGConfig()->FilterNum;
saved.bytes.filter = GetGConfig()->inputType;
EEPROM.write(SAVED_ADDR_FILTER, saved.bytes.filter);
EEPROM.write(SAVED_ADDR_INPUT, saved.bytes.input);
} else
{
// Put saved data to struct and DAC
SetFilter(&saved, true);
SetInput(&saved, true);
}
GetDACDataSerial();
PrintDisplay();
}
Функциональность легко отключается в main функции которая по сути вызывает блочно каждый элемент.
void loop() {
//
//CheckMode();
//
ButtonAction(&saved);
BlinkRdyLed(gBConf);
GetDACDataSerial();
ReturnToMainMode();
IndicatorAnalogs();
}
Заключение
Надеюсь мое решение будет полезно тем, кто тоже хочет сделать себе простой и качественный DIY ЦАП и сможет рассмотреть вариант системы как отправную точку.