Skip to content

coderkrp/RF-Switch-Control

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

⚑ RF-Switch-Control: Bare-Metal 433MHz Wireless Control System

MCU: CH32V003F4P6 Arch: RISC-V RV32EC Language: C11 Framework: Bare-Metal Environment: PlatformIO RF: 433.92MHz ASK/OOK

A high-performance, ultra-low-power, bare-metal wireless control system implemented on the cost-efficient CH32V003F4P6 (RISC-V) microcontroller. The project features a software-defined ASK/OOK physical layer protocol, custom frame decoding state machines, and deep standby power management (<10Β΅A idle).

It uses a one-way RF link at 433.92 MHz with the standard FS1000A transmitter and XY-MK-5V receiver modules to remotely control four independent momentary switches with dedicated LED status outputs.


πŸ—οΈ System Architecture

The system is split into two independent nodes: the Transmitter Unit and the Receiver Unit.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        TRANSMITTER UNIT          β”‚                    β”‚          RECEIVER UNIT          β”‚
β”‚       [CH32V003F4P6 MCU]         β”‚                    β”‚       [CH32V003F4P6 MCU]        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€                    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  PD0-PD3 ──▢ Input (Pull-Up)     β”‚                    β”‚  PD0-PD3 ──▢ Output (Push-Pull) β”‚
β”‚              [4x Push Buttons]   β”‚                    β”‚              [4x Status LEDs]   β”‚
β”‚                                  β”‚                    β”‚                                 β”‚
β”‚  PC1     ──▢ RF DATA OUT        │──── [433 MHz] ────▢│  PC1     ──▢ RF DATA IN         β”‚
β”‚              [FS1000A Modulator] β”‚     OOK Link       β”‚              [XY-MK-5V Receiver]β”‚
β”‚                                  β”‚                    β”‚                                 β”‚
β”‚  Power   ──▢ Standby WFE Mode   β”‚                    β”‚  Power   ──▢ Continuous Polling β”‚
β”‚              (<10Β΅A Idle Current)β”‚                    β”‚              (SysTick & TIM2)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Engineering Features

  • Bare-Metal Firmware: Written entirely in C using the WCH noneos-sdk framework, without any RTOS overhead, keeping flash and RAM footprint minimal.
  • Ultra-Low Power Standby (<10Β΅A): The transmitter MCU resides in deep standby mode (WFE mode) when idle. External GPIO interrupts on PD0-PD3 wake the processor instantly.
  • Software-Defined OOK Physical Layer: Eliminates hardware serial overhead (no UART/SPI) by bit-banging precise pulse widths on the GPIO pins using microsecond-level hardware timer resolution.
  • Resilient State-Machine Receiver: The receiver uses hardware Timer 2 (TIM2) in input capture style to decode the incoming raw bitstream, filter RF noise, validate addresses, verify XOR checksums, and timeout automatically.

πŸ“‘ Custom RF Protocol Design

Since cheap 433MHz ASK modules (like XY-MK-5V) feature Automatic Gain Control (AGC) that amplifies background RF noise when idle, standard serial framing (UART) is highly prone to corruption. This project implements a custom software-defined protocol designed specifically for noisy ASK/OOK mediums.

1. Physical Layer: Pulse-Width Modulation (PWM)

Instead of standard NRZ (Non-Return-to-Zero) encoding, bits are represented by unequal HIGH-to-LOW pulse ratios:

  • Logic 0: 500 Β΅s HIGH pulse followed by a 500 Β΅s LOW pulse (total 1.0 ms).
  • Logic 1: 1000 Β΅s HIGH pulse followed by a 500 Β΅s LOW pulse (total 1.5 ms).
Logic 0:  β”Œβ”€β”€β”€β”€β”€β”
          β”‚     β”‚
          β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜
          ◄─500─►◄─500─► (Β΅s)

Logic 1:  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚          β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜
          ◄──1000────►◄─500─► (Β΅s)

This variable-length symbol mapping ensures the receiver's AGC remains locked and makes the protocol self-clocking.

2. Link Layer: Packet Framing

Data is sent in structured packets of 4 bytes (32 bits):

Byte Field Name Value Purpose
0 Training Byte 0x55 Sent before the packet to settle the receiver's Automatic Gain Control (AGC).
1 Preamble / Sync 0xAA Used by the receiver to detect start of frame (SOF).
2 Device Address 0x42 8-bit addressing to reject interference from nearby transmitters.
3 Button State 0x0X 4-bit momentary bitmap (Bits 0-3 mapping to buttons 1-4).
4 XOR Checksum 0xXX Calculated as Preamble ^ Address ^ Button State to verify integrity.

3. Protocol Tradeoffs & Comparison (vs. RadioHead/VirtualWire)

