Based on the Falmec Nuvola 90's remote.
This project started because my range Falmec Nuvola 90 range hood controller stopped working. Luckily the remote still output some signal, with a few cm of range. Enough to capture the signal, but not enough to actually use. Instead of buying a new remote, i reversed their protocol and built a new 'remote'.
Hidden RF remote built into a lantern.
Design is based on modular Kumiko Lantern on MakerWorld. I have provided my alterations in docs/3d. This includes a battery compartment, hidden LED and radio tower, hidden button holder, PCB slot and wiring channels.
https://tool.itslitho.com/ was used to generate the backlit panels
The repository contains Open-source tools for each step of the process.
- Tools for decoding RF signals.
- Code and schematics for various transmitters
- Raspberry Pi-based transmitter
- a standalone ATTiny85 transmitter 9V
- a standalone ATTiny85 transmitter 5v
- Code and schematics for a receiver.
This section is for those looking for the Nuvola 90 remote protocol. I have seen some discussion online, but I have not seen the full protocol provided. For more information on reversing the protocol refer to receiver README.md.
FALMEC range hoods use a 433 MHz OOK (On-Off Keying) protocol at the physical layer — the transmitter module simply switches the carrier on or off via a DATA pin. The bit encoding on top of that carrier is a custom PWM-with-alternating-polarity scheme, not a standard protocol like PT2262/EV1527 or Manchester encoding. Each bit determines the duration of the next pulse (320 µs = 0, 640 µs = 1), and the line polarity flips with every pulse regardless of bit value. Each transmission encodes the entire desired state of the hood — fan speed and light — rather than individual toggle commands.
[13b Preamble] [6b Fan Speed] [2b Light] [6b Timer] [1b Toggle] [5b Suffix]
| Field | Bits | Description |
|---|---|---|
| Preamble | 13 | Fixed sync pattern: 0011010101010 |
| Fan Speed | 6 | 101010=OFF, 101001=1, 100110=2, 100101=3, 011010=4 |
| Light | 2 | 10=OFF, 01=ON |
| Timer | 6 | Static field (101010) |
| Toggle | 1 | Alternates 0/1 between consecutive frames |
| Suffix | 5 | Fixed terminator: 11010 |
Each bit determines the duration of one pulse in an alternating HIGH/LOW sequence:
- Bit
0→ 320 µs pulse - Bit
1→ 640 µs pulse - Inter-frame sync gap: 14 000 µs LOW
Frames are repeated 20–50 times per command for reliability.
scripts/
├── transmitter/ Raspberry Pi transmitter (pigpio waveforms)
│ ├── falmec_encoder.py Protocol encoder/decoder library
│ ├── falmec_transmit.py CLI transmitter
│ └── README.md
├── receiver/ Signal capture and analysis tools
│ ├── falmec_capture.py Live protocol decoder
│ ├── signal_visualizer.py Waveform plotter
│ └── README.md
├── attiny85/ Standalone ATtiny85 transmitter
│ ├── falmec_tx/ Battery-powered controller sketch
│ ├── blink/ Basic test sketch
│ ├── button_blink/ Button input test sketch
│ └── README.md
├── debug/ Low-level signal monitoring
└── tests/ Hardware and GPIO test scripts
docs/
└── hardware/
└── power.md Receiver voltage level notes
A battery-powered version using an ATtiny85 microcontroller. Single/double click to select fan speed and light state. Uses an STX882 transmitter module by default (FS1000A is a drop-in alternative).
See scripts/attiny85/README.md for details. Arduino sketch code, flashing setup and remote 9V wiring and 5V wiring.
Simple Raspberry Pi transmitter setup.
Both the FS1000A and STX882 are compatible 433 MHz OOK transmitter modules and work interchangeably for this project. The wiring and software are identical.
| Module | Voltage | Notes |
|---|---|---|
| FS1000A | 3.3V – 12V | Most widely available, paired with MX-RM-5V receiver |
| STX882 | 2V – 10V | Better sensitivity and range, used in the ATtiny85 build |
Simple Raspberry Pi receiver setup.
If the receiver is powered from 5V, add a resistor divider (10 kΩ / 20 kΩ) on DATA to bring it down to 3.3V. See docs/hardware/receiver-level-shifting.md.
- Raspberry Pi with
pigpiodinstalled and running - Python 3.10+
- FS1000A or STX882 transmitter module and/or MX-RM-5V receiver module
pip install -r requirements.txt
sudo pigpiod# Fan speed 2, light on
python3 scripts/transmitter/falmec_transmit.py --fan 2 --light on
# Fan off, light off
python3 scripts/transmitter/falmec_transmit.py --fan 0 --light off# Decode live signals from the original remote
python3 scripts/receiver/falmec_capture.py --gpio 27 --pull downpython3 scripts/receiver/signal_visualizer.py --duration 5shell_command:
rangehood_fan2_light: >
python3 /home/pi/falmec_radio/scripts/transmitter/falmec_transmit.py --fan 2 --light on
rangehood_off: >
python3 /home/pi/falmec_radio/scripts/transmitter/falmec_transmit.py --fan 0 --light offfrom scripts.transmitter.falmec_transmit import FalmecWaveTransmitter
tx = FalmecWaveTransmitter(gpio=17, short_us=320, long_us=640, sync_us=14000, settle_us=80)
# Build patterns with FALMECEncoder, then transmit
tx.close() ---Reasoning---
The IRF9530N (non-logic-level, Vgs(th) = −2 V to −4 V) dropped several hundred mV under the ~128 mA load on the 5 V build, browning out the ATtiny rail while the 4.8 V NiMH pack was still half-full. This lead to short operation time.
The fix was to swap the IRF9530N for the AO3401 (logic-level, Rds(on) ≈ 60 mΩ at Vgs = −4.5 V).
Channel drop < 10 mV → full battery capacity is usable.
Some older material that still says "IRF9530N" — use AO3401 instead wherever encountered.
Full updated BOM and pinout provided: docs/hardware/5V_attiny_remote_wiring_guide.md, docs/hardware/9V_attiny_remote_wiring_guide.md.
This project is provided as-is for educational and personal use.

