单片机串口控制树莓派3B播放HDMI视频,omxplayer,

2023-11-13

使用树莓派3B通过HDMI播放视频。并且使用串口去控制播放哪个视频。

 

1. 问题解耦

单片机串口控制树莓派3B播放视频? = 树莓派播放视频 + 单片机串口传参控制树莓派

  • 树莓派播放视频:树莓派播放视频,并且能用串口这种简单的通信方式去控制。应该是需要安装一个,只要命令行就可以控制的视频播放器。这里我们选用omxplayer。
  • 单片机串口传参控制树莓派:树莓派使用串口通信,解析串口消息帧,解析出视频编号,传入 omxplayer的命令行。这里我们使用 wiringPi库的串口函数,去进行串口消息的解析。解析出视频编号后,调用命令行,控制树莓派播放视频。

 

2. 串口通信帧协议,视频文件编号

单片机和树莓派的串口通信帧协议,我是这样定义的:

  • 每帧5个字节。其中2个字节为帧头,2个字节为帧尾,用来标记消息帧。第3个字节为要播放的视频编号,可以从 0 ~ 255。

(只定义了播放功能,并没有对暂停、结束、快进快退进行定义)

单片机和树莓派的串口通信消息帧协议
帧头1 帧头2 视频编号 帧尾1 帧尾2
0x3A 0x3B 0 ~ 255 0x7E 0x7F

 

  • 视频事先使用FTP传输,存储于树莓派的内存卡中,视频文件存放目录为 /home/pi/ ,也就是用户目录 ~
  • 统一视频文件的命名规则,进行编号:总计四位字符,0000 ~ 0255。例:0001.mp4,0058.mp4,0233.mp4。

例如:如果我们需要控制树莓派播放 0001.mp4 这个视频,只需要串口发送 3A 3B 01 7E 7F(十六进制数据)。

 

3. 安装播放器omxplayer

 

4. C代码

我们通过对 串口数据解析代码 的修改,增加 omxplayer的控制代码,实现播放对应编号的 .mp4视频。

serial.c

#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <stdlib.h>

// 最大帧长度
#define MaxFrameLength	10			// 对最大帧长度加以限定,防止接收到过长的帧数据
// 完整的帧头,2个字节
#define Frame_Header1   0x3A                    // 串口接收消息包的帧头的第1个字节
#define Frame_Header2   0x3B                    // 串口接收消息包的帧头的第2个字节
// 完整的帧尾,2个字节
#define Frame_Tail1     0x7E                    // 串口接收消息包的帧尾的第1个字节
#define Frame_Tail2     0x7F                    // 串口接收消息包的帧尾的第2个字节

int main(void)
{
    int hs1;
    int snum = 0;                               // 系统串口接收缓存区的可用字节数
    int tnum = 0;                               // 用户串口接收区的数目
    unsigned char chrtmp[100];                  // 用户串口接收区,将缓存的数据放入这里处理
    int f_h1_flag = 0;                          // 接收到帧头的第一个字节标志位
    int f_h_flag = 0;                           // 接收到帧头标志位
    int f_t1_flag = 0;                          // 接收到帧尾的第一个字节标志位


    wiringPiSetup();                            // 使用wiring编码去初始化GPIO序号
    //hs1 = serialOpen("/dev/ttyS0", 115200);     // 打开 /dev/ttyS0 串口设备,波特率115200
    hs1 = serialOpen("/dev/ttyUSB0", 115200);     // 打开 /dev/ttyUSB0 串口设备,波特率115200


    /*printf("ttyS0 uart test2:\n");              // 终端打印
    serialPrintf(hs1, "Hello World!\r\n");      // 串口打印
    serialPrintf(hs1, "Enter a paragraph and end with Enter:\r\n");*/

    while (1)
    {
        snum = serialDataAvail(hs1);                	// 获取串口接收缓存区的可用字节数
        if(snum > 0)
        {
            chrtmp[tnum] = serialGetchar(hs1);  		// 从接收缓存区读取一个字节

            if (f_h_flag == 1)  // 有帧头,判断帧尾,接收消息
            {
                if (f_t1_flag == 1) //有帧头,有帧尾1
                {
                    if (chrtmp[tnum] == Frame_Tail2)
                    {
                        /* 用户处理代码 */
                        /* 将接收到符合帧定义的帧,原路发送回去 */
                        int i = 0;
                        for (i = 0; i < (tnum + 1); i++)
                        {
                            serialPutchar(hs1, chrtmp[i]);	// 通过串口发送字节
                        }

                        //解析帧消息,播放对应编号的 .mp4视频
                        char str1[50], str2[50];

                        sprintf(str2, "echo \"\nomxplayer -o hdmi /home/pi/%04d.mp4\n\"", chrtmp[2]);
                        system(str2);

                        sprintf(str1, "omxplayer -o hdmi /home/pi/%04d.mp4", chrtmp[2]);
                        system(str1);

                        /*  处理完用户代码,重新接收计数 */
                        tnum = 0;
                    }
                    else
                    {
                        f_t1_flag = 0;
                        tnum ++;
                    }
                }
                else									// 有帧头,无帧尾1
                {
                    if (chrtmp[tnum] == Frame_Tail1)
                    {
                        f_t1_flag = 1;
                        tnum ++;
                    }
                    else								// 接收消息包中间内容
                    {
                        tnum ++;
                    }
                }
            }
            else										// 没有接收到帧头
            {
                if (f_h1_flag == 1)						//没有帧头,有帧头1。下一步判断是否为第2个字节
                {
                    if (chrtmp[tnum] == Frame_Header2)  // 如果为帧头的第2个字节,接收到帧头标志位标志位置1,tnum自增
                    {
                        f_h_flag = 1;
                        tnum ++;
                    }
                    else
                    {
                        f_h1_flag = 0;
                        tnum = 0;
                    }
                }
                else									//没有帧头,没有有帧头1。下一步判断,是否为帧头的第1个字节
                {
                    if (chrtmp[tnum] == Frame_Header1)  // 如果为帧头的第1个字节,标志位置1,tnum自增
                    {
                        f_h1_flag = 1;
                        tnum ++;
                    }
                    else                                // 否则,标志位清0,tnum清0
                    {
                        tnum = 0;
                    }
                }
            }

            // 大于MaxFrameLength个字节的帧不接收
            if (tnum > (MaxFrameLength - 1) )
            {
                tnum = 0;
                f_h1_flag = 0;
                f_h_flag = 0;
                f_t1_flag = 0;
                continue;
            }

        }
    }

    return 0;
}

 

