少年恃险若平地,独倚长剑凌清秋。这篇文章主要讲述#星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例)相关的知识,希望能为你提供帮助。
??本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0??
1. 项目来源
有一天半夜宿舍门被一个喝晕的哥们打开了,(说他晕吧他居然知道钥匙在门框上)于是有了设计自动门锁的想法。正好一直想用Hi3861做一个iot落地项目【之前挖的坑】,一切刚好!
2. 需求分析
无钥匙进入
手机端操作
不影响使用钥匙开门
无损安装、卸载自动开门机构
3. 宿舍门锁考察
水平向右移动拉闩1cm左右即可开门,由于宿舍们老旧,拉力实测在2.5L水左右。经过粗略计算,如果使用9g舵机来驱动,单杠驱动结构的话,杠杆长度比为2500/9≈278,尺寸有些夸张。不想在机械结构上费时间,所以选取大扭矩舵机驱动。
4.方案设计
4.1 机械结构
典型的曲柄滑块结构。选取了绳索拉动、连杆方案。综合考虑耐用度和安装便携性,选取绳索驱动方案。
使用套壳的方式安装在门锁体上,拉闩自由移动,不影响手动开门。
4.2 控制逻辑
Hi3861根据web端发送过来的质量控制舵机转动即可。控制信号来源于web端,采用MQTT协议来处理数据,电源使用5V 2A模块,一路单独给舵机。
5. 软件层
5.1 MQTT移值
这个直接参考连老师的这篇文章【??如何在鸿蒙系统中移植 Paho-MQTT 实现MQTT协议??】即可,感谢连老师!
本项目只需要将:服务器地址改为自己的IP、订阅自己web端的Topic、提取消息数据。
主要代码如下:
/*连接web端只展示主要逻辑,完整见附件*/
int mqtt_connect(void)
//0.连接web端
char* payload = "Hello Kun,have a Nice Day!";
int payloadlen = strlen(payload);
int len = 0;
char *host = "192.168.xxx.xx";
//自己的ip
int port = 1883;
//mqtt服务端口
mysock = transport_open(host, port);
/* 1.订阅web端话题*/
topicString.cstring = "porsche";
if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK)/* wait for suback */
rc = MQTTDeserialize_suback(&
submsgid, 1, &
subcount, &
granted_qos, buf, buflen);
/*2. 循环接收发布者的话题消息 */
topicString.cstring = "hi3861";
char door_passward[] ="notfound404";
//开门密令
char cmd_msg[12];
//存储web端发来的数据
while (!toStop)
if (MQTTPacket_read(buf, buflen, transport_getdata) == PUBLISH)
MQTTString receivedTopic;
rc = MQTTDeserialize_publish(&
dup, &
qos, &
retained, &
msgid, &
receivedTopic,
&
payload_in, &
payloadlen_in, buf, buflen);
for ( i = 0;
i <
payloadlen_in;
i++)
cmd_msg[i]=*payload_in;
//save message from MQTT web
payload_in++;
//pointer
printf("%c",cmd_msg[i]);
printf("cmd_msg:%s\\n",cmd_msg);
5.2 .舵机控制
Hi3861控制舵机之前【??这篇文章??】有配置过,调整20ms控制周期内高电平的占空比模拟PWM代码如下,进行了一下简单的封装,使用哪个IO口记得要初始化输出即可。
/** * @briefServocontrol *
@param servoID number of servo (GPIO) 7-8-9-10 *
@param angleinput value: 0-200 *
*/
void My_servo(uint8_t servoID,int angle)
int j=0;
int k=2000/200;
//实际应该是2000/180
angle = k*angle;
for (j=0;
j<
5;
j++)
GpiosetOutputVal(servoID, 1);
hi_udelay(angle);
//angle ms
GpioSetOutputVal(servoID, 0);
hi_udelay(20000-angle);
//
//20ms 控制舵机
5.3 业务逻辑
获取web端数据、匹配开门密令是否一致、一致则开门、每次输入密令可以开门三次、也可以一键上锁。
项目完整工程见?附件1?主要代码如下:
/*逻辑代码为了适应另外一个iot项目。看起来比较臃肿,但能用*/
int count =3; //开门次数
switch (cmd_msg[0])
case a: //一键开门
printf("up\\n");
cmd_msg[0]=n;
break;
case z: //一键上锁
printf("down\\n");
cmd_msg[0]=p;
count = 3;
break;
case s: //连接上led闪烁
printf("Start\\n");
GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
usleep(LED_INTERVAL_TIME_US);
GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
usleep(LED_INTERVAL_TIME_US);
break;
default:
break;
if(!(strcmp(cmd_msg,door_passward)))
if(count)
count --;
printf("Open the Door!\\n");
My_servo(10,100);
else count = 0;
else
printf("Close the Door!\\n");
My_servo(10,50);
6. 测试 【??见视频-3min10s??】
7. 其他案例
7.1 心率传感器
使用I2C通信,查看数据手册后,更具时许来读取数据,比较简单,参考MPU6050的读取方式。
这里展示一下读取max30102原始数据的函数,完整资源见附件2。代码如下:
/**
* @brief Send Write command to MAX30102 device before Read a register.
* @param regAddr the register address to Read or Writen.
* @return Returns@link IOT_SUCCESS if the operation is successful;
*returns an error code defined in @link iot_errno.h otherwise.
* */
uint8_t MAX_Cmd(uint8_t regAddr)
hi_i2c_idx id = MAX_I2C_IDX;
uint8_t buffer[] = regAddr;
hi_i2c_data i2cData;
i2cData.receive_buf = NULL;
i2cData.receive_len = 0;
i2cData.send_buf = buffer;
i2cData.send_len = sizeof(buffer)/sizeof(buffer[0]);
return hi_i2c_write((hi_i2c_idx)id, MAX30102_WR_address, &
i2cData);
//==发送器件地址+写命令 + 寄存器regAddr
/**
* @brief Read a data byte fromMAX30102 device.
* @paramregAddr the register address.8bit data
* @return *data
* */
uint32_t MAX_Read_Data(uint8_t regAddr, uint8_t *data, unsigned int dataLen)
hi_i2c_idx id = MAX_I2C_IDX;
hi_i2c_data i2cData;
i2cData.send_buf = NULL;
i2cData.send_len = 0;
i2cData.receive_buf = data;
i2cData.receive_len = dataLen;
MAX_Cmd(regAddr);
// write device add 0xAE + reg_ADD [目标寄存器]
return hi_i2c_read((hi_i2c_idx)id, I2C_READ_ADDR, &
i2cData);
/**
* @brief read FIFO data in max30102 FIFO register 0x07
*
* @param RED_channel_data
* @param IR_channel_data
*/
void max30102_FIFO_Read_Data(uint8_t *RED_channel_data, uint8_t *IR_channel_data)
uint8_t buff[6];
//LSB
/*组合数据
uint8_t H,M,L;
H=buff[0]&
0x03;
//bit17-bit16
M=buff[1];
//bit8-bit15
L=buff[2];
//bit0-bit7
*RED_channel_data = https://www.songbingjia.com/android/(H<
<
16)|(M<
<
8)|L;
*/
int res;
res=MAX_Read_Data(REG_FIFO_DATA, &
buff ,6);
if(res == IOT_SUCCESS)
*RED_channel_data=https://www.songbingjia.com/android/((buff[0]<
<
16)|(buff[1]<
<
8)|(buff[2]) &
0x03ffff);
//buff[0-2] 组合
*IR_channel_data=https://www.songbingjia.com/android/((buff[3]<
<
16)|(buff[4]<
<
8)|(buff[5]) &
0x03ffff);
//buff[3-5] 组合
读取到的数据:
?
7.2 Hi3861-润和套件开发案例
套件的模块除了NFC之外,其他都开发了一遍,不一一细说了,具体内容见附件3-个人开发PPT。
结语:
NFC开门是不是更加便捷呢? 手里没有运行HarmoneyOS的手机,软总线方案技术上自己估计做不到,先做做硬件层的吧,下一步抽空实现,只要有NFC功能的手机都可开门~估计得明年喽
??附件2_max30102_demo.zip??
??个人开发记录(基于Harmony2.0)by_Helloku.pptx??
??hi3861-iot-auto-door-lock.zip??
??想了解更多关于鸿蒙的内容,请访问:??
??51CTO和华为官方合作共建的鸿蒙技术社区??
??https://harmonyos.51cto.com/#bkwz??
?
【#星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例)】
推荐阅读
- AzureVMPowerShell 批量创建VM
- 14前缀树
- Airflow 2.2.3 + MySQL 8.0.27 + Redis 6.2 部署Airflow任务调度平台
- Linux之目录结构
- 使用Jenkins更改文件所有权
- 在自定义CSS WP中更改元素样式
- 将Bootstrap下拉菜单类更改为WordPress子菜单类
- WordPress帖子可以动态渲染吗()
- 无法使用remove_action()从wordpress WooCommerce钩子中删除函数