from machine import Pin, ADC
from time import sleep
# ==========================================================
# LCD1602 DRIVER (4-BIT MODE)
# ==========================================================
class LCD:
def __init__(self, rs, e, d4, d5, d6, d7):
self.rs = Pin(rs, Pin.OUT)
self.e = Pin(e, Pin.OUT)
self.d4 = Pin(d4, Pin.OUT)
self.d5 = Pin(d5, Pin.OUT)
self.d6 = Pin(d6, Pin.OUT)
self.d7 = Pin(d7, Pin.OUT)
sleep(0.05)
self._cmd(0x33)
self._cmd(0x32)
self._cmd(0x28)
self._cmd(0x0C)
self._cmd(0x06)
self._cmd(0x01)
sleep(0.005)
def _pulse(self):
self.e.value(1)
sleep(0.00001)
self.e.value(0)
sleep(0.0001)
def _write4(self, value):
self.d4.value((value >> 0) & 1)
self.d5.value((value >> 1) & 1)
self.d6.value((value >> 2) & 1)
self.d7.value((value >> 3) & 1)
self._pulse()
def _cmd(self, cmd):
self.rs.value(0)
self._write4(cmd >> 4)
self._write4(cmd & 0x0F)
def _data(self, data):
self.rs.value(1)
self._write4(data >> 4)
self._write4(data & 0x0F)
def clear(self):
self._cmd(0x01)
sleep(0.002)
def move(self, col, row):
addr = col + (0x40 if row else 0)
self._cmd(0x80 | addr)
def write(self, text):
for ch in text:
self._data(ord(ch))
# ==========================================================
# LCD CONNECTIONS
# ==========================================================
lcd = LCD(
rs=12,
e=11,
d4=5,
d5=4,
d6=3,
d7=2
)
# ==========================================================
# INPUTS
# ==========================================================
pot_temp = ADC(26)
pot_hr = ADC(27)
pot_bp = ADC(28)
# ==========================================================
# OUTPUTS
# ==========================================================
green_led = Pin(15, Pin.OUT)
red_led = Pin(14, Pin.OUT)
buzzer = Pin(13, Pin.OUT)
# ==========================================================
# SENSOR CONVERSIONS
# ==========================================================
def get_temperature(raw):
return 30.0 + (raw * 12.0 / 65535.0)
def get_heart_rate(raw):
return 40 + int(raw * 140 / 65535)
def get_blood_pressure(raw):
systolic = 60 + int(raw * 140 / 65535)
diastolic = int(systolic * 0.67)
if diastolic < 40:
diastolic = 40
if diastolic > 120:
diastolic = 120
return systolic, diastolic
# ==========================================================
# DIAGNOSIS
# ==========================================================
def get_diagnosis(temp, hr, sys, dia):
# Temperature
if temp >= 39.5:
return "CRIT FEVER", "SEEK HELP"
if temp >= 38.0:
return "HIGH FEVER", "REST/MEDS"
if temp <= 34:
return "HYPOTHERMIA", "EMERGENCY"
if temp <= 35.5:
return "LOW TEMP", "WARM BODY"
# Heart Rate
if hr > 120:
return "HIGH HEART", "EMERGENCY"
if hr > 100:
return "TACHYCARDIA", "SEE DOCTOR"
if hr < 50:
return "LOW HEART", "EMERGENCY"
if hr < 60:
return "BRADYCARDIA", "CHECK HEART"
# Blood Pressure
if sys >= 180 or dia >= 120:
return "BP CRISIS", "SEEK HELP"
if sys >= 160:
return "HIGH BP", "SEE DOCTOR"
if sys >= 140:
return "BP STAGE 1", "LIFESTYLE"
if sys <= 80:
return "LOW BP", "EMERGENCY"
if sys <= 90:
return "MILD LOW BP", "DRINK WATER"
return "ALL NORMAL", "VITALS GOOD"
# ==========================================================
# ALERT CHECK
# ==========================================================
def is_alert(temp, hr, sys, dia):
if temp < 36.1 or temp > 37.8:
return True
if hr < 60 or hr > 100:
return True
if sys < 90 or sys > 120:
return True
if dia < 60 or dia > 80:
return True
return False
# ==========================================================
# SPLASH SCREEN
# ==========================================================
def splash():
lcd.clear()
lcd.move(0, 0)
lcd.write("PATIENT MONITOR")
lcd.move(0, 1)
lcd.write("SYSTEM READY")
sleep(1.5)
lcd.clear()
lcd.move(0, 0)
lcd.write("TURN SLIDERS")
lcd.move(0, 1)
lcd.write("CHANGE VITALS")
sleep(1.5)
lcd.clear()
# ==========================================================
# DISPLAY CONTROL
# ==========================================================
display_counter = 0
def update_display(temp, hr, sys, dia, alert):
global display_counter
display_counter += 1
line1, line2 = get_diagnosis(
temp,
hr,
sys,
dia
)
lcd.clear()
# Every 5 cycles show actual values
if display_counter % 5 == 0:
lcd.move(0, 0)
lcd.write("T:{:4.1f} HR:{:3d}".format(temp, hr))
lcd.move(0, 1)
lcd.write("BP:{:3d}/{:3d}".format(sys, dia))
else:
lcd.move(0, 0)
lcd.write(line1[:16])
lcd.move(0, 1)
lcd.write(line2[:16])
if alert:
lcd.move(15, 0)
lcd.write("!")
# ==========================================================
# ALARM CONTROL
# ==========================================================
def update_alarm(alert):
if alert:
red_led.value(1)
green_led.value(0)
buzzer.value(1)
sleep(0.1)
buzzer.value(0)
else:
red_led.value(0)
green_led.value(1)
buzzer.value(0)
# ==========================================================
# STARTUP
# ==========================================================
splash()
# ==========================================================
# MAIN LOOP
# ==========================================================
while True:
raw_temp = pot_temp.read_u16()
raw_hr = pot_hr.read_u16()
raw_bp = pot_bp.read_u16()
temperature = get_temperature(raw_temp)
heart_rate = get_heart_rate(raw_hr)
systolic, diastolic = get_blood_pressure(raw_bp)
alert = is_alert(
temperature,
heart_rate,
systolic,
diastolic
)
update_display(
temperature,
heart_rate,
systolic,
diastolic,
alert
)
update_alarm(alert)
sleep(0.5)