AIoT应用创新大赛-基于TencentOS Tiny的办公区厕所蹲位监控系统

2022-03-14 11:57:08 浏览数 (2)

视频内容
AIoT应用创新大赛 - 基于TencentOS Tiny AIoT的办公区厕所蹲位监控系统_202203.pptx

一、方案说明:

这次有幸获得腾讯物联网和NXP联合推出的TencentOS Tiny EVB_AIoT开发板,是基于NXP的i.MX RT1062跨界MCU,其功能非常强大。因为时间关系,还有很多强大的功能尚在学习中,这次先运用学习的基础知识,做了一个有些趣味性的系统。

办公区的厕所,不用的时候,没什么人用,等到自己想去的时候,往往人满为患,甚至有瘾君子,蹲连往返,让真真有需要的人痛苦不堪。那我们的这个趣味型系统,就是:办公区厕所蹲位监控系统。

我们要实现的基本功能,就是检测到有人如厕,就会进行计数。至于计数后,有什么用,这个各位自己想了,例如可以把控制界面发给老板,老板看哪个蹲位占用时间比较长,就点一个警告按钮,催一催:):):)

二、系统设计:

有了想法以后,就进行了详细的规划,具体的逻辑流程如下:

在这个方案中,用到了两个人体感应传感器。主要是我手头刚好有E53_IS1的扩展板,带有人体感应传感器,而我同时还有一块单独的人体感应传感器模块。这两个人体感应传感器,都是触发型的,也就是检测到有人体靠近,就会触发高电平输出,但是当人体保持在传感器前面时,不能持续保持输出,所以只能想了一个变通的方案。

第一个人体感应传感器,位于蹲位单间门口,但要套上壳,只允许正前方的感应,而不接收片侧面方向的感应,避免误触,也就是当人体正常经过的时候,会进行触发。

第二个人体感应传感器,则位于蹲位单间内,当第一个人体感应传感器检测到数据,第二个也检测到,说明正式如厕,蹲位被占用,可以上报信息到云平台,并开始计数了。

对一个具体的蹲位,我们使用了三个IoT属性:蹲位是否占用、蹲位计数、蹲位警告开关,具体如下:

以上的内容,需要在腾讯IoT平台进行设置,具体请参考官方的入门指导。

三、硬件设计:

在该方案中,使用到了如下的硬件:

  1. TencentOS Tiny EVB_AIoT开发板
  2. E53_IS1扩展板
  3. PIR人体感应传感器
  4. LED两个
  5. 扩展板一个:主要是为了方便传感器、LED的供电和接地

TencentOS Tiny EVB_AIoT开发板上提供的直插接口,为E53接口,如果把E53_IS1扩展板直接插上,则接口不够,所以把E53_IS1扩展板取下来,用杜邦线进行连接。

具体的连线如下:

开发板E53接口的5V、GND,连接扩展板的5V、GND

E53_IS1扩展板的5V、GND,连接到扩展板的5V、GND,GPIO2接口,连接到开发板E53接口的GPIO2

PIR人体感应传感器的5V、GND,连接到扩展板的5V、GND,D-OUT接口,连接到开发板E53接口的GPIO3

两个LED的GND连接到扩展板的GND,LED1、LED2的控制引脚分别连接到开发板E53接口的GPIO5、GPIO1

通过查看TencentOS Tiny官方提供的《20211027_RT1062_Core_RevA03(确认).pdf》、《20211027_Tencent_AIoT_RevC03(确认).pdf》文档,我们可以得知开发板E53接口的GPIO2、GPIO3、GPIO5、GPIO1,分别对应RT1062的C14、B14、P2、J2。

因此需要在MCUXPresso IDE中,使用引脚功能进行配置,具体配置如下:

注意其中E53_GPIO32、E53_GPIO3对应引脚的设置注意其中E53_GPIO32、E53_GPIO3对应引脚的设置

四、软件设计:

首先,通过MCUXPresso IDE的例子程序进行了学习,然后通过学习TencentOS Tiny官方提供的IoT实例,进行了扩展。

在上面的工程中,分别为:

  1. hello world
  2. gpio_input_interrupt:按键输入
  3. gpio_led_output:点灯
  4. 官方IoT实例:连接到腾讯物联网平台

通过MCUXPresso IDE的引脚配置,最终我们定义了调用的头文件pin_config.h:

