Lebin Liang
Created June 19, 2020 © MIT

Future-Mask

An intelligent mask that can be automatically opened and closed and reusable through machine vision and multi-sensors. Protect & Detect

AdvancedFull instructions providedOver 2 days21
Future-Mask

Things used in this project

Hardware components

Sipeed Maix Bit
K210 platform AIOT
×1
nRF52810
E104-BT5010A
×1
GY906
IR sensor MLX90614
×1
SparkFun Air Quality Breakout - CCS811
SparkFun Air Quality Breakout - CCS811
×1
MyOctopus HDC1000 Breakout Module I2C  Humidity / Temperature Sensor
MyOctopus HDC1000 Breakout Module I2C Humidity / Temperature Sensor
×1
OV2640 camera
×1
Li-Ion Battery 1000mAh
Li-Ion Battery 1000mAh
×1
power manager
Charge Battery and output 5v
×1

Software apps and online services

nRF Connect SDK
Nordic Semiconductor nRF Connect SDK
F-Mask
build it by myself

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Hot melt glue gun

Story

Read more

Custom parts and enclosures

Future-Mask 1.0

Use in Fusion 360

Schematics

Future-Mask

Code

Future-Mask 2.3

MicroPython
Use in MaixPy IDE
base on K210 Maix Bit
##
'''
F-mask
time:2020.6.14
test2.3
'''
##
import sensor, image, lcd, time
import KPU as kpu
import utime
from Maix import GPIO
from board import board_info
from fpioa_manager import fm
from machine import Timer,PWM
from machine import I2C

i2c = I2C(I2C.I2C0, freq=100000, scl=32, sda=33) #I2C2 1号引脚2728 2号3233

color_R = (255, 0, 0)
color_G = (0, 255, 0)
color_B = (0, 0, 255)


##-----------------变量----------------##

link = False #BLE连接状态
m_state = False #隔板开合状态
IR_Tem = 25 #前方目标温度
CO2_cpp = 255 #环境Co2浓度
VOC_index = 10 #环境挥发性有机物浓度
En_Tem = 25 #环境温度
En_Hum = 30 #环境湿度
m_count = 0 #视野内戴口罩的人数
nm_count = 0 #视野内不带口罩的人数

Danger_Index = 0 #危险指数

Mode = 2 #模式选择 0-自动模式 1-夜间模式 2-手动模式

##-----------------指示灯---------------##

fm.register(board_info.LED_R,fm.fpioa.GPIO2)
led = GPIO(GPIO.GPIO2,GPIO.OUT)
led.value(1)

##--------------------------------##
##-----------------人脸识别检测---------------##

#lcd.init()
sensor.reset(dual_buff=True)
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_hmirror(0)
sensor.run(1)
task = kpu.load(0x500000)
anchor = (0.1606, 0.3562, 0.4712, 0.9568, 0.9877, 1.9108, 1.8761, 3.5310, 3.4423, 5.6823)
a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)

##--------------------------------##

##蓝牙连接中断(检测连接状态)
def blelink_irq(pin_num):
    global link
    link = bool(1-ble_link.value())
    if link:
        led.value(0)
        tim_BLEdata.start()
        print("Link")
    else:
        led.value(1)
        tim_BLEdata.stop()
        print("NO Link")

##触摸控制中断(手动控制)
def touchkey_irq(pin_num):
   print("touch")
   utime.sleep_ms(100)
   global m_state
   if pin_num.value() == 1:
        #print(m_state)
        if m_state:
            m_state = False
        else:
            m_state = True
        Servo_Ctl()


##-----------------BLE蓝牙---------------##
fm.register(board_info.PIN15,fm.fpioa.GPIOHS0)
ble_link = GPIO(GPIO.GPIOHS0,GPIO.IN,GPIO.PULL_NONE)
utime.sleep_ms(500)
ble_link.value()
ble_link.irq(blelink_irq,GPIO.IRQ_BOTH,GPIO.WAKEUP_NOT_SUPPORT,1)
fm.register(board_info.PIN9,fm.fpioa.UART2_TX)
fm.register(board_info.PIN10,fm.fpioa.UART2_RX)

uart_BLE = UART(UART.UART2, 115200, 8, None, 1, timeout=1000, read_buf_len=4096)

##--------------------------------##

##----------------电容触摸控制---------------##
fm.register(board_info.JTAG_TCK,fm.fpioa.GPIOHS1)#PIN0
touch_key = GPIO(GPIO.GPIOHS1,GPIO.IN,GPIO.PULL_DOWN)
utime.sleep_ms(500)
touch_key.value()
touch_key.irq(touchkey_irq,GPIO.IRQ_RISING,GPIO.WAKEUP_NOT_SUPPORT,2)

##------------舵机控制------------------##
tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
Servo = PWM(tim, freq=400, duty=0, pin=board_info.PIN17)
duty = 0
##--------------------------------##

