The Arduino output levels do not consistently match the relay module’s active-low input behavior, and the displayed state reports the output pin—not whether a relay contact or valve actually changed state. Correct the relay polarity first, then verify the pin, relay indicator, contact, and valve separately; the laptop supply alone does not test those signal and load paths.
Why polarity changes fail to match the display
The sketch defines as HIGH and as LOW. That is active-high logic. The hardware description says the two-channel relay module is active-low, which means a LOW input energizes a relay and a HIGH input releases it. If that description matches the board, the sketch’s labels are reversed at the module input.
The display reads and . On an Arduino output pin this reports the output latch level. It does not sense the module input terminal, relay coil, contact position, valve position, or fluid flow. A screen showing “ON” therefore means the sketch has written the level it labels ON; it is not proof that the load is energized.
Do not try to repair a polarity mismatch by changing phase durations or relying on the relay board LEDs. First establish what level turns each input on. With the machine in a safe state, compare the Arduino pin voltage to the relay IN terminal and observe the board indicator as the sketch commands each state. Confirm the contact changes with suitable test equipment before reconnecting a valve.
| Quantity or setting | Value in sketch | Where to verify / significance |
|---|---|---|
| Relay asserted level | HIGH |
; compare with the module input’s active level. |
| Relay released level | LOW |
; active-low boards commonly interpret this as asserted. |
| Output pins | Water 9; steam 8 | Check the sketch’s output and the matching physical IN terminals. |
| Temperature error checks | 5 failed reads or average ≥ 500 °C |
failCount / tempLimit; see the error path below. |
Output levels and relay contacts along the signal path
For an active-low module, swap the logical output definitions so an asserted relay command writes LOW and a released command writes HIGH. Keep the process names separate from electrical levels: “valve open” is not synonymous with “Arduino HIGH.” Confirm the valve’s electrical and mechanical response independently, because “normally closed” describes the valve’s de-energized condition, not the relay module’s input polarity.
The setup currently writes directly to both pins before the cycle starts. With the original definitions that drives both LOW at startup, which asserts an active-low relay. Reversing the definitions also changes this startup behavior. Check the initial relay/contact state after changing polarity and before allowing an automatic cycle. The error handler separately writes HIGH to both pins, bypassing both the symbolic definitions and setRelay(); update that path to use the intended safe state for the actual module and process.
Use a four-point check for each channel: commanded logical state, Arduino pin level, relay input/indicator, and contact/load state. If the screen and pin agree but the relay input does not, inspect wiring and common reference. If the relay indicator changes but the contact does not, isolate the relay/contact path. If the contact changes but the valve does not, investigate valve supply, wiring, coil, and mechanical operation. Do not infer a contact or valve fault from an LCD label alone.
Ignored commands during the protection interval
setRelay()The function has no indication to the caller that it skipped the write, while the cycle state and LCD continue to advance. On startup, the timestamps are zero, so early calls can also be ignored untilmillis() has passed the guard interval. This can make the requested phase and the physical output temporarily disagree.
Still, log or display the pin levels after each permitted write and test the actual transition. If the guard is needed to limit switching, make the function report whether it wrote the pin and base diagnostics on the accepted output, not just the requested state.
The phase timer uses millis()and state-entry timestamps. The elapsed counter includes time spent doing other loop work; it is not a dedicated timer interrupt. Time the state from its transition using a serial timestamp or external clock, and record the first displayed value after entry.
Countdown discrepancies and display refresh
On transition into a new state, stepStartTime is reset to the current millis(). The next call sets the state duration and computes remaining time from that timestamp.
Instrument each transition with the state number, transition timestamp, duration, and elapsed milliseconds. If measured duration is correct but the screen begins at 7, troubleshoot refresh and LCD update timing. If the measured duration is short, inspect whether the running sketch matches this listing and whether another code path modifiescycleStep, stepStartTime, or the durations.
The shown code clears the LCD continuously while inError is true, then returns from loop()That creates a blank/repeated error display and pauses normal cycle/display processing during the return, althoughmillis() continues advancing. Outside that branch, the display is rewritten without clearing every pass. Log the error condition and sensor values when a freeze or glitch occurs; distinguish an error-display loop from a stalled I2C/LCD update.
Temperature fault path and unsafe state changes
The sketch accepts a temperature only when it is not -127 and is no greater than 150 °C. On a failed read it substitutes lastValidTemp, increments failCount, and still adds that substituted value to the five-entry average. Five consecutive failed samples trigger the error path. At a 2-second sampling interval, that threshold is reached over successive samples rather than immediately.
The over-temperature threshold is 500.0 °C. Since accepted readings are capped at 150 °C and failed readings are replaced by the last valid value, this threshold cannot be reached by the normal values admitted into the average. The “OVER TEMP!” branch is therefore not a functioning protection threshold with these limits. Select a process-appropriate trip point from the sensor and equipment specifications, and validate sensor-failure and over-temperature behavior without exposing people or equipment to uncontrolled heat.
On an active-low relay board, HIGH releases the relays; whether that is safe depends on the contact wiring and valve function. After the delay it clearsinError and resumes the cycle; a continuing sensor fault may trigger the error again at the next temperature check. Define and test an explicit fault state that drives the process to its intended safe condition, prevents automatic cycle continuation, and records the fault cause.
Relay and LCD freeze diagnostics
A laptop-powered Arduino can run while the relay module, valve coil, wiring, and I2C display remain electrically disturbed by switching. Laptop power rules out only some supply problems; it does not establish the voltage at the relay board under switching load or eliminate inductive transients, shared-ground problems, or I2C wiring faults. Measure the Arduino and relay-board supply during transitions and inspect wiring, grounding, and load suppression against the actual component requirements.
Use serial logging to capture state number, temperature result, failCount, averageTemp, output-pin levels, and elapsed phase time. If serial logging continues while the LCD freezes, focus on the display/I2C path and how often the code updates it. If serial output also stops, inspect blocking code, power/reset behavior, and wiring. Repeated lcd.clear() calls in an error loop can visibly flicker; the sketch’s global String stageName also consumes dynamic memory on a small controller, so replacing it with fixed text or a character buffer is a reasonable stability test, not a proven diagnosis.
- Disconnect or otherwise isolate the valve loads and place the process in a safe test condition.
- Confirm whether each relay input is active LOW or active HIGH from the module markings or documentation, then test one channel at a time.
- Correct and ; make startup and fault writes use the same logical definitions.
- Record pin level, relay indicator, contact state, and valve response for each requested state.
- Time fill and boil transitions independently; log loop timestamps and sensor results during any countdown anomaly or display failure.
- Test sensor fault handling and the chosen safe fault state before returning the controller to service.
FAQ
How do I fix an active-low Arduino relay that is backwards?
Set the asserted state to LOW and the released state to HIGH, then verify each relay input and contact with the load isolated. Update startup and fault handling as well as the normal cycle.
How do I tell whether the LCD reports the real valve state?
It does not in this sketch: digitalRead() reports the Arduino output level. Check the relay contact and valve separately; add feedback sensing if the control system must report actual position.
How do I diagnose an Arduino LCD freeze after a few cycles?
Compare serial logging with LCD updates and record sensor/error status when the fault occurs. If serial continues, inspect the display and I2C wiring; if both stop, investigate blocking execution, reset, and supply behavior during relay switching.
How do I make the temperature error stop the cycle safely?
Choose a trip point suited to the process; the current 500 °C limit cannot be reached by readings accepted at no more than 150 °C. Implement a latched fault state that commands the verified safe relay/contact condition and requires deliberate reset.
Keep the controller out of service if relay state, valve position, or fault response is unpredictable. Escalate to the relay/module or controller manufacturer’s official support channel with the wiring diagram, exact module identification, measured input levels, and serial log.