Bad Apple 播放效果视频

http://www.qustsatia.cn/2018/09/25/%E5%88%A9%E7%94%A8pyboardcn-v2%E6%92%AD%E6%94%BEbad-apple/

一.前言

前段时间较为忙碌,一直未来得及学习交流。这次利用pyboardCN V2自带的SD卡来存储图片解码文件,通过定时器读取像素点信息文件并通过串口将信息发送给显示部分来播放B站比较火的Bad apple。

本来打算直接利用板子的I2C通信播放图片。但是官方的SSD1306库不是很完善,播放帧数略微感人。当然本人使用刷屏的方式也确实不太合理导致延迟严重。故使用外置的stm32f103来进行专门的图片播放,来减缓pyboard的压力。

二.工具

一款舒服的文本编辑器,如notepad++。

视频截取工具。如Potplayer。

图片转换器,将MP4转换为2位像素图。可以用ps进行批处理操作,也可以用专门软件进行转换。本文使用pconverter。下载链接:http://www.zxt2007.com/imageconverter.html

图片取模软件。可以用OLED附赠的资料,但是手动截图有些麻烦。本人参考他人设计,利用matlab进行图片取模。参考文章:https://blog.csdn.net/howlclat/article/details/50668521

MDK,给播放设备编程。

注:实际上本设备分为2部分,pyboardCN负责读取文件,定时串口发送,播放设备负责将串口接收到的图片码显示到OLED上。两个设备可以完全分开独立设计,互不影响。

三.图片处理

关于OLED显示一帧帧图片播放视频,大体思路如下:
        首先,找到视频源,一般为MP4文件。由于使用黑白OLED,所选取的视频尽量颜色少,最好也为黑白视频,因此选择Bad apple是较为合适的方案。
        第二步,截取视频,将图像进行转换。图像转换有如下要求:
                (1)黑白颜色
                (2)图像大小 128*64
                (3)图像格式BMP        先用potplayer截取。
在pconverter中设置如下图所示:

第三步,根据自己的刷屏方式,选择合适的图片取模方式。本人刚开始根据上文提到的参考作者的方案,进行横向8个像素点拼接成一位,如此调用pixel函数描点,结果由于循环次数较多,运算较为复杂,对micropython来说处理较慢,效果并不好。后来参考汉子显示的思路,利用OLED购买提供的例程直接显示图片,效果好很多。在pyboard里移植下这个函数应该也会快一些,不过由于本身在跑micropython,本人直接改用其他设备进行播放。这里虽然没能在pyboard上流畅播放,但是也是受了很大启发,感谢两位大大

http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=528783&typeid=426

https://www.cnblogs.com/xxosu/p/7602859.html

*程序中已将I2C直接驱动OLED部分注释掉了,同时刷屏方式也改了。可以参考注释掉的思路进行图片播放。程序见下文。

因此,这里的刷屏设置如下:

matlab程序如下,注意由于图片处理的软件有bug,图像整体右移了一列,因此要先左移回来再进行处理。

clc;clear;P = 'D:/pic-apple/';
D = dir([P '*.bmp']);for i = 1 : length(D)raw_data = imread([P D(i).name]);                            %软件有bug,第1列错位了c = [raw_data(:,2:end) raw_data(:,1)];raw_data = c;raw_data = double(raw_data‘);for j = 1:1024                                                % 128*64=8192=8*1024byte = 0;for k = 1:8                                        % 每个字节的处理,移位实现byte = byte + bitshift(raw_data(mod((j-1),128)+1,k+floor((j-1)/128)*8),k-1);endB(j) = byte;endnewName=sprintf('%d.bin', i);                  % 构造文件名fid = fopen(newName,'wb'); fwrite(fid,B,'uint8');fclose(fid);
end

四.py程序

程序主要用到文件操作和定时器的使用以及串口通信。源码如下:

# main.py -- put your code here!
from machine import I2C
from ssd1306 import SSD1306_I2C
from pyb import UART,Timer
import pyb
import micropython
micropython.alloc_emergency_exception_buf(100)
#i2c=machine.I2C(-1, sda=machine.Pin("X10"), scl=machine.Pin("X9"), freq=400000)
u1 = UART(1, 921600)
u1.write('ok')
pyb.delay(1000)
pyb.delay(1000)num=[]
flag = 0
i = 1
#for i in range(1,342):
filename="pic/"+str(i)+".bin"
f = open(filename,"rb")
num = f.read()#pyb.delay(36)def f2(t):global numglobal u1global iglobal flagu1.write(num)i = i+1flag = 1#filename="pic/"+str(i)+".bin"#f = open(filename,"rb")#num = f.read()tm=Timer(4, freq=10, callback=f2)while True:if flag == 1:filename="pic/"+str(i)+".bin"f = open(filename,"rb")num = f.read()u1.write(num)flag = 0

