Hauke’s Projects

Playin' around with Electronics and Computers

CEC-like Power Features with Non-CEC-Equipment

With a Raspberry Pico, I monitor my Sony amplifier from the 90s and my 2013 Dell monitor, and switch on my NUC-based media center if any of these devices are switched on. This is comparable to the CEC functionality that more modern devices provide via the HDMI port. I also utilize the USB/serial interface of the Pico to check if any of the two devices is still on to include this into my auto-shutdown script logic.

As a result, my media center boots up as soon as I switch on my amplifier or my monitor, and only auto-shuts down if both are off.

Click to skip the introductory blah blah.

Motivation

I contradict my claim, that my media center is not really important to me, by already posting the next blog article on it… I admit I got carried away for the fun of it! I guess this is partly because I by now enjoy Spotify quite a lot, and that made it a logical step to bring my venerable Sony TA-F 690 ES into the equation. This high end stereo amplifier from the early 90s has technical spec’s that, even today, put most audio equipment to shame, and it sounds just gorgeous! I mean: Which amp nowadays sports a THD of 0,005%?

The idea was, that if I switch on the amplifier, the NUC boots up without any need to press the power button. Also, I wanted the NUC to stay on as long as the amp is on. While the auto-shutdown script already tests for running audio output and prevents auto-shutdown in that case, it would fail to detect if I paused Spotify, e.g., because I receive a phone call, but plan to continue to listen at a later point. So it might happen that while I’m on the phone, the NUC auto-shuts down. Monitoring the amp’s power-state might prevent this.

Ach ja, first world problems…

And while I’m at it, why not also monitor the monitor 🙂 – if I switch it on, booting the NUC is just logical. For shutdown-control it is already monitored via I²C, but not for power-up.

First Idea

Analysing my options, I identified the following interfaces to make use of:

  • An internal CEC header in the NUC (which Intel names external CEC connector…). This provides 5V even if the NUC is off, and via CEC I can boot the NUC.
  • On the amplifier the tuner control port, which basically forwards the IR receiver signals to other contemporary Sony devices via a simple 4-pin 2.54 mm pitch connector. Fortunately the signal is inverted, so that with no IR signal present, the level is ~5V if the amplifier is switched on.
  • On the Dell monitor a 12V barrel connector output, intended to attach a soundbar to it.

So my original plan was to take an ATtiny85 MCU and make it a CEC client that communicates with the NUC via the CEC interface.

This plan was thwarted by the fact that the CEC interface of the NUC is not exposed to the OS running. Only the NUC BIOS can access the CEC interface. That would be OK if I only wanted to boot the NUC – BIOS would serve its purpose there. But I also intended to use the CEC bus to query the power state of amp and monitor by sending and receiving CEC data packages. That second part was off the table after reading this sentence in the Intel documentation:

The following Intel® NUC Kits have the above external CEC header and an onboard HDMI CEC controller that the BIOS controls. The onboard HDMI CEC controller only supports bidirectional power on/off control.

Whatever I tried, the OS would not identify the CEC controller and expose it via /dev/cec0. Which seems to be that way by design.

Plan B

Well, Plan B it is then. In one of my drawers there slumbered a Raspberry Pico. This 133 MHz dual-core ARM Cortex-M0+ based MCU board is way too powerful for the task at hand, basically it’s pearls before swine, but from an economical perspective it makes total sense. For just 5 € it is simply the cheapest option I could find that has an USB port which I can use for the communication between the OS/auto-shutdown script and the MCU. Even the cheapest Arduino boards with an USB port set you back by 20 bucks…

Implementation

Design Criteria

  • Do not modify any of the devices, i.e. use existing ports. No soldering directly to any device, ideally not even have a cable go into any device’s housing.
  • Avoid ground loops on the audio side (to avoid humming).
  • Low power consumption.
  • Play around with optocoupler ICs/isolator ICs. Not strictly necessary, since all devices are galvanically connected via the ground lines of the audio jack and the HDMI cable, but I was curious and wanted to learn.
  • Re-implement the Tardis light 🙂
    With the Raspberry Pi media center gone, there was no need anymore for the Tardis housing. But I got so used to it… Now the Pico is in the Tardis on top of the NUC, and so the Tardis flashlight of course needed to be back!

The Circuit

Raspberry Pico based power watchdog circuit
Raspberry Pico based power watchdog circuit

USB Connection: For Communication and Check if the NUC is On

The NUC has two internal USB 2 interfaces, which are 1.25 mm pitch Molex “PicoBlade” connectors. These are really a pain to crimp without the correct tool, but I did not want to buy crimp pincers for just a few connections. I managed with small standard pincers, and also by harvesting an existing cable from an old docking station.