This custom PWM-based protocol is designed to address constraints specific to bare-metal microcontrollers (like the CH32V003). Here is a comparison of this project's approach versus the widely used Arduino RadioHead (RH_ASK) / VirtualWire library:

Feature / Dimension Custom PWM Protocol (This Project) RadioHead (RH_ASK)
Simplicity High: Simple edge-timing classification, direct bit-shifting, and XOR checksum. No lookup tables or complex algorithms. Low: Requires 4-to-6 bit symbol conversion lookup tables, sub-bit clock sampling (PLL), and 16-bit CRC.
Memory Footprint Ultra-Low: Fits in under 2KB of flash and 300 bytes of RAM, leaving headroom on resource-constrained chips. Moderate: Requires library dependencies, buffers, and tables, which increase binary size.
Noise Immunity Moderate: Relies on a training byte and timing windows to filter out noise, but susceptible to strong interference. Excellent: Uses a 36-bit preamble to settle AGC and 4-to-6 bit encoding to maintain a constant signal balance (preventing AGC drift).
Error Detection Basic: An 8-bit XOR checksum has a 1-in-256 false-positive rate. Strong: A 16-bit CRC (CRC-CCITT) offers a 1-in-65,536 false-positive rate.
Clock Tolerance Low: Sensitive to clock frequency errors (requires calibrated delays via SystemCoreClockUpdate()). High: Incorporates software clock recovery (PLL) to track and adjust for oscillator drifts.

Key Takeaway:

  • Use this Custom PWM Protocol for ultra-cheap, highly resource-constrained microcontrollers (like the CH32V003 with 2KB RAM / 16KB Flash) where execution efficiency, low code size, and low power sleep modes are the primary constraints.
  • Use RadioHead for standard microcontrollers (e.g., ATmega328P/Arduino Uno) in environments with heavy RF congestion where maximum noise rejection and high-security packet validation are paramount.

⚑ Low-Power & Reliability Engineering

1. Transmitter Power Management

To maximize battery life on the transmitter, the system employs several advanced power-saving techniques:

  • Standby Mode via WFE: When no buttons are pressed, the transmitter configures GPIO Port D Pins 0-3 as external event sources (EXTI_Mode_Event) on the falling edge (active low buttons). It then invokes PWR_EnterSTANDBYMode(PWR_STANDBYEntry_WFE).
  • Zero-Power ASK Idle State: The FS1000A transmitter is connected directly to PC1. Since ASK (Amplitude Shift Keying) transmits power only when the input line is HIGH, holding PC1 RESET (LOW) disables the transmitter's internal oscillator, reducing transmitter power consumption to 0 mA without requiring a dedicated power-gating MOSFET.
  • Unused GPIO Stabilization: All unused GPIO pins are configured with internal pull-ups (GPIO_Mode_IPU) to prevent floating gate leakages that drain power.
  • Instant Wake & Debug Protection (PD1/SWIO Conflict): On the CH32V003, PD1 is the dedicated Single-Wire Interface (SWIO) pin used for programming and debugging. However, in this main branch, PD1 is also mapped as a GPIO pin (Button 2 on the transmitter, LED 2 on the receiver). Since the transmitter immediately enters deep Standby sleep (WFE) when idle, the internal clocks and SWIO block are shut down, locking out the debugger. To permit in-circuit debugger connections, a standard 2-second startup safety delay is implemented at boot. The MCU detects the Low-Power Reset flag (RCC_FLAG_LPWRRST); if it is a fresh power-on or programmer reset (flag is reset), the MCU waits for 2 seconds to allow the WCH-LinkE debugger to connect. If it is a standby wakeup (flag is set), the MCU clears the flag and immediately runs, bypassing the safety delay to achieve low button latency (<15ms).

2. Receiver Demodulation State Machine

The receiver runs a robust non-blocking decoding loop:

  1. Edge Detection: Reads PC1 and measures timing between edges using TIM2 (1 Β΅s tick rate).
  2. Pulsed Bit Demodulation:
    • A falling edge triggers high-pulse duration verification.
    • A rising edge triggers low-pulse verification (must be 300 Β΅s – 700 Β΅s).
    • If low-pulse timing is valid, the high pulse is classified into 0 or 1 based on timing thresholds.
  3. Preamble Synchronization: If in STATE_SEARCH_PREAMBLE, incoming bits are shifted into a register. When the lower 8 bits match 0xAA, the state transitions to STATE_RECEIVE_DATA.
  4. Validation: After 32 bits are received, the system validates the address and the XOR checksum. If valid, LED states on PD0-PD3 are immediately updated.
  5. Bit Timeout: If the gap between bits exceeds 2.5 ms, the state machine resets. This prevents partial transmissions or noise spikes from causing stuck frames.
  6. Safety Momentary Timeout: If no valid packets are received for 100 ms, a timeout function automatically clears all LED outputs. This prevents the outputs from being stuck "ON" if the transmitter button release packet is lost in transit due to RF collision.

