1141 {
1143
1144
1145 int start_pin = 0;
1146 int end_pin = 8;
1147 bool auto_apply = true;
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
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");
1167 }
1168
1169 FL_DBG(
"[PIN PROBE] Searching for connected pin pairs in range " << start_pin <<
"-" << end_pin);
1170
1171
1172 auto testPinPair = [](int tx, int rx) -> bool {
1173
1179
1180
1184
1185
1188
1189 return (rx_when_tx_low == LOW) && (rx_when_tx_high == HIGH);
1190 };
1191
1192
1193 int found_tx = -1;
1194 int found_rx = -1;
1196
1197 for (int pin = start_pin; pin < end_pin; pin++) {
1198 int tx_candidate = pin;
1199 int rx_candidate = pin + 1;
1200
1201
1202
1203
1205 pair.
set(
"tx",
static_cast<int64_t
>(tx_candidate));
1206 pair.
set(
"rx",
static_cast<int64_t
>(rx_candidate));
1207
1208
1209 bool connected_forward = testPinPair(tx_candidate, rx_candidate);
1210 if (connected_forward) {
1211 pair.
set(
"connected",
true);
1212 pair.
set(
"direction",
"forward");
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
1221 bool connected_reverse = testPinPair(rx_candidate, tx_candidate);
1222 if (connected_reverse) {
1223 pair.
set(
"connected",
true);
1224 pair.
set(
"direction",
"reverse");
1226 found_tx = rx_candidate;
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);
1234 }
1235
1236
1237
1238
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) {
1247 response.set(
"txPin",
static_cast<int64_t
>(found_tx));
1248 response.set(
"rxPin",
static_cast<int64_t
>(found_rx));
1249
1250
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
1260 if (rx_changed &&
mState->rx_factory) {
1261 mState->rx_channel.reset();
1263 if (!
mState->rx_channel) {
1264 FL_ERROR(
"[PIN PROBE] Failed to recreate RX channel on GPIO " << found_rx);
1265
1268 response.set(
"error",
"RxChannelCreationFailed");
1269 response.set(
"autoApplied",
false);
1271 }
1272 }
1273
1274 FL_DBG(
"[PIN PROBE] Auto-applied pins: TX=" << found_tx <<
", RX=" << found_rx);
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 {
1285 response.set(
"message",
"No connected pin pairs found. Please connect a jumper wire between adjacent GPIO pins.");
1286 }
1287
1289}
fl::shared_ptr< AutoResearchState > mState
void push_back(const json &value) FL_NOEXCEPT
fl::optional< i64 > as_int() const FL_NOEXCEPT
fl::optional< bool > as_bool() const FL_NOEXCEPT
bool contains(size_t idx) const FL_NOEXCEPT
void set(const fl::string &key, const json &value) FL_NOEXCEPT
static json object() FL_NOEXCEPT
static json array() FL_NOEXCEPT
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...
void pinMode(int pin, PinMode mode)
Set pin mode (input, output, pull-up, pull-down)
PinValue digitalRead(int pin)
Read digital value from pin.
void digitalWrite(int pin, PinValue val)
Write digital value to pin.