Esempio n. 1
0
def main():
    """ Main function running on uc. The part before while loop runs only once. """
    # Declare device id. This one is first made.
    device_id = '1'

    # Declare all of the instances needed.
    wireless = Wireless(id=device_id)
    sensor = Max30102()
    algorithm = HrSpOalgorithm()
    display = Display()
    led = Led()
    data = Data()

    # Connect with WiFi and MQTT.
    wireless.wifi_connect()
    wireless.mqtt_connect()

    # Show WiFi connection status for 3 seconds. Clear the display when time elapse.
    display.show_wifi_status(wireless.wifi_status())
    utime.sleep(3)
    display.clear()

    # Set RTC.
    if wireless.wifi_status():
        settime()

    # Prepare buffors responsible for collecting IR and RED leds data.
    red_buf = []
    ir_buf = []
    time_buf = []

    # Remember runtime just before running the while loop.
    previous_time = utime.ticks_ms()

    # Setup display before the while loop.
    display.setup()

    while True:
        # Get actual date and time. Then split them to hh:mm:ss and dd.mm.yy formats. Display when done.
        if wireless.wifi_status():
            [y, m, d, h, min, s] = utime.localtime()[0:6]
            h = 0 if h == 23 else h + 1
            realtime = str("%02d" % h) + ':' + str("%02d" % min) + ':' + str("%02d" % s)
            date = str("%02d" % d) + '.' + str("%02d" % m) + '.' + str(y)
        else:
            realtime ='--------'
            date = '----------'
            utime.sleep_ms(15)
        display.show_time(realtime, date, device_id)

        # Read values measured by sensor. Take time of measure in account as well.
        red, ir, temperature = sensor.read_values()
        time = utime.ticks_ms() - previous_time

        # Determine if any body was detected by sensor based on IR value.
        if ir <= 30000:
            # No body was detected. Set the idle state and start the loop from the beginning.
            display.idle_state()
            sensor.set_idle_current()
            continue
        elif ir > 30000 and ir < 70000:
            # Something was detected. Don't know what exactly though. Prepare algorithm and sensor to work.
            # Start loop from the beginning.
            algorithm.setup()
            sensor.set_work_current()
            continue
        elif ir > 70000 and algorithm.beats == 0:
            # Most likely the human body was detected. Set work state of display and go on with loop.
            data.reset()
            display.work_state()

        # Collect measured values to buffors.
        red_buf.append(int(red))
        ir_buf.append(int(ir))
        time_buf.append(time)

        # At least 5 readings are needed to succesfully count the hr and spo2 values.
        if len(red_buf) > 5:
            red_buf = red_buf[1::]
            ir_buf = ir_buf[1::]
            time_buf = time_buf[1::]
        elif len(red_buf) == 5:
            pass
        else:
            continue

        # Count moving average of obtained data. n samples are beineg averaged.
        n = 5
        red_averaged = algorithm.moving_average(red_buf, n)
        ir_averaged = algorithm.moving_average(ir_buf, n)
        time_averaged = algorithm.moving_average(time_buf, n)

        # Get the last measured values.
        ir_value = int(ir_averaged[-1])
        red_value = int(red_averaged[-1])
        now = time_averaged[-1]

        # Try to count hr and spo2 values based on readings. Start loop from beggining if any error occured.
        # Most of the time it is ZeroDivisionEror but except all errors to make sure device will not hang on.
        try:
            new, hr, spo2 = algorithm.count_hr_spo(ir_value, red_value, now)
        except:
            continue

        # If new values gotten, and both of hr and spo2 are not zeros it can be assumed that proper value was obtained.
        if new and hr != 0 and spo2 != 0:
            # Save beat time and temperature rounded to two decimals as seperated variables. Just for convenience.
            beat_time = int(algorithm.beat_time[-1])
            temperature = round(temperature, 2)

            # Turn on the led shortly just to inform that new data was received.
            led.toggle()

            # Display gotten values.
            display.show_values(hr, spo2, temperature)

            # Start verifying if any alarm was detected by making new, empty string variable. Then decide what type
            # of alarm occured and add suitable information to alarm variable.
            alarm =''

            hr_min = 50
            hr_max = 90
            spo2_min = 93
            temperature_max = 37

            if hr < hr_min:
                alarm += ('HR_TOO_LOW|')
            elif hr > hr_max:
                alarm += ('HR_TOO_HIGH|')

            if spo2 < spo2_min:
                alarm += ('SPO2_TOO_LOW|')

            if temperature > temperature_max:
                alarm += ('TEMP_TOO_HIGH')

            # Show if alarm detected.
            display.show_alarm(alarm=alarm)

            # Check if connected to any broker. If not this point is loops end.
            if wireless.mqtt_status:
                # If alarm was not detected change it to '-'. PC app receiving data reads it like this.
                if alarm == '':
                    alarm = '-'

                # Update data with all needed values.
                data.update(date, realtime, beat_time, hr, spo2, temperature, alarm )

                # Send data to broker if 10 measures collected. Then reset the data buffor.
                if data.check_amount() >= 10:
                    wireless.publish(ujson.dumps(data.get_buf()))
                    data.reset()