代码语言:javascript复制
#ifndef  TOS_PIN_CONFIG_H
#define  TOS_PIN_CONFIG_H

/*******************************************************************************
 * 引脚定义:
 * 1. E53的GPIO3、GPIO2做为人体感应器的输入
 * 2. E53的GPIO1、GPIO5控制LED
 ******************************************************************************/
#define EXAMPLE_SW_GPIO1         BOARD_INITPINS_E53_GPIO2_GPIO
#define EXAMPLE_SW_GPIO1_PIN     BOARD_INITPINS_E53_GPIO2_GPIO_PIN

#define EXAMPLE_SW_GPIO2         BOARD_INITPINS_E53_GPIO3_GPIO
#define EXAMPLE_SW_GPIO2_PIN     BOARD_INITPINS_E53_GPIO3_GPIO_PIN

#define EXAMPLE_SW_NAME1         "SW1"
#define EXAMPLE_SW_NAME2         "SW2"

#define EXAMPLE_LED_GPIO1     	BOARD_INITPINS_E53_GPIO5_GPIO
#define EXAMPLE_LED_GPIO1_PIN 	BOARD_INITPINS_E53_GPIO5_GPIO_PIN

#define EXAMPLE_LED_GPIO2     	BOARD_INITPINS_E53_GPIO1_GPIO
#define EXAMPLE_LED_GPIO2_PIN 	BOARD_INITPINS_E53_GPIO1_GPIO_PIN

#endif

然后进行了基础的测试:main.c

代码语言:javascript复制
#......
#include "pin_config.h"
#define IOT_CLOUD_ENABLE		0	// 1-启用物联网 0-不启用物联网

static int sw_flags[2] = {0,0};

int main(void)
{
    /* 输入和输出参数定义 */
    gpio_pin_config_t sw_config = {kGPIO_DigitalInput, 0, kGPIO_IntRisingEdge};
    gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};

    lpuart_config_t config;
    /* 开发板引脚、时钟、调试等初始化 */
    BOARD_ConfigMPU();
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    /* 输出欢迎信息 */
    PRINTF("Welcome to TencentOS tiny @ i.MX RT1062rn");

    /* 初始化输入 GPIO. */
    GPIO_PinInit(EXAMPLE_SW_GPIO1, EXAMPLE_SW_GPIO1_PIN, &sw_config);
    GPIO_PinInit(EXAMPLE_SW_GPIO2, EXAMPLE_SW_GPIO2_PIN, &sw_config);

    /* 初始化输出 GPIO. */
    GPIO_PinInit(EXAMPLE_LED_GPIO1, EXAMPLE_LED_GPIO1_PIN, &led_config);
    GPIO_PinInit(EXAMPLE_LED_GPIO2, EXAMPLE_LED_GPIO2_PIN, &led_config);

    /* 初始化点亮LED. */
    GPIO_PinWrite(EXAMPLE_LED_GPIO1, EXAMPLE_LED_GPIO1_PIN, 0U);
    GPIO_PinWrite(EXAMPLE_LED_GPIO2, EXAMPLE_LED_GPIO2_PIN, 0U);

    /* 人体感应传感器与LED 测试 */
#if IOT_CLOUD_ENABLE == 0
    while (1)
    {
    	tos_task_delay(1000);
		if (1 == GPIO_PinRead(EXAMPLE_SW_GPIO1, EXAMPLE_SW_GPIO1_PIN))
		{
			if(sw_flags[0]!=1) {
				sw_flags[0]=1;
				PRINTF("%s is turned on.rn", EXAMPLE_SW_NAME1);
				GPIO_PinWrite(EXAMPLE_LED_GPIO1, EXAMPLE_LED_GPIO1_PIN, 0U);
			}
		} else {
			if(sw_flags[0]!=0) {
				sw_flags[0]=0;
				PRINTF("%s is turned off.rn", EXAMPLE_SW_NAME1);
				GPIO_PinWrite(EXAMPLE_LED_GPIO1, EXAMPLE_LED_GPIO1_PIN, 1U);
			}
		}

		if (1 == GPIO_PinRead(EXAMPLE_SW_GPIO2, EXAMPLE_SW_GPIO2_PIN))
		{
			if(sw_flags[1]!=1) {
				sw_flags[1]=1;
				PRINTF("%s is turned on.rn", EXAMPLE_SW_NAME2);
				GPIO_PinWrite(EXAMPLE_LED_GPIO2, EXAMPLE_LED_GPIO2_PIN, 0U);
			}
		} else {
			if(sw_flags[1]!=0) {
				sw_flags[1]=0;
				PRINTF("%s is turned off.rn", EXAMPLE_SW_NAME2);
				GPIO_PinWrite(EXAMPLE_LED_GPIO2, EXAMPLE_LED_GPIO2_PIN, 1U);
			}
		}
    }