5. 运行

  • 我在树莓派的 /home/pi/ 目录,使用FTP传输, 存放了两个视频:0001.mp4、0002.mp4。
  • 之后再将 serial.c 通过FTP,存放于 demo/serial_hdmi_video_complete/c_demo/ 目录下。
  • 编译生成可执行文件:gcc serial.c -o serial -l wiringPi
  • 运行:./serial
  • 将显示器的 HDMI线连接到 树莓派的HDMI接口上。
  • 使用串口助手,115200波特率,十六进制发送 3A 3B 01 7E 7F,播放 /home/pi/0001.mp4。
  • 之后再发送 3A 3B 02 7E 7F,播放 /home/pi/0002.mp4。

测试过程:

 

 

6. 实际播放效果

 

7. 相关链接

omxplayer基本使用:树莓派3B omxplayer基本使用

树莓派3B串口通信及解析代码:树莓派3B串口通信及解析代码

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机串口控制树莓派3B播放HDMI视频,omxplayer, 的相关文章

随机推荐

  • 李宏毅老师机器学习选择题解析

    机器学习选择题解析加整理 项目说明 本项目是李宏毅老师在飞桨授权课程的配套问题 课程 传送门 该项目AiStudio项目 传送门 仅供学习参考 三岁出品必是精品 整理内容源于李宏毅老师机器学习课程群提问答疑解析内容 单选题 一 机器学习训练
  • nginx 禁止浏览器(www.xxxxx.com.cn/test/)访问目录,允许本地去访问目录和目录中文件

    location test return 404 解释 location 匹配浏览器的域名 区分大小写 test 域名后面跟着的目录名称 可以换成别的 return 404 也可以把 deny all 改换成 return 404 这样将返
  • TensorFlow安装使用问题集锦(不定期更新)

    记录TF安装使用过程中出现的bug进行记录与解决 1 SystemError Sonnet requires tensorflow probability minimum version 0 4 0 to be installed If u
  • 程序开发过程中的传值问题

    一 传参方式 单个值 二 传参方式 url传递多个值 用 三 传参方式 1 url传数组 2 url传多个参数 需要用 分号分割 3 案例 A页面向B页面传值几个步骤 1 先在A页面写单选提交事件传值 2 在传入页面B页面的onload里面
  • 高速下载百度网盘资料(Tampermonkey+百度网盘直链下载助手+xdown)

    下载百度网盘中的游戏 电影等文件时 由于百度自身对下载速度的限制 非VIP用户总是无法全速下载 下载速度一般在100KB s左右 如果短时间内下载文件 gt 10G还会有更严苛的下载速度限制 一般在50KB s 一周后解除限速 一旦我们想下
  • Unity5.x Animator之RootMotion

    Unity3D 中 Generic 动画导入设置和 Root Motion 之间的关系 Unity3D 的 Mecanim 动画系统可以直接复用 3DS MAX 中制作的动画文件中的位移 这个就是通过 applyRootMotion 来达成
  • UnityNative Plugin 导出时遇到的坑

    必须要在链接的输入里面添加模块定义文件 文件大概是这样 就是为了阻止名称混淆 否则UnityPluginLoad UnityPluginUnload这两个函数无法自动被Unity加载 file used by Visual Studio p
  • 死磕 java同步系列之JMM(Java Memory Model)

    简介 Java内存模型是在硬件内存模型上的更高层的抽象 它屏蔽了各种硬件和操作系统访问的差异性 保证了Java程序在各种平台下对内存的访问都能达到一致的效果 硬件内存模型 在正式讲解Java的内存模型之前 我们有必要先了解一下硬件层面的一些
  • Linux中三种引号(单引号、双引号、反引号)的区别

    1 双引号 保护特殊元字符和通配符不被shell解析 但是允许变量和命令的解析 以及转义符的解析 2 单引号 单引号内不允许任何变量 元字符 通配符 转义符被shell解析 均被原样输出 使用双引号或反斜杠转义可显示输出单引号 但是双引号和
  • 创建型设计模式之抽象工厂(Abstract Factory)模式

    定义 为创建一组相关或相互依赖的对象提供一个接口 而且无需指定他们的具体类 用意 客户端在不必指定产品的具体类型情况下 创建多个产品族中某个产品对象 定义图 参与者 抽象工厂 Creator 工厂方法核心 由一个接口或抽象类实现 具体工厂类
  • 【每日知识】点击下载按钮

    代码如下 methods OncilckUpload let link document createElement a 创建一个a标签 link style display none 将a标签隐藏 link href https api
  • $set在vue中的应用案例

    vue中this set在官方API中是这样说的 Vue set target propertyName index value 参数 Object Array target string number propertyName index
  • java api如何获取kafka所有Topic列表,并放置为一个list

    kafka内部所有的实现都是通过TopicCommand的main方法 通过java代码调用API TopicCommand main options 的方式只能打印到控制台 不能转换到一个list 下面讲解下如何转换为list 1 查看主
  • 三分钟快速搭建家纺行业小程序商城

    在互联网时代 越来越多的企业开始意识到小程序的重要性和价值 家纺行业也不例外 许多家纺企业开始关注和投入小程序商城的建设 然而 对于大多数家纺企业来说 搭建一个小程序商城可能会显得十分困难和复杂 但是 通过乔拓云平台 你只需要三分钟 就可以
  • 【Stm32野火】:野火STM32F103指南者开发板烧写官方示例程序LCD无法点亮?LCD示例程序无法使用?

    项目场景 大家好 最近在使用野火STM32F103指南者开发板的时候发现官方的示例程序LCD驱动代码居然无法直接驱动LCD点亮 这让我百思不得其解 以下就是我的踩坑填坑的过程 希望对大家有所帮助 野火官方资料下载文档链接 野火STM32F1
  • 计算机核心期刊排名及投稿信息

    1 计算机学报 北京 中国计算机学会等 2 软件学报 北京 中国科学院软件研究所 3 计算机研究与发展 北京 中国科学院计算技术研究所等 4 自动化学报 北京 中国科学院等 5 计算机科学 重庆 国家科技部西南信息中心 6 控制理论与应用
  • [Python图像处理] 三十七.OpenCV直方图统计两万字详解(掩膜直方图、灰度直方图对比、黑夜白天预测)

    该系列文章是讲解Python OpenCV图像处理知识 前期主要讲解图像入门 OpenCV基础用法 中期讲解图像处理的各种算法 包括图像锐化算子 图像增强技术 图像分割等 后期结合深度学习研究图像识别 图像分类应用 希望文章对您有所帮助 如
  • 线程池源码分析(一)

    最近在阅读 阿里巴巴Java开发手册 的时候 书中有这么一段话 线程池这块理解不是很深 今天就抽时间重新学习一遍 对于书中的问题分析完成后答案便一目了然 创建线程池的一个方式 ExecutorService e Executors newF
  • 三维重建_COLMAP安装、使用和参数说明(翻译自官方文档)

    近期因为想要入选学校某位很厉害的老师的某个项目 布置的小任务就是先把colmap以及openMVS跑一跑 我就记录了一下学习的经过 一 Ubuntu上源码编译colmap 参考网址 https colmap github io instal
  • 单片机串口控制树莓派3B播放HDMI视频,omxplayer,

    使用树莓派3B通过HDMI播放视频 并且使用串口去控制播放哪个视频 1 问题解耦 单片机串口控制树莓派3B播放视频 树莓派播放视频 单片机串口传参控制树莓派 树莓派播放视频 树莓派播放视频 并且能用串口这种简单的通信方式去控制 应该是需要安