基于M5StickC Plus实现俄罗斯方块,使用姿态传感器操作方块移动
基于M5StickC Plus实现俄罗斯方块,左右晃动方式操作方块移动
标签
嵌入式系统
俄罗斯方块
2022暑假在家练
M5StickC Plus
姿态传感器
安先生
更新2022-09-06
544
  • 开发板介绍
M5StickC PLUS  主控采用ESP32-PICO-D4模组,具备WIFI功能,小巧的机身内部集成了丰富的硬件资源,如红外、RTC、麦克风、LED、IMU、按键、蜂鸣器、PMU等,在保留原有M5StickC功能的基础上加入了无源蜂鸣器,同时屏幕尺寸升级到1.14寸、135*240分辨率的TFT屏幕,相较之前的0.96寸屏幕增加18.7%的显示面积,电池容量达到120mAh,接口同样支持HAT与Unit系列产品。
M5StickC PLUS 能够帮助你快速的搭建物联网产品原型,简化整个的开发过程.即便是刚开始接触编程开发的初学者,也能够搭建出一些有趣的应用,并应用到实际生活中。
小巧玲珑的开发工具,能够激发无限的创作可能。
自带表带,可以戴着手上,真正的可穿戴。
  • 开箱自测
开箱如下图所示

m5stickc_plus_01.webp

如上图简单介绍 开发板有如下
三个按键:
    • 用户按键A: 位于屏幕正下方
    • 用户按键B: 位于屏幕右侧
    • 电源/复位按键:位于屏幕左侧
开发板有如下传感器,内置的程序可以分别检测如下传感器是否正常。(通过按键A或者按键B进行切换)。以下分别说明出厂程序如何检测
    • BLE/WIFI:切换到BLE 界面 搜索M5开头的蓝牙名称 如果能搜到 代表正常
    • 6轴传感器:切换到立体正方形界面,晃动设备 有数据变化
    • LED:红色的灯大概5s一次的频率在闪烁
    • 红外发射管:切换到IR send界面 用手机摄像头对着看 能看到红色闪烁
    • 麦克风:切换到FFT界面 制造噪音 有明显的变化
    • 蜂鸣器:按键时有蜂鸣声 表示正常
    • LCD:开机显示各种颜色变化,能显示代表是正常
    • RTC: 时间显示,并且在稳定增加 则代表正常。
  • 任务描述
使用姿态传感器完成体感游戏手柄,并设计完成一个游戏,例如俄罗斯方块、左右晃动手柄使方块左右移动。
《俄罗斯方块》(俄语:Тетрис,英语:Tetris),是1980年末期至1990年代初期风靡全世界的电脑游戏,是落下型益智游戏的始祖,为苏联首个在美国发布的娱乐软件。

此游戏最初由阿列克谢·帕基特诺夫在苏联设计和编写,于1984年6月6日首次发布,当时他正在苏联科学院电算中心工作。

此游戏的名称是由希腊语数字“四”的前缀“tetra-”(因所有落下方块皆由四块组成)和帕基特诺夫最喜欢的运动网球(“tennis”)拼接而成,华语地区则因游戏为俄罗斯人发明普遍称为“俄罗斯方块”。

俄罗斯方块 - 维基百科,自由的百科全书 (wikipedia.org)

《俄罗斯方块》的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。

本次实现一个俄罗斯方块,并且可以左右晃动方块实现方块的左右移动。
从功能上实现俄罗斯方块游戏的实现,然后利用6轴传感器,实现左右晃动控制左右移动。
  • 程序框图

FvFkExdLPw5q5Wy2O2SGdmJV9fU5

  • 功能与展示
    • 开机时显示随机方块(按A按键开始下落)
    • 左移或者右移 对应方块左右移动
    • 按A键 可以变型方块
FsZhkd-uSztBqergSRdgNZMq4KqjFu8RylCNcepdGo_RibKegkci4FZ-FspFAjhfhOCPU5NXWRmfySyCmLhE
  • 代码片段
    • 显示方块
      void Draw() {  // Draw 120x240 in the center
          for (int i = 0; i < Width; ++i)
              for (int j = 0; j < Height; ++j)
                  for (int k = 0; k < Length; ++k)
                      for (int l = 0; l < Length; ++l)
                          backBuffer[j * Length + l][i * Length + k] =
                              BlockImage[screen[i][j]][k][l];
          M5.Lcd.drawBitmap(0, 0, 135, 240, (uint8_t*)backBuffer);
      }
    •  左右移动算法
   static int num = 0;
   #define a  0.5 
    M5.IMU.getAccelData(&accX, &accY, &accZ);
    accX = a*accX + (1-a)*pre_accX;
    accY = a*accY + (1-a)*pre_accY;
    accZ = a*accZ + (1-a)*pre_accZ;
    Serial.print("num:");
    Serial.print(num);
    Serial.print("\r\n");
    Serial.print("x:");
    Serial.print(accX);
    Serial.print("\r\n");
    Serial.print("y:");
    Serial.print(accY);
    Serial.print("\r\n");
    Serial.print("z:");
    Serial.print(accZ);
    Serial.print("\r\n");
    num++;
    //left x++
    //right x--
    float X_DIFF = accX - pre_accX ;
    Serial.print("X_DIFF:");
    Serial.print(X_DIFF);
    Serial.print("\r\n");
    if(accX - pre_accX >= 0.1){
      is_left = 1;
      Serial.print("Left \r\n");
     }else if(pre_accX - accX >= 0.1) {
      is_right = 1;
      Serial.print("Right \r\n");
    }

    float Y_DIFF = accY - pre_accY ;
    Serial.print("Y_DIFF:");
    Serial.print(Y_DIFF);
    Serial.print("\r\n");


    float Z_DIFF = accZ - pre_accZ ;
    Serial.print("Z_DIFF:");
    Serial.print(Z_DIFF);
    Serial.print("\r\n");

    pre_accX = accX;
    pre_accY = accY;
    pre_accZ = accZ;
  • 遇到的难题
    • 方块显示无法显示或者显示异常
最开始调试时,出现方块区域显示异常。表现为方块会有重叠。
经过仔细检查,发现是绘制方块区域的buffer不足,坐标设置错误。
在LCD显示需要特别注意framebuffer的大小设置。
Framebuffer是用一个视频输出设备从包含完整的帧数据的一个内存缓冲区中来驱动一个视频显示设备。
用于写入颜色值的颜色缓冲、用于写入深度信息的深度缓冲和允许我们根据一些条件丢弃特定片段的模板缓冲。这些缓冲结合起来叫做帧缓冲(Framebuffer),它被储存在内存。
    • 移动算法漂移
最开始的版本,表现非常差,经常左右晃动。仔细排查后,调整阈值,并加入滞后滤波,之后表现比较问题。
滞后滤波:  在电机控制中,有许多的物理量都要经过AD转换为数字量,才能在控制算法中使用,如母线电压、采样电阻电流、功率模块温度等。使用这些数字量时,既要做到有效地把物理量的真实值还原出来,还需要能够剔除一些可能引入的高频干扰,这在软件中就涉及到一个很普遍的方法:使用一阶低通数字滤波器。通常,在软件中会使用离散化且不断迭代的方法来实现这个过程,基本公式是:
Y(n)=a∗X(n)+(1−a)∗Y(n−1)
  • 计划与建议
开发板功能强大,这次只用到了6轴的传感器。
准备再做了一个强大的功能 用上红外 BLE 麦克风。
 
希望后续能提供更多强大的开发板 比如带摄像头 能玩上音视频整套。
 
附件下载
Tetris.ino
团队介绍
安迪,热爱嵌入式的程序猿一枚
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号