#else
    // 使能    TencentOS Tiny
    osKernelInitialize(); // 内核初始化
    osThreadCreate(osThread(application_entry), NULL); // 创建任务
    osKernelStart(); // 启动
#endif
}

在上面的代码中,sw_flags用来记录传感器的状态;因为人体感应传感器模块,触发后,会有一段时间的延时才会将为低电平,所以使用sw_flags来检测状态是否改变,才进行具体的处理。

这段代码的核心,就是输入和输出GPIO的初始化,以及GPIO读写。

运行这段代码,连接串口调试,用手分别接近两个传感器,就能够收到对应的输出信息。

基础的传感器信号读取和LED控制完成后,就可以开始mqtt连接IoT平台的部分了。

官方提供了一个py文件,来生成对应的mqtt调用信息,我进行了修改后,方便直接生成对应的头文件,以及对应的调用代码:

代码语言:javascript复制
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import base64
import hashlib
import hmac
import random
import string
import time
from string import Template

# bind raw_input to input in Python 2
try:
    input = raw_input
except NameError:
    pass

product_id = input("product id:")
dev_name = input("device name:")
passwd = input("password:")
sub = input("subscribe topic:[default:control]")
if sub == "":
    sub = "control"
pub = input("publish topic:[default:event]")
if pub == "":
    pub = "event"

client_id = product_id   dev_name
# expire time: 2^32 - 1 = 4294967295
username = client_id ";21010406;12365;{}".format(4294967295)

def hmacsha1(content, passwd):
        passwd_byte = base64.b64decode(passwd)
        return hmac.new(passwd_byte, content, digestmod=hashlib.sha1).hexdigest()

username = username.encode("utf-8")
passwd = passwd.encode("utf-8")
sign = hmacsha1(username, passwd)

template_header = ('#ifndef  TOS_MQTT_CONFIG_Hn'
            '#define  TOS_MQTT_CONFIG_Hn'
            'n'
            '#define MQTT_SERVER_IP          "111.230.189.156"n'
            '#define MQTT_SERVER_PORT        "1883"n'
            '#define MQTT_PRODUCT_ID         "$product"n'
            '#define MQTT_DEV_NAME           "$dev"n'
            '#define MQTT_CLIENT_ID          "$product$dev"n'
            '#define MQTT_USR_NAME           "$product$dev;21010406;12365;4294967295"n'
            '#define MQTT_PASSWORD           "$sign;hmacsha1"n'
            '#define MQTT_SUBSCRIBE_TOPIC    "$product/$dev/$sub"n'
            '#define MQTT_PUBLISH_TOPIC      "$product/$dev/$pub"n'
            'n'
            '#define MQTT_SERVER_DOMAIN      "$product.iotcloud.tencentdevices.com"n'
            '#define MQTT_TOPIC              "$product/$dev"n'            
            '#define MQTT_SUBSCRIBE_TOPIC_DOWN    "$thing/down/property/$product/$dev"n'
            '#define MQTT_PUBLISH_TOPIC_UP      "$thing/up/property/$product/$dev"n'
            'n'
            '#endifn'
            'n')

template_c = ('#ifndef  TOS_MQTT_CONFIG_Hn'
            'tos_sal_module_parse_domain(MQTT_SERVER_DOMAIN,host_ip,sizeof(host_ip));n'
            'n'
            'mqtt_set_port(client, MQTT_SERVER_PORT);n'
            'mqtt_set_host(client, host_ip);n'
            'mqtt_set_client_id(client, MQTT_CLIENT_ID);n'
            'mqtt_set_user_name(client, MQTT_USR_NAME);n'
            'mqtt_set_password(client, MQTT_PASSWORD);n'
            'mqtt_set_clean_session(client, 1);n'
            'n'
            'error = mqtt_subscribe(client, MQTT_SUBSCRIBE_TOPIC_DOWN, QOS0, tos_topic_handler);n'
            'n'
            'error = mqtt_publish(client, MQTT_PUBLISH_TOPIC_UP, &msg);n'
            'n'
            '#endifn'
            'n')

