| 1139 | } |
| 1140 | |
| 1141 | fl::json AutoResearchRemoteControl::findConnectedPinsImpl(const fl::json& args) { |
| 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; |
nothing calls this directly
no test coverage detected