Please help: two days of suffering with this IR transmitter circuit. I'm going nuts

Please help, I’ve been trying to solve this for two days and I’m going mad.

OK here’s what I’m trying to achieve. There’s a fan/light combo in a bedroom in my house, which doesn’t have a corresponding wall switch: it operates by an IR remote only. The remote has a habit of growing legs and hiding, so I want to replicate its functionality by building a box to install in the wall, based on a Wemos D1 and ESPhome.

Step 1 was to learn the codes, so I stuck an IR receiver on a Wemos D1 R2 (flashed with ESPhome), and pointed the remote at it. I got a list of codes, no problem.

First it detected a bunch of RAW codes, but on boot ESPhome threw up a warning about the pin being high and suggested I invert it. Once I did, it detected rc_remote_raw, protocol 4, and then an 11 digit binary code for each button on the remote.

Light ON 11000000100
Light OFF 11000010000
Fan OFF 11000001000
Fan L-Low 11000100001
Fan Low 11000000010
Fan Medium 11000000000
Fan High 11000000001

So far so good.

Then I built the transmitter. I got a new Wemos D1 R2, flashed it with ESPhome, and built the IR transmitter circuit shown here.

Here is my yaml file for the transmitter:

esphome:
  name: wem002
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: "REDACTED"
  password: "REDACTED"

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

remote_transmitter:
  pin: D6

switch:
  - platform: remote_transmitter
    name: "Light - Fan Light On"
    id: fan_light_on
    rc_switch_raw:
      code: '11000000100'
      protocol: 4
  - platform: remote_transmitter
    name: "Light - Fan Light Off"
    id: fan_light_off
    rc_switch_raw:
      code: '11000010000'
      protocol: 4
  - platform: remote_transmitter
    name: "Fan Off"
    id: fan0
    rc_switch_raw:
      code: '11000001000'
      protocol: 4
  - platform: remote_transmitter
    name: "Fan LLow"
    id: fan1
    rc_switch_raw:
      code: '11000100001'
      protocol: 4
  - platform: remote_transmitter
    name: "Fan Low"
    id: fan2
    rc_switch_raw:
      code: '11000000010'
      protocol: 4
  - platform: remote_transmitter
    name: "Fan Med"
    id: fan3
    rc_switch_raw:
      code: '11000000000'
      protocol: 4
  - platform: remote_transmitter
    name: "Fan High"
    id: fan4
    rc_switch_raw:
      code: '11000000001'
      protocol: 4

Now, it appears to work fine. I can direct my cellphone camera at it, and it fires spectacularly when asked to do so. But it does not trigger the ceiling fan.

Here are things I have tried so far.

  1. Built a totally different transmitter circuit, this time based on this Adafruit circuit diagram. It also fires successfully, although less powerfully. It also fails to trigger the ceiling fan.

  2. Used a brand new Wemos D1 Mini instead of the R2, with both transmitter circuits. No change - which is to say, it triggers the IR LEDs, but does not trigger the ceiling fan.

  3. Used different LEDs. Initially I used TSAL6400 LEDs because they were spec’d in the analysIR circuit, but I also tried regular 940nm LEDs, and 850nm LEDs.

  4. Tried different transistors. I’ve used the C33716 ones, and the 2N2222 ones from the Adafruit tutorial. The 2N2222s produced a significantly brighter output, but, still didn’t trigger the ceiling fan.

  5. Tried using the RAW codes I initially captured before inverting the receiver pin, instead of the rc_switch_raw codes I got afterwards.

  6. Tried new resistors. I mean, I’ve tried everything else, right?

  7. Tried moving the transmitter circuit to different GPIOs. No change.

  8. The last thing I have tried is to fire up my original Wemos D1 with the receiver attached and fire my homebrew transmitter at it. It does not detect a signal, even though I can see a signal through my phone camera. It does detect the actual remote. WHaaaaaaaat?

I am totally stumped at this point. Please, any ideas you have, share with me. I feel like I’m going mad.

EDIT: for what it’s worth, the RAW code I’m receiving looks like this:

