FastLED 3.9.15
Loading...
Searching...
No Matches

◆ findConnectedPinsImpl()

fl::json AutoResearchRemoteControl::findConnectedPinsImpl ( const fl::json & args)
private

Definition at line 1141 of file AutoResearchRemote.cpp.

1141 {
1142 fl::json response = fl::json::object();
1143
1144 // Parse optional arguments: [{startPin: int, endPin: int, autoApply: bool}]
1145 int start_pin = 0;
1146 int end_pin = 8; // Default range: GPIO 0-8 (safe range, avoids USB/flash/strapping pins)
1147 bool auto_apply = true; // If true, automatically apply found pins
1148
1149 if (args.is_array() && args.size() >= 1 && args[0].is_object()) {
1150 fl::json config = args[0];
1151 if (config.contains("startPin") && config["startPin"].is_int()) {
1152 start_pin = static_cast<int>(config["startPin"].as_int().value());
1153 }
1154 if (config.contains("endPin") && config["endPin"].is_int()) {
1155 end_pin = static_cast<int>(config["endPin"].as_int().value());
1156 }
1157 if (config.contains("autoApply") && config["autoApply"].is_bool()) {
1158 auto_apply = config["autoApply"].as_bool().value();
1159 }
1160 }
1161
1162 // Validate range
1163 if (start_pin < 0 || start_pin > 48 || end_pin < 0 || end_pin > 48 || start_pin >= end_pin) {
1164 response.set("error", "InvalidRange");
1165 response.set("message", "Pin range must be 0-48 with startPin < endPin");
1166 return response;
1167 }
1168
1169 FL_DBG("[PIN PROBE] Searching for connected pin pairs in range " << start_pin << "-" << end_pin);
1170
1171 // Helper lambda to test if two pins are connected
1172 auto testPinPair = [](int tx, int rx) -> bool {
1173 // Test 1: TX drives LOW, RX has pullup → RX should read LOW if connected
1174 pinMode(tx, OUTPUT);
1175 pinMode(rx, INPUT_PULLUP);
1176 digitalWrite(tx, LOW);
1177 delay(2); // Allow signal to settle
1178 int rx_when_tx_low = digitalRead(rx);
1179
1180 // Test 2: TX drives HIGH → RX should read HIGH if connected
1181 digitalWrite(tx, HIGH);
1182 delay(2); // Allow signal to settle
1183 int rx_when_tx_high = digitalRead(rx);
1184
1185 // Restore pins to safe state
1186 pinMode(tx, INPUT);
1187 pinMode(rx, INPUT);
1188
1189 return (rx_when_tx_low == LOW) && (rx_when_tx_high == HIGH);
1190 };
1191
1192 // Search for connected adjacent pin pairs (n, n+1)
1193 int found_tx = -1;
1194 int found_rx = -1;
1195 fl::json tested_pairs = fl::json::array();
1196
1197 for (int pin = start_pin; pin < end_pin; pin++) {
1198 int tx_candidate = pin;
1199 int rx_candidate = pin + 1;
1200
1201 // No pin skip logic needed - default range (0-8) is safe for all platforms
1202 // Higher pins (USB, flash, strapping) are excluded by the reduced default range
1203
1204 fl::json pair = fl::json::object();
1205 pair.set("tx", static_cast<int64_t>(tx_candidate));
1206 pair.set("rx", static_cast<int64_t>(rx_candidate));
1207
1208 // Test TX→RX direction
1209 bool connected_forward = testPinPair(tx_candidate, rx_candidate);
1210 if (connected_forward) {
1211 pair.set("connected", true);
1212 pair.set("direction", "forward");
1213 tested_pairs.push_back(pair);
1214 found_tx = tx_candidate;
1215 found_rx = rx_candidate;
1216 FL_DBG("[PIN PROBE] Found connected pair: TX=" << found_tx << " -> RX=" << found_rx);
1217 break;
1218 }
1219
1220 // Test RX→TX direction (reversed)
1221 bool connected_reverse = testPinPair(rx_candidate, tx_candidate);
1222 if (connected_reverse) {
1223 pair.set("connected", true);
1224 pair.set("direction", "reverse");
1225 tested_pairs.push_back(pair);
1226 found_tx = rx_candidate; // Swap since reversed
1227 found_rx = tx_candidate;
1228 FL_DBG("[PIN PROBE] Found connected pair (reversed): TX=" << found_tx << " -> RX=" << found_rx);
1229 break;
1230 }
1231
1232 pair.set("connected", false);
1233 tested_pairs.push_back(pair);
1234 }
1235
1236 // NOTE: testedPairs array omitted - causes heap exhaustion on ESP32 (21+ objects = ~1500 bytes)
1237 // Validation script doesn't use this data, only needs {found, txPin, rxPin}
1238 // response.set("testedPairs", tested_pairs);
1239 fl::json search_range = fl::json::array();
1240 search_range.push_back(static_cast<int64_t>(start_pin));
1241 search_range.push_back(static_cast<int64_t>(end_pin));
1242 response.set("searchRange", search_range);
1243
1244 if (found_tx >= 0 && found_rx >= 0) {
1245 response.set("success", true);
1246 response.set("found", true);
1247 response.set("txPin", static_cast<int64_t>(found_tx));
1248 response.set("rxPin", static_cast<int64_t>(found_rx));
1249
1250 // Auto-apply the found pins if requested
1251 if (auto_apply) {
1252 int old_tx = mState->pin_tx;
1253 int old_rx = mState->pin_rx;
1254 bool rx_changed = (found_rx != old_rx);
1255
1256 mState->pin_tx = found_tx;
1257 mState->pin_rx = found_rx;
1258
1259 // Recreate RX channel if pin changed
1260 if (rx_changed && mState->rx_factory) {
1261 mState->rx_channel.reset();
1262 mState->rx_channel = mState->rx_factory(found_rx);
1263 if (!mState->rx_channel) {
1264 FL_ERROR("[PIN PROBE] Failed to recreate RX channel on GPIO " << found_rx);
1265 // Restore old values
1266 mState->pin_tx = old_tx;
1267 mState->pin_rx = old_rx;
1268 response.set("error", "RxChannelCreationFailed");
1269 response.set("autoApplied", false);
1270 return response;
1271 }
1272 }
1273
1274 FL_DBG("[PIN PROBE] Auto-applied pins: TX=" << found_tx << ", RX=" << found_rx);
1275 response.set("autoApplied", true);
1276 response.set("previousTxPin", static_cast<int64_t>(old_tx));
1277 response.set("previousRxPin", static_cast<int64_t>(old_rx));
1278 } else {
1279 response.set("autoApplied", false);
1280 response.set("message", "Use setPins to apply the found pins");
1281 }
1282 } else {
1283 response.set("success", true); // Function succeeded, just no pins found
1284 response.set("found", false);
1285 response.set("message", "No connected pin pairs found. Please connect a jumper wire between adjacent GPIO pins.");
1286 }
1287
1288 return response;
1289}
fl::shared_ptr< AutoResearchState > mState
void push_back(const json &value) FL_NOEXCEPT
Definition json.h:745
fl::optional< i64 > as_int() const FL_NOEXCEPT
Definition json.h:255
fl::optional< bool > as_bool() const FL_NOEXCEPT
Definition json.h:254
bool contains(size_t idx) const FL_NOEXCEPT
Definition json.h:625
void set(const fl::string &key, const json &value) FL_NOEXCEPT
Definition json.h:701
static json object() FL_NOEXCEPT
Definition json.h:692
static json array() FL_NOEXCEPT
Definition json.h:688
#define FL_ERROR(X)
Definition log.h:219
#define FL_DBG
Definition log.h:388
void delay(u32 ms, bool run_async=true) FL_NOEXCEPT
Public delay wrapper that keeps bare Arduino delay() preferred after using fl::delay; while still all...
Definition delay.h:98
void pinMode(int pin, PinMode mode)
Set pin mode (input, output, pull-up, pull-down)
Definition pin.cpp.hpp:378
PinValue digitalRead(int pin)
Read digital value from pin.
Definition pin.cpp.hpp:55
void digitalWrite(int pin, PinValue val)
Write digital value to pin.
Definition pin.cpp.hpp:51
corkscrew_args args
Definition old.h:149

References args, fl::json::array(), fl::json::as_bool(), fl::json::as_int(), fl::json::contains(), FL_DBG, FL_ERROR, fl::json::is_bool(), fl::json::is_int(), mState, fl::json::object(), fl::json::push_back(), and fl::json::set().

Referenced by registerFunctions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: