Debugging Atlas Scientific pH Sensor with Mycodo on Raspberry Pi (I²C & UART Troubles)
TL;DR
My Atlas Scientific pH EZO sensor worked fine with Mycodo on Raspberry Pi—until it didn’t. It suddenly stopped responding over I²C after long stable operation. Switching to UART helped temporarily, but odd behavior followed. This post documents the problem, the debugging journey, and how it was finally solved.
Setup Summary
- Sensor: Atlas Scientific pH EZO
- Controller: Raspberry Pi 4B (Bullseye)
- Platform: Mycodo
- First interface: I²C
- Later interface: UART (via
/dev/ttyS0
) - Power source: Dedicated clean 5V PSU
- Other tools: PL2303 USB to UART adapter, PuTTY, Python serial script
Problem Description
After a few months of stable measurements, the sensor stopped responding through I²C.
Over I²C:
i2cdetect
no longer showed the EZO board.- Mycodo logs had:
Read failed. No device detected at address.
- Even after reboots and reconfiguration, Mycodo failed to read.
Switched to UART:
-
Initially worked.
-
But later, the following began appearing in Mycodo logs:
SerialException: device reports readiness to read but returned no data
UnicodeDecodeError: invalid start byte
AttributeError: 'NoneType' object has no attribute 'isalpha'
-
Sending
R
via PuTTY or a Python script returned:*OK57.11
or
*ER
-
The sensor responded inconsistently, especially after using continuous mode
C
. -
Eventually, no data was received.
Suspected Root Causes
These issues seem to stem from one or more of the following:
- Sensor Buffer Corruption due to prolonged use of continuous mode (
C
) - Improper interface switching between I²C and UART without full power cycle
- Multiple processes accessing UART (e.g. Mycodo + PuTTY at the same time)
- Over-polling the sensor at too short intervals (e.g. 1-second loop)
- Leftover configuration from Mycodo conflicting with manual serial reads
- PL2303 USB adapter on Windows not properly releasing the COM port
- Garbage data from sensor when in an unknown internal state
Solution (What Worked)
-
Factory reset the sensor using UART:
→ Command: Factory ← Response: *OK
-
After reset:
- Normal
R
reads returned6.554
, etc. - No more errors unless continuous mode was enabled again.
- Normal
-
Fully disconnected power when switching between I²C and UART modes.
-
Ensured only one interface enabled at a time—removed I²C pull-ups and jumpers when using UART.
-
Set Mycodo polling interval to 5 seconds or more.
-
Disabled continuous mode (
C,0
) and only used discrete reads (R
). -
Used Python +
pyserial
script to test commands safely outside Mycodo.
Python Debug Terminal (UART)
import serial
ser = serial.Serial("COM6", 9600, timeout=1)
print("Atlas pH Sensor Terminal. Type 'exit' to quit.")
print("-" * 50)
while True:
cmd = input("→ Command: ")
if cmd.lower() == "exit":
break
ser.write((cmd + "\r").encode())
resp = ser.readline().decode(errors="ignore").strip()
print("← Response:", resp)
ser.close()
Signs of Recovery
After re-integrating with Mycodo and properly configuring the UART input:
- Readings like
success: ['6.544', '*OK']
began appearing. - pH values were stored in InfluxDB successfully.
- Temperature compensation from another sensor (
?T,27.0
) was confirmed working. - No more decoding or attribute errors.
- Uptime remained stable over several hours.
Final Thoughts
Atlas Scientific pH sensors are precise but can be sensitive to communication state. This incident taught me a few critical lessons:
Lessons Learned
- Always isolate interfaces: don’t leave I²C and UART jumpers both connected.
- Avoid continuous mode (
C,1
) unless necessary. It tends to cause state lockups. - Restart hardware when switching modes.
- If Mycodo fails suddenly after working: check UART/I²C conflicts and reset the sensor.
- Use manual tools (PuTTY / Python) to confirm hardware is functioning before debugging Mycodo.
- Add logging in your scripts to trace unexpected states.
Most Important:
Even if your system was stable for hours or days, sudden crashes can and do happen. Don’t assume hardware failure. Debug layer by layer.
Tags: atlas-scientific
, ph-sensor
, raspberry-pi
, mycodo
, uart
, i2c
, sensor-troubleshooting
, diy
, pyserial
, factory-reset
, ezo