src_header = Template(template_header)
src_c = Template(template_c)

d = {
        'product':product_id,
        'dev':dev_name,
        'sign':sign,
        'sub':sub,
        'pub':pub,
        'thing':'$thing'
    }

#do the substitution
dst_header = src_header.substitute(d)
dst_c = src_c.substitute(d)
print("===============Generate mqtt_config.h==================")
print(dst_header)
with open('mqtt_config.h', 'w') as f:
    f.write(dst_header)

print("===============Generate mqtt_connect_demo.c==================")
print(dst_c)
with open('mqtt_connect_demo.h', 'w') as f:
    f.write(dst_c)

参考官方的调用方法运行后,得到的头文件如下:

代码语言:javascript复制
#ifndef  TOS_MQTT_CONFIG_H
#define  TOS_MQTT_CONFIG_H

#define MQTT_SERVER_IP          "111.230.189.156"
#define MQTT_SERVER_PORT        "1883"
#define MQTT_PRODUCT_ID         "FVR9566ISL"
#define MQTT_DEV_NAME           "dev01"
#define MQTT_CLIENT_ID          "FVR9566ISLdev01"
#define MQTT_USR_NAME           "FVR9566ISLdev01;21010406;12365;4294967295"
#define MQTT_PASSWORD           "b07060f02090e090c030f05010c000c050505020;hmacsha1"
#define MQTT_SUBSCRIBE_TOPIC    "FVR9566ISL/dev01/control"
#define MQTT_PUBLISH_TOPIC      "FVR9566ISL/dev01/event"

#define MQTT_SERVER_DOMAIN      "FVR9566ISL.iotcloud.tencentdevices.com"
#define MQTT_TOPIC              "FVR9566ISL/dev01"
#define MQTT_SUBSCRIBE_TOPIC_DOWN    "$thing/down/property/FVR9566ISL/dev01"
#define MQTT_PUBLISH_TOPIC_UP      "$thing/up/property/FVR9566ISL/dev01"

#endif

对应的mqttclient_iot_explorer.c文件内容如下:

代码语言:javascript复制
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_gpio.h"
#include "cmsis_os.h"
#include "fsl_lpuart.h"
#include "sal_module_wrapper.h"
#include "ec600s.h"
#include "tos_at.h"
#include "mqttclient.h"
#include "cjson.h"
#include "sal_module_wrapper.h"

#include "mqtt_config.h"
#include "pin_config.h"

#define USE_ESP8266

#if defined(USE_ESP8266)
#include "esp8266.h"
#endif

#ifdef USE_ESP8266 
static hal_uart_port_t esp8266_port = HAL_UART_PORT_2;

void mqtt_set_esp8266_port(hal_uart_port_t port) {
    esp8266_port = port;
}
#endif

extern volatile bool g_pinSet;
static int sw_flags[2];

k_event_t report_result_event;
k_event_flag_t report_success = 1<<0;
k_event_flag_t report_fail    = 1<<1;