##CCS811初始化函数
def ccs811Init():
    information=i2c.readfrom_mem(90,0x20,1)
    #print(information)
    #information1=i2c.readfrom_mem(90,0x23,2)
    #information2=i2c.readfrom_mem(90,0x24,2)
    #i2c.writeto_mem(90,0xF3,0xF0)
    status=i2c.readfrom_mem(90,0x00,1)
    status=int.from_bytes(status,b'big')
    if(int(status)&0x10):
       i2c.writeto_mem(90,0xF4,'')
    status=i2c.readfrom_mem(90,0x00,1)
    MeasureMode=i2c.readfrom_mem(90,0x01,1)
    i2c.writeto_mem(90,0x01,0x40)
    time.sleep_ms(10)

##GY906读取函数
def readtemp():
    i2c.writeto(0x00,'7')
    Data=i2c.readfrom_mem(0x00,0x07,3)
    ret=Data[0]
    ret|=Data[1]<<8
    ret=ret*0.02-273.15
    return ret

##CSS811读取函数
def ccs811read():
    status=i2c.readfrom_mem(90,0x00,1)
    #print("sta")
    #print(status)
    Error_id=i2c.readfrom_mem(90,0xE0,1)
    #print("error")
    #print(Error_id)
    Data=i2c.readfrom_mem(90,0x02,8)
    co2=int(Data[0])*256+int(Data[1])
    tvoc=int(Data[2])*256+int(Data[3])
    information=i2c.readfrom_mem(90,0x20,1)
    #print(information)
    return co2,tvoc

##HDC1080初始化函数
def HDC1080init():
    i2c.scan()
    config = 0
    b = config.to_bytes(2,'big')
    i2c.writeto_mem(64,0x02,b)
    time.sleep_ms(10)
    MID=i2c.readfrom_mem(64,0xFE,2)
    time.sleep_ms(10)
    DID=i2c.readfrom_mem(64,0xFF,2)
    time.sleep_ms(10)
    CFG=i2c.readfrom_mem(64,0x02,2)
    return MID,DID,CFG

##HDC1080温度读取函数
def HDC1080_Tem():
    c= 0
    c = c.to_bytes(1,'big')
    #print("c:"+str(c))
    i2c.writeto(64,c)
    time.sleep_ms(10)
    T = i2c.readfrom(64,2)
    Tem = T[0]<<8 |T[1]
    TEM = (Tem / pow(2,16)) *165.0-40.0
    return TEM

##HDC1080湿度读取函数
def HDC1080_Hum():
    d= 1
    d = d.to_bytes(1,'big')
    #print("d:"+str(d))
    i2c.writeto(64,d)
    time.sleep_ms(12)
    H = i2c.readfrom(64,2)
    Hum = H[0]<<8 |H[1]
    HUM = (Hum / pow(2,16))*100.0
    return HUM

##指令分析函数
def OrderAns(read_str):
    #print("ANS")
    global Mode #模式选择 0-自动模式 1-夜间模式 2-手动模式
    global m_state
    if read_str[0] == 'M':
       Mode = read_str[1]
       #print("Mode"+Mode)
    if read_str[0] == 'C':
       m_state = bool(1-int(read_str[1]))
       #print(str(m_state))
       Servo_Ctl()

##舵机状态自更新函数
def Servo_Ctl():
    if m_state:
        Servo_Control(60)
    else:
        Servo_Control(0)

##舵机控制函数
def Servo_Control(target):
   global duty
   if target < duty:
    dir = False
   else:
    dir = True
   while target != duty:
    if dir:
        duty += 5
    else:
        duty -= 5
    if duty>100:
        duty = 100
    elif duty<0:
        duty = 0
    time.sleep(0.001)
    Servo.duty(duty)

##危险系数计算函数
def DangerIndexCount():
    global Danger_Index #危险指数
    num_peo = m_count + nm_count
    Co2_factor=0.0  #Co2因子
    Tem_factor=0.0  #温度因子
    Hum_factor=0.0  #湿度因子
    Peo_factor=0.0  #人员因子
    if CO2_cpp<450 and CO2_cpp>350:
       Co2_factor=1
    elif CO2_cpp>=450 and CO2_cpp<1000:
       Co2_factor=2
    elif CO2_cpp>=1000:
       Co2_factor=3
    if En_Tem<20:
       Tem_factor=1
    elif En_Tem>=20 and En_Tem<30:
       Tem_factor=0.5
    elif En_Tem>=30 and En_Tem<40:
       Tem_factor=0.1
    elif En_Tem>=40:
       Tem_factor=0
    if En_Hum<0.23:
       Hum_factor=0.7
    elif En_Hum>=0.23 and En_Hum<0.3:
       Hum_factor=1
    elif En_Hum>=0.3 and En_Hum<0.4:
       Hum_factor=0.5
    elif En_Hum>=0.4:
       Hum_factor=0
    if num_peo==0:
       Peo_factor=0
    elif num_peo>0 and num_peo<3:
       Peo_factor=nm_count*2
    elif num_peo>=3:
       Peo_factor+nm_count*5
    Danger_Index=int(Co2_factor+Tem_factor+Hum_factor+Peo_factor)
    #print("Count")

