C++ on a Mega 2560, no RTOS. Every task owns a millis() window and checks it on each pass through the loop, so control, display, buttons, alarms and telemetry interleave without any of them waiting on the others: 2500 ms for the screen rotation, 150 ms for button debounce, 60 ms for the alarm LED blink, 60 and 100 s for the trend windows, and 300000 ms for the alarm lockout during warm up.
The PWM window is the sensor's own refresh rate
The PID output limits are not a constant, they are set to PeriodoDHT, which is read from the DHT driver's min_delay at startup. You cannot modulate the humidifier faster than you can measure the humidity, so the duty cycle window is the measurement period by construction and the PID output maps directly onto it.
Driving an appliance that only has a button
pulso() pulls the line LOW for 300 ms and releases it, which is exactly what pressing the humidifier's button did. apagar() calls it twice with 50 ms between, because a double press is what that appliance reads as off. The relay is active low as well, so the heater is turned off by writing HIGH, which is why the disconnection path can force it off with a single write.
The ESP32 is a pipe, and that is a choice
It reads one line off Serial2 at 9600 baud and republishes the string unchanged to the incubator's MQTT topic. Nothing is parsed, so adding a field on the Mega needs no change on the radio at all. The cost is that a malformed line reaches the broker intact, and that reconnection is only handled at startup.