гений или нет не скажу, но что весьма одарённый, тут не о чем спорить )))
Я не спорю. Вы не верно трактовали ответ. В качестве блиблиотеки хорошая идея конечно же. Я подумаю над этим.
Учту)
Ну вот опять) идея это идея. Я не открыл Америку. И даже не претендую на это). Идея заключается в том, чтобы в своих проектах использовать данный подход инициализации модулей (например).
Ага, только версий гайвер-лампы полно в сети (загорелся народ этой штуковиной). Так что, есть лентяи а есть не лентяи. Тут как посмотреть ![]()
Гайвер тут не в авторитете, ибо “хороший блогер, так себе программист” (с) (фраза на английском в комментариях под одним из его роликов на ютубе).
тогда надо устранить непорядок, сделать реаниматор на ESP32C3 к примеру:
/*
* HC-12: чтение настроек + сброс к заводским по кнопке / команде "setdef"
* ESP32-C3
*/
#include <HardwareSerial.h>
// ---------- Настройки железа ----------
#define HC12_SERIAL Serial1
#define HC12_RX_PIN 6 // ESP RX <- HC-12 TX
#define HC12_TX_PIN 7 // ESP TX -> HC-12 RX
#define HC12_SET_PIN 4 // SET HC-12
#define BUTTON_PIN 9 // кнопка на GND (BOOT)
#define HC12_BAUD 9600 // скорость командного режима
// ---------- Управление AT-режимом ----------
void enterATMode() {
digitalWrite(HC12_SET_PIN, LOW);
delay(60); // даташит: не менее 40 мс
}
void exitATMode() {
digitalWrite(HC12_SET_PIN, HIGH);
delay(100);
}
// ---------- Отправка AT-команды и чтение ответа ----------
String sendAT(const char* cmd, uint32_t timeoutMs = 500) {
while (HC12_SERIAL.available()) HC12_SERIAL.read(); // очистить буфер
HC12_SERIAL.print(cmd);
HC12_SERIAL.print("\r\n");
String resp = "";
unsigned long t = millis() + timeoutMs;
while (millis() < t) {
while (HC12_SERIAL.available()) resp += (char)HC12_SERIAL.read();
delay(5);
}
resp.trim();
return resp;
}
// ---------- Извлечь число после указанной буквы в ответе ----------
String extractValue(const String& resp, char key) {
int idx = resp.indexOf(key);
if (idx < 0) return "";
int start = idx + 1;
int end = start;
while (end < resp.length() &&
(isDigit(resp[end]) || resp[end] == '.')) end++;
return resp.substring(start, end);
}
// ---------- Чтение и расшифровка настроек ----------
void readSettings() {
Serial.println(F("\n================ HC-12 SETTINGS ================"));
// Версия прошивки
String ver = sendAT("AT+V", 400);
Serial.print(F("Firmware : "));
Serial.println(ver.length() ? ver : F("(no response)"));
// Все основные параметры одним запросом
String rx = sendAT("AT+RX", 900);
if (rx.length() == 0) {
Serial.println(F("AT+RX: no response — проверьте подключение."));
Serial.println(F("================================================"));
return;
}
String baud = extractValue(rx, 'B');
String chan = extractValue(rx, 'C');
String pow = extractValue(rx, 'P');
// UART
Serial.print(F("UART baud: "));
if (baud.length()) { Serial.print(baud); Serial.println(F(" bps")); }
else Serial.println(F("?"));
// Канал + частота
Serial.print(F("Channel : "));
if (chan.length()) {
int ch = chan.toInt();
float freq = 433.4f + (ch - 1) * 0.4f; // 001 -> 433.4 МГц
Serial.print(chan);
Serial.print(F(" ("));
Serial.print(freq, 1);
Serial.println(F(" MHz)"));
} else {
Serial.println(F("?"));
}
// Мощность
Serial.print(F("Power : "));
if (pow.length()) {
int p = pow.toInt();
const char* desc;
if (p <= 2) desc = "min (~ -1 dBm)";
else if (p <= 5) desc = "mid (~ 8 dBm)";
else desc = "max (~20 dBm)";
Serial.print(pow);
Serial.print(F(" "));
Serial.println(desc);
} else {
Serial.println(F("?"));
}
// Сырой ответ — на всякий случай
Serial.println(F("-----------------------------------------------"));
Serial.println(F("Raw AT+RX:"));
Serial.println(rx);
Serial.println(F("================================================"));
}
// ---------- Проверка триггера: кнопка или "setdef" ----------
bool checkTrigger() {
// --- Кнопка (активна низким уровнем) ---
if (digitalRead(BUTTON_PIN) == LOW) {
delay(30); // антидребезг
if (digitalRead(BUTTON_PIN) == LOW) {
while (digitalRead(BUTTON_PIN) == LOW) delay(10); // ждём отпускания
Serial.println(F("\n>>> Trigger: BUTTON pressed"));
return true;
}
}
// --- Команда в мониторе порта ---
static String line = "";
while (Serial.available()) {
char c = (char)Serial.read();
if (c == '\r' || c == '\n') {
line.trim();
line.toLowerCase();
if (line == "setdef") {
line = "";
Serial.println(F("\n>>> Trigger: command 'setdef'"));
return true;
}
line = "";
} else if (isPrintable(c)) {
line += c;
if (line.length() > 32) line = line.substring(line.length() - 32);
}
}
return false;
}
// ---------- Setup ----------
void setup() {
Serial.begin(115200);
delay(400);
Serial.println(F("\n\n=== HC-12 Reset Tool for ESP32-C3 ==="));
pinMode(HC12_SET_PIN, OUTPUT);
digitalWrite(HC12_SET_PIN, HIGH); // обычный режим по умолчанию
pinMode(BUTTON_PIN, INPUT_PULLUP);
HC12_SERIAL.begin(HC12_BAUD, SERIAL_8N1, HC12_RX_PIN, HC12_TX_PIN);
delay(150);
// Входим в AT-режим
enterATMode();
// Проверка связи
String test = sendAT("AT", 400);
if (test.indexOf("OK") < 0) {
Serial.println(F("!! HC-12 не ответил на AT. Проверьте:"));
Serial.println(F(" - питание модуля (просадки недопустимы)"));
Serial.println(F(" - TX<->RX перекрещены"));
Serial.println(F(" - SET действительно на GND во время сессии"));
} else {
Serial.println(F("HC-12 online."));
}
// Первичное чтение настроек
readSettings();
Serial.println(F("\n================================================"));
Serial.println(F(" Ожидание триггера сброса:"));
Serial.print (F(" * нажать кнопку на GPIO"));
Serial.println(BUTTON_PIN);
Serial.println(F(" * или ввести 'setdef' + Enter в мониторе"));
Serial.println(F("================================================"));
}
// ---------- Loop ----------
void loop() {
if (checkTrigger()) {
Serial.println(F("\n--- Восстановление заводских настроек ---"));
// Небольшая пауза, затем команда
String resp = sendAT("AT+DEFAULT", 1200);
Serial.print(F("AT+DEFAULT -> "));
Serial.println(resp.length() ? resp : F("(no response)"));
if (resp.indexOf("OK") >= 0) {
Serial.println(F("Reset OK."));
delay(300);
// Подтверждение: считываем настройки заново
readSettings();
} else {
Serial.println(F("Reset FAILED. Модуль не подтвердил AT+DEFAULT."));
}
Serial.println(F("\nГотов к следующему срабатыванию..."));
}
delay(40);
}
Полезно знать
-
Короткое нажатие BOOT после загрузки скетча безопасно. Опасна только ситуация «держу BOOT во время reset/power-on» — тогда C3 уходит в ROM-загрузчик и скетч просто не стартует.
-
Если в вашей плате BOOT подключён не к GPIO9 (есть редкие варианты с GPIO2/GPIO8), проверьте распиновку конкретной платы и поменяйте
BUTTON_PIN. -
Если хотите всё время держать HC-12 в AT-режиме — ничего дополнительно делать не нужно: скетч уже это делает. Если нужно, чтобы модуль возвращался в рабочий режим после сброса, добавьте в конец
loop()(после успешного сброса) вызовexitATMode();, а в началеcheckTrigger()при обнаружении триггера —enterATMode();.
ты опять полез писать коды, “я ж не программист”?
да потрындеть ему не с кем
@ua6em
Открой свой профиль на полчасика, а то с заблоченным профилем я тебя даже в игнор не могу добавить, вечно твое нытье во всех темах на глаза лезет
Это не для тебя, это я сделал для себя, на будущее, нану я не использую, адаптирую под то, что есть
ЗЫ что ты так ревностно относишься к написанным кодам, ИИ помножит на ноль, так нет, всё течёт всё меняется, сам он сочинить ничего не может, развивайся, пиши код под новое железо
Маленькое замечание ТСу. Если собираешься использовать эти модули, то обязательно на пины питания модуля поставь электролитический конденсатор не менее 100мкф и параллельно керамику 0.1 . Иначе иногда будешь искать причину почему отвалилась внезапно связь или вообще ее нет при одинаковой настройке модулей.
Это замечание надо применять к любым передающим модулям.
нет предела совершенству
А “baud” это что!? ![]()
Наверно скорость работы порта
А, вон оно чо!
@AVTORЕвгений А “channel” это что?
частота! ну вон же он код оставил, там же все указанно… ээээх)))
Ага, спасибо!
@AVTORЕвгений А “mode” это что?
Это он лишнюю n написал.





