Wake Huzzah Feather ESP8266 с герконом
Простите, если это действительно глупый вопрос, но я новичок в Интернете вещей и оборудовании в целом.
У меня есть Huzzah Feather ESP8266, и я пытаюсь сделать датчик присутствия для ванной. Я использую стандартный герконовый датчик двери (пример здесь).
В конечном итоге я хочу, чтобы это устройство выполняло следующие функции:
Планируется, что устройство будет выходить из режима глубокого сна при закрытии двери. Согласно документации, GPIO16 необходимо подключить к RST для отправки сигнала пробуждения.
После пробуждения проверьте геркон и отправьте сообщение в Azure IoT Hub о том, что
ванная комната занята, если дверь закрыта.- Переведите устройство в режим глубокого сна, пробуждая его каждые 30 секунд.
- Каждый раз, когда устройство просыпается, проверяю выключатель. Как только дверь открывается, я отправляю Azure сообщение о том, что
ванная комната свободна, а затем перехожу в режимdeepSleep(0)(т.е. засыпает, пока дверь снова не закроется, затем процесс повторяется)
Сейчас всё работает, но с точностью до наоборот. Я могу разбудить устройство при открытии двери, сообщение успешно отправляется в Azure.
Судя по моему крайне ограниченному пониманию, то, что я хочу сделать, кажется, осуществимо. Полагаю, я упускаю что-то очень простое, но здесь я уперся в стену.
Я не умею делать схемы электропроводки, поэтому, надеюсь, описания моей установки будет достаточно:
- GPIO 16: Провод датчика двери №2
- RST: GPIO 16
- GND: Провод датчика двери №2
Упрощенный пример кода:
void setup()
{
initSerial(); //инициализирует серийный номер
initWifi(); //включить Wi-Fi
door_open(); //отправляет сообщение
}
void door_open() {
IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, HTTP_Protocol);
if (iotHubClientHandle == NULL)
{
Serial.print("Failed on IoTHubClient_LL_Create\r\n");
}
else
{
// Поскольку он может проводить опрос «через 9 секунд», опросы будут происходить
// эффективно примерно через 10 секунд.
// Обратите внимание, что для масштабируемости значение по умолчанию minimumPollingTime
// составляет 25 минут. Подробнее см.:
// https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
unsigned int minimumPollingTime = 9;
if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
{
Serial.print("failure to set option \"MinimumPollingTime\"\r\n");
}
if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
{
Serial.printf("failure to set option \"TrustedCerts\"\r\n");
}
if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, IoTHubMessage, NULL) != IOTHUB_CLIENT_OK)
{
Serial.print("unable to IoTHubClient_SetMessageCallback\r\n");
}
IOTHUB_MESSAGE_HANDLE messageHandle;
if(digitalRead(DOOR) == LOW)
{
messageHandle = IoTHubMessage_CreateFromString("closed");
Serial.println("Door closed");
}
else
{
messageHandle = IoTHubMessage_CreateFromString("open");
Serial.println("Door Open");
}
if (messageHandle == NULL)
{
Serial.print("unable to create a new IoTHubMessage\r\n");
}
else
{
MAP_HANDLE propMap = IoTHubMessage_Properties(messageHandle);
if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)1) != IOTHUB_CLIENT_OK)
{
Serial.print("failed to hand over the message to IoTHubClient");
}
else
{
Serial.print("IoTHubClient accepted the message for delivery\r\n");
}
IoTHubMessage_Destroy(messageHandle);
}
while (1)
{
IoTHubClient_LL_DoWork(iotHubClientHandle);
ThreadAPI_Sleep(100);
}
}
}
Уточнение: Сейчас моё устройство выходит из спящего режима при разъединении магнитных частей дверных датчиков. Я хочу, чтобы устройство выходило из спящего режима при замыкании цепи (т.е. когда датчики соединяются).
@maccettura, 👍1
Обсуждение2 ответа
Вывод RST (сброс) ESP работает как вывод сброса любого другого микроконтроллера. Если вы подадите на него низкий уровень достаточно долго (пороговое значение наверняка указано в техническом описании), весь микроконтроллер перезагрузится, как если бы вы отключили и снова включили питание. Таким образом, это не выведет его из спящего режима, а полностью сбросит.
Верно, можно использовать GPIO16, подключенный к RST, чтобы ESP мог самостоятельно выйти из глубокого сна. Похоже, это внутренняя аппаратная функция, отличная от обычного оборудования ввода-вывода. Но вы не можете использовать тот же вывод для других функций одновременно. Геркон закрыт, если дверь закрыта. Поэтому он подаёт низкий уровень на GPIO16 и RST, удерживая их в состоянии сброса. В этом состоянии никакой код не выполняется, поэтому вы никогда не получите сообщение о том, что дверь закрыта. Когда вы затем откроете дверь, выключатель также откроется. Поскольку вывод RST больше не подтянут к низкому уровню, ESP может загрузиться и выполнить ваш код. Дверь открыта, поэтому вы получите соответствующее сообщение.
Поэтому вам придется использовать другой штифт для геркона.
Можно ли включить очень простую «схему электропроводки», чтобы добиться того, что я хочу сделать? Я _совсем_ новичок в этом, ха-ха., @maccettura
Просто подключите один провод от геркона к свободному контакту Feather и настройте свой код на соответствующем контакте. У меня нет Feather, и я не уверен, какой вариант будет хорошим. А как насчёт GPIO4 или 5? Похоже, вам не нужен аппаратный интерфейс I2C на них., @chrisl
Итак, один провод от геркона идёт, скажем, к GPIO5, а второй куда, RST? Нужно ли заземлять переключатель?, @maccettura
Знаете ли вы, как работает определение состояния переключателя? Похоже, что нет. Другой провод от геркона должен быть подключен к земле, чтобы контакт был подтянут к низкому уровню при замыкании переключателя. Также следует активировать внутренний подтягивающий резистор командой pinMode(DOOR, INPUT_PULLUP), иначе контакт будет находиться в состоянии «плавающего» при открытой двери и будет случайным образом менять своё состояние. Вам стоит изучить руководство по переключателям/кнопкам, чтобы действительно понимать, что там происходит., @chrisl
Как я уже говорил в посте, я абсолютный новичок в железе. У меня нет никакого опыта в электротехнике. Хочу убедиться, что правильно вас понял, поэтому и задаю дополнительные вопросы. Вы хотите сказать, что моя конфигурация будет работать, если я переключусь с GPIO16 на GPIO5? Итак, «Геркон 1» — на GPIO5, «Геркон 5» — на RST, а «Геркон 2» — на GND., @maccettura
Нет, геркон 1 к GPIO5, RST к GPIO16, а геркон 2 к GND. Суть моего ответа была в том, чтобы НЕ использовать один и тот же контакт для геркона и одновременного пробуждения. Пробуждение из глубокого сна — это аппаратная функция, которая доступна только на GPIO16. Поэтому вам придётся переместить переключатель на другой контакт., @chrisl
Итак, с такой настройкой мой коммутатор вообще не будет выводить устройство из спящего режима, верно? Ведь к RST ничего не подключено. Вот почему ваши комментарии меня смутили. Насколько я понимаю, такая настройка отдалит меня ещё дальше от цели., @maccettura
Давайте [продолжим это обсуждение в чате](https://chat.stackexchange.com/rooms/77083/discussion-between-chrisl-and-maccettura)., @chrisl
Я бы взял нормально замкнутый или нормально разомкнутый геркон, противоположный тому, что у вас сейчас, только наоборот. Затем я бы избавился от всех этих функций пробуждения из спящего режима и включал бы устройство через геркон, чтобы оно получало питание при закрытии двери, если это происходит чаще, чем при её открытии. При закрытии (при подаче питания) микроконтроллер при загрузке отправляет на сервер команду «Эй, я закрыл», и переходит в режим глубокого сна на 10 секунд.
После пробуждения отправьте пинг с сообщением «Я всё ещё занят». Серверу нужна небольшая хитрость — функция тайм-аута, которая установит состояние двери как открытой через 12 секунд после последнего пинга (10 секунд + немного с учётом задержек Wi-Fi).
Эта конфигурация НЕ использует энергию в режиме ожидания и работает только в течение небольшого количества времени, которое потребляет заряд батареи, поэтому она должна прослужить намного дольше, чем попытки перехода в спящий режим и последующего внешнего пробуждения.
Для повышения эффективности рассмотрите возможность сборки маршрутизатора ESPNOW с двумя дополнительными ESP8266. После настройки и запуска маршрутизатора ESPNOW вы сможете отправлять пинги примерно за 200 мс (при холодной/горячей загрузке) вместо 2000 мс при использовании Wi-Fi, а затем возвращаться в спящий режим. Это продлевает время работы от аккумулятора примерно в 10 раз, но ценой круглосуточной работы двух дополнительных ESP в местах с доступом к питанию.
- Как читать и записывать EEPROM в ESP8266
- Как сделать выводы Tx и Rx на ESP-8266-01 в выводах GPIO?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
- Как заставить 5-вольтовое реле работать с NodeMCU
- Как исправить: Invalid conversion from 'const char*' to 'char*' [-fpermissive]
- ESP8266 не подключается к Wi-Fi
- esp8266 не отвечает на AT-команды
- Разница между этими двумя платами NodeMCU?
Ваш код ВАЖЕН. Скорее всего, именно он и является причиной вашей проблемы. Поэтому покажите нам свой код (в виде текста и в правильном формате). И ещё: что вы подразумеваете под «AND RST»?, @chrisl
@chrisl добавил пример кода, хотя мне (разработчику .NET) удобнее всего работать с этим кодом. Проблема в том, что он активируется при разъединении датчиков (открытии двери). Мне же нужно, чтобы он активировался при их сближении (закрытии двери)., @maccettura
@chrisl Я тоже пытался разъяснить свою схему проводки в редактировании: один из проводов датчика двери подключен к GPIO16, затем у RST есть провод к GPIO16, затем другой провод датчика двери подключен к GND., @maccettura
Зачем вы подключаете контакт сброса ESP к геркону? Это будет удерживать его в состоянии сброса, пока вы не откроете дверь., @chrisl
@chrisl Я думал, что это нужно для сброса устройства. Я хочу, чтобы устройство включалось/выходило из глубокого сна при закрытии двери. Судя по тому, что я читал о ESP8266, для «пробуждения» из глубокого сна нужно подать сигнал на RST (из документации: «GPIO16 необходимо привязать к RST для пробуждения из глубокого сна»). Именно так я и думал., @maccettura