import time
import uasyncio as asyncio
from machine import Pin, I2C
import ssd1306
from hx711 import HX711
# ================= OLED =================
i2c = I2C(0, scl=Pin(1), sda=Pin(0))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# ================= HX711 =================
hx = HX711(dt=4, sck=5)
# wait to stabilize first before tare
time.sleep(3) # MANDATORY
hx.tare()
# ================= HC-SR04 =================
trig = Pin(2, Pin.OUT)
echo = Pin(3, Pin.IN)
def read_height():
trig.low()
time.sleep_us(2)
trig.high()
time.sleep_us(10)
trig.low()
timeout = time.ticks_us() + 30000
start = 0
end = 0
while echo.value() == 0:
start = time.ticks_us()
if time.ticks_us() > timeout:
return 0
while echo.value() == 1:
end = time.ticks_us()
if time.ticks_us() > timeout:
return 0
duration = time.ticks_diff(end, start)
distance = (duration * 0.0343) / 2
if distance <= 0 or distance > 400:
return 0
return round(distance / 100, 2)
# ================= BMI =================
def bmi(weight, height):
if height <= 0:
return 0
return round(weight / (height * height), 2)
def nutrition_status(bmi_value):
if bmi_value < 18.5:
return "UNDERWEIGHT"
elif bmi_value < 25:
return "NORMAL"
elif bmi_value < 30:
return "OVERWEIGHT"
return "OBESE"
# ================= DATA =================
data = {}
# ================= SENSOR =================
async def sensor_task():
global data
while True:
weight = hx.get_weight(scale=300) # 🔥 MAIN FIX
height = read_height()
data["weight"] = weight
data["height"] = height
print("Weight:", weight, "Height:", height)
await asyncio.sleep(2)
# ================= PROCESS =================
async def process_task():
global data
while True:
weight = data.get("weight", 0)
height = data.get("height", 0)
data["bmi"] = bmi(weight, height)
data["status"] = nutrition_status(data["bmi"])
await asyncio.sleep(1)
# ================= OLED =================
def oled_show():
oled.fill(0)
oled.text("BMI SYSTEM", 20, 0)
oled.text("W:{}kg".format(data.get("weight", 0)), 0, 15)
oled.text("H:{}m".format(data.get("height", 0)), 0, 25)
oled.text("BMI:{}".format(data.get("bmi", 0)), 0, 40)
oled.text(data.get("status", ""), 0, 55)
oled.show()
async def oled_task():
while True:
oled_show()
await asyncio.sleep(1)
# ================= CLOUD =================
async def cloud_task():
while True:
print("UPLOAD:", data)
await asyncio.sleep(5)
# ================= MAIN =================
async def main():
await asyncio.gather(
sensor_task(),
process_task(),
oled_task(),
cloud_task()
)
asyncio.run(main())