首先是文件操作。类似C语言,直接打开文件,读取,存到数组。比C方便的是在python中有类似C++的字符串拼接操作,循环简单。
       其次是串口,直接write即可。不过在用之前需要确定波特率。这里为了速度用了921600
       最关键的还是定时器。还是这位大大的文章,帮了不小的忙。链接:http://bbs.eeworld.com.cn/thread-485618-1-1.html        关于定时器的使用,大大说的很清楚了,文档里也有示例。这里主要记录下出现的问题。
(1)输出调试中的错误。在调试过程中可能会有内存、堆栈等问题,导致程序直接崩掉。我们需要分配中断异常处理的堆栈,才能正常输出我们的问题。

import micropython
micropython.alloc_emergency_exception_buf(100)

(2)定时器使用回调函数方式,因此不能直接在定时器中断里分配内存。例如本程序里涉及到文件操作,对文件进行打开、处理等操作,无法在回调函数中进行。程序中对回调函数做了一个信号量控制主循环文件读取使能以及串口发送。外部变量要用global声明。

def f2(t):global numglobal u1global iglobal flagu1.write(num)i = i+1flag = 1#filename="pic/"+str(i)+".bin"#f = open(filename,"rb")#num = f.read()tm=Timer(4, freq=10, callback=f2)

五.stm32程序

stm32端主要是一个串口中断,贴上代码,暂不详细展开。

#define MAX_LENGTH      4096
volatile char receiveBuffer[MAX_LENGTH];
volatile uint16_t receiveLength = 0;
volatile uint8_t rxFlag = 0;
unsigned int Times = 1;
static unsigned char str[MAX_LENGTH + 1];  unsigned char* USART_GetString(void)
{  uint16_t temp;  while(!rxFlag);     //等待接收数据,在串口接收到一帧数据时 rxFlag 将会被置 1 (USART3 中断服务函数中)  while(rxFlag)  {  temp = receiveLength;  delay_us(8);      //等待 500us   if(temp == receiveLength)   //判断 receiveLength 是否发生变化(USART3 中断函数中 receiveLength 会有变化),如果没有,证明已经收完所有的数据,否则等待接收完成  {  rxFlag = 0;  }  }  //    for(temp = 0; temp < receiveLength; temp++)
//    {
//        str[temp] = receiveBuffer[temp];
//    }  receiveLength = 0;  //show OLED_DrawBMP(0,0,128,8,(unsigned char*)receiveBuffer);return str;
} void USART1_IRQHandler(void)
{  char temp;  if(USART_GetITStatus(USART1, USART_IT_RXNE))  {  USART_ClearITPendingBit(USART1, USART_IT_RXNE);  temp = USART_ReceiveData(USART1);if(receiveLength == MAX_LENGTH)  {  return;  }  if(!rxFlag)  {  rxFlag = 1;  }  receiveBuffer[receiveLength++] = temp;  }
}

六.效果

将串口连接好,py以及生成的图片码bin文件放到SD卡中,播放。

由于速度问题,视频截取频率为10Hz,即100ms一张。最高能到13Hz,需要改一下定时器数值。
附件:
链接:https://pan.baidu.com/s/1UaEq1j10xK2zc9-thLU_Hg 密码:g1c5

原文发表在 电子工程世界 论坛,由原作者转载。转载请注明出处。

