惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Full Disclosure
WordPress大学
WordPress大学
小众软件
小众软件
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
腾讯CDC
量子位
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
Scott Helme
Scott Helme
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Hacker News
The Hacker News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
Jina AI
Jina AI
Attack and Defense Labs
Attack and Defense Labs
S
SegmentFault 最新的问题
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
Last Week in AI
Last Week in AI
博客园 - 【当耐特】
Google Online Security Blog
Google Online Security Blog
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
罗磊的独立博客
L
LINUX DO - 最新话题
博客园 - Franky
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
The Last Watchdog
The Last Watchdog
J
Java Code Geeks
AI
AI
C
Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cyber Attacks, Cyber Crime and Cyber Security
Cisco Talos Blog
Cisco Talos Blog
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
Help Net Security
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
I
Intezer
S
Securelist

Simply Explained

Converting a Tuya Thermostat to ESPHome Bringing Foam Monsters to Life: How I Wrote and Illustrated a Children's Book Using AI How I Built an NFC Movie Library for my Kids Analyzing Link Rot in My Newsletter (After 31 Editions) How I Use Alfred to Search My Obsidian Notes Faster (with Spotlight!) Year in review: 2022 Smart lights behind a wall switch (Shelly, Z-Wave, ESPHome) Serverless Anagram Solver with Cloudflare R2 and Pages Integrate Home Assistant with Apple Reminders How WebP Images Reduced My Bandwidth Usage by 50% Tracking gas usage with ESPHome, Home Assistant, and TCRT5000 My Sixth Year as YouTube Creator (statistics + retrospective) EZStore: a tiny serverless datastore for IoT data (DynamoDB + Lambda) ESP-IDF: Storing AWS IoT certificates in the NVS partition (for OTA) How to securely access your home network with Cloudflare Tunnel and WARP I Built a CO2 Sensor and It Terrifies Me Filtering spam on YouTube with TensorFlow & AI Building a killer NAS with an old Rackable Server How I Structure My ESPHome Config Files Howto Virtualize Unraid on a Proxmox host MAX17043: Battery Monitoring Done Right (Arduino & ESP32) Preventing Cumulative Layout Shifts with lazy loaded images (Eleventy + markdown-it) Migrating This Blog From Jekyll to Eleventy Good Home Automation Should be Boring ESP32 Cam: cropping images on device Retrospective: My Fifth Year on YouTube Secure Home Assistant Access with Cloudflare and Ubiquiti Dream Machine Shelly 2.5 + ESPHome: potential fire hazard + fix Impact of Adblockers on Google Analytics (vs. Plausible) Shelly 2.5: Flash ESPHome Over The Air! Tuya IR Hub: control Daikin AC (Home Assistant + ESPHome) Building Air Quality Sensor: Luftdaten + Home Assistant HEIC to JPG: Build a Quick Action with Automator Make Your Garage Door Opener Smart: Shelly 1, ESPHome and Home Assistant Static webhosting benchmark: AWS, Google, Firebase, Netlify, GitHub & Cloudflare Why I don't take sponsorships Monitoring my 3D printer with a Pi Zero, Home Assistant and TinyCore Linux Home Energy Monitor: V2 Retrospective: 4 years on YouTube
ESP32: Keep WiFi connection alive with a FreeRTOS task
Xavier Decuy · 2020-02-17 · via Simply Explained

I have a few ESP32's running in my house. A few of them are running 24/7 and require an always-on WiFi connection. That's been quite tricky to implement. I used to include various checks throughout my code, but that's not scalable.

What I need is something running in the background that is continuously monitoring my WiFi connection, regardless of what other code is running. Luckily we can use FreeRTOS on the ESP32 to do just that!

I created a FreeRTOS task that checks the WiFi connection every 10 seconds. WiFi up? Good, do nothing, and check again in 10 seconds. WiFi down? Connect it again!

Flowchart of the FreeRTOS task

In code:

// Include the necessary libraries
#include <Arduino.h>
#include "WiFi.h"

#define WIFI_NETWORK "--- your WiFi network name ---"
#define WIFI_PASSWORD "--- your WiFi password ---"
#define WIFI_TIMEOUT_MS 20000 // 20 second WiFi connection timeout
#define WIFI_RECOVER_TIME_MS 30000 // Wait 30 seconds after a failed connection attempt

