I wanted to make some battery-powered decorative kits controllable from Home Assistant without killing the batteries. I already had some IR-controlled candles, and it turns out IR control is a pretty good fit for battery projects: the passive current draw can be very low, and the receiver can sit there waiting for a command while the microcontroller mostly sleeps. This circuit should moreless be able to turn anything on/off using infrared that is battery powered.
At some point it dawned on me I could dim the book nook and add candle flicker as a pretty cool upgrade to the original. The trickiest unknown when I started is on the the teacups there's a touch sensor and I wasn't sure I could reliably spoof it. The control board is tiny surface mount suff and hard to tap -- so spoofing did work but was an unknown at the start.
This project is SUPER cool because it shows using IR receiver you could activate just about anything that runs on battery.
I also already had a Bond Bridge, so the idea became:
- Use the Bond Bridge as a programmable IR transmitter, then put a tiny low-power IR receiver/controller inside each battery-powered puzzle.
This ended up working flawlessly for two different devices:
- Tonecheer Book Nook: Keep the original PIR/motion behavior, but add IR override, dimming, and candle flicker.
- ROKR EA04 Tilt-A-Whirl / Teacups: Simulate the capacitive touch button without soldering to the main board, using a foil sleeve around the touch-sensor wire.
The Core Hardware
- ATtiny85-20PU
- TSOP39238 38 kHz IR receiver
- 3xAA or 3xAAA battery power from the original device
- ZVN4206A MOSFET for the booknook to handle the LED power
Other Components
- Bond Bridge as IR transmitter (or any really)
- To program Attiny 85: Tiny AVR Programmer
- I used ElectroCookie Mini Solderable Breadboards
The TSOP39238 receiver is always powered. It draws about 450 µA typical supply current and works from 2.5 V to 5.5 V, which fits 3-cell AA/AAA battery devices well. The ATtiny85 spends most of its time in sleep and wakes on the IR receiver output. This seems to work without issue.
Why IR codes?
I used simple NEC-style IR commands. A standard NEC command contains:
- 38 kHz carrier bursts
- 9 ms leader burst
- 4.5 ms leader space
- address byte
- inverse address byte
- command byte
- inverse command byte
- stop burst
So each device can share one address but use different command bytes. My project uses NEC address: 0x7D.
Book Nook command set:
0x31= full ON, then sleep0x32= release PIR / OFF, then sleep0x34= 50% dim, stay awake0x35= 25% dim, stay awake0x36= full candle flicker, stay awake0x37= 50% max candle flicker, stay awake0x38= 25% max candle flicker, stay awake
Teacups command set:
0x70= single tap0x71= double tap
Note: The teacups codes start far away from the book nook codes so there is no accidental overlap.
Pictures
[Picture 1: Book nook controller board]. We need to pull the negative side of the LED output to ground (splice into that wire). I pulled power by splicing into positive and negative battery wires.
All that you can see when installed is the TSOP sticking out in the back.
This shows the board inside the booknook-- I justed used velcro to attach.
Here's a board close up of the book nook.
Here's where I mounted the TSOP IR rcvr on the teacups puzzle. The whole inner part and battery box rotates so this was a bit tricky to pack in there. I used shrink wrap on the device. Note the colors are wrong in the pic with etching out it's really left to right unused | v+ | signal out | negative, I didn't take a picture of the board but I used a dremel to cut just the needed 4-5 rows of breadboard to cram it into just the right spot.
To spoof the touch sensor on the teacups I used aluminum duct tape and wrapped it around the insulated green touch wire with a long exposed section of wire (red in pic) so it could impart a bit of capacitance.
Here's the EA04 control board. I had to tap the battery power on the board (solder direct) and then bring the wires out through drilled holes in the cover.
This shows where I cut the board and shoved it into the tiny volume above the battery area with all the wires in place.
Bond Bridge Raw IR Transmit
I used the Bond Local API directly. Bond’s raw signal transmit endpoint is: PUT /v2/signal/tx
The payload I used is:
{
"freq": 38,
"modulation": "OOK",
"encoding": "hex",
"bps": 40000,
"reps": 1,
"data": "HEX_DATA_HERE"
}
Bond’s local API documents hex encoding, bps, and reps; hex encoding is limited to 40000 bps, and reps is the number of times to repeat the data if supplied.
Test the Bond Bridge:
export BOND_IP="192.168.1.xxx"
export BOND_TOKEN="your_local_token_here"
curl -H "BOND-Token: $BOND_TOKEN" \
"http://$BOND_IP/v2/sys/version"
Transmit raw IR:
curl -X PUT "http://$BOND_IP/v2/signal/tx" \
-H "BOND-Token: $BOND_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"freq": 38,
"modulation": "OOK",
"encoding": "hex",
"bps": 40000,
"reps": 1,
"data": "YOUR_GENERATED_HEX"
}'
Home Assistant Integration:
I'm still working on this but you should be able to use a REST command like this:
rest_command:
bond_raw_ir:
url: "[http://192.168.1.xxx/v2/signal/tx](http://192.168.1.xxx/v2/signal/tx)"
method: PUT
headers:
BOND-Token: "YOUR_LOCAL_TOKEN"
Content-Type: "application/json"
payload: >
{
"freq": 38,
"modulation": "OOK",
"encoding": "hex",
"bps": 40000,
"reps": 1,
"data": "{{ data }}"
}
Another option is you can push new commands to the device so the bond native integration should work fine. The below would create a saved command under a device called Book Nook On :
curl -i -X POST "http://$BOND_IP/v2/devices/DEVICE_ID/commands" \
-H "BOND-Token: $BOND_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Book Nook On",
"action": "TurnOn",
"icon": "power",
"category_name": "Book Nook",
"button_type": "tap",
"hidden": false
}'
Then store the IR code on that command
curl -i -X PUT "http://$BOND_IP/v2/devices/DEVICE_ID/commands/$BOOK_ON_COMMAND_ID/signal" \
-H "BOND-Token: $BOND_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"freq": 38,
"modulation": "OOK",
"encoding": "hex",
"bps": 40000,
"reps": 1,
"data": "GENERATED_HEX_HERE"
}'
Book Nook Hardware
The Tonecheer book nook already had a PIR/motion controller. I wanted to preserve that and add a parallel override.
Measurements showed:
- Battery pack: ~4.0 V with NiMH cells
- LED board current: ~57 mA at full brightness
- LED board voltage: ~4 V when on
- LED+ is connected to battery+
- LED− is low-side switched by the factory controller
So the LED path is essentially: Battery+ → LED board → LED− → factory low-side switch → Battery−
That means the remote override can be a second low-side MOSFET in parallel:
- LED− → MOSFET drain
- MOSFET source → battery−
- MOSFET gate → ATtiny PB3 through 100Ω
- 100k pulldown from gate to battery−
Remote behavior:
- IR full ON: MOSFET on → LED− pulled to battery− → LEDs forced on
- IR OFF: MOSFET off → factory PIR resumes control
Important subtlety: OFF does not force darkness. It releases the override back to the PIR board. That is exactly what I wanted.
Book Nook Parts
- ATtiny85-20PU, DIP-8
- 8-pin DIP socket
- Vishay TSOP39238 38 kHz IR receiver
- ZVN4206A N-channel MOSFET, TO-92
- 100Ω gate resistor
- 100kΩ gate pulldown
- 0.1 µF capacitor across TSOP VCC/GND
- Optional 4.7–47 µF bulk capacitor across battery rails
- ElectroCookie mini/micro solderable breadboard
- Wire/test pads for
BAT_POS,BAT_NEG,LED_NEG
Note: If you reverse drain/source, it can sort-of work but badly: I saw dim leakage when “off” and weird partial brightness. Fixing MOSFET orientation fixed that. Double check the spec sheets on TSOP and MOSFET orientations and don't trust my diagrams!
https://www.vishay.com/docs/82778/tsop392.pdf
https://www.mouser.com/datasheet/2/115/zvn4206a-1165266.pdf
Book Nook Firmware Behavior
Full ON and OFF are static latch states:
- Full ON: PB3 HIGH, MOSFET on, ATtiny goes back to sleep (output pin remains high).
- OFF: PB3 LOW, MOSFET off, PIR resumes, ATtiny goes back to sleep.
Dimming and flicker are different:
- 50% / 25% dim: software PWM on PB3 (ATtiny must stay awake).
- Candle flicker: random-walk PWM brightness (ATtiny must stay awake).
That is a tradeoff. Static ON/OFF has long shelf life. Dimming/flicker costs more current because the ATtiny has to keep running. The realistic candle version is not random jumping; it slowly slews brightness toward random targets with occasional dips.
Teacups / ROKR EA04 Hardware
The teacups puzzle was much harder mechanically. The board has:
- U1 = custom MCU
- IC1 = AM01B capacitive touch IC
- IC2 = HF2035F motor driver
The capacitive touch sensor wire goes to the AM01B. I did not want to cut motor power or solder into the main board if I could avoid it.
The final working method was:
- ATtiny PB3 → 68k resistor → aluminum foil/copper tape sleeve.
- Sleeve wraps around the insulated capacitive touch-sensor wire.
- No direct electrical connection to the touch wire.
WoodTrick (Electric Series)
Cutebee
Hands Craft
Ugears
Anavrin
Rolife (by Robotime)
Key Discovery: A high-frequency burst above ~20 kHz, applied to foil wrapped around the touch-sensor wire, reliably simulates a touch.
I tried a lot of signals (DC high/low, square waves from 1 Hz up to 60 kHz, PWM ramps). The reliable family was: 20 kHz and above, 125 ms burst duration.
I settled on:
- Single Tap: 25 kHz burst for 250 ms, floating release afterward.
- Double Tap: 25 kHz burst for 250 ms → 100 ms floating gap → 25 kHz burst for 250 ms → floating release.
The TTP233D-HA6 (AM01B) capacitive touch sensor detects shifts in electrical capacitance on its sense wire to trigger the motor controller, remaining in its high-responsiveness "Fast mode" for "ABOUT 10 SEC" after any detected activity, which requires the ATtiny to provide a 250 ms burst length to reliably overlap with the chip's slower 125–160 ms low-power sampling window.
The teacups board does not need a MOSFET because the capacitive sleeve is driven directly through a resistor from the ATtiny pin.
Teacups Parts
- ATtiny85-20PU, DIP-8
- 8-pin DIP socket
- Vishay TSOP39238 38 kHz IR receiver
- 68k resistor from ATtiny PB3 to foil sleeve
- 0.1 µF capacitor across ATtiny VCC/GND
- Optional 4.7–47 µF bulk capacitor
- ElectroCookie mini/micro solderable breadboard (cut down to fit)
- Aluminum/Copper tape
- Wires to EA04 battery+, battery−, and foil sleeve
TSOP39238 Pinout Warning
The thing I struggled with most was the TSOP IR receiver orientation. My TSOP39238 part has 4 leads. Label your PCB clearly and verify against your physical part/datasheet before soldering. For my final header I wanted the board order labeled clearly as:
GND | IR_DATA | VCC | GND
There was a lot of confusion because the package/view orientation matters. Do not trust a generic 3-pin TSOP diagram; this part/package was 4-pin.
Programming the ATtiny85 on Linux
I used the Amazon bundle: risingsaplings 2pcs ATtiny85-20PU + Tiny AVR Programmer (a USBtinyISP-style programmer with a DIP-8 socket).
Programming flow:
- Install Arduino IDE
- Install SpenceKonde ATTinyCore
- Install Arduino-IRremote library by Armin Joachimsmeyer
- Insert ATtiny85 into the programmer socket, notch aligned correctly
Arduino IDE settings:
- Board: ATtiny25/45/85
- Chip: ATtiny85
- Clock: 8 MHz internal
- B.O.D.: Disabled
- Programmer: USBtinyISP
First time only:
Tools → Burn Bootloader(Sets fuses/clock. It does not install a normal bootloader).
Upload firmware:
Sketch → Upload Using Programmer(Do not use normal Upload).
Important Warning: Do not insert the ATtiny backwards. It gets hot very quickly. Ask me how I know.
Battery Life Estimates
The TSOP39238 dominates standby current:
- TSOP39238: ~0.45 mA
- ATtiny asleep: a few µA
- Total standby: roughly 0.36–0.47 mA
Book Nook (3xAA, assuming 2000–2500 mAh):
- Standby: ~181 to 226 days (about 6–7.5 months).
- Full-on LED runtime (57 mA): ~35 to 44 hours.
- 50% dim runtime (ATtiny awake): ~55–75 hours.
- 25% dim runtime (ATtiny awake): ~90–130 hours.
Teacups (3xAAA, assuming 900–1100 mAh):
- Standby: ~81 to 100 days (about 2.5–3.5 months).
- The teacups burst itself is very short, so active use has negligible impact compared with standby.
If I ran the ATtiny awake all the time, standby would be weeks instead of months. Sleep mode is critical.
Key Lessons
- IR is great for battery projects if the receiver current is low enough. The TSOP39238’s ~450 µA current is acceptable for AA/AAA shelf-life.
- Sleeping ATtiny + IR decode needs a wake strategy. A dummy wake burst before the real command made decoding reliable.
- Bond Bridge raw IR works well. Sent generated NEC waveforms through
/v2/signal/tx. Broadlink also worked fine. - MOSFET orientation matters. Reversing drain/source caused dim leakage.
- No-solder capacitive injection worked. Wrapped foil around the insulated sensor wire and drove it with a 25 kHz / 125 ms burst.
- Static ON/OFF can sleep. Dimming/flicker cannot. PWM effects require the ATtiny to stay awake, costing more battery, but saving overall.
- Label TSOP and ATtiny orientation clearly. These were the easiest ways to make mistakes.
These boards should work for:
WoodTrick (Electric Series)
Cutebee
Hands Craft
Ugears
Anavrin
Rolife (by Robotime)
--CONTINUED-- I'll post all the C++ code for the ATtiny and my linux command line tests on the first reply.