Important: 5V Vbus are not connected to the Raspberry Pico Vbus! This is because I want to power the Pico from the 5V Standby rail, and I wanted to avoid connecting the standby rail to the “hot” 5V rail via the Pico. Still, I use the 5V Vbus from the USB connector for the Pico to check if the NUC is on. Since Pico GPIO uses 3.3V and is not 5V tolerant, with two resistors I created a voltage divider to be compatible.

Monitor 12V Jack

Here I used an isolator IC that pulls down the Pico GPIO if the monitor delivers 12V, i.e. it is on. The isolator IC is not really necessary, I could have used an voltage divider as well. Still, I wanted to try out if I can get it right. The resistor is calculated for less than 4 mA If at 1.2 V Uf. Works like a charm.

Amplifier Tuner Control Out

My multimeter told me that the IR signal pin provides 4.6-4.8 V, but in order to better understand my options, e.g., how much current I could draw, I searched for the service manual for the Sony TA-F 690 ES, which luckily is available as scan on the internet. Here is a condensed version of the circuit plans that shows the relevant parts:

Amplifier circuit part for the IR signal processing
Amplifier circuit part for the IR signal processing (© Sony Corporation 1992)

The manual tells me that I should expect something around 3.8 V. From the 1N4148 diode up to 5 V I’d more expect 4.3 V with the 0.7 V voltage drop across a silicon diode. I decided to play it safe and create a voltage divider that assumes ~5 V input, and it works very well.

Only caveat: my oscilloscope showed that ever once in a while some stray IR light triggers the IR receiver, and for a short pulse it pulls down the line. So I’d need to do a bit of debouncing in the code later.

Final remark: I first also connected GND from the tuner port to the Pico GND. This caused nasty humming from a ground loop, since the 3.5 mm audio jack from the NUC to the amp already connects GND. Removed the GND wire from the PICO, and humming gone, functionality still OK.

NUC Power Switch & 5V Standby

The internal CEC header (which Intel calls the external header) provides the power switch pin and 5V standby. It is again a 1.25 mm Molex “PicoBlade” connector. 5V go to VSYS of the Pico and keeps it juiced all the time.

The NUC power switch pin is pulled up to 3.3 V, and Intel documentation tells you that you should pull it down to ground for 50 ms minimum to trigger boot. I decided to do this again via isolator IC, which makes the program logic simple. I can configure the relevant GPIO as output, set it to low, and switch it shortly to high to trigger the power switch. Without the isolator I would have needed to configure the GPIO as input (high impedance), and to trigger the switch I’d have to reconfigure as output and then pull it low to trigger the switch.

The Pico GPIO by default can source 4 mA of current, which you can reconfigure for higher values. The isolator IC I used, the LTV 825, according to the datasheet already goes into saturation at as low as 0.5 mA across the LED, so no need to crank it up. The resistor limits the current to just above 3 mA, and it works fine.

Tardis Flashlight

Simple NPN driver circuit for a white LED, which, using PWM, allows to have the LED going slowly bright and dark again. Read all about it here.

Hardware done.

Software

Raspberry Pico

Setting Up the Arduino IDE

The Pico can be programmed with several tools – since I’m used to the Arduino IDE, I decided to use it here also. There are more than one board library for RP2040 based boards. I went for the library of Earle F. Philhower, III. Thanks for providing that! You need to install the repository as additional board manager URL via the preferences.

Also, I use the RPi Pico Timer-Interrupt library by Khoi Hoang. Thanks for this library! It comes with the Arduino package and can be directly installed via “Manage Libraries”.

If you have never done the above steps, please refer to the Appendix for a screenshot guide.

The Code

The code is not really complicated. Some key elements:

Flashlight via Timer

For the Tardis light timing I did not want to rely on the standard loop, which – depending on other tasks – may not have always the same execution time, which might cause flickerings in the Tardis light. Instead, using the TimerInterrupt library, I link the function for the LED PWM to a timer. That allows accurate changes to the PWM duty cycle, resulting in a smooth transition from dark to bright and back to dark.

Power State Monitoring and Debouncing

To avoid the NUC to wake up just because the IR receiver got some stray light, I require the change in state to last for at least 1 second. Every ~5 ms the state is measured, and only if it stays changed from the previous state for 200 measurements, it is considered as truly changed. 200 × 5 ms = 1 s.

The green onboard LED of the Pico is used to reflect the current state: If it is on, it tells that amplifier and monitor are off. As soon as one of them is registered as on, the green LED is switched off.

Virtual Button Press

