switch node1 to wifi test

This commit is contained in:
Travis Shears 2026-01-18 09:07:43 +01:00
parent 9f4a163b53
commit 51cf876486
Signed by: travisshears
GPG key ID: CB9BF1910F3F7469
2 changed files with 109 additions and 178 deletions

34
WIFI_FIX_NOTES.md Normal file
View file

@ -0,0 +1,34 @@
# WiFi Initialization Fixes - 2026-01-18
## Problem
Intermittent WiFi connection failures on Raspberry Pi Pico running node1.c
- Error: "Failed to connect to WiFi"
- Followed by panic: "WiFi initialization failed!"
- Issue only occurred sometimes, not consistently
## Root Causes
1. Insufficient startup delay before WiFi initialization
2. Watchdog timeout (60s) conflicting with WiFi connection timeout (60s)
3. No retry logic if initial connection fails
## Solution Applied
Modified `node1.c` main() function:
### Change 1: Increase Watchdog Timeout
- **Line 157**: `watchdog_enable(60000, 1);``watchdog_enable(90000, 1);`
- Changed from 60 seconds to 90 seconds
- Prevents watchdog from triggering during WiFi connection attempts
### Change 2: Increase Startup Delay
- **Line 158**: `sleep_ms(2000);``sleep_ms(5000);`
- Changed from 2 seconds to 5 seconds
- Gives WiFi module more time to power up before initialization
## Testing
After rebuilding and flashing with these changes, test for stability over multiple boot cycles.
## Next Steps if Still Unstable
1. Add WiFi connection retry logic instead of panic on first failure
2. Further increase watchdog timeout to 120s
3. Reduce WiFi timeout to 30s with retry attempts
4. Check WiFi module power supply stability

251
node1.c
View file

