[Bug]: Battery Voltage and Environment Sensors Not Working on Seeed Wio-WM1100 devices
Category
Hardware Compatibility
Hardware
Seeed Wio Tracker 1110, Other
Firmware Version
2.5.14.f2ee0df
Description
- Factory-reset the device
- Flash latest stable firmware
- Enable telemetry (power metrics & environment metrics module)
- Check the node details, following two screenshots of the Android app
Whether the device is powered through USB or not, connected to the battery or not, the battery always shows 0.00V and plugged-in icon:
Also the built-in environment sensors are not working:
This issue applies to both Seeed Wio-WM1100 devices, the "Wio Tracker 1110" and also the "WM110 Dev Kit".
There is no issue with the "T1000-E", which is working well since https://github.com/meshtastic/firmware/pull/5141 . I tried to compare variant.h of all 3 devices, but PIN numbers are all different and I was not able to come up with an idea how to solve this.
Relevant log output
No response
Thanks for the report! Is it possible for you to provide some logs of the early start-up, perhaps from the serial console from flasher.meshtastic.org ?
Thanks a lot for looking into this issue! I tried to capture the complete log after a factory reset. I ran the following CLI commands:
meshtastic --ble "Meshtastic_5001" --factory-reset-device
meshtastic --ble "Meshtastic_5001" --set telemetry.environment_measurement_enabled true --set telemetry.power_measurement_enabled true
See attached the recorded log from the "Wio Tracker 1110". I didn't know exactly what the first log entry is after the factory reset, so I also kept the lines before.
meshtastic_wio_tracker_1110_log.txt
I can try to create such a log also for the "WM110 Dev Kit", but I first need to figure out how as connecting is a bit more complicated. So I first wanted to ask, if this log format is the correct one. Let me know, if there is any other information needed.
Thanks for that. I have both of these devices, will try and replicate soon.
A fresh flash of 2.5.16 and temperature works straight away:
DEBUG | ??:??:?? 2 Scan for I2C devices on port 1
INFO | ??:??:?? 2 LIS3DH found at address 0x19
INFO | ??:??:?? 2 SSD1306 found at address 0x3c
INFO | ??:??:?? 2 SSD1306 found at address 0x3c
DEBUG | ??:??:?? 2 0x3 subtype probed in 2 tries
INFO | ??:??:?? 2 SHT4X found at address 0x44
INFO | ??:??:?? 2 3 I2C devices found
...
INFO | ??:??:?? 13 [EnvironmentTelemetry] Opened SHT4X sensor on i2c bus
INFO | ??:??:?? 14 [EnvironmentTelemetry] Send: barometric_pressure=0.000000, current=0.000000, gas_resistance=0.000000, relative_humidity=51.484550, temperature=24.866486
INFO | ??:??:?? 14 [EnvironmentTelemetry] Send: voltage=0.000000, IAQ=0, distance=0.000000, lux=0.000000
INFO | ??:??:?? 14 [EnvironmentTelemetry] Send: wind speed=0.000000m/s, direction=0 degrees, weight=0.000000kg
INFO | ??:??:?? 14 [EnvironmentTelemetry] Send: radiation=0.000000##R/h
I see that your sensor is detected as an SHT31 ... it should be an SHT4X ... checking.
@dkastl : Inside this zip is a uf2 file with the latest firmware and an additional debug line for the SHT4x. Can you flash it and send the logs? That will enable me to fix the detection for the SHT4x for your device. firmware.zip
Thanks a lot, @fifieldt ! Find attached the log file.
20241224_meshtastic_wio_tracker_1110_log.txt
Like last time I did a factory reset first, then started logging, enabled telemetry and the device rebooted when saving the settings.
On my device the sensors still show NaN, so could it be that hardware has changed, because you say it works with your devices?
Does the battery voltage reading also work correctly in your case?
Thanks for this. So I can see the serial number for the SHT4x isn't matching, which is why temperature isn't working.
Plan now is to look at the code and work out whether we're doing something wrong given the many different serial numbers we are seeing.
On power, I haven't looked into it yet, apologies.
Just curious, which file contains the logic based on serial numbers? I'm still new to Meshtastic and tried to understand what can be found in /variants/, without success.
https://github.com/meshtastic/firmware/blob/ed39d14c8525130b9ef86cae03c575484a18e6cf/src/detect/ScanI2CTwoWire.cpp#L330
Thanks! I don't really understand how to know these serial numbers, but I 'm able to build the firmware. So whether you have a branch with changes to test or a list of serial numbers to try, just let me know if there is something I can help.
Amazing. Well, if you put your serial number in there (0xd3b ) you should get temperature :)
What I'm wondering is whether we're reading the wrong bits from that register.
If you look at the manual https://sensirion.com/media/documents/33FD6951/662A593A/HT_DS_Datasheet_SHT4x.pdf
0x89 is a 6 bit thing, but we not using all of it: [2 * 8-bit data; 8-bit CRC; 2 * 8-bit data; 8-bit CRC]
That helped! Adding the device serial makes the environmental telemetry show up again.
Here is the change, rather trivial after your instructions: https://github.com/meshtastic/firmware/compare/master...dkastl:dkastl/issue5552
Do you think there is a better way to avoid adding more and more devices over time, or would this be good enough for now? I will later also test it on the "WM110 Dev Kit". If mine has the same number or if there is again another one.
It appears that I'm running into the same issue, and my serial number is different too, but not the same as @dkastl. Using the firmware posted with the 0x89 i2c command baked in, I was able to find that my sensors serial number is: 0x12bf. Added that to the ScanI2CTwoWire.cpp and it worked.
My Adafruit SHT40 board has a serial of 0x109cc7ac as detected by Adafruit's SHT4X CircuitPython library.
but it's detected as an SHT31 by 2.6.2.31c0e8f: (I'm using a Station G2)
INFO | ??:??:?? 1 SHT31 found at address 0x44
INFO | ??:??:?? 1 2 I2C devices found
...
INFO | 01:23:01 11 [EnvironmentTelemetry] Environment Telemetry: init
INFO | 01:23:01 11 [EnvironmentTelemetry] Init sensor: SHT31
INFO | 01:23:01 11 [EnvironmentTelemetry] Opened SHT31 sensor on i2c bus
I see no mention of a serial number command in the SHT31 datasheet, but via the SHT4x datasheet it is of course 0x89. I'm skeptical that checking the serial number allows detecting an SHT4x; I see no mention of serial prefixes or anything:
Each sensor has a unique serial number, that is assigned by Sensirion during production. It is stored in the one-time-programmable memory and cannot be manipulated after production. The serial number is accessible via I2C command 0x89 and is transmitted as two 16-bit words, each followed by an 8-bit CRC.
Perhaps the sensor version needs to be manually selected?
Each sensor has a unique serial number, that is assigned by Sensirion during production. It is stored in the one-time-programmable memory and cannot be manipulated after production. The serial number is accessible via I2C command 0x89 and is transmitted as two 16-bit words, each followed by an 8-bit CRC.
Perhaps the sensor version needs to be manually selected?
Noticing the same thing as well. If I update the code to ignore the serial number (which I think is useless here as you posted above) and force to a SHT4X, it appears to work. After doing some reading, seems like one method possibly to use is basically try to read the value. If it doesn't work as one, try the other. If neither work, return no value.
Doing some testing, probably could do this cleaner:
src/detect/ScanI2CTwoWire.cpp
Added:
bool trySHTXXReadSensorData(uint8_t i2cAddr, uint8_t cmdMsb, uint8_t cmdLsb, int delayMs) {
LOG_DEBUG("Trying to auto detect if a SHT3x or SHT4x sensor at address 0x%02X", i2cAddr);
Wire.beginTransmission(i2cAddr);
if (cmdLsb == 0xFF) { // SHT4x uses a single-byte command (0xFD)
Wire.write(cmdMsb);
} else { // SHT3x uses a two-byte command (e.g., 0x2400)
Wire.write(cmdMsb);
Wire.write(cmdLsb);
}
byte error = Wire.endTransmission();
if (error != 0) {
return false;
}
delay(delayMs); // Wait for measurement to complete
// Request and read 6 bytes (Temp MSB, Temp LSB, Temp CRC, Hum MSB, Hum LSB, Hum CRC)
if (Wire.requestFrom(i2cAddr, 6) == 6) {
// Read the bytes to clear the buffer, even if we don't use them for this check
for (int i = 0; i < 6; i++) {
Wire.read();
}
return true; // Successfully received 6 bytes
} else {
return false; // Did not receive the expected number of bytes
}
}
then
case SHT31_4x_ADDR_ALT: // same as OPT3001_ADDR
if (trySHTXXReadSensorData((uint8_t)addr.address, 0xFD, 0xFF, 20)) {
type = SHT4X;
logFoundDevice("SHT4X", (uint8_t)addr.address);
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
type = OPT3001;
logFoundDevice("OPT3001", (uint8_t)addr.address);
} else if (trySHTXXReadSensorData((uint8_t)addr.address, 0x24, 0x00, 20)) {
type = SHT31;
logFoundDevice("SHT31", (uint8_t)addr.address);
}
break;
This works for the SHT4x, waiting on an SHT3x this week to validate. Not sure if a cleaner way? But quick and dirty.
SHT3x came in, hopefully get it tested over the next few days. Not sure if this code is good enough for a PR or needs some TLC
Are these checking for serial numbers? I don't understand what the switch statement is using to determine which sensor it is.
Are these checking for serial numbers? I don't understand what the switch statement is using to determine which sensor it is.
From what I have read, checking for the serial number on a sht4x sensor is useless as every one of them has a unique value stored in that location set in the factory. I created a custom function that instead attempts to read the sensor values to determine the device type. Shtx3x and sht4x have different commands to read the temperature and humidity, so using those commands instead to check for which senors it is.
The old case statements basically did a useless serial number check, if that failed (which for pretty much everyone it would), it then tried the opt3000 check, if that failed, then the code just assumed it was a sht3x and moved on. This method should be smarter to make sure we have to right sensor vs guessing.
The other option here is to get rid of this case statement entirely, and then consolidate the sht4x and sht3x functions under telemetry / sensors to have a generic shtXX check with essentially the same code as above.
Ah, okay, excellent! That's why I asked. Not that I have any authority in this repo, but with the addition of some comments to explain, this would look good to me. :)
Just a heads up, finally got a SHT3x and code still isn't detecting it correctly, so still some work to be done. Haven't given up, but may a couple weeks before I can really get too deep to figure out what's up. But planning to hopefully get it working and submit a PR