3. Independent Watchdog Timer (IWDG) Integration

To ensure system-wide fault tolerance and defense against hardware lockups (such as unexpected EMI interference, power line glitches, or clock failures), both nodes run the hardware Independent Watchdog (IWDG):

  • Timeout Period: Both nodes configure the IWDG with a prescaler of 32 and reload value of 1250. Ticking from the chip's internal Low-Speed Oscillator (LSI ~40kHz), this establishes a ~1.0-second recovery timeout window.
  • Transmitter Node: The watchdog is initialized immediately after the 2-second debugger safety delay. It is fed at the start of each button scanning iteration. Before transitioning into deep Standby sleep (WFE), a final watchdog feed is performed. In deep Standby, the watchdog is automatically frozen by the chip's hardware configuration, preventing loop reset cycles.
  • Receiver Node: The watchdog is initialized during boot after standard timer/GPIO setups and is fed continuously at the start of the while (1) event decoding loop. Any unexpected lockup in bit processing triggers a hardware reset within 1 second.

Important

PD1 / SWIO Debug Pin Sharing Conflict: Because PD1 is shared between Button 2/LED 2 and the debugger interface, there is a risk of programmer lockout. For an alternative hardware wiring scheme that completely resolves this conflict by mapping the buttons and LEDs to PC4-PC7 and leaving PD1 dedicated exclusively to SWIO, switch to the simplified-pins branch (git checkout simplified-pins).


πŸ”Œ Pin Mapping

Transmitter Pins (CH32V003F4P6)

MCU Pin Function Direction Configuration Hardware Connection
PD0 Button 1 Input Internal Pull-Up Tactile Switch (Active Low)
PD1 Button 2 Input Internal Pull-Up Tactile Switch (Active Low)
PD2 Button 3 Input Internal Pull-Up Tactile Switch (Active Low)
PD3 Button 4 Input Internal Pull-Up Tactile Switch (Active Low)
PC1 RF DATA Output Push-Pull FS1000A DATA IN

Receiver Pins (CH32V003F4P6)

MCU Pin Function Direction Configuration Hardware Connection
PD0 LED 1 Output Push-Pull Red LED (via Current Limiter)
PD1 LED 2 Output Push-Pull Green LED (via Current Limiter)
PD2 LED 3 Output Push-Pull Blue LED (via Current Limiter)
PD3 LED 4 Output Push-Pull Yellow LED (via Current Limiter)
PC1 RF DATA Input Floating XY-MK-5V DATA OUT

πŸ› οΈ Project Structure

.
β”œβ”€β”€ platformio.ini         # PlatformIO Multi-Environment Configuration
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ common/
β”‚   β”‚   └── protocol.h     # Shared RF parameters, sync word, and bit thresholds
β”‚   β”œβ”€β”€ transmitter/
β”‚   β”‚   └── main.c         # Transmitter entry point, low power manager, & modulator
β”‚   └── receiver/
β”‚       └── main.c         # Receiver entry point, SysTick timer, & TIM2 demodulator
└── docs/
    β”œβ”€β”€ PRD.md           # Product Requirements Document
    β”œβ”€β”€ ARCHITECTURE.md  # Detailed System Architecture
    └── HARDWARE_GUIDE.md          # Hardware details, BOM, antenna & wiring guide

πŸš€ Building & Flashing

This project uses PlatformIO with the open-source community platform for CH32V MCUs.

Prerequisites

  1. Install PlatformIO IDE (VS Code extension) or the PlatformIO CLI.
  2. A WCH-LinkE programmer (connected to the SWIO line of the CH32V003).

Using the Command Line

To build both environments:

pio run

To flash the transmitter node:

pio run -e transmitter --target upload

To flash the receiver node:

pio run -e receiver --target upload

βš™οΈ Key Engineering Principles

This repository implements several production-grade firmware design methodologies:

  • Custom Protocol Implementation: Implementing robust physical and link layers from scratch to solve real-world hardware limits (ASK noise).
  • Deep System-Level Integration: Configuring interrupts, timers, low-power registers, and clock trees at the register level using vendor headers.
  • Low-Power Optimization: Achieving sub-microamp consumption of peripherals (like RF transceivers) through clever driver and pin-state management.
  • Defensive Firmware Design: Incorporating recovery delays, timeout watchdogs, packet validation, and automatic output shutdowns to prevent lockups.

About

Battery-powered 433MHz RF switch built on the CH32V003 RISC-V MCU featuring a custom wireless protocol, low-power operation, and robust watchdog-based reliability.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages