FastLED 3.9.15
Loading...
Searching...
No Matches
RX.ino
Go to the documentation of this file.
1// @filter: (platform is esp32)
2
25// bash debug RX --expect "TX Pin: GPIO 0" --expect "RX Pin: GPIO 1" --expect "RX Backend: RMT" --fail-on ERROR
26
27#include <FastLED.h>
28#include "fl/stl/singleton.h"
29#include "test.h"
30#include "SketchHalt.h"
31
32// ============================================================================
33// Configuration
34// ============================================================================
35
36// ⚠️ DO NOT CHANGE THESE PIN ASSIGNMENTS - NO EXCEPTIONS! ⚠️
37// These specific pins are required for hardware testing infrastructure.
38// Changing PIN_TX or PIN_RX will break automated testing equipment.
39// PHYSICALLY CONNECT GPIO 0 TO GPIO 19 WITH A WIRE FOR THIS TEST.
40#define EDGE_BUFFER_SIZE 100
41#define WAIT_TIMEOUT_MS 100
42
43// Pin and RX type configuration (extern for test.cpp access)
44const int PIN_TX = 0; // DO NOT CHANGE - REQUIRED FOR TEST INFRASTRUCTURE
45const int PIN_RX = 1; // DO NOT CHANGE - REQUIRED FOR TEST INFRASTRUCTURE
47
48// ============================================================================
49// Pin Toggle Pattern
50// ============================================================================
51
52// Pattern: HIGH 1ms, LOW 1ms, HIGH 2ms, LOW 2ms, HIGH 3ms, LOW 100us
54 {true, 1000}, // HIGH for 1ms
55 {false, 1000}, // LOW for 1ms
56 {true, 2000}, // HIGH for 2ms
57 {false, 2000}, // LOW for 2ms
58 {true, 3000}, // HIGH for 3ms
59 {false, 100} // LOW for 100us (end)
60}};
61
62// ============================================================================
63// Global State
64// ============================================================================
65
69
70// Sketch halt controller - handles safe halting without watchdog timer resets
72
73// ============================================================================
74// Arduino Setup & Loop
75// ============================================================================
76
77void setup() {
78 Serial.begin(115200);
79 while (!Serial && millis() < 3000);
80 const char* loop_back_mode = PIN_TX == PIN_RX ? "INTERNAL" : "JUMPER WIRE";
81
82 FL_WARN("\n=== FastLED RX Channel Test ===");
83 FL_WARN("Platform: ESP32");
84 FL_WARN("TX Pin: GPIO " << PIN_TX);
85 FL_WARN("RX Pin: GPIO " << PIN_RX);
86 FL_WARN("RX Backend: " << (RX_BACKEND == fl::RxBackend::RMT ? "RMT" : "ISR"));
87 FL_WARN("LOOP BACK MODE: " << loop_back_mode);
88
89 // Sanity check: Verify jumper wire connection when TX and RX are different pins
90 if (PIN_TX != PIN_RX) {
92 halt.error("Missing jumper wire between TX and RX pins");
93 return;
94 }
95 } else {
96 FL_WARN("TX and RX use same pin (" << PIN_TX << ") - no jumper wire needed");
97 }
98
99 FL_WARN("");
100
101 // Create RX channel for testing
102 // Use 1MHz resolution for better timing accuracy (1us per tick)
103 FL_WARN("Creating RX channel for testing...");
104 fl::RxChannelConfig test_channel_config(PIN_RX, RX_BACKEND);
105 auto rx_test = FastLED.addRx(test_channel_config);
106 if (!rx_test) {
107 halt.error("Failed to create RX channel for testing");
108 return;
109 }
110
111 // Initialize test RX channel with config
113 test_config.edge_capacity = 10;
114 test_config.hz = 1000000; // 1MHz resolution for better timing accuracy
115 test_config.signal_range_min_ns = 100;
116 test_config.signal_range_max_ns = 10000000;
117 test_config.start_low = true;
118
119 if (!rx_test->begin(test_config)) {
120 halt.error("Failed to initialize test RX channel");
121 return;
122 }
123
124 // Test RX channel functionality
125 if (!testRxChannelSanity(rx_test, PIN_TX)) {
126 halt.error("RX channel sanity check failed - RX not working");
127 return;
128 }
129 FL_WARN("");
130
131 // Create main RX channel for the loop
132 // Use 1MHz resolution to allow longer timeouts (40MHz = ~819us max, 1MHz = ~32ms max)
133 FL_WARN("Creating main RX channel...");
134 fl::RxChannelConfig main_channel_config(PIN_RX, RX_BACKEND);
135 rxChannelSingleton() = FastLED.addRx(main_channel_config);
136 if (!rxChannelSingleton()) {
137 halt.error("Failed to create main RX channel");
138 return;
139 }
140 FL_WARN("✓ Main RX channel created\n");
141
142 delay(1000);
143}
144
145void loop() {
146 // IMPORTANT: Must be first line - handles halt state and prevents watchdog resets
147 if (halt.check()) return;
148
149 FL_WARN("\n╔════════════════════════════════════════════════════════════════╗");
150 FL_WARN("║ RX DEVICE TEST");
151 FL_WARN("╚════════════════════════════════════════════════════════════════╝\n");
152
153 // Configure RX channel
156 config.hz = 1000000; // 1MHz resolution (allows up to ~32ms timeout)
157 config.signal_range_min_ns = 100; // 100ns glitch filter
158 config.signal_range_max_ns = 10000000; // 10ms idle timeout (1MHz RMT allows up to ~32ms)
159 config.start_low = true; // Pin starts LOW
160
161 // Execute toggles and capture data
162 FL_WARN("[TEST] Initializing RX channel and executing toggles...");
163 auto& rx_channel = rxChannelSingleton();
164 rx_channel->setConfig(config);
166
167 // Wait for capture completion
168 FL_WARN("[TEST] Waiting for capture (timeout: " << WAIT_TIMEOUT_MS << "ms)...");
169 auto wait_result = rx_channel->wait(WAIT_TIMEOUT_MS);
170
171 if (wait_result == fl::RxWaitResult::TIMEOUT) {
172 FL_ERROR("Timeout waiting for data");
173 } else if (wait_result == fl::RxWaitResult::BUFFER_OVERFLOW) {
174 FL_ERROR("Buffer overflow during capture");
175 } else {
176 FL_WARN("[TEST] ✓ Data captured successfully");
177
178 // Get edge timings
180 size_t edge_count = rx_channel->getRawEdgeTimes(edge_buffer);
181
182 // Validate edge timing against expected pattern
183 const uint32_t TOLERANCE_PERCENT = 15; // ±15% tolerance for timing jitter
184 validateEdgeTiming(edge_buffer, edge_count, TEST_PATTERN, TOLERANCE_PERCENT);
185 }
186
187 FL_WARN("\n╔════════════════════════════════════════════════════════════════╗");
188 FL_WARN("║ TEST COMPLETE - Waiting 5 seconds...");
189 FL_WARN("╚════════════════════════════════════════════════════════════════╝\n");
190
191 delay(5000);
192}
#define PIN_TX
const fl::RxBackend RX_BACKEND
#define PIN_RX
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
fl::shared_ptr< fl::RxChannel > & rxChannelSingleton()
Definition RX.ino:66
void setup()
Definition RX.ino:77
SketchHalt halt
Definition RX.ino:71
#define EDGE_BUFFER_SIZE
Definition RX.ino:40
#define WAIT_TIMEOUT_MS
Definition RX.ino:41
const fl::array< PinToggle, 6 > TEST_PATTERN
Definition RX.ino:53
void loop()
Definition RX.ino:145
Sketch halting mechanism that prevents watchdog timer resets.
Definition SketchHalt.h:25
A fixed-size array implementation similar to std::array.
Definition array.h:27
#define FL_WARN(X)
Definition log.h:276
#define FL_ERROR(X)
Definition log.h:219
RxBackend
Definition types.h:8
@ RMT
ESP32-only RMT capture backend.
Definition types.h:10
@ TIMEOUT
Operation timed out.
Definition rx.h:153
@ BUFFER_OVERFLOW
Buffer overflow.
Definition rx.h:154
fl::optional< u32 > hz
Definition config.h:18
u32 signal_range_max_ns
Definition config.h:20
size_t edge_capacity
Definition config.h:17
u32 signal_range_min_ns
Definition config.h:19
#define Serial
Definition serial.h:304
void executeToggles(fl::RxChannel &rx, fl::span< const PinToggle > toggles, int pin_tx, uint32_t wait_ms)
Execute pin toggles and initialize RX channel for capture.
Definition test.cpp:36
bool testRxChannelSanity(fl::shared_ptr< fl::RxChannel > rx, int pin_tx)
Test RX channel functionality with low-frequency pattern.
Definition test.cpp:160
bool validateEdgeTiming(fl::span< const fl::EdgeTime > edges, size_t edge_count, fl::span< const PinToggle > expected_pattern, uint32_t tolerance_percent)
Validate captured edge timings against expected pattern.
Definition test.cpp:60
bool verifyJumperWire(int pin_tx, int pin_rx)
Verify jumper wire connection between TX and RX pins.
Definition test.cpp:7