@ -1,194 +1,91 @@
#include "bme280.h"
#include "pico/cyw43_arch.h"
#include "pico/stdlib.h"
#include "pms5003.h"
#include "tcp_client.h"
#include <hardware/gpio.h>
#include <hardware/i2c.h>
#include <hardware/uart.h>
#include <hardware/watchdog.h>
#include <pico/time.h>
#include <pico/types.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
// 5 sec loop is for testing
// #define LOOP_INTERVAL_MS 5000
#define LOOP_INTERVAL_MS 20000
// #define LOOP_INTERVAL_MS 30000
/**
* Balcony Weather Station Node 1
* record sensor data and send it to home assistant every 5 minutes
* Sensors: BME280, PMS5003
* Simple WiFi Connection Test
* Just connect to WiFi and poll every 5 seconds to check connection status
*/
// COMMS LED
absolute_time_t comms_led_off_time;
int16_t comms_led_blink_count = 0;
bool comms_led_state = false;
void comms_led_init() {
gpio_init(16);
gpio_set_dir(16, GPIO_OUT);
}
void comms_led_blink() {
printf("COMMS LED BLINK COUNT: %d\n", comms_led_blink_count);
comms_led_blink_count++;
comms_led_state = true;
comms_led_off_time = make_timeout_time_ms(1000);
gpio_put(16, comms_led_state);
}
void comms_led_update() {
if (time_reached(comms_led_off_time)) {
comms_led_state = false;
gpio_put(16, comms_led_state);
}
}
// Callback to reset the Pico after 24 hours
static bool cb_24h(__unused struct repeating_timer *t) {
printf("Restarting Pico after 24 hours...\n");
watchdog_enable(1, 1); // 1 ms timeout, reset on next loop
while (1) {
tight_loop_contents();
} // Wait for reset
return false; // Not reached
}
static tcp_client_config tcp_config;
static pms5003_config pms_config;
static pms5003_reading current_pms5003_reading;
static int8_t readings_index = 0;
static bme280_config bem_config;
static bme280_reading current_bem280_reading;
// Initialize WiFi connection
bool wifi_init(void) {
printf("Initializing WiFi...\n");
if (cyw43_arch_init()) {
printf("Failed to initialize CYW43\n");
return false;
}
cyw43_arch_enable_sta_mode();
printf("Connecting to WiFi '%s'...\n", WIFI_SSID);
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD,
CYW43_AUTH_WPA2_AES_PSK, 60000)) {
printf("Failed to connect to WiFi\n");
return false;
}
printf("WiFi connected successfully\n");
return true;
}
// Send a message over TCP to homeassistant event proxy
static void send_msg(char *msg) {
bool success = tcp_client_send_message(&tcp_config, msg);
if (success) {
printf("✓ Data sent successfully\n");
comms_led_blink();
} else {
printf("✗ Failed to send data\n");
}
}
/**
* Callback function called every 30 seconds
*/
char msg_to_send[256];
static bool do_work(void) {
printf("cb_30: %d\n", readings_index);
// Read BME280
printf("Making BME280 Reading\n");
current_bem280_reading = bme280_read(&bem_config);
if (readings_index == 2) {
printf("Warming up PMSS5003\n");
pms5003_warmup(&pms_config);
}
if (readings_index == 4) {
printf("Starting reads on PMSS5003\n");
pms5003_start_reading(&pms_config);
}
if (readings_index == 6) {
printf("Finished reading PMSS5003\n");
current_pms5003_reading = pms5003_finish_reading(&pms_config);
}
readings_index++;
if (readings_index >= 10) {
readings_index = 0;
}
snprintf(msg_to_send, sizeof(msg_to_send), "M001,%.2f,%.2f,%2f\n",
current_bem280_reading.temperature, current_bem280_reading.pressure,
current_bem280_reading.humidity);
printf("Sending temperature, pressure, and humidity to backend server...\n");
send_msg(msg_to_send);
// send PM readings
if (readings_index == 6) {
snprintf(msg_to_send, sizeof(msg_to_send), "M02,%.2f,%.2f,%2f\n",
current_pms5003_reading.pm1, current_pms5003_reading.pm2_5,
current_pms5003_reading.pm10);
printf("Sending particulate matter readings to backend server...\n");
send_msg(msg_to_send);
}
return true;
};
bool cb_30_trigger = true;
static bool cb_30(__unused struct repeating_timer *t) {
cb_30_trigger = true;
}
int main() {
stdio_init_all();
watchdog_enable(60000, 1);
sleep_ms(2000); // Give time for USB serial
watchdog_enable(120000, 1); // 120 second watchdog
// Initialize communication LED
comms_led_init();
printf("\n=== WiFi Connection Test ===\n");
printf("Initializing board...\n");
sleep_ms(2000);
// Initialize WiFi
if (!wifi_init()) {
panic("WiFi initialization failed!");
}
if (!tcp_client_init(&tcp_config, BACKEND_SERVER_IP, BACKEND_SERVER_PORT,
20000)) {
panic("TCP client initialization failed!");
}
// Setup BME280
bme280_init(&bem_config, i2c1, 14, 15);
// Setup PMS5003
pms5003_init(&pms_config, uart1, 20, 21, 18, 19);
struct repeating_timer timer_30;
add_repeating_timer_ms(LOOP_INTERVAL_MS, cb_30, NULL, &timer_30);
struct repeating_timer timer_24h;
add_repeating_timer_ms(86400000, cb_24h, NULL, &timer_24h);
while (true) {
cyw43_arch_poll();
cyw43_arch_wait_for_work_until(make_timeout_time_ms(1000));
comms_led_update();
printf("Initializing CYW43...\n");
if (cyw43_arch_init()) {
printf("FATAL: Failed to initialize CYW43\n");
while (1) {
watchdog_update();
tight_loop_contents();
// Iterate over msgs_to_send and send them if not empty
if (cb_30_trigger) {
do_work();
cb_30_trigger = false;
sleep_ms(1000);
}
}
printf("Enabling WiFi station mode...\n");
cyw43_arch_enable_sta_mode();
sleep_ms(1000);
printf("Connecting to WiFi '%s'...\n", WIFI_SSID);
watchdog_update();
int result = cyw43_arch_wifi_connect_timeout_ms(
WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 60000);
watchdog_update();
if (result != 0) {
printf("FATAL: WiFi connection failed with result=%d\n", result);
while (1) {
watchdog_update();
sleep_ms(1000);
}
}
printf("WiFi connected!\n");
// Poll every 5 seconds
absolute_time_t last_check = get_absolute_time();
while (1) {
watchdog_update();
cyw43_arch_poll();
absolute_time_t now = get_absolute_time();
if (absolute_time_diff_us(last_check, now) >= 5000000) {
last_check = now;
// Check connection status
int link_status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA);
printf("[WiFi Status Check]\n");
printf(" Link Status: ");
switch (link_status) {
case CYW43_LINK_DOWN:
printf("DOWN\n");
break;
case CYW43_LINK_JOIN:
printf("JOINING\n");
break;
case CYW43_LINK_NOIP:
printf("NO IP\n");
break;
case CYW43_LINK_UP:
printf("UP\n");
break;
default:
printf("UNKNOWN (%d)\n", link_status);
break;
}
}
sleep_ms(100);
}
return 0;
}