利用pyboardCN V2播放Bad apple相关推荐

  1. 示波器播放Bad apple坏苹果教程XY模式

    偏娱乐方向了,感兴趣的朋友可以玩下,顺便可以了解下示波器的XY模式 麦科信示波器XY模式播放Bad apple坏苹果教程

  2. 【国信长天蓝桥杯】CT117E-M4 嵌入式开发板 显示屏播放Bad Apple,采用OLED_ToolBox

    摘要 最近在指导学生参见 蓝桥杯 嵌入式比赛,比赛完成后开发板就闲置了,于是准备拿过来做一个好玩的东东. 总体思路是这样的,计算机端通过上位机获取视频信息,并将视频信息转换成显示屏可现实的数据,然后通 ...

  3. 用ESP8266播放播放bad apple(一):点亮LED——IO口的简单输出应用

    一.前言: 这是我的第一篇CSDN博客,从这学期开学开始接触单片机,期间从C51,到Arduino,再到ESP8266以及现在刚刚开始学期的32,已经整整一个学期.虽然不敢说多么精通,但还是希望通过一 ...

  4. stm32 播放高帧率高分辨率视频和照片详细制作过程(播放Bad Apple为例)

    stm32 播放高帧率高分辨率视频和照片详细制作过程 下文以播放Bad Apple视频为例. 文章是我边调试边写的,质量不好请见谅. 文章目录 stm32 播放高帧率高分辨率视频和照片详细制作过程 硬 ...

  5. 利用单片机延时播放孤勇者

    利用单片机延时播放孤勇者 采用的单片机为aducm4050 adi_gpio_Toggle(Port0,Pin8);函数即切换电平状态 void play_NOTE(uint32_t freq_t,f ...

  6. QT:利用计时器连续播放图片组成动图效果

    一.效果展示 (该动图完全由jpg图片连续播放构成) 二.步骤(代码解释+注意问题) 1. 配置头文件 头文件我就直接上代码了 #ifndef DIALOG_H #define DIALOG_H#in ...

  7. Win10 下,利用 AutoHotKey v2 恢复任务栏图标的右键菜单关闭之快捷键 c

    正文 在 MS Windows 系列 OS 中,当鼠标右击任务栏某个正在运行的程序图标,弹出的菜单最后一项一般是关闭,同时在 XP 系统下提供了一个快捷键c,个人感觉甚是好用,但可惜可能从 Windo ...

  8. unity3d中利用AVPro video播放mkv视频切换音轨,多音轨切换,实现ktv开启或关闭原唱功能

    unity3d利用插件AVPro视频播放mkv格式视频,切换音轨,实现ktv点歌伴唱功能 (貌似只支持Win10和Android设备) 一,播放MKV文件 首先将高版本(低版本好像不支持mkv)插件A ...

  9. 51单片机控制lcd12864播放bad apple!

    源码网盘链接:https://pan.baidu.com/s/1APv5yVAqrYj4KkkIafegrQ 提取码:b628 B站:https://www.bilibili.com/video/BV ...

  10. (4)ESP32 Python 用OLED播放Bad Apple

    之前已经实现过了,把OLED当作一个状态显示器.但是,仅仅显示文字肯定是不够炫酷的,因为有屏幕的地方就应该有Bad Apple. 这次我们尝试一下把OLED播放一下 Bad Apple. Bad Ap ...

最新文章

  1. jquery 在div追加文本_前端技术--JQuery
  2. 探讨TensorRT加速AI模型的简易方案 — 以图像超分为例
  3. SAP CRM和C4C的订单Number range
  4. 数据挖掘的相关知识例子
  5. java nginx 例子_Java及nginx实现文件权限控制代码实例
  6. 移动端web开发技巧
  7. Android性能检测--traceview工具各个参数的意思
  8. plotting and saving over line in paraView
  9. 了解PS、学习使用html语义化标签和CSS术语
  10. 第34届越秀区青少年科技创新大赛_创客集结号上报名已开始啦
  11. 2021年美赛B题——解题参考
  12. 联想笔记本电脑键盘灯怎么开启_win10系统笔记本电脑开启/关闭键盘背光灯的方法...
  13. 扩展欧几里得算法推导
  14. 已知坐标增量求坐标方位角_全站仪坐标导线测量及平差方法的比较
  15. 【bug解决】上传图片后,取消这次上传 再次执行上传,上次的图片还存在
  16. 智能交通领域权威期刊会议
  17. 单反相机的传奇—佳能单反50年辉煌之路(连载十五)
  18. vs2010c语言一闪而过,[转载]关于vs2010运行C程序时,运行结果窗口一闪而过的问题...
  19. 到处excel表格的数据和页面的数据不一致
  20. 江苏省发布大数据引领推动融合发展专项行动计划

热门文章

  1. 服装计算机辅助设计论文,服装设计计算机辅助设计应用探索-服装设计论文-设计论文.docx...
  2. python extractor_Day 16: Goose Extractor —— 好用的文章提取工具
  3. JavaCV:将任意视频转码为h264编码的mp4格式视频
  4. 5W2H法分析用户流失内因
  5. Linux 安装.deb软件包之前 dpkg-deb 命令查看.deb文件详细信息 版本号 包名
  6. S7-1200使用集成库FB285控制G120变频器的基本步骤
  7. NodeJS 服务 Docker 镜像极致优化指北
  8. mongoDB快速入门
  9. JNCIS翻译文档之------接口2
  10. 用userAgent判断手机类型