If the power state of amplifier or monitor has indeed changed from off to on, the Pico checks if the NUC is already on – which it knows via the NUC’s USB Vbus. If the NUC is off, the power switch line of the NUC is pulled down for 250 ms, which should be enough to get the NUC booting.

In combination with the debouncing mechanism there’s a second effect: If I actively shut down the NUC, the debounce mechanism avoids that the Pico restarts the NUC immediately in case some periphery is still on.

Serial Communication

For the communication of the auto-shutdown script with the Pico, the USB-based serial interface is used. I kept this very simple: If the Pico receives any kind of input via serial, it will answer “On” if amplifier or monitor are on, and “Off” if none is on. It will then empty the serial input stream buffer, and wait for any new input.

Auto-Shutdown Script

The auto-shutdown script needs to have serial communication added to query the Pico for the state of the peripheral devices. In theory it should be a simple echo/read sequence with the serial as target, but I could not get it to work reliable:

Somehow the read often did not receive anything, as if the answer was caught before by some other process. Browsing through tons of ideas on the net, I finally ended up with this code:

This is far from elegant, but it works reliably. Still, I was so annoyed by this that I shortly considered rewriting the auto-shutdown script in Python…

So here’s the modified auto_shutdown.sh (to understand the idea behind it please read “Media Center Auto Shutdown and RTC Wakeup Based on tvheadend Recording Schedule”) – note that the highlighted lines need to be adjusted for your environment:

Configuration

When I first tried the setup, I was in for a bad surprise: The Pico did not stay on when the NUC went into S5 power state (i.e. as off as it can be with external power still on). Turns out that only the 3.3V standby power rail is powered in S5. As much as I would have liked to use the 3.3 V standby voltage, it is not exposed to any header. Fortunately, the 5V standby power can be activated via BIOS – you need to deactivate the “Deep S4/S5” feature:

Deactivate Deep S5 in the BIOS
Deactivate Deep S5 in the BIOS

This will certainly raise the S5-power consumption of the NUC. When I can lay my hands on a power meter, I’ll check the numbers.

Housing

It would have been possible to squeeze the Raspberry Pico somehow into the NUC itself, but as already indicated earlier, I really like my Tardis housing that I used for the Raspberry Pi based media center incarnation. Now I wanted to have the Tardis sitting on top of the NUC, and the cables that go into the NUC (slightly deviating from the design principles) to run through the cover.

Intel does a cool thing: They publish their design files for the NUC covers! (Edit: It seems that only recently Intel removed the relevant files from their pages, since Asus has taken over the NUC brand/support. I yet did not find the lid files published by Asus, but due to copyright reasons I am reluctant to publish the previously downloaded file here on my blog. At the time of this writing, the direct link to the ZIP file at Intel’s pages still worked.) So based on that I was able to design my own NUC cover:

Cover (Bottom View)
Cover (Bottom View)

I decided to make the bumps of the noses, that click into the NUC base, considerably thinner. I was afraid that they’d break off from the mechanical strain, as the 3D printing layer structure would be weak in that direction. Turns out I was right: the smaller noses all broke off very quickly – so consider to remove them before 3D printing. The larger ones are OK. Or do a resin print, might be the better choice here if you have that option.

Cover (Top View)
Cover (Top View)

You can see the recess where the Tardis sits in.

And here’s how it looks in reality:

Tardis has landed on the NUC
The Tardis has landed on the NUC

This is now in place since a few weeks, and I’m quite happy how it performs! The only “problem” I identified: If I just want to listen to a CD, the media center not involved at all, it switches on due to the amplifier switched on. Since there are so many unused GPIO pins on the Pico, I may consider including the CD player power state to be monitored, and have the NUC only boot if amp is on but CD player is off… back to first world problems…

Appendix: Setting Up the Arduino IDE

Installing the Board Manager

To install the Raspberry Pico board manager library, open the Arduino Preferences:

Open Aduino Preferences
Open Aduino Preferences

Then, click on the edit icon right of the “Additional Boards Manager URLs”:

Arduino Preference dialog
Arduino Preference dialog

Then add to the list the JSON-URL from the library github:

https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

Confirm your modifications and open the Boards Manager:

Boards manager menu
Boards Manager menu

Now locate the board library and install it:

RP2040 board library (already installed)
RP2040 board library (already installed)

You can now select the Raspberry Pico from the regarding list:

Board selection
Board selection

The default settings were just right for me.

Installing the TimerInterrupt Library

The library is already part of the “stock” libraries that come with the IDE, but you still have to install it. Just open the Library manager:

Open the library manager
Open the library manager

Locate the correct library and select install:

Installing the TimerInterrupt library
Installing the TimerInterrupt library (already installed here)

Now you’re set up to compile my code.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top