Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!
Posted: Mon Nov 21, 2022 6:19 pm
Well, now that it's been raining quite heavily during the past 16hrs or so, it was inevitable that my SHT30 device would eventually fail because of it. It seems actually that it's failed on quite a few occassions, and it seems that my program is not as hardy against this as I'd thought. I now have a string of errors in my errorlog.txt file i'd like to share with you all.
Errorlog.txt file contents since last post:
This was my program at the time of these errors:
I've now enhanced it further with even more appendfile messages for even better transparency of where my code is not resilient enough to recover from a fault. Clearly it has recovered on quite a few occassions, but the final failure was obviously the nail in the coffin it seems. I'm unsure of why it has not recovered this time, even if this needed to be a complete automatic Pico W reboot...? (If anyone fancied a challenge at helping me identify?)
You'll notice i'm still resisting using the watchdog.
Errorlog.txt file contents since last post:
Code: Select all
MQTT Error: [Errno 113] EHOSTUNREACH
MQTT Error: [Errno 113] EHOSTUNREACH
MQTT Error: [Errno 107] ENOTCONN
SHT Error: Bus error
SHT Error: Bus error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: Bus error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: CRC error
SHT Error: Bus error
Code: Select all
#Necessary library imports for this code to function
from secrets import SSID
from secrets import PASSWORD
from secrets import IP
from secrets import IP_mask
from secrets import IP_gateway
from secrets import IP_DNS
from secrets import MQTTSERVE
from umqtt.simple import MQTTClient
import time
import network
import ubinascii
import socket
from machine import I2C, Pin, #wdt
import sht30
from sht30 import SHT30
from sht30 import SHT30Error
led = machine.Pin("LED", machine.Pin.OUT)
#initialise LED to OFF
led.off()
# def appendfile(message, error):
# file=open("errorlog.txt","a")
# errorstring=str(error)
# file.write(message)
# file.write(errorstring)
# file.write("\n")
# file.close()
#file.flush()
def appendfile(message, error):
with open('errorlog.txt', 'a') as file:
file.write(message)
errorstring=str(error)
file.write(errorstring)
file.write('\n')
file.close()
def sht_error(ex):
print("something went wrong reading the SHT-30!")
print('Error:', ex)
message = 'SHT Error: '
appendfile(message, ex) #message, error
#Define the interface of the SHT30 Temp/Humidity sensor with the Pico W
i2c=I2C(0, sda=Pin(4), scl=Pin(5), freq=5000)
sht=sht30.SHT30(i2c=i2c, i2c_address=68)
def readsensor():
global temperature
global humidity
try:
sensor = sht.measure()
except SHT30Error as ex:
#print(ex)
sht_error(ex)
try:
print("resetting SHT30")
restartsensor = SHT30(i2c)
time.sleep(1)
restartsensor.reset()
time.sleep(2)
print("SHT30 reset")
sensor = sht.measure()
except:# SHT30Error as ex:
#sht_error(ex)
print("rebooting Pico W")
time.sleep(10)
machine.reset()
temperature, humidity = sensor
#wdt = wdt(timeout= 8000)
readsensor()
#wdt.feed()
#print("woof!...good boy!")
print('SHT Temperature: {:3.1f}ºC'.format(temperature))
print('SHT Humidity: {:3.1f}%'.format(humidity))
#Define the onboard Pico Temperature sensor and necessary conversion factor
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)
#Configure this Pico W for a static IP address on router using the following
UseStaticIP = True
IP = IP
IP_mask = IP_mask
IP_gateway = IP_gateway
IP_DNS = IP_DNS
#Active the onboard Pico W Wi-Fi and connect to home network defined through "secrets.py"
wlan = network.WLAN(network.STA_IF)
#Read the MAC address from the Pico W itself
mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
print()
print("MAC address for this Pico W:", mac)
print()
#Configure a high power wi-fi connection
wlan.config(pm = 0xa11140)
wlan.active(True)
print("Scanning Available Wifi Connections...")
time.sleep(5)
#wdt.feed()
#print("woof!...good boy!")
print(wlan.scan())
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
led.on()
#wdt.feed()
#print("woof!...good boy!")
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
try:
wlan.connect(SSID, PASSWORD)
except:
try:
print("first attempt to connect to router failed!")
print("cycling wifi for retry")
wlan.active(False)
led.toggle()
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
led.toggle()
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
wlan.active(True)
time.sleep(2)
print(wlan.scan())
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
wlan.connect(SSID, PASSWORD)
except:
print("wifi connecting failed. Rebooting...")
time.sleep(10)
machine.reset()
#wdt.feed()
#print("woof!...good boy!")
led.off()
# Wait for connect or fail (3mins)
max_wait = 90
attempt = 1
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
#print(wlan.status)
#break
led.on()
max_wait -= 1
#print(wlan.status)
print()
print("Connection status attempt: ", attempt)
print()
print('connection is good...continuing')
print()
attempt += 1
time.sleep(1)
led.off()
time.sleep(1)
break
#wdt.feed()
#print("woof!...good boy!")
# Handle connection error
if wlan.status() != 3:
print("Connection status attempt: ", attempt)
max_wait -= 1
attempt += 1
print()
print("Network connection attempt failed!")
print()
#raise RuntimeError('network connection attempt failed')
time.sleep(5)
#machine.reset()
while max_wait == 0:
print()
print("cannot connect to the wifi!")
print("rebooting...")
led.on()
time.sleep(10)
machine.reset()
else:
time.sleep(1)
print("Pico W Wi-Fi is connected to: ",SSID)
status = wlan.ifconfig()
print( "ip address for this Pico W: " + status[0] )
print()
print("Channel: ", wlan.config('channel'))
print("SSID: ", wlan.config('essid'))
print("TXPOWER: ", wlan.config('txpower'))
stringstatus = str(status[0])
if stringstatus == IP:
print()
print("IP is good for MQTT connection! -> ", stringstatus)
print("Moving on to next stage")
else:
print()
print("IP is bad for MQTT connection! Rebooting...")
time.sleep(10)
machine.reset()
#wdt.feed()
#print("woof!...good boy!")
print()
print("Flashing LEDs for success display")
print()
#wdt.feed()
#print("woof!...good boy!")
#Show some onboard LED flashing to show that attempting to connect to the Wi-Fi has been completed
time.sleep(2)
led.off()
time.sleep(2)
led.toggle()
print("3")
time.sleep(0.2)
led.toggle()
time.sleep(1)
#wdt.feed()
#print("woof!...good boy!")
led.toggle()
print("2")
time.sleep(0.2)
led.toggle()
time.sleep(1)
#wdt.feed()
#print("woof!...good boy!")
led.toggle()
print("1")
time.sleep(0.2)
led.toggle()
time.sleep(1)
led.toggle()
print("blast off!")
print()
#wdt.feed()
#print("woof!...good boy!")
time.sleep(2)
#Setup MQTT server, local client ID (not really required),
#and published data transmissions hierarchy
mqtt_server = MQTTSERVE
client_id = b'PICOW'
#topic_pub1 = b'PicoW/OS_Temp'
#topic_pub2 = b'PicoW/OS_Hum'
#topic_pub3 = b'PicoW/Pico_Temp'
topic_pub1 = b'PicoW/OS_Temp'
topic_pub2 = b'PicoW/OS_Hum'
topic_pub3 = b'PicoW/Pico_Temp'
#For the above topics, use "PicoW/+"
#at the subscriber side to receive all
#three messages at once or use the full
#titles individually i.e PicoW/OS_Temp for
#just the outside temperature variable
def mqtt_connect():
attempt2 = 5
while attempt2 > 0:
try:
client = MQTTClient(client_id, mqtt_server, keepalive=3600)
client.connect()
print('Connected to %s MQTT Broker'%(mqtt_server))
return client
except:
client.disconnect()
print('Failed to connect to the MQTT Broker. Giving it some time!')
print(attempt2)
attempt2 -= 1
time.sleep(5)
#client.connect()
#break
while attempt2 == 0:
reconnect()
def reconnect():
print('Failed to connect to the MQTT Broker. Rebooting...')
time.sleep(5)
machine.reset()
print("Attempting to connect to MQTT Broker...")
print()
#wdt.feed()
#print("woof!...good boy!")
try:
client = mqtt_connect()
except OSError as mqtterror:
print(mqtterror)
message2 = 'MQTT Error: '
mqtterror2 = str(mqtterror)
appendfile(message2, mqtterror2)
reconnect()
#wdt.feed()
#print("woof!...good boy!")
#The main script of repeativeness for reading in from the connected sensor
#and taking in onboard temperature readings
while True: #do stuff here
led.on()
time.sleep(0.5)
#Collect readings from the SHT-30
readsensor()
#wdt.feed()
#print("woof!...good boy!")
#Collect temperature reading for the Pico W CPU
def cpumeasure():
global picotemp
try:
reading = sensor_temp.read_u16() * conversion_factor
picotemp = 27 - (reading - 0.706)/0.001721
except OSError as cpu:
print("something went wrong reading the onboard CPU Temperature!")
print(cpu)
print("rebooting...")
message3 = 'CPU Temp Error: '
cpu2 = str(cpu)
appendfile(message3, cpu2)
time.sleep(5)
machine.reset()
cpumeasure()
#make readings 1 decimal place
tpm1 = round(temperature,1)
tpm2 = round(humidity,1)
tpm3 = round(picotemp,1)
#convert float reading values into bytes ready for MQTT transmission
tpm4 = f"{tpm1}".encode()
tpm5 = f"{tpm2}".encode()
tpm6 = f"{tpm3}".encode()
topic_msg1 = tpm4
topic_msg2 = tpm5
topic_msg3 = tpm6
#Message displayed to the screen
print()
print("Publishing...")
print()
print('SHT Temperature: {:3.1f}ºC'.format(tpm1))
print('SHT Humidity: {:3.1f}%'.format(tpm2))
print('Pico W Temperature: {:3.1f}ºC'.format(tpm3))
print()
#Equivalent transmission of displayed readings above
#(reverse order to match above order on subscriber receipt)
try:
client.publish(topic_pub3, topic_msg3)
client.publish(topic_pub2, topic_msg2)
client.publish(topic_pub1, topic_msg1)
print("Publishing complete")
except:
print("Disconnected from MQTT Broker! Attempting Reconnection...")
print()
try:
client = mqtt_connect()
except OSError as mqtterror:
print(mqtterror)
message4 = 'MQTT2 Error: '
mqtterror3 = str(mqtterror)
appendfile(message4, mqtterror3)
reconnect()
led.off()
#wdt.feed()
#print("woof!...good boy!")
time.sleep(5)
#wdt.feed()
#print("woof!...good boy!")
time.sleep(5)
You'll notice i'm still resisting using the watchdog.
Code: Select all
#Necessary library imports for this code to function
from secrets import SSID
from secrets import PASSWORD
from secrets import IP
from secrets import IP_mask
from secrets import IP_gateway
from secrets import IP_DNS
from secrets import MQTTSERVE
from umqtt.simple import MQTTClient
import time
import network
import ubinascii
import socket
from machine import I2C, Pin, #wdt
import sht30
from sht30 import SHT30
from sht30 import SHT30Error
led = machine.Pin("LED", machine.Pin.OUT)
#initialise LED to OFF
led.off()
# def appendfile(message, error):
# file=open("errorlog.txt","a")
# errorstring=str(error)
# file.write(message)
# file.write(errorstring)
# file.write("\n")
# file.close()
#file.flush()
def appendfile(message, error):
with open('errorlog.txt', 'a') as file:
file.write(message)
errorstring=str(error)
file.write(errorstring)
file.write('\n')
file.close()
def sht_error(ex):
print("something went wrong reading the SHT-30!")
print('Error:', ex)
message = 'SHT Error: '
appendfile(message, ex) #message, error
#Define the interface of the SHT30 Temp/Humidity sensor with the Pico W
i2c=I2C(0, sda=Pin(4), scl=Pin(5), freq=5000)
sht=sht30.SHT30(i2c=i2c, i2c_address=68)
def readsensor():
global temperature
global humidity
try:
sensor = sht.measure()
except SHT30Error as ex:
#print(ex)
sht_error(ex)
try:
print("resetting SHT30")
restartsensor = SHT30(i2c)
time.sleep(1)
restartsensor.reset()
appendfile("SHT30 reset", "command")
time.sleep(2)
print("SHT30 reset")
sensor = sht.measure()
except:# SHT30Error as ex:
#sht_error(ex)
print("cannot read from SHT30, rebooting Pico W")
appendfile("cannot read from SHT30, rebooting Pico W", "command")
time.sleep(10)
machine.reset()
temperature, humidity = sensor
#wdt = wdt(timeout= 8000)
readsensor()
#wdt.feed()
#print("woof!...good boy!")
print('SHT Temperature: {:3.1f}ºC'.format(temperature))
print('SHT Humidity: {:3.1f}%'.format(humidity))
#Define the onboard Pico Temperature sensor and necessary conversion factor
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)
#Configure this Pico W for a static IP address on router using the following
UseStaticIP = True
IP = IP
IP_mask = IP_mask
IP_gateway = IP_gateway
IP_DNS = IP_DNS
#Active the onboard Pico W Wi-Fi and connect to home network defined through "secrets.py"
wlan = network.WLAN(network.STA_IF)
#Read the MAC address from the Pico W itself
mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
print()
print("MAC address for this Pico W:", mac)
print()
#Configure a high power wi-fi connection
wlan.config(pm = 0xa11140)
wlan.active(True)
print("Scanning Available Wifi Connections...")
time.sleep(5)
#wdt.feed()
#print("woof!...good boy!")
print(wlan.scan())
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
led.on()
#wdt.feed()
#print("woof!...good boy!")
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
try:
wlan.connect(SSID, PASSWORD)
except:
try:
print("first attempt to connect to router failed!")
print("cycling wifi for retry")
wlan.active(False)
led.toggle()
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
led.toggle()
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
wlan.active(True)
time.sleep(2)
print(wlan.scan())
time.sleep(2)
#wdt.feed()
#print("woof!...good boy!")
wlan.connect(SSID, PASSWORD)
except:
print("wifi connecting failed. Rebooting...")
appendfile("wifi connecting failed. Rebooting...", "command")
time.sleep(10)
machine.reset()
#wdt.feed()
#print("woof!...good boy!")
led.off()
# Wait for connect or fail (3mins)
max_wait = 90
attempt = 1
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
#print(wlan.status)
#break
led.on()
max_wait -= 1
#print(wlan.status)
print()
print("Connection status attempt: ", attempt)
print()
print('connection is good...continuing')
print()
attempt += 1
time.sleep(1)
led.off()
time.sleep(1)
break
#wdt.feed()
#print("woof!...good boy!")
# Handle connection error
if wlan.status() != 3:
print("Connection status attempt: ", attempt)
max_wait -= 1
attempt += 1
print()
print("Network connection attempt failed!")
print()
#raise RuntimeError('network connection attempt failed')
time.sleep(5)
#machine.reset()
while max_wait == 0:
print()
print("cannot connect to the wifi!")
print("rebooting...")
led.on()
appendfile("cannot connect to the wifi!", "reboot command")
time.sleep(10)
machine.reset()
else:
time.sleep(1)
print("Pico W Wi-Fi is connected to: ",SSID)
status = wlan.ifconfig()
print( "ip address for this Pico W: " + status[0] )
print()
print("Channel: ", wlan.config('channel'))
print("SSID: ", wlan.config('essid'))
print("TXPOWER: ", wlan.config('txpower'))
stringstatus = str(status[0])
if stringstatus == IP:
print()
print("IP is good for MQTT connection! -> ", stringstatus)
print("Moving on to next stage")
else:
print()
print("IP is bad for MQTT connection! Rebooting...")
appendfile("IP is bad for MQTT connection! Rebooting...", "command")
time.sleep(10)
machine.reset()
#wdt.feed()
#print("woof!...good boy!")
print()
print("Flashing LEDs for success display")
print()
#wdt.feed()
#print("woof!...good boy!")
#Show some onboard LED flashing to show that attempting to connect to the Wi-Fi has been completed
time.sleep(2)
led.off()
time.sleep(2)
led.toggle()
print("3")
time.sleep(0.2)
led.toggle()
time.sleep(1)
#wdt.feed()
#print("woof!...good boy!")
led.toggle()
print("2")
time.sleep(0.2)
led.toggle()
time.sleep(1)
#wdt.feed()
#print("woof!...good boy!")
led.toggle()
print("1")
time.sleep(0.2)
led.toggle()
time.sleep(1)
led.toggle()
print("blast off!")
print()
#wdt.feed()
#print("woof!...good boy!")
time.sleep(2)
#Setup MQTT server, local client ID (not really required),
#and published data transmissions hierarchy
mqtt_server = MQTTSERVE
client_id = b'PICOW'
#topic_pub1 = b'PicoW/OS_Temp'
#topic_pub2 = b'PicoW/OS_Hum'
#topic_pub3 = b'PicoW/Pico_Temp'
topic_pub1 = b'PicoW/OS_Temp'
topic_pub2 = b'PicoW/OS_Hum'
topic_pub3 = b'PicoW/Pico_Temp'
#For the above topics, use "PicoW/+"
#at the subscriber side to receive all
#three messages at once or use the full
#titles individually i.e PicoW/OS_Temp for
#just the outside temperature variable
def mqtt_connect():
attempt2 = 5
while attempt2 > 0:
try:
client = MQTTClient(client_id, mqtt_server, keepalive=3600)
client.connect()
print('Connected to %s MQTT Broker'%(mqtt_server))
return client
except:
client.disconnect()
print('Failed to connect to the MQTT Broker. Giving it some time!')
appendfile('Failed to connect to the MQTT Broker. Giving it some time!', "command")
print(attempt2)
attempt2 -= 1
time.sleep(5)
#client.connect()
#break
while attempt2 == 0:
reconnect()
def reconnect():
print('Failed to connect to the MQTT Broker. Rebooting...')
appendfile('Failed to connect to the MQTT Broker. Rebooting...',"command")
time.sleep(5)
machine.reset()
print("Attempting to connect to MQTT Broker...")
print()
#wdt.feed()
#print("woof!...good boy!")
try:
client = mqtt_connect()
except OSError as mqtterror:
print(mqtterror)
message2 = 'MQTT Error 2: '
mqtterror2 = str(mqtterror)
appendfile(message2, mqtterror2)
reconnect()
#wdt.feed()
#print("woof!...good boy!")
#The main script of repeativeness for reading in from the connected sensor
#and taking in onboard temperature readings
while True: #do stuff here
led.on()
time.sleep(0.5)
#Collect readings from the SHT-30
readsensor()
#wdt.feed()
#print("woof!...good boy!")
#Collect temperature reading for the Pico W CPU
def cpumeasure():
global picotemp
try:
reading = sensor_temp.read_u16() * conversion_factor
picotemp = 27 - (reading - 0.706)/0.001721
except OSError as cpu:
print("something went wrong reading the onboard CPU Temperature!")
print(cpu)
print("rebooting...")
message3 = 'CPU Temp Error: '
cpu2 = str(cpu)
appendfile(message3, cpu2)
time.sleep(5)
machine.reset()
cpumeasure()
#make readings 1 decimal place
tpm1 = round(temperature,1)
tpm2 = round(humidity,1)
tpm3 = round(picotemp,1)
#convert float reading values into bytes ready for MQTT transmission
tpm4 = f"{tpm1}".encode()
tpm5 = f"{tpm2}".encode()
tpm6 = f"{tpm3}".encode()
topic_msg1 = tpm4
topic_msg2 = tpm5
topic_msg3 = tpm6
#Message displayed to the screen
print()
print("Publishing...")
print()
print('SHT Temperature: {:3.1f}ºC'.format(tpm1))
print('SHT Humidity: {:3.1f}%'.format(tpm2))
print('Pico W Temperature: {:3.1f}ºC'.format(tpm3))
print()
#Equivalent transmission of displayed readings above
#(reverse order to match above order on subscriber receipt)
try:
client.publish(topic_pub3, topic_msg3)
client.publish(topic_pub2, topic_msg2)
client.publish(topic_pub1, topic_msg1)
print("Publishing complete")
except:
print("Disconnected from MQTT Broker! Attempting Reconnection...")
print()
try:
client = mqtt_connect()
except OSError as mqtterror:
print(mqtterror)
message4 = 'MQTT2 Error 4: '
mqtterror3 = str(mqtterror)
appendfile(message4, mqtterror3)
reconnect()
led.off()
#wdt.feed()
#print("woof!...good boy!")
time.sleep(5)
#wdt.feed()
#print("woof!...good boy!")
time.sleep(5)