Closed ChaiFox closed 1 year ago
Moved this to the Enviro repo for you! Please can you post your code, what version of the firmware you're running and the contents of your log.txt
after the crash happens?
Thanks for moving this to the right place. Other than the changes to convert to Imperial in OrderedDict and the few lines in Startup for the bme configure its the stock weather.py. Version is enviro-1.19.7 v0.0.7. As far as the log.txt is concerned its only two lines neither of which is an error so I don't think its crashing per se but rather failing to start correctly with no other info being given.
import time, math
from breakout_bme280 import BreakoutBME280
from breakout_ltr559 import BreakoutLTR559
from machine import Pin, PWM
from pimoroni import Analog
from enviro import i2c, hold_vsys_en_pin
import enviro.helpers as helpers
from phew import logging
RAIN_MM_PER_TICK = 0.2794
bme280 = BreakoutBME280(i2c, 0x77)
ltr559 = BreakoutLTR559(i2c)
wind_direction_pin = Analog(26)
wind_speed_pin = Pin(9, Pin.IN, Pin.PULL_UP)
def startup():
import wakeup
#adjust sensor values to match oem recommended for weather stations and hopefully help with heating
#https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf
# defaults here
#https://github.com/pimoroni/pimoroni-pico/tree/main/micropython/modules/breakout_bme280
bme280.configure(FILTER_COEFF_OFF, STANDBY_TIME_0_5_MS, OVERSAMPLING_1X, OVERSAMPLING_1X, OVERSAMPLING_1X, FORCED_MODE)
#bme280.configure(FILTER_COEFF_2, STANDBY_TIME_0_5_MS, OVERSAMPLING_16X, OVERSAMPLING_2X, OVERSAMPLING_1X)
# check if rain sensor triggered wake
rain_sensor_trigger = wakeup.get_gpio_state() & (1 << 10)
if rain_sensor_trigger:
# read the current rain entries
rain_entries = []
if helpers.file_exists("rain.txt"):
with open("rain.txt", "r") as rainfile:
rain_entries = rainfile.read().split("\n")
# add new entry
logging.info("> add new rain trigger at {helpers.datetime_string()}")
rain_entries.append(helpers.datetime_string())
# limit number of entries to 190 - each entry is 21 bytes including
# newline so this keeps the total rain.txt filesize just under one
# filesystem block (4096 bytes)
rain_entries = rain_entries[-190:]
# write out adjusted rain log
with open("rain.txt", "w") as rainfile:
rainfile.write("\n".join(rain_entries))
# go immediately back to sleep, we'll wake up at next scheduled reading
hold_vsys_en_pin.init(Pin.IN)
def wind_speed(sample_time_ms=1000):
# get initial sensor state
state = wind_speed_pin.value()
# create an array for each sensor to log the times when the sensor state changed
# then we can use those values to calculate an average tick time for each sensor
ticks = []
start = time.ticks_ms()
while time.ticks_ms() - start <= sample_time_ms:
now = wind_speed_pin.value()
if now != state: # sensor output changed
# record the time of the change and update the state
ticks.append(time.ticks_ms())
state = now
# if no sensor connected then we have no readings, skip
if len(ticks) < 2:
return 0
# calculate the average tick between transitions in ms
average_tick_ms = (ticks[-1] - ticks[0]) / (len(ticks) - 1)
# work out rotation speed in hz (two ticks per rotation)
rotation_hz = (1000 / average_tick_ms) / 2
# calculate the wind speed in metres per second
radius = 7.0
circumference = radius * 2.0 * math.pi
factor = 0.0218 # scaling factor for wind speed in m/s
wind_m_s = rotation_hz * circumference * factor
return wind_m_s
def wind_direction():
# adc reading voltage to cardinal direction taken from our python
# library - each array index represents a 45 degree step around
# the compass (index 0 == 0, 1 == 45, 2 == 90, etc.)
# we find the closest matching value in the array and use the index
# to determine the heading
ADC_TO_DEGREES = (0.9, 2.0, 3.0, 2.8, 2.5, 1.5, 0.3, 0.6)
closest_index = -1
last_index = None
# ensure we have two readings that match in a row as otherwise if
# you read during transition between two values it can glitch
# fixes https://github.com/pimoroni/enviro/issues/20
while True:
value = wind_direction_pin.read_voltage()
closest_index = -1
closest_value = float('inf')
for i in range(8):
distance = abs(ADC_TO_DEGREES[i] - value)
if distance < closest_value:
closest_value = distance
closest_index = i
if last_index == closest_index:
break
last_index = closest_index
return closest_index * 45
def timestamp(dt):
year = int(dt[0:4])
month = int(dt[5:7])
day = int(dt[8:10])
hour = int(dt[11:13])
minute = int(dt[14:16])
second = int(dt[17:19])
return time.mktime((year, month, day, hour, minute, second, 0, 0))
def rainfall():
if not helpers.file_exists("rain.txt"):
return 0
now = timestamp(helpers.datetime_string())
with open("rain.txt", "r") as rainfile:
rain_entries = rainfile.read().split("\n")
# count how many rain ticks in past hour
amount = 0
for entry in rain_entries:
if entry:
ts = timestamp(entry)
if now - ts < 60 * 60:
amount += RAIN_MM_PER_TICK
return amount
def get_sensor_readings():
# bme280 returns the register contents immediately and then starts a new reading
# we want the current reading so do a dummy read to discard register contents first
bme280.read()
time.sleep(0.1)
bme280_data = bme280.read()
ltr_data = ltr559.get_reading()
from ucollections import OrderedDict
return OrderedDict({
#convert from celcius to fahrenheit
"temperature": round(((bme280_data[0]*1.8)+32), 2),
"humidity": round(bme280_data[2], 2),
"pressure": round(bme280_data[1] / 100.0, 2),
"light": round(ltr_data[BreakoutLTR559.LUX], 2),
#convert from m/s to mph
"wind_speed": round(wind_speed()*2.236936,1),
"rain": rainfall(),
"wind_direction": wind_direction()
})
Log.txt
2022-12-01 15:48:48 [debug / 115kB] > performing startup
2022-12-01 15:49:40 [debug / 115kB] > performing startup
I should also mention the same issue happens when using the default args with configure() as well.
Recommend updating to the newest firmware, the logging is a lot better!
I'm getting
2022-12-01 16:36:46 [exception / 114kB] ! Traceback (most recent call last):
File "<stdin>", line 32, in <module>
File "enviro/__init__.py", line 409, in startup
File "enviro/boards/weather.py", line 32, in startup
NameError: name 'FILTER_COEFF_OFF' isn't defined
I think you might just need to import all those constants at the beginning of weather.py
?
from breakout_bme280 import BreakoutBME280, FILTER_COEFF_OFF, STANDBY_TIME_0_5_MS, OVERSAMPLING_1X, OVERSAMPLING_1X, OVERSAMPLING_1X, FORCED_MODE
Well with updating to the new firmware and adding the imports it still doesn't actually behave correctly. Now the led is just solid and its indicating its getting hung at connecting to wifi which I find doubtful as it connects fine with the line commented out and the device is unresponsive to the poke button.
new log.txt
2022-12-01 18:37:36 [debug / 115kB] > performing startup
2022-12-01 18:37:36 [info / 119kB] - wake reason: usb_powered
2022-12-01 18:37:36 [debug / 117kB] - turn on activity led
2022-12-01 18:37:36 [debug / 115kB] > 104 blocks free out of 212
2022-12-01 18:37:36 [debug / 113kB] > taking new reading
2022-12-01 18:37:36 [info / 108kB] - seconds since last reading: 24
2022-12-01 18:37:38 [debug / 99kB] > caching reading for upload
2022-12-01 18:37:38 [info / 95kB] > 1 cache file(s) need uploading
2022-12-01 18:37:38 [info / 120kB] > connecting to wifi network 'FOO'
Ah, sorry that didn't help. Mine seems to be running fine with the addition of your bme.configure
line though?
If you run main.py
through Thonny does it provide any useful errors?
After checking it today its running just fine so I really have no idea what was going on. Looks like the original problem though was just missing those explicit imports so I'll mark this closed and hope it behaves itself
Whenever I add the configure method from breakout_bme280 to my enviro weather but when ever I include it it fails to actually read anything and no longer responds to pokes. On reboot it will show the white flag as normal then no response from it at all and nothing gets written to mqtt as its set up to do. Unfortunately when it reboots thonny has to be reconnected so if its throwing an error I can't actually see it.