// 消息接收回调
static void tos_topic_handler(void* client, message_data_t* msg)
{
    (void) client;
    cJSON* cjson_root   = NULL;
    cJSON* cjson_status = NULL;
    cJSON* cjson_method = NULL;
    cJSON* cjson_params = NULL;
    char* status = NULL;
    char* method = NULL;
    int power_switch = 0;
    k_event_flag_t event_flag = report_fail;

    /* 打印收到的消息 */
    MQTT_LOG_I("-----------------------------------------------------------------------------------");
    MQTT_LOG_I("%s:%d %s()...ntopic: %s, qos: %d. nmessage:nt%sn", __FILE__, __LINE__, __FUNCTION__, 
            msg->topic_name, msg->message->qos, (char*)msg->message->payload);
    MQTT_LOG_I("-----------------------------------------------------------------------------------n");
    
    /* 解析收到的消息内容,转换为JSON */
    cjson_root = cJSON_Parse((char*)msg->message->payload);
    if (cjson_root == NULL) {
        printf("report reply message parser failrn");
        event_flag = report_fail;
        goto exit;
    }

    /* 获取本次收到消息的method */
    cjson_method = cJSON_GetObjectItem(cjson_root, "method");
    method = cJSON_GetStringValue(cjson_method);
    if (method == NULL || method == NULL) {
        printf("message method parser failrn");
        event_flag = report_fail;
        goto exit;
    }
    MQTT_LOG_I("report mthod is %srn", method);

    if(strcmp(method, "report_reply")==0) {
    	// 服务端对报告信息的返回
		/* 获取消息中的status */
		cjson_status = cJSON_GetObjectItem(cjson_root, "status");
		status = cJSON_GetStringValue(cjson_status);
		if (cjson_status == NULL || status == NULL) {
			printf("report reply status parser failrn");
			event_flag = report_fail;
			goto exit;
		}

		/* 检查回报状态是否为success */
		if (strstr(status,"success")) {
			event_flag = report_success;
		}else {
			event_flag = report_fail;
		}
    } else if(strcmp(method, "control")==0) {
    	event_flag = report_success;
    	cjson_params = cJSON_GetObjectItem(cjson_root, "params");
    	power_switch = cJSON_GetObjectItem(cjson_params, "toilet_switch_1")->valueint;
    	MQTT_LOG_I("Control set toilet_switch_1:%drn", power_switch);
    	if(power_switch) {
    		GPIO_PinWrite(EXAMPLE_LED_GPIO2, EXAMPLE_LED_GPIO2_PIN, 1U);
    	} else {
    		GPIO_PinWrite(EXAMPLE_LED_GPIO2, EXAMPLE_LED_GPIO2_PIN, 0U);
    	}
    } else {
        printf("message method is know: %srn", method);
        event_flag = report_fail;
        goto exit;
    }

    // 清理并返回
exit:
    cJSON_Delete(cjson_root);
    cjson_root = NULL;
    status = NULL;
    method = NULL;
    
    tos_event_post(&report_result_event, event_flag);
    
    return;
}


#define REPORT_DATA_TEMPLATE "{"method":"report","clientToken":"00000001", 
								"params":{ 
												"toilet_status_1":%d, 
												"toilet_count_1":%d 
											} 
								}"
char report_buf[500];

