6个嵌入式项目交流分享(部分可提供完整源码)
牛客高级系列专栏
安卓(安卓系统开发也要掌握)
- 想通关安卓面试,请看:《150道安卓高频面试题目录及答案链接》
- 想通关安卓系统面试,请看:《140道安卓系统Framework面试题目录及答案链接》
- 想进阶安卓开发,请看:《Android进阶知识体系解析_15大安卓进阶必备知识点》
- 想了解安卓APP完整开发流程,请看:《安卓APP完整开发流程》
- 想掌握安卓App性能优化,请看:《安卓性能优化讲解和实战专栏》
- 想掌握Gradle语法,制作Gradle插件,请看:《安卓Gradle语法解析和实践大全》
嵌入式
- 想通关嵌入式面试,请看(承诺免费技术答疑): 《111道嵌入式面试题目录及答案链接》
- 想多掌握几个嵌入式项目,请看:《6个嵌入式项目交流分享(附源码)》
简介
本人2020年本硕毕业于广东工业大学:嵌入式许乔丹,牛客高级专栏作者,牛客大学讲师,本科阶段搞了4年单片机、曾参加全国大学生恩智浦汽车竞赛,发表4个硬件专利。研究生阶段找了嵌入式linux的实习,毕业后拿到珠海格力,云从科技,CVTE,小米,美的,华为的嵌入式offer,签约CVTE嵌入式岗位。
在CVTE先后做过嵌入式Linux开发和安卓系统开发,参与过TV板卡、显示屏板卡、智能家居板卡、希沃网课学习机的开发。
整理111道嵌入式面试题目答案解析(链接见文章开头),本专栏内容主要是面试过程口头提问的问题答案汇总,也有C++资料和笔试真试题:
⭐ 不要评论区回复私人邮箱!!有事私聊即可!
做项目的思路是:视频/书+开发板+百度
项目一:基于Linux6818开发版的视频播放器(可提供源码)
1、 项目描述
本项目基于嵌入式linux6818开发板,制作一个音视频播放器。开发板移植安装好mplayer,我提前下载了5个mv,使用mplayer命令分别在5个视频里截取某一秒的画面,共得到5张图片,也就是所谓的视频缩略图,将5个缩略图显示在显示屏的右边,当作是播放列表,支持上下滑动浏览播放列表,点击其中某个图片,即可播放对应视频,并实现播放器常见的开始、停止、上下首、音量调节、进度调节、全屏、静音等功能。
2、使用到的技术
● 多进程通讯:有名管道、消息队列、信号量;
● 多线程通讯:互斥锁、条件变量;
● 其他知识:C语言、链表、嵌入式开发;
● mplayer:mplayer移植(自行百度,很多资料,跟着敲指令即可),语法(可参考:https://blog.csdn.net/weixin_43288201/article/details/105847664);
3、推荐人群
该项目适合正在学习嵌入式Linux系统编程的同学,可以让你更高效了解多进程、多线程通讯,如消息队列,信号量,互斥锁、条件变量等知识点。
4、 项目源码讲解
4.1 运行
在命令行输入:./app video 即可。
其中app是源码通过makefile编译出来的可执行文件,video是你自己去创建的一个目录,里面放着各种mp4视频,我这边没有提供这个目录。
4.2 文件目录
4.2.1 src目录
main.c:主文件
secondary.c:副文件
pthread.c:子线程文件
lcd.c:对lcd显示屏的操作文件
freetype.c:字符操作文件
file_list.c:对照片的操作的文件,如如何打印,打印下一张或者上一张
display_jpeg.c:存放对jpeg图片的打印函数,包括特效打印
4.2.2 include目录
src目录中的c文件对应的头文件,以及jpeg图像和freetype2字符库相关的头文件。
4.2.3 lib目录
jpeg图片库和freetype2字符库(本项目需要在显示屏显示图片和显示字符)。
4.2.4 data目录
simsun.ttc :宋体库,为了在屏幕上显示中文。
4.2.5 material目录
我在百度找到的一些图片,比如开始播放,停止播放的jpg图片。
4.3 源码逻辑
1、在main.c文件的主函数先初始化各种互斥锁,条件变量,FIFO管道,并且遍历material目录下的图片信息,主要是获取图片的像素信息,如图片高度/宽度。接着遍历video视频目录里的视频,获取视频信息,以及获取每个视频的一帧截图,遍历的结果都是放在链表里面;
2、 初始化显示屏,并在显示屏上面:如right_display_picture()是在显示屏右边将视频截图显示出来,然后就可以点击每个截图来播放对应的视频;display_main_material()把material目录下的图片显示在屏幕上,
3、 创建一个子进程,并使用mplayer播放视频;
4、 创建3个子线程,这三个子线程的代码在pthread.c :
1)查询触屏指令的get_main_instrcution()
2)写指令来获取视频播放进度的write_command():该子线程一直写{"get_percent_pos\n","get_time_length\n"}来查询播放进度,为何是写这个指令,是mplayer工具规定的。可见上述参考链接;
3)获取视频播放进度信息的get_video_info():通过write_command和get_video_info两个子线程,就能实时获取播放进度,实时更新进度条啦。
5、 最后就是在主函数的while循环里,等待get_main_instrcution子线程有触摸事件后,主函数再去执行对应操作,如“下一首”,“静音”等。
以下是main函数,其他源码有偿提供:
#include <file_list.h> #include <lcd.h> #include <display_jpeg.h> #include <pthread.h> int main(int argc, const char *argv[]) { int lcd_fd; //打开lcd设备 int retval; int first_video_pid;//打开播放第一个视频的pid g_wWrite_command_flg = 1; g_wPrint_type = 0; /***************初始化互斥锁和条件变量***********/ pthread_mutex_init(&g_write_command_m,NULL); pthread_cond_init(&g_write_command_v,NULL); pthread_mutex_init(&g_main_instruction_m,NULL); pthread_cond_init(&g_main_instruction_v,NULL); /**********创建保存文件信息的链表并初始化*********/ g_video_head_node = create_file_link_init(); /**********遍历整个目录,将视频文件保存下来********/ retval = list_for_all_file(argv[1],g_video_head_node); PrintError(retval,"list for all file failed"); /**********创建保存jpeg信息的链表并初始化*********/ g_jpeg_head_node = create_jpeg_link_init(); /**********遍历整个目录,将jepg文件保存下来*******/ retval = list_for_all_jpeg_file("material",g_jpeg_head_node); PrintError(retval,"list for all jpeg file failed"); /**********打开lcd设备,获得地址映射地址**********/ lcd_fd = open_lcd_device(&p_wLcd_fb_ptr); PrintError(lcd_fd,"open lcd failed"); /****************创建有名管道*******************/ OpenFifo(PATH_COMMAND); OpenFifo(PATH_INFORMATION); /*************打开写命令的FIFO******************/ int fifo_command_fd = open(PATH_COMMAND, O_RDWR); PrintError(fifo_command_fd,"open fifo error"); /***************打开获得触屏指令的POSIX有名信号量********************/ sem_t *g_main_instruction_sem; g_main_instruction_sem = sem_open(MAIN_SEMNAME, O_CREAT, 0777, 0); /**************逐一显示一帧图片 检验遍历目录是否正确*************** display_all_jpeg(p_wLcd_fb_ptr, g_video_head_node); */ /**************在lcd右边打印预览界面,获得指向当前图像的指针**********/ g_now_jpeg_pos = (&(g_video_head_node->list))->next; right_display_picture(p_wLcd_fb_ptr,g_now_jpeg_pos,g_video_head_node); /******************创建子进程,播放第一个视频*******************/ g_now_play_pos = g_now_jpeg_pos; first_video_pid = fork(); if(first_video_pid == 0) { int fifo_fd2; fifo_fd2 = open(PATH_INFORMATION, O_RDWR); dup2(fifo_fd2,STDOUT_FILENO); linklist_t ptr; ptr = list_entry(g_now_play_pos, linknode_t, list); execlp("mplayer","mplayer","-slave","-quiet","-input","file=/tmp/videoplayer/myfifo","-geometry",\ "0:0","-zoom","-x","610","-y","370",ptr->info.file_name,NULL); exit(0); } waitpid(first_video_pid,NULL,WNOHANG); //非阻塞等待 /***************打开查询触屏、写指令、读视频信息的3个线程*****************/ pthread_t get_main_instrcution_tid; pthread_create(&get_main_instrcution_tid, NULL, get_main_instrcution, NULL); pthread_t write_command_tid; pthread_create(&write_command_tid, NULL, write_command, NULL); pthread_t get_video_info_tid; pthread_create(&get_video_info_tid, NULL, get_video_info, (void*)p_wLcd_fb_ptr); /********打印素材图片*******/ display_main_material(p_wLcd_fb_ptr,g_jpeg_head_node); /********将进度条、声音控制条的背景纯色化******************/ clean_main_rate_frame_buf(p_wLcd_fb_ptr); clean_main_sound_frame_buf(p_wLcd_fb_ptr); void *ret; /***********开始操作触摸屏*************/ int continue_flg = 1; while(continue_flg&&1) { /*****等待有触屏操作,防止重复执行上一个命令,进入死循环********/ sem_wait(g_main_instruction_sem); /************按触屏指令进行操作****************/ main_interface_control(g_main_instruction); } /******************回收线程******************/ pthread_join(get_main_instrcution_tid,NULL); pthread_join(write_command_tid,NULL); pthread_join(get_video_info_tid,NULL); /*************关闭lcd,删除视频文件链表***********/ close_lcd_device(lcd_fd, p_wLcd_fb_ptr,g_video_head_node); return 0; }
项目二:基于人脸属性识别的嵌入式电影推荐系统(研究生毕业设计、可提供源码)
1)情况:为解决“信息过载”问题,提出基于人脸属性识别的广告推荐系统。
2)目标:独立负责,摄像头捕捉人脸并预测年龄、性别,显示屏可输入用户职业,系统根据此三大信息推荐8部电影并在显示屏显示。
3)行动:搭建RK3399开发板开发环境,通过OpenCV获取摄像头图像,Dlib检测人脸,采用WRN神经网络预测年龄、性别,结合基于用户的协同过滤以及决策树模型进行电影推荐。使用PyQt5设计人机交互界面实现职业获取和电影信息显示。
4)成果:在RK3399开发板可实时获取被推荐人年龄、性别、职业,据此推荐8部电影并将其电影名字和海报图显示在屏幕上。
这是我研究生毕业设计,上面的介绍采用STAR法则,该法则适用于简历项目编写和面试时的项目介绍,是在简历中复制黏贴过来。采用RK3399开发板,搭配一个USB摄像头,可在人机交互界面选择自己的职业,并按下人机交互界面上的“start”按键,探测出出人脸,并进行年龄性别的预测,系统根据年龄、性别、职业三大信息,推荐出8部电影出来。
其中摄像头采用OpenCV的API函数可直接获取图像,采用Dlib库可以探测出人脸,采用宽残差神经网络可预测人脸的年龄性别,电影推荐采用MovieLens轻量级数据库,该数据集包含6040位样本用户对约4000部电影的近100万条评分以及每位用户的信息,电影推荐的思想是:首先,通过基于用户的协同过滤算法为6040位样本用户各自推荐出8部该用户可能喜欢的电影。接着,根据得到的被推荐人的年龄、性别、职业三大信息,在6040位样本用户里找出与被推荐人最接近的若干个用户组成相似用户群。将相似用户群所有样本用户已推荐的所有电影送入事先训练好的决策树模型,可进一步筛选出最可能是被推荐用户喜欢的8部电影。
大概的思想差不多这样子,需要的技术有Pyhon、开发板环境搭建,OpenCV和Dlib库的简单API函数调用,卷积神经网络(我只会嵌入式当时恶补了这个知识)、Python QT设计人机交互界面、网络爬虫爬取电影中文名和海报图(MovieLens数据集只有电影英文名)。如果对在嵌入式开发板实现人工智能算法的同学可以咨询我。
推荐人群
:该项目的方向(嵌入式人工智能)适合研究生毕业课题(我做的深度还不够深,还有很多需要改善的)以及在学校是学习
算法但毕业想往嵌入式方向靠拢的同学。
项目三:全国大学生“恩智浦”杯智能汽车竞赛 (大学生竞赛/两届)
1)全国大学生五大电子竞赛之一,追逐组难度最高。制作两部可自动识别路径的智能车,并在规定区域实现自主超车。
2)任队长。主要负责软件代码和控制算法,参与硬件设计和机械方面的调整。
3)负责路径提取、舵机电机控制算法的设计和调试,并改用150度广角镜头,较上一年的代码适应性提高30%。独立调试分离式超声波模块,实现360度测距;使用NRF24L01无线模块实现双车通讯。改进速度PID,并结合阿克曼差速定理,速度可达2.4m/s,并成功完成3次追逐。
4)代表学校赴中南大学参加华南赛,荣获华南赛追逐组二等奖。
解析:这应该是做嵌入式的同学都听过或者参加甚至跟我一样参加了2年的大学生竞赛,我负责的是软件代码的编写,主要是路径提取、舵机和电机控制算法的设计和调试,相信其他做软件编写的同学也是大概分成这3部分,有一个是 知识点和技巧 是,大部分负责代码编写的同学,其实不懂摄像头如何获取图像以及无线模块通讯的原理,至少我本人是直接可以通过“野火”商家提供的模板代码,直接获得摄像头所采集的图像数据,其实是一个二位数组,也可以直接实现了无线模块之间的数据通信,但我并不知道其底层原理,所以技巧就是在介绍项目的时候直接和面试管说我做的是得到图像数据后如何去提取路径,无线模块可以通讯后,如何进行两辆车直接的通讯(我参加的是双车追逐组,第11届首次出现双车),直接承认不懂底层原理,将面试官关注点集中在我们的三大软件代码,讲我们懂的,避开不懂(问我摄像头驱动,无线通讯原理我就跪了)。
推荐人群:参加过该比赛的同学或者想了解的。
项目四:视频网络聊天工具(课外作品)
1)使用嵌入式linux6818开发板和PC机,基于QT实现一个仿QQ视频网络聊天工具。
2)独立负责,实现好友文字聊天,视频对接,文件传送,以及可修改密码,账号绑定和找回功能(QQ基本功能)。
3)QT界面设计,摄像头采集图像,制定数据传输和解析协议,采用TCP通讯协议,传输文件和文字,编程采用线程池技术,实现多线程,采用SqLite数据库,存储账号密码以及聊天记录。
4)实现了开发板与PC机之间,可进行仿QQ的聊天功能。
解析
没错,也是简历上复制下来的哈。这是我学习QT的时候自己摸索出来的小作品(放在简历最末尾凑数),使用的是一个叫做粤嵌的培训机构的6818开发板,当时是跟一个本科的师弟买的,咸鱼上面也有人卖, 是一个很适合入门的开发板,当时看的QT视频我已经找不到了,不过网上一大堆学习资料,就差你去发现。开发板和电脑都要安装好QT5,我是看着视频,每教一个知识点,我就会构思我能做出什么项目,这个 学习方法也推荐各位看学习视频的同学 ,比如视频里有教怎么通过网络编程发送文字和图片,怎么使用数据库增删改查,最终就很容易联想到做一个聊天工具,所使用的技术都是教程里教的,难度不高。
推荐人群
:适合新手入门或者没项目的同学短时间内掌握。
项目五:智能家居报警系统(新手请看)
解析:
这个是我临时构思的适合学习嵌入式Linux的同学做的项目,是项目三的解析里所述的简易的“ 智能报警系统”的升级版,简单说下思路,经过考虑技术路线后,确定了方案的可行性,同样采用6818开发板,同样是采用 人体红外传感器,火焰传感器,温湿度传感器等传感器实现智能报警。都是在QT5开发环境下。
1)通过QT5设计一个人机交互界面,可进行一定程序的控制或者显示,如如按下按键,开启摄像头监控,或显示温度湿度,检测到人或者着火则打印一段话等,还有个常见的是利用网络编程,网上获取当前时间和当前地区的天气湿度。
2)可以接入USB摄像头,采集的图像显示在交互界面上。
3)我当时针对这几个简单的传感器,编写了驱动程序后直接进行内核裁剪,将驱动加入内核,不需要再次insmod进去,所以大家也可以照着这个思路做,难度不高的。
4)再拓展下去就可以使用QT数据库编程,纪录一些信息,比如有没有检测到人或着火,时间是多少之类的。
推荐人群
:该项目适合正在入门嵌入式Linux的同学。
项目六:可自定义IO端口数量的嵌入式软PLC控制系统及其设计方法(发明专利)
1)嵌入式软PLC是架构在嵌入式系统上的软PLC,在自动化领域采用基于嵌入式系统的软PLC来代替传统硬PLC已经成为一个趋势。
2)负责控制系统硬件电路图的设计和制作,参与软件代码编写。
3) 本系统分为核心板和外围板。核心板是STM32微处理器的最小系统,并将芯片引脚与外围板引脚连通,外围板包括输入光耦隔离电路及继电器输出电路。
4) 设计出64*64固定输入/输出触点控制系统,及可以灵活配置输入/输出端口的64触点系统,后续该课题共申请3个发明专利,1个实用新型专利(已授权),并成功运用在智能炒菜机上。
解析:
这是我本科毕业设计以及研一阶段继续深入的课题,真正体现嵌入式软硬结合的特点,也是常见的项目,自己从0开始设计制作一个开发板,并烧录进代码,完成一整个系统的设计。该课题主要负责电路图设计和制作,因为只是两层板,难度不高,观看
郭天祥的Altium Designer教程
就可以,不过该课题不止我一人做,如果是完成整个系统,还需要软件代码编写,所以在此只是做个案例共参考,各位同学可以自己做一个stm32最小系统,关于电路图的设计可以参考正点原子stm32教程,我的最小系统就是参考他们的。做出一个最小系统后,可以淘宝买一些传感器,比如人体红外传感器,火焰传感器,温湿度传感器,都是非常容易用的,价格也便宜,这样子就可以自己从0搭建了一个简易的“ 智能报警系统”。同时有同学问我嵌入式 怎么发专利容易,就是从0自己做出一个系统。
推荐人群 :适合想学习或者入门硬件电路板设计搭配软件代码编写的同学。
#嵌入式#