当前位置:   article > 正文

单片机串口控制树莓派3B播放HDMI视频,omxplayer,_hdmi可以在单片机当普通线用吗

hdmi可以在单片机当普通线用吗

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

 

1. 问题解耦

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

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

 

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

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

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

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

单片机和树莓派的串口通信消息帧协议
帧头1帧头2视频编号帧尾1帧尾2
0x3A0x3B0 ~ 2550x7E0x7F

 

  • 视频事先使用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

  1. #include <stdio.h>
  2. #include <wiringPi.h>
  3. #include <wiringSerial.h>
  4. #include <stdlib.h>
  5. // 最大帧长度
  6. #define MaxFrameLength 10 // 对最大帧长度加以限定,防止接收到过长的帧数据
  7. // 完整的帧头,2个字节
  8. #define Frame_Header1 0x3A // 串口接收消息包的帧头的第1个字节
  9. #define Frame_Header2 0x3B // 串口接收消息包的帧头的第2个字节
  10. // 完整的帧尾,2个字节
  11. #define Frame_Tail1 0x7E // 串口接收消息包的帧尾的第1个字节
  12. #define Frame_Tail2 0x7F // 串口接收消息包的帧尾的第2个字节
  13. int main(void)
  14. {
  15. int hs1;
  16. int snum = 0; // 系统串口接收缓存区的可用字节数
  17. int tnum = 0; // 用户串口接收区的数目
  18. unsigned char chrtmp[100]; // 用户串口接收区,将缓存的数据放入这里处理
  19. int f_h1_flag = 0; // 接收到帧头的第一个字节标志位
  20. int f_h_flag = 0; // 接收到帧头标志位
  21. int f_t1_flag = 0; // 接收到帧尾的第一个字节标志位
  22. wiringPiSetup(); // 使用wiring编码去初始化GPIO序号
  23. //hs1 = serialOpen("/dev/ttyS0", 115200); // 打开 /dev/ttyS0 串口设备,波特率115200
  24. hs1 = serialOpen("/dev/ttyUSB0", 115200); // 打开 /dev/ttyUSB0 串口设备,波特率115200
  25. /*printf("ttyS0 uart test2:\n"); // 终端打印
  26. serialPrintf(hs1, "Hello World!\r\n"); // 串口打印
  27. serialPrintf(hs1, "Enter a paragraph and end with Enter:\r\n");*/
  28. while (1)
  29. {
  30. snum = serialDataAvail(hs1); // 获取串口接收缓存区的可用字节数
  31. if(snum > 0)
  32. {
  33. chrtmp[tnum] = serialGetchar(hs1); // 从接收缓存区读取一个字节
  34. if (f_h_flag == 1) // 有帧头,判断帧尾,接收消息
  35. {
  36. if (f_t1_flag == 1) //有帧头,有帧尾1
  37. {
  38. if (chrtmp[tnum] == Frame_Tail2)
  39. {
  40. /* 用户处理代码 */
  41. /* 将接收到符合帧定义的帧,原路发送回去 */
  42. int i = 0;
  43. for (i = 0; i < (tnum + 1); i++)
  44. {
  45. serialPutchar(hs1, chrtmp[i]); // 通过串口发送字节
  46. }
  47. //解析帧消息,播放对应编号的 .mp4视频
  48. char str1[50], str2[50];
  49. sprintf(str2, "echo \"\nomxplayer -o hdmi /home/pi/%04d.mp4\n\"", chrtmp[2]);
  50. system(str2);
  51. sprintf(str1, "omxplayer -o hdmi /home/pi/%04d.mp4", chrtmp[2]);
  52. system(str1);
  53. /* 处理完用户代码,重新接收计数 */
  54. tnum = 0;
  55. }
  56. else
  57. {
  58. f_t1_flag = 0;
  59. tnum ++;
  60. }
  61. }
  62. else // 有帧头,无帧尾1
  63. {
  64. if (chrtmp[tnum] == Frame_Tail1)
  65. {
  66. f_t1_flag = 1;
  67. tnum ++;
  68. }
  69. else // 接收消息包中间内容
  70. {
  71. tnum ++;
  72. }
  73. }
  74. }
  75. else // 没有接收到帧头
  76. {
  77. if (f_h1_flag == 1) //没有帧头,有帧头1。下一步判断是否为第2个字节
  78. {
  79. if (chrtmp[tnum] == Frame_Header2) // 如果为帧头的第2个字节,接收到帧头标志位标志位置1,tnum自增
  80. {
  81. f_h_flag = 1;
  82. tnum ++;
  83. }
  84. else
  85. {
  86. f_h1_flag = 0;
  87. tnum = 0;
  88. }
  89. }
  90. else //没有帧头,没有有帧头1。下一步判断,是否为帧头的第1个字节
  91. {
  92. if (chrtmp[tnum] == Frame_Header1) // 如果为帧头的第1个字节,标志位置1,tnum自增
  93. {
  94. f_h1_flag = 1;
  95. tnum ++;
  96. }
  97. else // 否则,标志位清0,tnum清0
  98. {
  99. tnum = 0;
  100. }
  101. }
  102. }
  103. // 大于MaxFrameLength个字节的帧不接收
  104. if (tnum > (MaxFrameLength - 1) )
  105. {
  106. tnum = 0;
  107. f_h1_flag = 0;
  108. f_h_flag = 0;
  109. f_t1_flag = 0;
  110. continue;
  111. }
  112. }
  113. }
  114. return 0;
  115. }

 

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串口通信及解析代码

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号