【ElfBoard】基于 Linux 的智能家居小项目

2024-02-29 07:44

本文主要是介绍【ElfBoard】基于 Linux 的智能家居小项目,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是 Hello阿尔法,这段时间参与了保定飞凌嵌入式技术有限公司举办的 ElfBoard 共创社招募活动,并有幸成为了一名共创官,官方寄来了一块 ELF 1 开发板,开箱看这里 ELF 1 开箱初体验。

作为共创官,我使用 ELF 1 完成了一个智能家居的小项目。除了 ELF 1 开发板之外,还使用了一块其他厂商的 Linux 开发板 IMX6U,主要原因是在多次抽奖中都没有抽中显示屏,只有我的 IMX6U 有屏幕,其实这样也正好符合项目背景,带有屏幕的 IMX6U 作为智能家居的控制面板,ELF 1 作为被控终端设备,它可以是电灯、电扇、空调器,也可以是冰箱、彩电、洗衣机……实现效果如下图所示:

项目简介

IMX6U 模拟智能家居中的主控面板,实时刷新显示时间、天气、空气质量、温湿度等信息,实现对家居设备电灯、窗帘、通风扇的控制,天气数据来自于心知天气;ELF 1 模拟终端设备,三个 LED 分别代表电灯、窗帘、通风扇,ADC 模拟空气质量检测器,温湿度则用来检测环境中的温湿度。IMX6U 和 ELF 1 两者通过以太网实现交互,ELF 1 和 IMX6U 均基于 Linux 系统开发,资源使用情况如下所示:

  • ELF 1 开发板:3 个 LED、ADC、温湿度传感器、以太网口
  • IMX6U 开发板:5inch RGB 显示屏、以太网口

IMX6U 工程

  • IMX6U 源码工程结构如图所示:

  • IMX6U 源码工程以 LVGL 的 Linux 移植工程为基础,具体实现请阅读 嵌入式 Linux 下的 LVGL 移植;
  • app 文件夹存放应用源码;
  • build 文件夹为编译输出目录;
  • ui 文件夹存放 UI 界面源码,具体实现请阅读 基于 LVGL 使用 SquareLine Studio 快速设计 UI 界面。

app

  • app 文件夹包括有 cJSON 解析器、通信协议 Protocol、网络编程接口 Socket、天气获取、按键以及时间、温湿度数据更新等;
  • cJSON 是使用了一个开源的、C 语言编写的超轻量级 JSON 解析器;
  • 关于 Protocol 请阅读 一个简洁实用的自定义通信协议;
  • socket 文件夹主要内容为 TCP 服务端和客户端的创建,请阅读 Linux 下 socket 编程介绍及 TCP 客户端与服务端创建示例
  • 天气数据通过心知天气 API 获取,相关实现代码如下:
// weather.c
int weather_init(void)
{weather_client_fd = client_init_socket();/* 组合 GET 请求 */sprintf(weather_buffer, GET_REQUEST_PACKAGE, DAILY_JSON, API_KEY, WUHAN);/* 发送请求 */client_send_data(weather_client_fd, weather_buffer, strlen(weather_buffer));/* 接收天气数据 JSON 格式*/client_receive_data(weather_client_fd, weather_json, &weather_json_size);/* 解析天气数据 */cJSON_Daily_WeatherParse(weather_json, &Weather_now);/* 更新天气显示 */memset(weather_buffer, 0, BUFFER_SIZE);sprintf(weather_buffer, "%s / %s", Weather_now.text_day[0], Weather_now.text_night[0]);lv_label_set_text(ui_TextDay, weather_buffer);lv_label_set_text(ui_MinTemp, Weather_now.low[0]);lv_label_set_text(ui_MaxTemp, Weather_now.high[0]);lv_label_set_text(ui_outHum, Weather_now.humidity[0]);/* 更新天气图片 */int code = *Weather_now.code_day[0] - 48;switch (code){case 0: lv_img_set_src(ui_weatherImg, &ui_img_icons_00_png); break;......case 99: lv_img_set_src(ui_weatherImg, &ui_img_icons_99_png); break;default: break;}client_close_socket(weather_client_fd);return 0;
}
  • 以按键为例,实现数据打包、发送相关代码:
static void led_ryg_turn(int cmd, int code)
{/* 组合命令 */msg_frame_t led_msg_frame;led_msg_frame.type = LED_RYG;led_msg_frame.cmd = cmd;led_msg_frame.code = code;led_msg_frame.datalen = 0;/* 打包命令 */msg_buf_t *_msg_buf = pkg_frame(&led_msg_frame);/* 发送按键命令 */server_send_data(client_fd, (char *)_msg_buf->buf_ptr, _msg_buf->buf_size);
}static void btn1_click_cb(lv_event_t *event) 
{printf("Button1 clicked\n");static char flag = 0;if(flag == 0){flag = 1;led_ryg_turn(LED_R, LED_ON);}else{flag = 0;led_ryg_turn(LED_R, LED_OFF);}
}static void btn2_click_cb(lv_event_t *event) 
{// ...
}static void btn3_click_cb(lv_event_t *event) 
{// ...
}int button_init(void)
{lv_obj_add_event_cb(ui_Button1, btn1_click_cb, LV_EVENT_CLICKED, NULL);lv_obj_add_event_cb(ui_Button2, btn2_click_cb, LV_EVENT_CLICKED, NULL);lv_obj_add_event_cb(ui_Button3, btn3_click_cb, LV_EVENT_CLICKED, NULL);return 0;
}
  • 数据接收、解析、命令执行相关代码:
static int ctrl_dev_aht20(msg_frame_t *_msg_pack)
{// ...return 0;
}static int ctrl_dev_adc(msg_frame_t *_msg_pack)
{printf("--- ctrl_dev_adc ---\r\n");uint16_t adc_raw = (uint16_t)(_msg_pack->data[0] << 8) + _msg_pack->data[1];uint8_t pm2_5 = adc_raw / 16;char pm2_5_src[4];printf("adc raw value: %d, pm2_5 value: %d \r\n", adc_raw, pm2_5);lv_arc_set_value(ui_Air, pm2_5);snprintf(pm2_5_src, sizeof(pm2_5_src), "%d", pm2_5);lv_label_set_text(ui_AirValue, pm2_5_src);return 0;
}static int ctrl_cmd_func(const msg_pkg_t *_msg_pkg)
{printf("--- ctrl_cmd_func ---\r\n");switch(_msg_pkg->pkg->type){case AHT20: ctrl_dev_aht20(_msg_pkg->pkg); break;case ADC: ctrl_dev_adc(_msg_pkg->pkg); break;default: return -1;}return 0; 
}static void *recv_thread(void *arg)
{recv_msg_buf->buf_ptr=recv_msg_buf->buf;while(1){if(server_receive_data(client_fd, (char *)recv_msg_buf->buf_ptr, (ssize_t *)&recv_msg_buf->buf_size) == 0){printf("thread recv \r\n");msg_buf_print(recv_msg_buf);/* 解析数据包命令 */msg_pkg_t *_msg_pkg = unpkg_frame(recv_msg_buf->buf_ptr, recv_msg_buf->buf_size);/* 执行命令 */ctrl_cmd_func(_msg_pkg);} }return NULL;
}/* 线程创建 */
pthread_create(&recv_thread_id, NULL, recv_thread, NULL);

ELF 1 工程

  • ELF 1 源码工程结构如图所示:

  • src 文件夹存放源文件,inc 文件夹存放头文件,obj 为编译输出目录;
  • 客户端创建、数据打包、发送、接收、命令执行与 IMX6U 工程实现类似,不再介绍,数据采集、LED 控制采用文件操作实现。

功能演示

  • 抖音视频链接

更多内容

  • CSDN博客:@Hello阿尔法
  • 哔哩哔哩:@Hello阿尔法
  • 知乎:@Hello阿尔法

这篇关于【ElfBoard】基于 Linux 的智能家居小项目的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/758040

相关文章

Linux配置IP地址的三种实现方式

《Linux配置IP地址的三种实现方式》:本文主要介绍Linux配置IP地址的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录环境RedHat9第一种安装 直接配置网卡文件第二种方式 nmcli(Networkmanager command-line

Ubuntu中Nginx虚拟主机设置的项目实践

《Ubuntu中Nginx虚拟主机设置的项目实践》通过配置虚拟主机,可以在同一台服务器上运行多个独立的网站,本文主要介绍了Ubuntu中Nginx虚拟主机设置的项目实践,具有一定的参考价值,感兴趣的可... 目录简介安装 Nginx创建虚拟主机1. 创建网站目录2. 创建默认索引文件3. 配置 Nginx4

Linux下修改hostname的三种实现方式

《Linux下修改hostname的三种实现方式》:本文主要介绍Linux下修改hostname的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下修改ho编程stname三种方式方法1:修改配置文件方法2:hFvEWEostnamectl命

Linux虚拟机不显示IP地址的解决方法(亲测有效)

《Linux虚拟机不显示IP地址的解决方法(亲测有效)》本文主要介绍了通过VMware新装的Linux系统没有IP地址的解决方法,主要步骤包括:关闭虚拟机、打开VM虚拟网络编辑器、还原VMnet8或修... 目录前言步骤0.问题情况1.关闭虚拟机2.China编程打开VM虚拟网络编辑器3.1 方法一:点击还原VM

Linux搭建Mysql主从同步的教程

《Linux搭建Mysql主从同步的教程》:本文主要介绍Linux搭建Mysql主从同步的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux搭建mysql主从同步1.启动mysql服务2.修改Mysql主库配置文件/etc/my.cnf3.重启主库my

SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法

《SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法》本文主要介绍了SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法,具有一定的参考价值,感兴趣的可以了解一下... 目录方法1:更改IDE配置方法2:在Eclipse中清理项目方法3:使用Maven命令行在开发Sprin

Linux系统之authconfig命令的使用解读

《Linux系统之authconfig命令的使用解读》authconfig是一个用于配置Linux系统身份验证和账户管理设置的命令行工具,主要用于RedHat系列的Linux发行版,它提供了一系列选项... 目录linux authconfig命令的使用基本语法常用选项示例总结Linux authconfi

Nginx实现高并发的项目实践

《Nginx实现高并发的项目实践》本文主要介绍了Nginx实现高并发的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用最新稳定版本的Nginx合理配置工作进程(workers)配置工作进程连接数(worker_co

jdk21下载、安装详细教程(Windows、Linux、macOS)

《jdk21下载、安装详细教程(Windows、Linux、macOS)》本文介绍了OpenJDK21的下载地址和安装步骤,包括Windows、Linux和macOS平台,下载后解压并设置环境变量,最... 目录1、官网2、下载openjdk3、安装4、验证1、官网官网地址:OpenJDK下载地址:Ar

linux本机进程间通信之UDS详解

《linux本机进程间通信之UDS详解》文章介绍了Unix域套接字(UDS)的使用方法,这是一种在同一台主机上不同进程间通信的方式,UDS支持三种套接字类型:SOCK_STREAM、SOCK_DGRA... 目录基础概念本机进程间通信socket实现AF_INET数据收发示意图AF_Unix数据收发流程图A