#星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例 原创 精华

Hello_Kun
发布于 2021-12-30 12:28
浏览
7收藏

本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0

1. 项目来源
      有一天半夜宿舍门被一个喝晕的哥们打开了,(说他晕吧他居然知道钥匙在门框上)于是有了设计自动门锁的想法。正好一直想用Hi3861做一个iot落地项目【之前挖的坑】,一切刚好!

2. 需求分析
       无钥匙进入

       手机端操作

       不影响使用钥匙开门

       无损安装、卸载自动开门机构

3. 宿舍门锁考察
水平向右移动拉闩1cm左右即可开门,由于宿舍们老旧,拉力实测在2.5L水左右。经过粗略计算,如果使用9g舵机来驱动,单杠驱动结构的话,杠杆长度比为2500/9≈278,尺寸有些夸张。不想在机械结构上费时间,所以选取大扭矩舵机驱动。

 #星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例-鸿蒙开发者社区

4.方案设计

4.1 机械结构
         典型的曲柄滑块结构。选取了绳索拉动、连杆方案。综合考虑耐用度和安装便携性,选取绳索驱动方案。

         使用套壳的方式安装在门锁体上,拉闩自由移动,不影响手动开门。

 #星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例-鸿蒙开发者社区

4.2 控制逻辑
       Hi3861根据web端发送过来的质量控制舵机转动即可。控制信号来源于web端,采用MQTT协议来处理数据,电源使用5V 2A模块,一路单独给舵机。 #星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例-鸿蒙开发者社区

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口记得要初始化输出即可。

/** * @brief  Servo  control *
 @param servoID number of servo (GPIO) 7-8-9-10 * 
 @param angle  input 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

 #星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例-鸿蒙开发者社区

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 from  MAX30102 device.
 * @param  regAddr 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 = (H<<16)|(M<<8)|L; */
	int res;
	res=MAX_Read_Data(REG_FIFO_DATA, &buff ,6);
	if(res == IOT_SUCCESS)
	{
       *RED_channel_data=((buff[0]<<16)|(buff[1]<<8)|(buff[2]) & 0x03ffff);  //buff[0-2] 组合
	   *IR_channel_data=((buff[3]<<16)|(buff[4]<<8)|(buff[5]) & 0x03ffff);  //buff[3-5] 组合
	}

}

读取到的数据:

 #星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例-鸿蒙开发者社区

7.2 Hi3861-润和套件开发案例

套件的模块除了NFC之外,其他都开发了一遍,不一一细说了,具体内容见附件3-个人开发PPT。

 #星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例-鸿蒙开发者社区 #星光计划2.0# 鸿蒙设备开发Hi3861-IoT落地-自动门锁(附多案例-鸿蒙开发者社区

结语:

NFC开门是不是更加便捷呢? 手里没有运行HarmoneyOS的手机,软总线方案技术上自己估计做不到,先做做硬件层的吧,下一步抽空实现,只要有NFC功能的手机都可开门~估计得明年喽

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
附件2_max30102_demo.zip 4.94K 207次下载
个人开发记录(基于Harmony2.0)by_Helloku.pptx 76.64M 207次下载
hi3861-iot-auto-door-lock.zip 4.89K 195次下载
已于2021-12-30 12:34:37修改
8
收藏 7
回复
举报
3条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

感谢喝晕的哥们让我们看到这篇文章

已于2021-12-30 14:06:31修改
2
回复
2021-12-30 14:02:50
Hello_Kun
Hello_Kun 回复了 红叶亦知秋
感谢喝晕的哥们让我们看到这篇文章

哈哈哈,这是真事儿,那天我晚上还拍了视频,一晚上宿舍笑翻了

回复
2021-12-30 14:30:14
物联风景
物联风景

太强了,给你点赞

回复
2021-12-30 21:39:21
回复
    相关推荐