Toggle Navigation
Hatchery
Eggs
sensible_card10
__init__.py
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
__init__.py
raw
Content
from bluetooth import BLE import bme680 import display import leds import power from struct import pack import time DEVICE_NAME = b"card10" # 9 characters max. INTERVAL = 3 # Don't set this below 3. LED_FLASH_DURATION = 20 BATTERY_WARN = 20 # At what percentage to start warning about battery power. def adv_element(typ: int, content: bytes) -> bytes: size = len(content) + 1 return pack("<BB", size, typ) + content def adv_service_data(uuid: int, content: bytes) -> bytes: return adv_element(0x16, pack("<H", uuid) + content) def sensor_data(reading, bat_p): bsec = isinstance(reading, bme680.BSECData) print(reading) return pack("<HhHLBHHB", 0xccc1, round(reading.temperature * 100), # temperature (centidegrees C) round(reading.humidity * 100), # rel. humidity (centi-percent) round(reading.pressure * 1000), # pressure (deci-Pascal) reading.iaq_accuracy if bsec else 0xff, # enum reading.iaq if bsec else 0, # rating 0 (best) to 500 (worst) round(reading.eco2) if bsec else 0, # ppm bat_p, # battery percentage ) def adv_data(reading, bat_p): data = \ adv_service_data(0x181a, sensor_data(reading, bat_p)) + \ adv_element(0x09, DEVICE_NAME) if len(data) > 31: raise ValueError("adv_data is {} bytes long, maximum is 31".format(len(data))) return data def loop(): ble = BLE() ble.active(True) with display.open() as disp: disp.backlight(0) with bme680.Bme680() as bme: while True: # Get battery percentage (4.2V LiPo design maximum to 3.4V cutoff). bat_p = round(max(0, min(100, (power.read_battery_voltage() - 3.4) / 0.8 * 100))) # Light the blue rocket for as long as the sensor reading takes, # but at least for LED_FLASH_DURATION ms. end = time.ticks_ms() + LED_FLASH_DURATION leds.set_rocket(0, 1) reading = bme.get_data() time.sleep_ms(min(LED_FLASH_DURATION, end - time.ticks_ms())) leds.set_rocket(0, 0) # Enable (or update) the BLE advertisement we send. ble.gap_advertise( INTERVAL * 1_000_000 + 500_000, adv_data(reading, bat_p), connectable=False, ) time.sleep(1) if bat_p <= BATTERY_WARN: red_count = min(11, round(11 / 20 * bat_p)) leds.set_all( [(15,0,0)]*(11-red_count) + \ [(255,0,0)]*red_count + \ [(31,0,0)]*4) time.sleep(1) leds.set_all( [(15 if bat_p <= BATTERY_WARN else 0,0,0)]*11 + \ [(31 if bat_p <= BATTERY_WARN else 0,0,0)]*4) time.sleep(INTERVAL - 2) if __name__ == "__main__": loop()