##模式选择函数
def Mode_Select(mode):
    global m_state
    if mode == 0:
        tim_camera.start()
        if Danger_Index >= 3:
            m_state = False
        else:
            m_state = True
    elif mode == 1:
        tim_camera.stop()
        if Danger_Index >= 3:
            m_state = False


##BLE传输函数
def BLEdata_task(timer):
    s = str(Danger_Index) + '|' +'N'+str(nm_count)+'Y'+str(m_count)+'|'+str(IR_Tem)+'|'+str(VOC_index)+'|'+str(CO2_cpp)+'|'+str(En_Tem)+'|'+str(En_Hum)
    uart_BLE.write(s)

##IR测温 温湿度 CO2 VOCS函数
def Sensor_task(timer):
    global IR_Tem #前方目标温度
    global CO2_cpp #环境Co2浓度
    global VOC_index  #环境挥发性有机物浓度
    global En_Tem  #环境温度
    global En_Hum #环境湿度
    i2c = I2C(I2C.I2C0,mode=I2C.MODE_MASTER,freq=100000, scl=32, sda=33)
    CO2_cpp,VOC_index = ccs811read()
    En_Tem = HDC1080_Tem()
    En_Hum = HDC1080_Hum()
    i2c.deinit()
    time.sleep_ms(100)
    i2c = I2C(I2C.I2C0,mode=I2C.MODE_MASTER,freq=100000, scl=27, sda=28)
    IR_Tem = readtemp()
    i2c.deinit()
    time.sleep_ms(100)
    DangerIndexCount()
    #s = str(Danger_Index) + '|' +'N'+str(nm_count)+'Y'+str(m_count)+'|'+str(IR_Tem)+'|'+str(VOC_index)+'|'+str(CO2_cpp)+'|'+str(En_Tem)+'|'+str(En_Hum)
    #print(s)

##口罩佩戴检测函数
def reg_face_mask(timer):
    global m_count
    global nm_count
    img = sensor.snapshot()
    code = kpu.run_yolo2(task, img)
    if code:
        m_count = 0
        nm_count = 0
        totalRes = len(code)
        img.draw_string(0, 0 ,'total:'+str(totalRes) , color=color_B, scale=2.5)
        for item in code:
            confidence = float(item.value())
            itemROL = item.rect()
            classID = int(item.classid())

            if classID == 1 and confidence > 0.65:
                a = img.draw_rectangle(itemROL, color_G, tickness=5)
                m_count+=1
            else:
                a = img.draw_rectangle(itemROL, color=color_R, tickness=5)
                nm_count+=1

        img.draw_string(0, 100 ,("Y:%d" %(m_count)) , color=color_G, scale=2.5)
        img.draw_string(0, 50 ,("N:%d" %(nm_count)) , color=color_R, scale=2.5)
        #a = lcd.display(img)
    else:
        m_count = 0
        nm_count = 0
        #a = lcd.display(img)
##------------中断配置-----------##
tim_camera = Timer(Timer.TIMER0, Timer.CHANNEL1,mode=Timer.MODE_PERIODIC,period=100,unit=Timer.UNIT_MS,callback=reg_face_mask,arg=reg_face_mask,start=True,priority=3,div=0)
tim_Sensor = Timer(Timer.TIMER1, Timer.CHANNEL0,mode=Timer.MODE_PERIODIC,period=1000,unit=Timer.UNIT_MS,callback=Sensor_task,arg=Sensor_task,start=True,priority=4,div=0)
tim_BLEdata = Timer(Timer.TIMER2, Timer.CHANNEL0,mode=Timer.MODE_PERIODIC,period=1000,unit=Timer.UNIT_MS,callback=BLEdata_task,arg=BLEdata_task,start=False,priority=5,div=0)

##-----------------------------##


#--------------主函数-----------##

link = bool(1-ble_link.value())
if link:
    led.value(0)
    tim_BLEdata.start()
    print("Link")
else:
    led.value(1)
    tim_BLEdata.stop()
    print("NO Link")


print(i2c.scan())
HDC1080init()
ccs811Init()

while(True):

    Mode_Select(Mode)
    #Servo_Ctl()
    if link:
        read_data = uart_BLE.read()
        if read_data :
            read_s = read_data.decode('utf-8')
            OrderAns(read_s)

Credits

Lebin Liang

Lebin Liang

1 project • 1 follower
make life better

Comments