feat: add WebSocket support for ESP32 simulation in nginx configuration; clean up example code by removing unused WDT functions

pull/65/head
David Montero Crespo 2026-03-24 17:02:23 -03:00
parent 9d45484fce
commit dc335c666e
2 changed files with 15 additions and 120 deletions

View File

@ -28,6 +28,21 @@ server {
proxy_set_header Host $host; proxy_set_header Host $host;
} }
# WebSocket endpoints (ESP32 simulation, etc.)
# Must come BEFORE the generic /api/ block so nginx matches it first.
location /api/simulation/ws/ {
proxy_pass http://127.0.0.1:8001/api/simulation/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
# Proxy /api/* requests to the FastAPI backend. # Proxy /api/* requests to the FastAPI backend.
# FastAPI Swagger UI is at /api/docs (moved from /docs to avoid # FastAPI Swagger UI is at /api/docs (moved from /docs to avoid
# conflicting with the frontend /docs/* documentation routes). # conflicting with the frontend /docs/* documentation routes).

View File

@ -2034,23 +2034,12 @@ void loop() {
// Blinks the built-in LED (GPIO2) and an external LED (GPIO4) // Blinks the built-in LED (GPIO2) and an external LED (GPIO4)
// Requires arduino-esp32 2.0.17 (IDF 4.4.x) — see docs/ESP32_EMULATION.md // Requires arduino-esp32 2.0.17 (IDF 4.4.x) — see docs/ESP32_EMULATION.md
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
#define LED_BUILTIN_PIN 2 // Built-in blue LED on ESP32 DevKit #define LED_BUILTIN_PIN 2 // Built-in blue LED on ESP32 DevKit
#define LED_EXT_PIN 4 // External red LED #define LED_EXT_PIN 4 // External red LED
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void setup() { void setup() {
disableAllWDT();
Serial.begin(115200); Serial.begin(115200);
pinMode(LED_BUILTIN_PIN, OUTPUT); pinMode(LED_BUILTIN_PIN, OUTPUT);
pinMode(LED_EXT_PIN, OUTPUT); pinMode(LED_EXT_PIN, OUTPUT);
@ -2058,7 +2047,6 @@ void setup() {
} }
void loop() { void loop() {
disableAllWDT();
digitalWrite(LED_BUILTIN_PIN, HIGH); digitalWrite(LED_BUILTIN_PIN, HIGH);
digitalWrite(LED_EXT_PIN, HIGH); digitalWrite(LED_EXT_PIN, HIGH);
Serial.println("LED ON"); Serial.println("LED ON");
@ -2090,20 +2078,9 @@ void loop() {
// Echoes anything received on Serial (UART0) back to the sender. // Echoes anything received on Serial (UART0) back to the sender.
// Open the Serial Monitor, type something, and see it echoed back. // Open the Serial Monitor, type something, and see it echoed back.
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void setup() { void setup() {
disableAllWDT();
Serial.begin(115200); Serial.begin(115200);
delay(500); delay(500);
Serial.println("ESP32 Serial Echo ready!"); Serial.println("ESP32 Serial Echo ready!");
@ -2111,7 +2088,6 @@ void setup() {
} }
void loop() { void loop() {
disableAllWDT();
if (Serial.available()) { if (Serial.available()) {
String input = Serial.readStringUntil('\\n'); String input = Serial.readStringUntil('\\n');
input.trim(); input.trim();
@ -2933,8 +2909,6 @@ void loop() {
code: `// ESP32 — 7-Segment Display Counter 0-9 code: `// ESP32 — 7-Segment Display Counter 0-9
// Segments: a=12, b=13, c=14, d=25, e=26, f=27, g=32 // Segments: a=12, b=13, c=14, d=25, e=26, f=27, g=32
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
const int SEG[7] = {12, 13, 14, 25, 26, 27, 32}; const int SEG[7] = {12, 13, 14, 25, 26, 27, 32};
@ -2951,14 +2925,6 @@ const bool DIGITS[10][7] = {
{1,1,1,1,0,1,1}, // 9 {1,1,1,1,0,1,1}, // 9
}; };
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void showDigit(int d) { void showDigit(int d) {
for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++)
@ -2966,14 +2932,12 @@ void showDigit(int d) {
} }
void setup() { void setup() {
disableAllWDT();
for (int i = 0; i < 7; i++) pinMode(SEG[i], OUTPUT); for (int i = 0; i < 7; i++) pinMode(SEG[i], OUTPUT);
Serial.begin(115200); Serial.begin(115200);
Serial.println("ESP32 7-Segment Counter"); Serial.println("ESP32 7-Segment Counter");
} }
void loop() { void loop() {
disableAllWDT();
for (int d = 0; d <= 9; d++) { for (int d = 0; d <= 9; d++) {
showDigit(d); showDigit(d);
Serial.print("Digit: "); Serial.println(d); Serial.print("Digit: "); Serial.println(d);
@ -3751,8 +3715,6 @@ void loop() {
// Wiring: DATA → GPIO4 | VCC → 3V3 | GND → GND // Wiring: DATA → GPIO4 | VCC → 3V3 | GND → GND
#include <DHT.h> #include <DHT.h>
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
#define DHT_PIN 4 // GPIO 4 #define DHT_PIN 4 // GPIO 4
#define DHT_TYPE DHT22 #define DHT_TYPE DHT22
@ -3760,17 +3722,8 @@ void loop() {
DHT dht(DHT_PIN, DHT_TYPE); DHT dht(DHT_PIN, DHT_TYPE);
// Disable hardware Timer Group WDTs (QEMU emulation is slower than real time) // Disable hardware Timer Group WDTs (QEMU emulation is slower than real time)
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void setup() { void setup() {
disableAllWDT();
Serial.begin(115200); Serial.begin(115200);
dht.begin(); dht.begin();
delay(2000); delay(2000);
@ -3778,7 +3731,6 @@ void setup() {
} }
void loop() { void loop() {
disableAllWDT();
delay(2000); delay(2000);
float h = dht.readHumidity(); float h = dht.readHumidity();
@ -3810,23 +3762,12 @@ void loop() {
code: `// ESP32 — HC-SR04 Ultrasonic Distance Sensor code: `// ESP32 — HC-SR04 Ultrasonic Distance Sensor
// Wiring: TRIG → D18 | ECHO → D19 | VCC → 3V3 | GND → GND // Wiring: TRIG → D18 | ECHO → D19 | VCC → 3V3 | GND → GND
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
#define TRIG_PIN 18 #define TRIG_PIN 18
#define ECHO_PIN 19 #define ECHO_PIN 19
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void setup() { void setup() {
disableAllWDT();
Serial.begin(115200); Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT); pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT); pinMode(ECHO_PIN, INPUT);
@ -3844,7 +3785,6 @@ long measureCm() {
} }
void loop() { void loop() {
disableAllWDT();
long cm = measureCm(); long cm = measureCm();
if (cm < 0) Serial.println("Out of range"); if (cm < 0) Serial.println("Out of range");
else Serial.printf("Distance: %ld cm\\n", cm); else Serial.printf("Distance: %ld cm\\n", cm);
@ -3872,25 +3812,14 @@ void loop() {
// Requires: Adafruit MPU6050, Adafruit Unified Sensor libraries // Requires: Adafruit MPU6050, Adafruit Unified Sensor libraries
// Wiring: SDA → D21 | SCL → D22 | VCC → 3V3 | GND → GND // Wiring: SDA → D21 | SCL → D22 | VCC → 3V3 | GND → GND
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
#include <Adafruit_MPU6050.h> #include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h> #include <Adafruit_Sensor.h>
#include <Wire.h> #include <Wire.h>
Adafruit_MPU6050 mpu; Adafruit_MPU6050 mpu;
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void setup() { void setup() {
disableAllWDT();
Serial.begin(115200); Serial.begin(115200);
Wire.begin(21, 22); // SDA=21, SCL=22 Wire.begin(21, 22); // SDA=21, SCL=22
if (!mpu.begin()) { if (!mpu.begin()) {
@ -3904,7 +3833,6 @@ void setup() {
} }
void loop() { void loop() {
disableAllWDT();
sensors_event_t a, g, temp; sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp); mpu.getEvent(&a, &g, &temp);
@ -3936,8 +3864,6 @@ void loop() {
code: `// ESP32 — PIR Motion Sensor code: `// ESP32 — PIR Motion Sensor
// Wiring: OUT → D5 | VCC → 3V3 | GND → GND // Wiring: OUT → D5 | VCC → 3V3 | GND → GND
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
#define PIR_PIN 5 #define PIR_PIN 5
#define LED_PIN 2 // built-in blue LED on ESP32 DevKit #define LED_PIN 2 // built-in blue LED on ESP32 DevKit
@ -3945,17 +3871,8 @@ void loop() {
bool prevMotion = false; bool prevMotion = false;
unsigned long detections = 0; unsigned long detections = 0;
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void setup() { void setup() {
disableAllWDT();
Serial.begin(115200); Serial.begin(115200);
pinMode(PIR_PIN, INPUT); pinMode(PIR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT);
@ -3965,7 +3882,6 @@ void setup() {
} }
void loop() { void loop() {
disableAllWDT();
bool motion = (digitalRead(PIR_PIN) == HIGH); bool motion = (digitalRead(PIR_PIN) == HIGH);
if (motion && !prevMotion) { if (motion && !prevMotion) {
detections++; detections++;
@ -4001,8 +3917,6 @@ void loop() {
// Pot : SIG → D34 | VCC → 3V3 | GND → GND // Pot : SIG → D34 | VCC → 3V3 | GND → GND
#include <ESP32Servo.h> #include <ESP32Servo.h>
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
#define SERVO_PIN 13 #define SERVO_PIN 13
#define POT_PIN 34 // input-only GPIO (ADC) #define POT_PIN 34 // input-only GPIO (ADC)
@ -4010,24 +3924,14 @@ void loop() {
Servo myServo; Servo myServo;
// Disable hardware Timer Group WDTs (QEMU emulation is slower than real time) // Disable hardware Timer Group WDTs (QEMU emulation is slower than real time)
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void setup() { void setup() {
disableAllWDT();
Serial.begin(115200); Serial.begin(115200);
myServo.attach(SERVO_PIN, 500, 2400); // standard servo pulse range myServo.attach(SERVO_PIN, 500, 2400); // standard servo pulse range
Serial.println("ESP32 Servo + Pot control"); Serial.println("ESP32 Servo + Pot control");
} }
void loop() { void loop() {
disableAllWDT(); // keep WDTs disabled (FreeRTOS may re-enable)
int raw = analogRead(POT_PIN); // 04095 (12-bit ADC) int raw = analogRead(POT_PIN); // 04095 (12-bit ADC)
int angle = map(raw, 0, 4095, 0, 180); int angle = map(raw, 0, 4095, 0, 180);
myServo.write(angle); myServo.write(angle);
@ -4059,31 +3963,19 @@ void loop() {
// Wiring: HORZ → D35 | VERT → D34 | SEL → D15 // Wiring: HORZ → D35 | VERT → D34 | SEL → D15
// VCC → 3V3 | GND → GND // VCC → 3V3 | GND → GND
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
#define JOY_HORZ 35 // input-only ADC pin #define JOY_HORZ 35 // input-only ADC pin
#define JOY_VERT 34 // input-only ADC pin #define JOY_VERT 34 // input-only ADC pin
#define JOY_BTN 15 // GPIO with pull-up #define JOY_BTN 15 // GPIO with pull-up
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void setup() { void setup() {
disableAllWDT();
Serial.begin(115200); Serial.begin(115200);
pinMode(JOY_BTN, INPUT_PULLUP); pinMode(JOY_BTN, INPUT_PULLUP);
Serial.println("ESP32 Joystick ready"); Serial.println("ESP32 Joystick ready");
} }
void loop() { void loop() {
disableAllWDT();
int x = analogRead(JOY_HORZ); // 04095 int x = analogRead(JOY_HORZ); // 04095
int y = analogRead(JOY_VERT); // 04095 int y = analogRead(JOY_VERT); // 04095
bool btn = (digitalRead(JOY_BTN) == LOW); bool btn = (digitalRead(JOY_BTN) == LOW);
@ -4121,8 +4013,6 @@ void loop() {
// Wiring: DATA → GPIO3 | VCC → 3V3 | GND → GND // Wiring: DATA → GPIO3 | VCC → 3V3 | GND → GND
#include <DHT.h> #include <DHT.h>
#include <soc/timer_group_struct.h>
#include <soc/timer_group_reg.h>
#define DHT_PIN 3 // GPIO 3 #define DHT_PIN 3 // GPIO 3
#define DHT_TYPE DHT22 #define DHT_TYPE DHT22
@ -4130,17 +4020,8 @@ void loop() {
DHT dht(DHT_PIN, DHT_TYPE); DHT dht(DHT_PIN, DHT_TYPE);
// Disable hardware Timer Group WDTs (QEMU emulation is slower than real time) // Disable hardware Timer Group WDTs (QEMU emulation is slower than real time)
void disableAllWDT() {
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_config0.en = 0;
TIMERG0.wdt_wprotect = 0;
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG1.wdt_config0.en = 0;
TIMERG1.wdt_wprotect = 0;
}
void setup() { void setup() {
disableAllWDT();
Serial.begin(115200); Serial.begin(115200);
dht.begin(); dht.begin();
delay(2000); delay(2000);
@ -4148,7 +4029,6 @@ void setup() {
} }
void loop() { void loop() {
disableAllWDT();
delay(2000); delay(2000);
float h = dht.readHumidity(); float h = dht.readHumidity();