[10:17:27][D][remote.raw:054]: Received Raw: -1266, 420, -1266, 420, -480, 1205, -423, 1261, -423, 1263, -422, 1262, -423, 1262, -423, 1263, -1264, 421, -422, 1262, -423, 1262, -423, 8002, -1266, 420, -1322, 363, -422, 1263, -423, 1262, -422, 1263, -479, 1205, -423, 1263, -422, 1263, 
[10:17:27][D][remote.raw:054]:   -1265, 423, -419, 1263, -422, 1263, -423, 8001, -1266, 420, -1265, 420, -480, 1204, -423, 1263, -422, 1263, -423, 1262, -423, 1262, -423, 1262, -1322, 363, -423, 1262, -480, 1206, -479, 7944, -1266, 420, -1265, 420, -480, 1205, -423, 1262, -423, 1262, 
[10:17:27][D][remote.raw:054]:   -423, 1262, -481, 1204, -423, 1263, -1264, 420, -423, 1262, -424, 1262, -422, 8002, -1265, 421, -1265, 420, -423, 1262, -479, 1206, -422, 1263, -422, 1263, -422, 1264, -422, 1262, -1266, 419, -423, 1262, -423, 1262, -423, 8001, -1267, 419, -1266, 419, 
[10:17:27][D][remote.raw:067]:   -423, 1262, -423, 1262, -423, 1263, -422, 1263, -422, 1263, -422, 1263, -1265, 420, -480, 1205, -423, 1263, -421, 10000

That’s for the LIGHT ON button. If I invert the receiver, it’s read as rc_switch_raw, protocol 4, 11000000100

Have you tried moving the IR transmitter closer to the fan?

Neither of those circuits will have a significant range. This is an IR blaster circuit I designed for use with my

Global Cache IP to IR bridge. It can easily control equipment across a 6m room.

I also designed a (mostly) surface mount version. https://oshpark.com/shared_projects/hZcFpg71

1 Like

The only thing I can figure is maybe the recorded codes are wrong, possibly because of a wrong carrier frequency or light wavelength of the IR receiver diode?

Hi @tom_l. Yes, I’ve tried it right against the receiver. I’d agree with you about the Adafruit circuit, but the analysIR circuit is (allegedly) designed to have significant range.

Thank you for sharing your circuit, I’m going to have a look at it this afternoon. First I need to go scream into a pillow, and then fetch my kids from school.

It seems suspicious that your receiver circuit doesn’t pick up your transmitter, would be interesting to read the original remote IR pins with a scope

Hi @Snedig. I think you may be right.

Since I made the post, I switched to a different IR Receiver module (it occurred to me that this was the only thing I hadn’t tried). There was no change (it works the same as the previous one), but then it occurred to me that I hadn’t tried transmitting RAW codes at my own receiver.

I did that, and now I’m receiving. My circuit is still not triggering the ceiling light, but at least I know that the problem is not hardware now. I think it is likely to do with carrier frequency - I just noticed that there’s an option for this in the docs.

Do you know a way of detecting the carrier frequency from the RAW received data? What I have begun doing in the meantime is specifying it in the yaml file, compile, upload, test. Seems like a very long way round.

I don’t think there is an option to get the carrier frequency from the RAW data, as from what I gather the IR receiver circuits generally have a built in frequency. I think you need to be “closer to the source” to find it, although from memory pretty much everything is either at 38(?)kHz or 56(?)kHz

@Snedig Thank you for your useful suggestion. I’m going to keep testing and let you know how it goes.

It should be possible to make a simple input circuit to an ESP and measure the pulses as they are sent by the remote, although it does entail disassembling the remote.

Anyway, have a nice day at work, heading out here also:)

It will also fry most IR LEDs if the input is not pulsed but is instead left high.

The peak current in that circuit and mine are very similar (130mA vs 260mA) , however my circuit will only let that current through at 37-38kHz. DC current drops back to 50mA which a lot of IR LEDs can handle.

These are not valid IR codes, you are using rc_switch_ those are intended for RF signals. The raw codes you put later makes more sense for IR signals, it should work if you transmit those codes as is.
Also you should have the 50% duty somewhere.
Read docs again and bear in mind this is controlling RF and IR remotes.
Also I would use IRRemoteESP8266 there is a “sample” which is a full mqtt ir bridge with a web front end. It might be easier to get experience on IR with that, then you can come back to ESPHome.

For IR codes decoded you should see something like NEC, JVC, Panasonic… etc, that should show the log when you use the dump: all option

Updating in case anyone is following, or searching this issue. It’s still not solved, but here’s what I’ve done in the meantime.

I disassembled the actual remote to see if I could figure out the frequency. First, there’s a single IC with the code BEC BA5104 (… and some other digits I can’t read right now). Googling produced a spec sheet entirely in Chinese, but I was able to ascertain that it will kick out 38kHz. So that’s one mystery solved: the carrier frequency is definitely 38kHz. Hooray!

So now I’m in a situation where I’m attempting to transmit RAW IR codes, at the correct carrier frequency. I’ve tested my circuit against a receiver circuit, and I’m definitely transmitting. Moreover, what I’m transmitting is arriving unchanged at the receiver, ie, my raw code block is received exactly as it is sent. This is progress.