// mqtt客户端任务
void mqttclient_task(void)
{
    int error;
    
    mqtt_client_t *client = NULL;
    mqtt_message_t msg;
    k_event_flag_t match_flag;
    
    char  host_ip[20];
    memset(&msg, 0, sizeof(msg));

	// 使用ESP8266联网
    esp8266_sal_init(esp8266_port);
    esp8266_join_ap("OpenBSD", "********");

    mqtt_log_init();
    client = mqtt_lease();

    tos_event_create(&report_result_event, (k_event_flag_t)0u);

    // 设置mqtt连接信息
    tos_sal_module_parse_domain(MQTT_SERVER_DOMAIN,host_ip,sizeof(host_ip));
    mqtt_set_port(client, MQTT_SERVER_PORT);
    mqtt_set_host(client, host_ip);
    mqtt_set_client_id(client, MQTT_CLIENT_ID);
    mqtt_set_user_name(client, MQTT_USR_NAME);
    mqtt_set_password(client, MQTT_PASSWORD);
    mqtt_set_clean_session(client, 1);

    // 连接服务端
    error = mqtt_connect(client);
    if(error!=0) {
    	MQTT_LOG_D("mqtt connect error is %#0x", error);
    } else {
    	MQTT_LOG_D("mqtt connect success.");
    }

    // 订阅服务端发送的消息
    error = mqtt_subscribe(client, MQTT_SUBSCRIBE_TOPIC_DOWN, QOS0, tos_topic_handler);
    if(error!=0) {
    	MQTT_LOG_D("mqtt subscribe error is %#0x", error);
    } else {
    	MQTT_LOG_D("mqtt subscribe success.");
    }
    
    int first = 1;
    int step = 0;
    int count = 0;
    while (1) {
        // 读取1号状态
		if (1 == GPIO_PinRead(EXAMPLE_SW_GPIO1, EXAMPLE_SW_GPIO1_PIN))
		{
			if(sw_flags[0]!=1) {
				if(step<=1) {
					// 进入处理逻辑,需要进行循环处理
					step = 2;
				}
				if(step>=3) {
					// 再次通过1号传感器
					step = 0;
					GPIO_PinWrite(EXAMPLE_LED_GPIO2, EXAMPLE_LED_GPIO1_PIN, 0U);
				}
				sw_flags[0]=1;
				MQTT_LOG_D("%s is turned on.rn", EXAMPLE_SW_NAME1);
			}
		} else {
			if(step==2) {
				// 通过1号传感器
				step = 3;
			}
			if(sw_flags[0]!=0) {
				sw_flags[0]=0;
				MQTT_LOG_D("%s is turned off.rn", EXAMPLE_SW_NAME1);
			}
		}

		if(step>=3) {
			// 读取2号状态
			if (1 == GPIO_PinRead(EXAMPLE_SW_GPIO2, EXAMPLE_SW_GPIO2_PIN))
			{
				if(sw_flags[1]!=1) {
					if(step==3) {
						step = 4;
					}
					sw_flags[1]=1;
					PRINTF("%s is turned on.rn", EXAMPLE_SW_NAME2);
					GPIO_PinWrite(EXAMPLE_LED_GPIO2, EXAMPLE_LED_GPIO1_PIN, 1U);
				}
			} else {
				if(sw_flags[1]!=0) {
					sw_flags[1]=0;
					PRINTF("%s is turned off.rn", EXAMPLE_SW_NAME2);
				}
			}
		}

		MQTT_LOG_D("step = %d", step);
		if(step>=4) {
			count = count   1;
		}
		if(first==1 || step==0 || step == 4 || (count>0 && count%5 == 0)) {
			// 上报数据
			first = 0;

			if(step==0) {
				count = 0;
				step = 1;
			}
			else {
				step = 5;
			}

			// 生成上报数据信息
			snprintf(report_buf, sizeof(report_buf), REPORT_DATA_TEMPLATE, step >= 4 ? 1 : 0, count/5);

			memset(&msg, 0, sizeof(msg));

			// 发送消息
			msg.qos = QOS0;
			msg.payload = (void *) report_buf;
			error = mqtt_publish(client, MQTT_PUBLISH_TOPIC_UP, &msg);
			if(error) {
				MQTT_LOG_D("mqtt publish error is %#0x", error);
			} else {
				MQTT_LOG_D("mqtt publish success: >>>%s<<<", report_buf);
			}

			tos_event_pend(&report_result_event,
						   report_success|report_fail,
						   &match_flag,
						   TOS_TIME_FOREVER,
						   TOS_OPT_EVENT_PEND_ANY | TOS_OPT_EVENT_PEND_CLR);

			if (match_flag == report_success) {
				printf("report to Tencent IoT Explorer successrn");

			}else if (match_flag == report_fail){
				printf("report to Tencent IoT Explorer failrn");
			}
		}

        tos_task_delay(200);
    }
}

// tos app入口
void application_entry(void *arg)
{
    mqttclient_task();
    while (1) {
        tos_task_delay(1000);
    }
}

官方提供的IoT例子程序中,接收到消息后,只有对上报回复消息的处理,没有对控制指令下发消息的处理。所以在上述代码中,tos_topic_handler()回调部分,包含了对接收到的消息中,method的处理,如果为control,则表示为下发的控制指令,根据实际情况,进行具体的处理。

上面的演示代码中,读取人体感应传感器状态、控制LED,都基于main.c中的基础。把main.c中的IOT_CLOUD_ENABLE设置为1,就能启用IoT部分的代码。

五、运行效果:

因为是演示,所以要遵循一定的使用流程:

  1. 先将整套设备,置于不容易被人体感应误触的地方和方向
  2. 用手滑过E53_IS1对应的人体感应传感器,该扩展板上的指示灯会亮,表示感应到了;表示经过了蹲位的门
  3. 再用手滑过PIR人体感应传感器,该传感器上的指示灯会亮,同时,LED1会亮;表示正式如厕。
  4. 用微信的腾讯连连,打开对应的调试界面,就会看到蹲位的占用情况,以及计数情况;可以点蹲位警告灯,此时LED2会亮,以示警告。
  5. 经过一段时间后,再用手滑过E53_IS1对应的人体感应传感器,该扩展板上的指示灯会亮,表示感应到了,同时LED1会熄灭;表示如厕完毕,走人了。

六、后续展望

目前完成的功能,还比较基础。后续进一步完善的话,会更换人体感应传感器,用单个传感器,持续感应即可。

另外,还可以通过附带的屏幕,展示当前蹲位的情况,让想要如厕的同事一目了然。

当然,这个项目只是一个趣味型的实例,可以很方便的切换到其他场景使用。

0 人点赞