0


智能垃圾分类垃圾桶(K210+stm32mp157)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

有需要源码参考的可以点赞在评论区留邮箱

K210识别垃圾

k210识别2

文章目录

  • 一、垃圾分类识别+舵机控制(K210)
  • 二、语音控制(K210+ld3320)(UART通信)
  • 三、满溢度距离传感器数据获取(STM32MP157)
  • 四、图像获取以及传输(STM32MP157)(UDP)

前言

最近做了一个多功能智能垃圾桶,主要用了k210开发板来做识别和控制以及用stm32mp157来做传感器数据采集以及图像传输。主要功能如下

垃圾分类识别+舵机控制

语音控制垃圾桶开关

检测垃圾桶的满溢程度

摄像头读取图像信息并通过UDP传输至客户端

一、垃圾分类识别+舵机控制

垃圾分类使用的开发板是K210

模型训练可以用mxyolov3平台,也可以用官方的训练平台(这个比较容易使用,但有数据集20M大小的限制),使用开发板前需要用KFLASH烧录.bin后缀的固件包,将训练完成的kmodel文件烧录至开发板,然后需要一段执行代码,后续的功能联调也是需要在识别代码基础上添加

识别完需要进行一些控制,不然结果也就只是结果。我在项目中通过pwm信号控制舵机转动,来识别垃圾桶的识别功能。

为了防止误判,我在识别代码里加了连续10帧检测同一物体才驱动舵机

识别控制

以下是舵机转动角度的函数,主要是改变PWM信号的占空比

  1. def Servo(servo,angle):
  2. servo.duty((angle+90)/180*10+2.5)

二、语音控制

语音控制

ld3320语音模块控制垃圾桶的开关(也就是ld3320跟K210通信,K210控制舵机转动)

ld3320跟K210通过UART串口通信

ld3320模块,识别到垃圾桶打开的指令,就通过串口向K210发送‘aa’的数据,在K210端进行UART串口信息的检测,若收到的信息为‘aa’ 就控制舵机转动

  1. read_data = uart_wifi.read()
  2. #下面是开盖 并进入检测 servo是转动角度的函数
  3. if(read_data == b'bb'):
  4. Servo(S3,-30)
  5. flag = 1;
  6. if(read_data == b'aa'):
  7. Servo(S3,60)
  8. flag = 0;

三、满溢度距离传感器数据获取(STM32MP157)

检测垃圾桶有没有满,距离检测主要用stm32mp157开发板上的ap3216c传感器。

对传感器数据的读取是读取设备文件数据,****是通过文件 I/O 的方式来实现。在应用层编写代码读取设备下的数据即可

以下为传感器数据读取的代码

  1. QString Ap3216c::readPsData()
  2. {
  3. char const *filename = "/sys/class/misc/ap3216c/ps";
  4. int err = 0;
  5. int fd;
  6. char buf[10];
  7. fd = open(filename, O_RDONLY);
  8. if(fd < 0) {
  9. close(fd);
  10. return "open file error!";
  11. }
  12. err = read(fd, buf, sizeof(buf));
  13. if (err < 0) {
  14. close(fd);
  15. return "read data error!";
  16. }
  17. close(fd);
  18. QString psValue = buf;
  19. QStringList list = psValue.split("\n");
  20. return list[0];
  21. }

四、图像获取以及传输(STM32MP157)(UDP)

获取开发板摄像头的数据,并通过UDP传输至客户端

在QT中使用UDP传输流程:

服务器端创建socket,就可以直接使用writeDatagram函数发送信息,在函数的参数中需要写入数据,数据大小接收端的IP,端口号

(使用TCP的话一般服务器端是需要创建socket,bind,listen监听,并accept客户端的connect,我们这里传输视频信息,用UDP延时会比较小,当然只是理论,我并没有测试过)

客户端创建socket,绑定自己的IP和端口号,就可以用readDatagram函数接收数据

这里就用自己的电脑作为客户端,来获取垃圾桶的实时状况。(其实这个功能只是我为了学习网络编程强加的,功能比较鸡肋,主要是学习)

服务器端的代码

  1. //摄像头通过调用opencv库获取到的数据类型为mat 需要先转成QImage类型
  2. //QImage类型的图像放入QByteArray中,然后进行base64编码的压缩
  3. //接收端在进行base64解码
  4. /* udp套接字 */
  5. QUdpSocket udpSocket;
  6. /* QByteArray类型 */
  7. QByteArray byte;
  8. /* 建立一个用于IO读写的缓冲区 */
  9. QBuffer buff(&byte);
  10. /* image转为byte的类型,再存入buff */
  11. qImage.save(&buff, "JPEG", -1);
  12. /* 转换为base64Byte类型 */
  13. QByteArray base64Byte = byte.toBase64();
  14. /* 由udpSocket以单播的形式传输数据,端口号为8888 */
  15. udpSocket.writeDatagram(base64Byte.data(), base64Byte.size(), QHostAddress("192.168.10.200"), 8888);

客户端代码

  1. udpSocket = new QUdpSocket(this);
  2. udpSocket->bind(QHostAddress("192.168.10.200"), 8888);
  3. QByteArray datagram;
  4. udpSocket->readDatagram(datagram.data(), datagram.size());
  5. //String-Base64编码转QByteArray
  6. QByteArray decryptedByte;
  7. decryptedByte = QByteArray::fromBase64(datagram.data());
  8. //比如读入一张BMP格式的文件到QByteArray对象中,再调用该函数,那么该函数就会根据QByteArray中数据进行解析,分析图像的格式等
  9. QImage image;
  10. image.loadFromData(decryptedByte);
  11. videoLabel->setPixmap(QPixmap::fromImage(image));

总结

整个的项目用了2个架构的开发板K210(RISV-C)和stm32mp157(cortex-A)

主要是为了学习一些嵌入式方面的知识,并把他实际运用上。

标签: 分类 stm32 arm

本文转载自: https://blog.csdn.net/weixin_53776127/article/details/125258823
版权归原作者 weixin_53776127 所有, 如有侵权,请联系我们删除。

“智能垃圾分类垃圾桶(K210+stm32mp157)”的评论:

还没有评论