/**
 * Task: monitor the WiFi connection and keep it alive!
 * 
 * When a WiFi connection is established, this task will check it every 10 seconds 
 * to make sure it's still alive.
 * 
 * If not, a reconnect is attempted. If this fails to finish within the timeout,
 * the ESP32 will wait for it to recover and try again.
 */
void keepWiFiAlive(void * parameter){
    for(;;){
        if(WiFi.status() == WL_CONNECTED){
            vTaskDelay(10000 / portTICK_PERIOD_MS);
            continue;
        }

        Serial.println("[WIFI] Connecting");
        WiFi.mode(WIFI_STA);
        WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD);

        unsigned long startAttemptTime = millis();

        // Keep looping while we're not connected and haven't reached the timeout
        while (WiFi.status() != WL_CONNECTED && 
                millis() - startAttemptTime < WIFI_TIMEOUT_MS){}

        // When we couldn't make a WiFi connection (or the timeout expired)
		  // sleep for a while and then retry.
        if(WiFi.status() != WL_CONNECTED){
            Serial.println("[WIFI] FAILED");
            vTaskDelay(WIFI_RECOVER_TIME_MS / portTICK_PERIOD_MS);
			  continue;
        }

        Serial.println("[WIFI] Connected: " + WiFi.localIP());
    }
}

Here is how I run the task (it's pinned to the core used by the Arduino framework):

xTaskCreatePinnedToCore(
	keepWiFiAlive,
	"keepWiFiAlive",  // Task name
	5000,             // Stack size (bytes)
	NULL,             // Parameter
	1,                // Task priority
	NULL,             // Task handle
	ARDUINO_RUNNING_CORE
);

Feel free to use this in your own code. Just don't forget to change the configuration variables:

  • WIFI_NETWORK and WIFI_PASSWORD is where you store your WiFi credentials.
  • WIFI_TIMEOUT_MS is a timeout for the WiFi connection (in milliseconds). If no connection could be established within this timeout, we stop and wait a bit. No need to keep trying.
  • WIFI_RECOVER_TIME_MS defines how long we should wait between a failed connection attempt and a retry (also in milliseconds).

How it works

The task is an endless for loop that checks if we are connected to WiFi. If that's the case, the task doesn't have to do anything. It pauses itself for 10 seconds and then restarts the for loop by calling continue.

if(WiFi.status() == WL_CONNECTED){
	vTaskDelay(10000 / portTICK_PERIOD_MS);
	continue;
}

This is the best-case scenario. The FreeRTOS scheduler will run the task every 10 seconds and check if the WiFi is still up.

If there is no WiFi connection, we try to connect. This can happen when your WiFi network went offline for a while or when the ESP32 just booted.

Serial.println("[WIFI] Connecting");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD);

Now, I don't want the ESP32 to try to connect to WiFi endlessly, so I added a timeout condition. It will attempt to connect to WiFi until either a connection was established or the timeout was reached:

unsigned long startAttemptTime = millis();

// Keep looping while we're not connected and haven't reached the timeout
while (WiFi.status() != WL_CONNECTED && 
        millis() - startAttemptTime < WIFI_TIMEOUT_MS){}

The last thing to do is check if we now have a WiFi connection. If not, the timeout was probably reached, and we should rerun the task after a short waiting period (which I call WIFI_RECOVER_TIME_MS).

if(WiFi.status() != WL_CONNECTED){
	Serial.println("[WIFI] FAILED");
	vTaskDelay(WIFI_RECOVER_TIME_MS / portTICK_PERIOD_MS);
	continue;
}

And that's how the task works. Simple and yet very effective.

Personal experience

I've been running this FreeRTOS task on my home energy monitor for a couple of months now. So far, it's been rock solid! When the WiFi goes out, the ESP32 just keeps trying to reconnect until it is successful.

And because it's a FreeRTOS task that keeps running, I don't have to worry about checking my WiFi connectivity at other places in my code.

In FreeRTOS we trust.

Feedback

What do you think about this solution? Let me know in the comments below!