本文共 6655 字,大约阅读时间需要 22 分钟。
冬天的早上比较冷,早上6点半起不来,于是就想用这个做一个小闹钟,利用蜂鸣器响铃来强迫自己起床。
当然同时还有更多的功能,比如温湿度检测,消息推送,闹钟响铃后打开LED灯。作品功能列表:
-LCD显示温湿度
aht10采集的温湿度,ap3216c采集的光照强度和距离传感器的AD值;-NTP同步时间 板子联网后,使用netutils的NTP功能,同步时间,显示当前日期和时间到LCD上;-开发板接收红外遥控LED 开发板接收到红外遥控器的编码后将其存储,然后控制LED灯。闹钟响起后向微信(利用Server酱:http://sc.ftqq.com/3.version" target="_blank提供的接口)发送一条温湿度的信息。
利用ap3216c的接近传感器AD值判断是否开启LED
当接近传感器的AD值大于400(离得越近值越大)时,发送红外编码,控制灯的开或者关。综上,在到达闹钟设定时间(早上6点半)后,蜂鸣器响起,打开LED灯(晚上睡觉灯默认关闭),然后会往微信发送一条当前室内温湿度的信息。
aht10软件包
ap3216c软件包
EasyFlash和FAL
infrared软件包
mbedtls软件包
netutils软件包
LCD软件包
使用该软件包读取当前温湿度,用于LCD显示和微信推送;
1...2//读取温度3rt_device_read(temp_dev,0,&sensordata,1);4read_data->temperature = sensordata.data.temp;56//读取湿度7rt_device_read(humi_dev,0,&sensordata,1);8read_data->humidity = sensordata.data.humi;9...
使用该软件包读取光照和距离传感器的AD值;
1...2//读取光照强度 lux3rt_device_read(lux_dev,0,&sensordata,1);4read_data->lux = sensordata.data.light;56//读取距离(AD值 0~1023 离得越近值越大)7rt_device_read(dis_dev,0,&sensordata,1);8read_data->distance = sensordata.data.proximity;9...
距离传感器的AD值用来感应打开/关闭LED灯。
1... 2//红外控制灯的开关 3void task_auto_open_led_pro(void) 4{ 5 struct infrared_decoder_data sendvalue; 6 if(myhome_sensor.distance >= OPEN_THRESHOLD_AD_VAL) 7 { 8 //发送红外数据 9 sendvalue.data.nec.addr = 0;10 sendvalue.data.nec.key = myhome_sensor.infrared_recv[0];11 sendvalue.data.nec.repeat = 0;12 infrared_write("nec",&sendvalue);13 rt_thread_mdelay(200);14 }1516}17...
存储红外编码值,当按下红外遥控器时,接收红外编码,存储至flash。
存储WiFi名称和密码。
1... 2else if(infrared_read("nec",&recvinfrared_data) == RT_EOK) 3{ 4 myhome_sensor.infrared_recv[0] = recvinfrared_data.data.nec.key; 5 //转字符串 6 sprintf(tempvalue, "%d", recvinfrared_data.data.nec.key); 7 //保存接收的key 8 ef_set_and_save_env("led_infrared_data",tempvalue); 910 rt_pin_write(PIN_LED_B,PIN_LOW);11}12...
c
1... 2//读取数据暂存 3 openled_infrared_data = ef_get_env("led_infrared_data"); 4 //读取失败 5 if(openled_infrared_data == RT_NULL) 6 { 7 openled_infrared_data[0] = '0'; 8 } 9 //读取的红外编码值存到myhome_sensor10 myhome_sensor.infrared_recv[0] = (rt_uint8_t)atoi(openled_infrared_data);11...
发送和接收控制红外编码。
发送:1...2sendkeyvalue.data.nec.key = atoi(readtemp);3sendkeyvalue.data.nec.repeat = 0;4//发送红外数据5infrared_write("nec",&sendkeyvalue);6...
接收:
1if(infrared_read("nec",&recvinfrared_data) == RT_EOK)
用于推送消息至微信。
如果是HTTP格式的,可以直接使用webclient软件包进行post和get推送,这里因为是HTTPS,所以要使用本软件包。1... 2while ((ret = mbedtls_client_write(tls_session, (const unsigned char *) sREQUEST, rt_strlen(sREQUEST))) <= 0) 3{ 4 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) 5 { 6 rt_kprintf("mbedtls_ssl_write returned -0x%x\n", -ret); 7 goto __exit; 8 } 9}10rt_kprintf("Writing HTTP request success...\n");11...
另外在发送消息时无法直接推送中文,所以要将中文进行urlEncode编码
比如:%e4%b8%bb%e4%ba%ba%ef%bc%8c%e6%97%a9%e4%b8%8a%e5%a5%bd
编码的意思是
主人,早上好
编码的网址:urlEncode编码/解码
使用这个软件包进行时间同步,没有掉电存储时钟的情况下,使用软时钟进行时间同步。
1...2//同步网络时间3ntp_sync_to_rtc(RT_NULL);4time_t now;5now = time(RT_NULL);67tm = localtime(&now);8rt_kprintf("now time:%d-%d-%d\n", tm->tm_hour,tm->tm_min,tm->tm_sec);9...
LCD显示传感器等信息。
1... 2//第一行 3lcd_show_string(0,0,24,"temp: %3d.%d C",(tsensor)->temperature/10,(tsensor)->temperature%10); 4//第二行 5lcd_show_string(0,0+24,24,"humi: %3d.%d%%",(tsensor)->humidity/10,(tsensor)->humidity%10); 6//第三行 7lcd_show_string(0,0+24+24,24,"lux : %3d.%d(lux)",(tsensor)->lux/10,(tsensor)->lux%10); 8//第四行 9lcd_show_string(0,0+24+24+24,24,"dist: %4d",(tsensor)->distance);10...
软件流程图如下:
定义传感器结构体
1//板子传感器定义,用于LCD显示 2struct board_sensor 3{ 4 rt_int32_t temperature;//温度0.1C 5 rt_int32_t humidity; //湿度% 6 rt_int32_t lux; //光照强度LUX 7 rt_int32_t distance; //接近传感器,距离AD值 8 rt_int32_t close_flag;//靠近标志 9 rt_uint8_t infrared_recv[2];//红外编码10 struct tm *date;//日期11};12typedef struct board_sensor *home_sensor;//定义结构体指针,传参时候使用13//传感器数据结构体14extern struct board_sensor myhome_sensor;
main函数如下:
1int main(void) 2{ 3 int result = RT_EOK; 4 //当前时间 5 static struct tm *tm; 6 //读取红外编码值到临时变量 7 char *openled_infrared_data; 8 9 /* 设置 LED 引脚为输出模式 */10 rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);11 rt_pin_mode(PIN_LED_B, PIN_MODE_OUTPUT);12 //初始化蜂鸣器13 rt_pin_mode(PIN_BEEP,PIN_MODE_OUTPUT);1415 //这两个函数在wifi config.c中的wlan_autoconnect_init()初始化16 //初始化flash17 //fal_init();18 //easyflash初始化,读取红外编码1920 /* 配置 wifi 工作模式 */21 rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);22 /* 初始化 wlan 自动连接功能 */23 wlan_autoconnect_init();24 /* 使能 wlan 自动连接功能 */25 rt_wlan_config_autoreconnect(RT_TRUE);26 /* 创建 'net_ready' 信号量 */27 result = rt_sem_init(&net_ready, "net_ready", 0, RT_IPC_FLAG_FIFO);28 if (result != RT_EOK)29 {30 return -RT_ERROR;31 }32 /* 注册 wlan 连接网络成功的回调,wlan 连接网络成功后释放 'net_ready' 信号量 */33 rt_wlan_register_event_handler(RT_WLAN_EVT_READY, wlan_ready_handler, RT_NULL);34 /* 注册 wlan 网络断开连接的回调 */35 rt_wlan_register_event_handler(RT_WLAN_EVT_STA_DISCONNECTED, wlan_station_disconnect_handler, RT_NULL);3637 //读取数据暂存38 openled_infrared_data = ef_get_env("led_infrared_data");39 //读取失败40 if(openled_infrared_data == RT_NULL)41 {42 openled_infrared_data[0] = '0';43 }44 //读取的红外编码值存到myhome_sensor45 myhome_sensor.infrared_recv[0] = (rt_uint8_t)atoi(openled_infrared_data);4647 //lcd init48 lcd_clear(WHITE);49 lcd_set_color(WHITE,BLACK);5051 //查找传感器并打开,采集数据52 sensor_pro_thread_create();5354 //创建infrared处理线程并启动55 infrared_pro_thread_create();5657 //lcd显示线程创建并启动58 lcd_dis_thread_create();59 //事件处理60 event_pro_thread_create();6162 /* 等待 wlan 连接网络成功 */63 result = rt_sem_take(&net_ready, RT_WAITING_FOREVER);64 if (result != RT_EOK)65 {66 LOG_E("Wait net ready failed!");67 rt_sem_delete(&net_ready);68 return -RT_ERROR;69 }70 else71 {72 //同步网络时间73 ntp_sync_to_rtc(RT_NULL);74 time_t now;75 now = time(RT_NULL);7677 tm = localtime(&now);78 rt_kprintf("now time:%d-%d-%d\n", tm->tm_hour,tm->tm_min,tm->tm_sec);79 }80}
github:https://github.com/Rayuu/W601_RT-thread_Alarm(请复制至外部浏览器打开)
本期分享来自RT-Thread软件包大赛三等奖获得者熊昌昱,如果你也有文章愿意分享/希望获得官方的写作指导,可以发送文章/联系方式邮件至邮箱:xuqianqian@rt-thread.com
往期回顾
1.
7.
你可以添加微信17775982065为好友,注明:公司+姓名,拉进 RT-Thread 官方微信交流群!
RT-Thread
让物联网终端的开发变得简单、快速,芯片的价值得到最大化发挥。Apache2.0协议,可免费在商业产品中使用,不需要公布源码,无潜在商业风险。长按二维码,关注我们
点击阅读原文,进入RT-Thread GitHub首页
你点的每个“在看”,我都认真当成了喜欢
转载地址:http://honef.baihongyu.com/