"""
MicroPython Vital Signs Monitoring
This MicroPython script simulates a vital signs monitoring system using the Wokwi simulator.
The system gathers data from various sensors and sends it to an MQTT broker for monitoring.
Here's an explanation of the simulation:
1. Sensors Used:
- DHT22 (body_sensor): Simulates body temperature and humidity.
- Potentiometer (potentiometer): Simulates heart rate. The potentiometer value is scaled to simulate heart rate values from 0 to 220.
- MPU6050 Accelerometer and Gyroscope (mpu): Simulates breath quality. The AcZ value is scaled to simulate breath quality values
from 0 to 100. The temperature is also simulated from the accelerometer.
2. LED Indicators:
- Three LEDs (led_red, led_yellow, led_green) are used to indicate the status of the system.
- Green LED: Lights up when data is successfully sent to the MQTT broker.
- Red LED: Lights up in case of an error while publishing to MQTT.
- Yellow LED: Lights up when there is no change in the sensor data.
3. Patient Interaction:
- A button is incorporated into the system (button). When pressed, it sets the variable 'swallow_pill' to True,
indicating that the patient has swallowed a pill.
Note: The 'swallow_pill' variable signifies patient interaction and can be used to monitor medication adherence in the overall system.
4. **MQTT Communication:**
- The script connects to an MQTT broker (broker.mqttdashboard.com) using the specified credentials.
- It publishes the gathered sensor data to the "vital-signs" topic in JSON format.
- The script uses the umqtt.simple library for MQTT communication.
5. Note:
- The rotation and acceleration data from the MPU6050 are not currently utilized in the script. You can incorporate these
values into the message if needed.
The script creates a comprehensive simulated environment for monitoring vital signs and can be used as a starting point for
building an actual IoT system with physical sensors.
To view the data:
1. Go to http://www.hivemq.com/demos/websocket-client/
2. Click "Connect"
3. Under Subscriptions, click "Add New Topic Subscription"
4. In the Topic field, type "vital-signs" then click "Subscribe"
Now simulate changes in the potentiometer and the accelerometer in physical simulation,
and you should see the message appear on the MQTT Broker, in the "Messages" pane.
Copyright (C) 2024, Leandro Luna
"""
import network
import time
from machine import Pin, ADC, SoftI2C
import mpu6050
import dht
import ujson
from umqtt.simple import MQTTClient
# MQTT Server Parameters
MQTT_CLIENT_ID = "micropython-weather-demo"
MQTT_BROKER = "broker.mqttdashboard.com"
MQTT_USER = "luna"
MQTT_PASSWORD = "leandro"
MQTT_TOPIC = "vital-signs"
# Sensors
body_sensor = dht.DHT22(Pin(15))
button = Pin(27, Pin.IN, Pin.PULL_UP)
led_red = Pin(2, Pin.OUT)
led_yellow = Pin(0, Pin.OUT)
led_green = Pin(4, Pin.OUT)
potentiometer = ADC(Pin(35))
potentiometer.atten(potentiometer.ATTN_11DB)
i2c = SoftI2C(scl = Pin(25), sda = Pin(26))
mpu = mpu6050.accel(i2c)
# Connect to Wifi
print("Connecting to WiFi", end="")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('Wokwi-GUEST', '')
while not sta_if.isconnected():
print(".", end="")
time.sleep(0.1)
print("Connected!")
# Connect to MQTT Server
print("Connecting to MQTT server... ", end="")
mqtt_client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, user=MQTT_USER, password=MQTT_PASSWORD)
mqtt_client.connect()
print("Connected!")
ACZ_MAX = 32767
ACZ_MIN = 32768
POTENTIOMETER_MAX = 4095
HEART_RATE_THRESHOLD = [60, 100] # BPM unit
BODY_TEMPERATURE_THRESHOLD = 37 # Celsius unit
SHIRT_HUMIDITY_THRESHOLD = 30 # Percentage (Hypothetical)
BREATH_RATE_THRESHOLD = [12, 18] # Breaths per/min
ENV_TEMPERATURE_THRESHOLD = [5, 35] # Celsius unit
previous_data = ""
swallow_pill = False
while True:
# Read potentiometer simulating heart rate
heart_rate = int((potentiometer.read() / POTENTIOMETER_MAX) * 220)
# Read accelerometer data simulating breath rate and environment temperature
accelerometer_gyroscope = (mpu.get_values())
breath_rate = int(((accelerometer_gyroscope["AcZ"] + ACZ_MIN) / (ACZ_MAX + ACZ_MIN)) * 25)
environment_temperature = round(float(accelerometer_gyroscope["Tmp"]), 1)
# Reading the sensor simulating body temperature and humidity
body_sensor.measure()
# Check if the button is pressed (logic level is 0), indicating the patient has swallowed a pill in a specific day
if button.value() == 0:
swallow_pill = True
# Check for atypical vital sign
abnormal_sign = []
if body_sensor.temperature() > BODY_TEMPERATURE_THRESHOLD:
abnormal_sign.append("High body temperature")
if body_sensor.humidity() > SHIRT_HUMIDITY_THRESHOLD:
abnormal_sign.append("High sweat")
if heart_rate < HEART_RATE_THRESHOLD[0] or heart_rate > HEART_RATE_THRESHOLD[1]:
abnormal_sign.append("Uncommon heart rate")
if breath_rate < BREATH_RATE_THRESHOLD[0] or breath_rate > BREATH_RATE_THRESHOLD[1]:
abnormal_sign.append("Unusual breath rate")
if environment_temperature < ENV_TEMPERATURE_THRESHOLD[0] or environment_temperature > ENV_TEMPERATURE_THRESHOLD[1]:
abnormal_sign.append("Not safest environment temperature")
if not abnormal_sign:
abnormal_sign.append("All vital signs are within normal range")
print("Measuring vital signs... ", end="")
message = ujson.dumps({
"body_temperature": body_sensor.temperature(),
"shirt_humidity": body_sensor.humidity(),
"heart_rate": heart_rate,
"breath_rate": breath_rate,
"env_temperature": environment_temperature,
"swallow_pill_today": swallow_pill,
"abnormal_sign": abnormal_sign
})
if message != previous_data:
print("Updated!")
print("Sending to MQTT topic '{}': {}".format(MQTT_TOPIC, message))
try:
mqtt_client.publish(MQTT_TOPIC, message)
led_green.on()
time.sleep(1)
led_green.off()
previous_data = message;
except Exception as e:
print("Error publishing to MQTT:", e)
led_red.on()
time.sleep(1)
led_red.off()
else:
print("No change")
led_yellow.on()
time.sleep(1)
led_yellow.off()
time.sleep(5)