def draw(self, x, y): yt = y + self.tyo # draw tag self.tag_font.text(self.tag, x + self.txo, yt, self.tag_color) # draw unit, if provided if self.unit is not None: self.tag_font.text(self.unit, x + self.uxo, yt, self.unit_color) # draw number txt = self.fmt % self.value if self.font is None: # no font -> draw seven degment digits using lines seg7.draw_number(Screen.fb, txt, x + self.sxo, y + self.syo, self.sw, self.sh, self.color, 3) else: self.font.text(txt, x + self.nxo, y + self.nyo, self.color)
async def next_mode(pin): global mode # new mode assuming long press (mode_max+1 reverts to 0 after first display) m = mode_max + 1 if mode > 0 else 1 # check for long press for i in range(10): await asyncio.sleep_ms(100) if pin.value(): # user let go of button -> short press if mode: m = mode % mode_max + 1 # cycle among test modes else: m = 0 # stay in normal run mode break mode = m # if display: display.fill(1) seg7.draw_number(display, str(mode % (mode_max + 1)), 50, 10, 24, 48, 0, 3) display.show() # log.info("MODE = %d", mode)
async def query_sensors(client, topic, interval): global bme680, si7021, sht31, pmsx003, anemo, vane, rain global cwop, display global pm_cnt, pm_sum global mode t0 = time.ticks_ms() while True: data = {} gas, pm25 = None, None # convert the bme680 if bme680: await asyncio.sleep_ms(bme680.convert()) while not bme680.ready(): await asyncio.sleep_ms(10) (t, h, p, gas) = bme680.read_data() tF = t * 1.8 + 32 log.info("BME680 : T=%.1f°F H=%.0f%% P=%.3fmBar G=%.3fkΩ", tF, h, p, gas / 1000) (data["t_bme680"], data["h_bme680"]) = (t, h) (data["p_bme680"], data["g_bme680"]) = (p / 1000, gas) # read the si7021 if si7021: await asyncio.sleep_ms(si7021.convert() + 2) (t, h) = si7021.read_temp_humi() log.info("Si7021 : T=%.1f°F H=%.0f%%", t * 1.8 + 32, h) (data["t_si7021"], data["h_si7021"]) = (t, h) # read sht31 if sht31: await asyncio.sleep_ms(sht31.convert() + 2) (t, h) = sht31.read_temp_humi() log.info("SHT31 : T=%.1f°F H=%.0f%%", t * 1.8 + 32, h) (data["t_sht31"], data["h_sht31"]) = (t, h) # read wind if anemo: (w, g) = anemo.read() logstr = "Wind : %.0fmph gust:%.0fmph" logvars = [w, g] (data["wind"], data["gust"]) = (w*0.44704, g*0.44704) # in m/s if vane: d = vane.read() logstr += " dir=%0f°" logvars.append(d) data["wdir"] = d log.info(logstr, *logvars) # read rain gauge # TODO! # insert averaged dust data if pm_cnt > 0: d = [v / pm_cnt for v in pm_sum] pm25 = d[0] data["pm25"] = pm25 log.info("PMSx003: D=%.1fµg/m³ X=%.1f", d[0], d[1]) pm_sum = [0 for _ in pm_sum] pm_cnt = 0 # AQI conversions if gas is not None: data["aqi_tvoc"] = aqi.tvoc_bme680(gas) if pm25 is not None: data["aqi_pm25"] = aqi.pm25(pm25) if display: display.fill(0) if mode == 1: # Test mode for wind vane wdir = data.get("wdir", -1) display.text("Wind dir: %d" % wdir, 0, 0) wdir_str = "%3do" % wdir seg7.draw_number(display, wdir_str, 10, 14, 18, 48, 1, 3) elif mode == 2: # Test mode for wind speed wspd = data.get("wind", -1) * 2.237 display.text("Wind: %.1f mph" % wspd, 0, 0) wspd_str = "%4.1f" % (wspd/2.5) seg7.draw_number(display, wspd_str, 10, 14, 18, 48, 1, 3) # else mode == 3: # regular function is rapid update test mode, "falls thru" into else # else mode == 4: # regular function 1 quick update then switch to mode 0, "falls thru" else: # Regular operating mode, display lots of data and send it too # publish data if mode == 0 and any(d is not None for d in data): log.debug("pub: %s", data) await client.publish(topic, json.dumps(data), qos=1, sync=False) # display data display.text( "BME {:.1f}F {:.0f}%".format(data["t_bme680"] * 1.8 + 32, data["h_bme680"]), 0, 0, ) display.text( " {:.0f}mB {:.0f}kO".format( data["p_bme680"] * 1000, data["g_bme680"] / 1000 ), 0, 9, ) display.text( "SHT {:.1f}F {:.0f}%".format(data["t_sht31"] * 1.8 + 32, data["h_sht31"]), 0, 18, ) display.text( "Si {:.1f}F {:.0f}%".format(data["t_si7021"] * 1.8 + 32, data["h_si7021"]), 0, 27, ) display.text("PM {:.1f} Rn {:.2f}".format(data.get("pm25", -1), 0), 0, 36) display.text( "Wnd {:.0f} {:3d}*".format(data.get("wind", -1), data.get("wdir", -1)), 0, 45 ) display.text("Free {:d} {:d}".format(gc.mem_free(), gc.mem_maxfree()), 0, 54) if mode_led: await mode_blink() display.show() if mode == 0 and cwop: asyncio.get_event_loop().create_task( cwop( temp=data.get("t_bme680", None), hum=data.get("h_bme680", None), baro=data.get("p_bme680", None), winddir=data.get("wdir", None), windspeed=data.get("wind", None), windgust=data.get("gust", None), ) ) # sleep iv = interval while True: t1 = time.ticks_ms() dt = time.ticks_diff(t1, t0) if dt >= iv or mode and dt > mode_period[mode]: break await asyncio.sleep_ms(min(iv - dt, 500)) if dt >= iv and dt < iv * 3 / 2: t0 = time.ticks_add(t0, iv) else: t0 = time.ticks_ms() if mode > mode_max: # hack to get mode 0 to display immediately when switching to it mode = 0
# show splash screen on display import machine, time from ssd1306 import SSD1306_I2C import seg7 scl1, sda1 = 18, 4 # oled scl1_pin = machine.Pin(scl1) sda1_pin = machine.Pin(sda1) display = SSD1306_I2C(128, 64, machine.I2C(scl=scl1_pin, sda=sda1_pin, freq=1000000)) display.fill(1) display.fill_rect(10, 10, 108, 44, 0) display.text("7-SEG test", 20, 20, 1) display.show() time.sleep_ms(1000) while True: for i in range(256): i_str = "%x:%04.1fo" % (i & 0xF, i / 10) display.fill(0) #seg7.draw_number(display, i_str, 1, 10, 16, 48, 1, i % 3 + 1) seg7.draw_number(display, i_str, 1, 10, 12, 32, 1, i % 3 + 1) display.show() time.sleep_ms(500)