As the conversation progressed, it became apparent that a more versatile solution would be preferrable. Such a solution would be compatible with most of the available USB interfaces, such as the Amanero Combo384, the DIYINHK XMOS interface, the JLSounds I2SoverUSB interface, the WaveIO, etc.
It would also have to be better looking. A bunch of LEDs just wouldn’t cut it. It was decided that a small OLED display was a better idea. There was also a request that classic 7-segment LED displays be supported. Finally, it was to be galvanically isolated from the USB to I2S interface that it was monitoring.
Thus was born the Arduino-based Universal USB to I2S Interface Indicator.
It is based on the Arduino Nano and sports a 0.96″ or 1.3″ OLED display with a resolution of 128 x 64.
From the beginning it became obvious that the Arduino Nano would be a no brainer for this application. It is small, thus it does not take up too much PCB real estate. It has more than enough I/O for our application. It includes a USB port for easy programming. It is readily available and it costs just a few Euros.
The screen was more of a conversation piece. It was decided that a TFT would be overkill, since we only needed to display a sampling rate, or at most also the signal type (PCM or DSD).
I pitched the idea of a small OLED display, something low-cost and easy to come by. Luckily, Ebay has tons of 0.96″ and 1.3″ OLEDs for a few Euros. They can be had with either SPI or I2C interfaces.
It was requested that 7-segment LED displays be supported as well and the easiest way to do that was to use a LED driver IC that would communicate with the Nano over I2C. Like this one.
Since we would be using I2C for the LED display, it made sense to also use it for driving the OLED display. We decided to go with one like this one. It is just 0.96″ in diagonal and has a resolution of 128 x 64, but we wouldn’t be needing anything bigger. Here it is, next to a USB WiFi adapter for scale:
The requirement of driving the LED display eventually went away, but the I2C interface for the OLED display remained.
Next up, we wanted electrical isolation. Silicon Labs’ isolators came to mind, since they are reasonably priced and readily available. Plus, I have a lot of experience with them. We chose to use two ICs, an Si8065 and an Si8045. The idea was to install the Si8065 and if more than 6 sense lines were needed to also install an Si8045 for another 4.
Later on in the development cycle we decided to make the project a little more universal, so now for the second isolator the end user may choose between the Si8045 or the Si8642, getting respectively 4 more inputs or 2 inputs and 2 outputs.
We also decided to support IR remote functionality. This way we could give the project remote control capabilities such as remote power on/off and source selection. The library that I have used supports a long list of IR protocols.
So, that covered the hardware. On to the software.
The code is pretty simple, really.
It’s just a few digital inputs with code to recognise the various combinations of digital highs and lows of the various USB interfaces and some code to drive the OLED accordingly.
The IRremote library supports all kinds of remotes so you shouldn’t have much trouble finding a suitable one. The current version of the code is set to decode all IR signals and to send through the serial port the IR codes that it does not recognise as valid commands. This way it is easy to discover a working remote and to find out the exact IR code that you should put in the relevant section:
#define POWER_CODE 0xFF48B7 // Code for power on/off
#define SOURCE1_CODE 0xFF827D // Code for source 1
#define SOURCE2_CODE 0xFFB24D // Code for source 2
The custom PCB that has been designed for this project has 10 sense lines, labeled I1 to I10. They correspond to D2 through D11 of the Nano. Optionally, instead of 10 sense (input) lines, it may be built to support 8 inputs and 2 outputs. More details can be found on the PCB’s post. It also has a header bringing out the unused I/O of the Nano, for future use.
It was also meant to support the connection of an IR decoder module to Pin A7. At the time of the PCB design I was under the impression that it was possible to use pin A7 as a digital input for the IR sensor but that proved to be false. It turns out that the necessary function pulseIn() requires a real digital line. A solution is to connect pin 1 of the IR header to D12 on the bottom of the board and to not install Q2 & R3. It is also a good idea to cut the trace going from Pin 1 of the IR header to A7.
The code will expect these sense lines for the USB interfaces:
|Nano Pin||PCB Pin||Amanero Combo384||DIYINHK XMOS||JLSounds||WaveIO|
|D8||I7||Cable Unplugged||L7 (Host Active)|
|D9||I8||MUTE||L8 (Audio Streaming)|
At the moment the code is tested and found to be functioning properly with the Combo384, the WaveIO, the DIYINHK XMOS and the JLSounds I2SoverUSB interfaces.
Very detailed connection diagrams to all of the above USB interfaces can be found on the PCB’s post.
Here is the prototype in action, “reading” the output of a DIYINHK XMOS board in my Soekris DAM1021:
And here is a short video of the prototype in action:
The most current version of the code (v1.37) is here: Universal USB to I2S Indicator (code) (602 downloads)
This is the change log:
- Changed once again DSD detection code for Amanero. Now properly supports DSD256/512.
- Changed DSD detection code for Amanero. Now supports DSD64/128/256/512.
- Added support for SH1106-based OLED displays.
- Added code to send any non-recognized IR codes to the serial port.
- JLsounds code is fully tested and working OK.
- Remote power on/off implemented.
- JLsounds code is not working! To be fixed soon..
- Signal type is now displayed (for 3 seconds).
- IR remote control supported for changing sources.
- Source name is displayed (in case of USB for 3 seconds).
- Updated WaveIO code to also display 352.8K & 384K. It is now fully tested.
- Fixed decimal point display bug.
- Amanero code is fully tested and working OK.
- First public release.
- Sampling Rate now displayed as float (with decimal point). Slightly smaller font.
v0.33 24/04/2015 :
- Debugged Amanero code. Should be fine now. Still not tested.
- Added DSD detection for the JLSounds interface (not properly documented, so not sure if it works OK).
- Added support for WaveIO interface (not tested).
- Initial version. Shows only the sampling rate (type INT for now).
- Compatible with 0.96″ OLED display (SSD1306, 128 x 64)
- Compatible with Amanero Combo384 (not tested), DIYINHK XMOS & JLSounds interfaces (not tested).