Created
September 15, 2026 18:30
-
-
Save K4zoku/b10bb399d58d5d58b7d494da7853b3ca to your computer and use it in GitHub Desktop.
HyperWork Luna (HPWDL01) 433 MHz desk lamp remote protocol
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * HPWDL01.h - HyperWork Luna (HPWDL01) 433 MHz desk lamp remote protocol. | |
| * | |
| * SPDX-License-Identifier: CC0-1.0 | |
| * | |
| * Wire protocol reverse-engineered from stock remote captures. | |
| * Dedicated to the public domain under CC0 1.0: free to copy, modify, | |
| * reuse and redistribute for any purpose, no attribution required. | |
| * https://creativecommons.org/publicdomain/zero/1.0/ | |
| * | |
| * Pure ISO C: no platform or hardware dependencies. Radio setup VALUES | |
| * live here; applying them to a transceiver and driving the data line | |
| * stay in the application. | |
| * | |
| * Transport: 433.92 MHz OOK carrier at 2.4 kbaud, asynchronous serial | |
| * data on one GPIO. HIGH = carrier on, LOW = carrier off. | |
| * | |
| * Payload: 24-bit code, sent MSB first, OOK pulse-length coded: | |
| * code = HPWDL01_PREFIX << 8 | command | |
| * | |
| * One frame: | |
| * 1. HIGH HPWDL01_LEADER_US (preamble) | |
| * 2. LOW HPWDL01_START_GAP_US (sync gap) | |
| * 3. 24 bits, MSB first; each bit = time HIGH, then time LOW: | |
| * bit 1 -> HIGH HPWDL01_LONG_US, LOW HPWDL01_SHORT_US | |
| * bit 0 -> HIGH HPWDL01_SHORT_US, LOW HPWDL01_LONG_US | |
| * 4. the last bit ends HIGH; HPWDL01_GAP_US runs with the line | |
| * still HIGH (carrier on), then the next repeated frame starts | |
| * | |
| * All timings are microseconds. | |
| */ | |
| #ifndef HPWDL01_H | |
| #define HPWDL01_H | |
| #include <stdint.h> | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif | |
| /* Radio transport parameters: | |
| * 433.92 MHz OOK carrier, 2.4 kbaud asynchronous serial data line. */ | |
| #define HPWDL01_RF_FREQ_MHZ 433.92f | |
| #define HPWDL01_TX_DATA_RATE_KBAUD 2.4f | |
| #define HPWDL01_MODULATION 2 /* ASK/OOK */ | |
| #define HPWDL01_CC_MODE 0 /* infinite packet mode */ | |
| #define HPWDL01_PKT_FORMAT 3 /* asynchronous serial mode */ | |
| #define HPWDL01_IOCFG0_GDO0_TX 0x0D /* data pin = async serial TX stream */ | |
| /* Bit / frame timing (us) */ | |
| #define HPWDL01_SHORT_US 430 | |
| #define HPWDL01_LONG_US 1280 | |
| #define HPWDL01_LEADER_US 1100 | |
| #define HPWDL01_START_GAP_US 12000 | |
| #define HPWDL01_GAP_US 12080 | |
| /* 24-bit payload: HPWDL01_PREFIX << 8 | command */ | |
| #define HPWDL01_PREFIX 0x1397UL | |
| /* Command table (X-macro): HPWDL01_X(name, commandByte). | |
| * The stock remote also knows COLOR_ALT (0x55), same effect as COLOR. */ | |
| #define HPWDL01_COMMAND_TABLE(X) \ | |
| X(COLOR, 0xAA) \ | |
| X(COLOR_ALT, 0x55) \ | |
| X(BRIGHTNESS_UP, 0xAD) \ | |
| X(BRIGHTNESS_DOWN, 0x05) \ | |
| X(OFF, 0xFF) | |
| /* 8-bit command bytes. */ | |
| enum { | |
| #define HPWDL01_X(name, byte) HPWDL01_CMD_##name = (byte), | |
| HPWDL01_COMMAND_TABLE(HPWDL01_X) | |
| #undef HPWDL01_X | |
| }; | |
| /* Actual 24-bit wire codes: HPWDL01_PREFIX << 8 | command byte. */ | |
| enum { | |
| #define HPWDL01_X(name, byte) \ | |
| HPWDL01_CODE_##name = ((uint32_t)HPWDL01_PREFIX << 8) | (uint32_t)(byte), | |
| HPWDL01_COMMAND_TABLE(HPWDL01_X) | |
| #undef HPWDL01_X | |
| }; | |
| /* Frames per burst for each action */ | |
| #define HPWDL01_COLOR_REPEATS 2 | |
| #define HPWDL01_BRIGHTNESS_BASE_REPEATS 1 | |
| #define HPWDL01_OFF_REPEATS 22 | |
| #define HPWDL01_BRIGHTNESS_MAX_LEVEL 10 | |
| /* One payload bit on the wire: time HIGH, then time LOW. */ | |
| typedef struct { | |
| uint16_t highUs; | |
| uint16_t lowUs; | |
| } HPWDL01_BitPulse; | |
| static inline HPWDL01_BitPulse HPWDL01_bitPulse(uint8_t bit) | |
| { | |
| /* Row 0 = bit 0, row 1 = bit 1. */ | |
| static const HPWDL01_BitPulse PULSES[2] = { | |
| {HPWDL01_SHORT_US, HPWDL01_LONG_US}, | |
| {HPWDL01_LONG_US, HPWDL01_SHORT_US} | |
| }; | |
| return PULSES[bit != 0]; | |
| } | |
| #ifdef __cplusplus | |
| } | |
| #endif | |
| #endif /* HPWDL01_H */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment