IR-controlled A/C (5/many) - Where the problems start

4 minute read

This is when it becomes clear that nothing is going to go according to plans.

Summary of previous episodes: I have reached a point where I can control any unit remotely through a nice enough UI, and each receiver should be able to issue the IR command through lircd, with a USB “IR Toy”.

Hardware is here

Oh, the sweet surprise (when package tracking doesn’t work and all you know is that your shipment from China is stuck at the border customs) to get that package. My IR transmitters had arrived.\ And within a few days, the Raspberry Pi Zeros as well.

Small things - RPi Zero setup

There are plenty guides out there explaining how to prepare a headless RPi, the only things I needed (SSH server and Wifi) where covered in this one and many others.

It should have been super easy, but it wasn’t: for some reason the Pi never showed up in the list of devices in the Google Home app (I use Googl Wifi at home). I waited and waited, and nothing.\ So I looked at the SD card again, and the wpa_supplicant.conf file was gone! It took me quite some time to read that this is perfectly normal, that file is read at boot time, and removed from the boot partition. 🤷

In all cases, I just scripted the ping of every IP address on the private networks (fortunately it’s a class C, so ~255 to go) and found the Pi was there, totally fine.\ For good measures I hard-configured the IP for later reboots / lease expirations, etc.\ When I tried to reproduce with the other Pis, the issue never showed up, and they showed in the Google Home app. Go figure.

Now the real piece

LIRCd, PWM, is it better when things never work or when they work occasionally?

One the first Pi Zero set up, I put the IR transmitter on a breadboard, hooked with power, ground, and GPIO, copy over the now large lircd.conf file, and off I go, issuing the first command.\ Setup included using a GPIO for signal, instead of a UART over USB that is used for the IRToy. It’s actually quite a difference.\ There again, many guides to help you do this, for example this — and our use case is actually simpler, we aren’t trying to receive anything, just send.

So I use lirc command line, and … nothing happened. I repeated many times, and still nothing. Tried to get closer to the AC unit in case it’s just about the LED range, and still nothing.

The main difference I could see really was around USB vs. GPIO, and that’s a big one, but all these people reporting they had a working setup … One thing I found was around PWM (Pulse Width Modulation) - from what I understand, it’s a way to have the “average” power/voltage out of the GPIO vary, by sending waves or variable length. A bit like dithering in video encoding.

I proceeded to try that option in the boot/config.txt file, not really knowing what I was doing. It turns out there are 2 separate “drivers” really for the GPIOs, and I was really hoping that this thread would help me (spoiler: it didn’t).

After a reboot, I tried, and retried, and … now it works sometimes — around 5% of the time, I actually get a “beep” from the AC unit.

Now, this looks like progress, except is it really?

Where my mind wandered, more things that don’t work, and so many rabbit holes

What could possibly explain that it works every now and then? I ruled out the LED power by getting 1 inch away from the IR sensor on the AC unit. So what does it leave? Essentially timing: maybe the GPIO’s timing isn’t precise enough, depending on other things happening on the board like interruptions.

Now, how would I go measuring that? Well, it so happens I had been playing with that IRToy, which is both an IR transmitter and an IR receiver! So I hooked it up to my PI 3 in “listening mode”, ie. with LIRC dumping whatever it receives. And I was just going to compare what the actual remote was sending, and what the GPIO-driven IR LED was sending.

It all went wrong, and to explain how it went wrong, I have to dig a little bit in the Daikin IR protocol. Each bit is the result of a high state followed by a low state. The high state always has the same duration, approximatively 430ms. The low state can be short, ie. 430ms for a 0, or long ie. 1320ms for a 1. This is all explained here.
Two caveats: first, the last bit needs to be followed by a high state, otherwise how do you know the duration?. And then there are special signals in between the 3 frames that make the message, which don’t follow that pattern.

Bit value pattern

So with that in mind, I start recording the signal from the official remote control, and to my greatest surprise, the low duration varies … and by a lot (not nearly staying between 400 and 500) after a few bytes — not twice the same number of bytes.

I try to record what my Pi Zero with the GPIO-connected LED sends, and same thing.

At this point, I remember the whole thing about a patched version of LIRC, and I really don’t know whether it’s relevant to my use case since I’m capturing with the USB “IRToy” and these articles were all about using GPIO to receive IR.

At this point, I’m doubting everything, and I’m about to travel to my parents, where there happens to be an oscilloscope…. who knows, maybe I’ll use it and check what’s happening on the GPIOs.