However, the ceiling fan is still not responding to the homebrew transmitter. Logically, this says to me that I have not managed to sniff the correct codes from the remote.

So, back to the drawing board. I started out fresh, went back to the Arduino IDE, and just to be safe, I even opened up a fresh Wemos D1 R2. Loaded up the default IRrecvDumpV2 sketch, and ran it on the fresh board with IR receiver attached.

Now, it’s reading codes fine, but what I noticed was that I’m getting different codes on the same button. There is a broad correlation between the codes I’m getting, but they are slightly different every time - for instance, one positive value might read as 1200, but then read as 1208 next time. I googled this problem and found a thread where someone suggested that the lighting in the room - even the lighting from my screens - might be doing this. I turned off my overhead lighting, which seemed to have an effect - the codes are still different but the variance is lower. I can’t really turn my screens off because then I won’t be able to see the output. In the meantime I wrapped the receiver in black tape and shoot the IR at it down this tube.

Still haven’t managed to get a consistent read, though.

The only other weirdness I haven’t chased yet is this. I noticed that on the original transmitter, there is a 10v 100uF capacitor in series with the LED, attached to the positive leg. So it’s between 3VDC and the LED. I assume that this is to stabilise the power for when the batteries start to get low. Given where it is in the circuit, I don’t think it’s really affecting the pulses - but, maybe I should bang one in there on my transmitter just to be sure?

Aluta continua.

If it really is in series:

The more current you put through the LED the better the range. LEDs can handle much higher pulsed currents than DC currents. So there is probably little current limiting. As mentioned above this can cause the LED to burn out if the LED is left on. The 100u cap is used as protection. At DC the capacitor is an open circuit, at 38kHz it’s essentially a short circuit.

1200 to 1208 is not a difference at all.
That numbers are the milliseconds the led is either on or off. It is measured by the sender and the receiver each one with their own clock so it might differ slightly still be very same signal code.
Can you paste raw capture again?
There should be consistency on most lengths be comparable in value. E.g many values equal to 1200 many equal to 600, etc.
A difference might be the wavelength of the ir transmitter led. Just an idea

Hi @glmnet, thank you for your feedback. I’ve noticed that the amount of raw data I get really depends on how long I hold the remote button down. But, the fan responds to the actual remote even on the shortest of presses, so I’ve tried to capture as short a press as I can (I unfortunately have fat fingers).

Raw capture looks like this:

[03:16:52][D][remote.raw:054]: Received Raw: -1247, 436, -1245, 436, -404, 1278, -364, 1317, -365, 1316, -365, 1316, -365, 1317, -364, 1316, -1206, 474, -404, 1279, -365, 1315, -365, 8038, -1209, 474, -1244, 438, -403, 1294, -349, 1317, -365, 1315, -365, 1317, -365, 1317, -364, 1317, 
[03:16:52][D][remote.raw:067]:   -1204, 475, -403, 1280, -364, 1317, -364, 10000

I don’t know what the difference between raw:054 and raw:067 is, but the numbers are pretty consistent even with the arduino sketch; but this output is easier to use for copying and pasting.

So from that, I edit it down to:

switch:
  - platform: remote_transmitter
    name: "Light - Fan Light On"
    id: fan_light_on
    raw:
      carrier_frequency: 38kHz
      data: [-1247, 436, -1245, 436, -404, 1278, -364, 1317, -365, 1316, -365, 1316, -365, 1317, -364, 1316, -1206, 474, -404, 1279, -365, 1315, -365, 8038, -1209, 474, -1244, 438, -403, 1294, -349, 1317, -365, 1315, -365, 1317, -365, 1317, -364, 1317, -1204, 475, -403, 1280, -364, 1317, -364]

It compiles fine. It uploads fine. Using a cellphone camera, I can see the LEDs firing when I call that switch in HA. But, no response from the actual fan.

Actually, @glmnet, something you said got me thinking. I don’t know for sure that my hobby-kit IR receiver reads 38kHz. It’s probably close to that, but maybe not actually that.

I’m ordering a couple of 38kHz receivers to be on the safe side, they’re dirt cheap. It’s just possible that the receiver in the fan is fussy.

The receiver has integrated logic to decode 38Khz, or 32Khz, etc… and will send the decoded signal to ESP chip. i.e. the ESP cannot decode the carrier frequency.
The LEDs does not have logic at all, the ESP itself will modulate the signal. You can put the Khz you want, so feel free to try other frequencies like 32, 36, 40 etc.

Post the configuration of the remote_transmitter: too, I did not see you are using the 50% duty, also you can try values like 33%, or 66%

Most likely the line number of the source code generating the log message.

@DeeBeeKay did you ever work this out? I feel like I have this exact same issue with a fan/light IR remote.