迪文科技论坛

 找回密码
 立即注册
搜索
查看: 74|回复: 0

【2025.02.14获奖项目】基于T5L迪文屏的零食机

[复制链接]

580

主题

171

回帖

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
12795
发表于 2025-3-6 13:54:04 | 显示全部楼层 |阅读模式
【开源】基于T5L迪文屏的零食机

一、背景介绍

        抓零食, 抓玩具等各种游戏机, 它们有的是用LCD12864单色屏做的,有的是用更简单的数码管做的,不管外观咋样,仪器内部的实现原理基本都是差不多的,大概可以分为如下几部分构成:
        1.电机,机械臂,导轨等结构
        2.摇杆, 按键, 显示系统, 投币器, 光耦定位等硬件
        3.游戏状态机, 充值, 厂家后台等软件组件

       大家都知道现在商场里面的游戏机都是可以调节难易程度的, 一般小白可能不知情哈, 这里我给大家解密一下, 这些调节参数都是在我们的"厂家后台"软件组件中调节的, 比如调节爪子力度大小, 中奖概率, 电机移动速度, 送币概率, 下降绳长等参数,当然了
我们用户一般是无法进入到这个"厂家后台"调试界面的, 一般在游戏机柜内有一个按键, 可以通过长按来触发进入的,
    好了现在进入主题, 本项目采用了迪文触摸彩屏来实现零食机, 也算是市面上的一个革新点吧, 然后还有许多硬件模块其实它内部是封装好了的, 它内部处理掉了复杂的处理事项, 只是暴露简单的接口来供我们控制, 比如其中的投币器





二、GUI设计

1.所有图片素材如下:




2.首先游戏机开机后会进入到开机界面,这里其实是在完成各组件模块的自检流程,如果出错了,就会跳到相应的报错界面






3.自检没有问题后,就会进入到正常的主界面,也就是所谓的游戏状态机
在这里会显示用户投币的累计总局数,每玩一次会减少1, 然后还会显示每一次游戏的倒计时,时间一到系统将会自动出爪,然后还会显示投几个币才能玩一局等,
当然了这里的时间,和几币一局都是在后台可以设置的喔


4.然后就是前面我们所说到的"厂家后台"界面,它是通过长按一个按键来进入的,后台系统的界面是比较复杂的,它不仅要给车间工人提供调试接口,还要给游戏厅老板提供参数设定接口

看上图就知道复杂程度了,里面的每一个一级菜单项又细分出来了很多二级菜单项的,比如"C基础设置"




三、代码设计


1.迪文屏和主控的通信代码


  1. void uart2_master_isr()        interrupt 4
  2. {
  3.         u8 res;
  4.         
  5.         if(RI0)
  6.         {
  7.                 RI0 = 0;
  8.                 res = SBUF0;
  9.                 uart2_rx_timeout = UART2_RX_TIMEOUT;
  10.                 if((uart2_rx_sta&UART2_PACKET_OK)==0)
  11.                 {
  12.                         if(step==0)
  13.                         {
  14.                                 recv_len = 0;
  15.                                 if(res==0x15)
  16.                                         step = 1;
  17.                         }else if(step==1)
  18.                         {
  19.                                 date_len = res;
  20.                                 step  = 2;
  21.                                 if(date_len>UART2_PACKET_MAX_LEN)
  22.                                         step = 0;
  23.                         }else if(step==2)
  24.                         {
  25.                                 if(recv_len==date_len)
  26.                                 {
  27.                                         step = 0;
  28.                                         if(res==0x16)
  29.                                         {
  30.                                                 uart2_rx_sta = date_len;
  31.                                                 uart2_rx_sta |= UART2_PACKET_OK;
  32.                                         }
  33.                                 }else
  34.                                         uart2_buf[recv_len++] = res;
  35.                         }
  36.                 }
  37.         }        
  38. }
复制代码



2.电机的驱动代码

  1. void motor_move(MOTOR motor,MOTOR_DIR dir)
  2. {        
  3.         if(motor==MOTOR_Z)//Z轴上的爪子电机
  4.         {
  5.                 if(dir==MOTOR_DIR_NONE)//停止
  6.                 {
  7.                         MOTOR_Z_DISABLE();
  8.                 }else
  9.                 {
  10.                         if((IS_MOTOR_Z_BACKWARD_POS()&&(dir==MOTOR_DIR_BACKWARD))
  11.                                 ||(IS_MOTOR_Z_FORWARD_POS()&&(dir==MOTOR_DIR_FORWARD)))
  12.                         {
  13.                                 MOTOR_Z_DISABLE();
  14.                                 dir = MOTOR_DIR_NONE;
  15.                         }else
  16.                         {
  17.                                 MOTOR_Z_ENABLE();
  18.                                 MOTOR_Z_DIR_PIN = (dir==MOTOR_DIR_BACKWARD);
  19.                         }
  20.                 }
  21.         }else if(motor==MOTOR_X)//X轴移动电机
  22.         {
  23.                 if(dir==MOTOR_DIR_NONE)//停止
  24.                 {
  25.                         MOTOR_X_DISABLE();
  26.                 }else
  27.                 {
  28.                         if(IS_MOTOR_X_BACKWARD_POS()&&(dir==MOTOR_DIR_BACKWARD))
  29.                         {
  30.                                 MOTOR_X_DISABLE();
  31.                                 dir = MOTOR_DIR_NONE;
  32.                         }else
  33.                         {
  34.                                 MOTOR_X_ENABLE();
  35.                                 MOTOR_X_DIR_PIN = (dir==MOTOR_DIR_BACKWARD);
  36.                         }
  37.                 }
  38.                 x_last_dir = dir;
  39.         }else if(motor==MOTOR_Y)//Y轴移动电机
  40.         {
  41.                 if(dir==MOTOR_DIR_NONE)//停止
  42.                 {
  43.                         MOTOR_Y_DISABLE();
  44.                 }else
  45.                 {
  46.                         if((IS_MOTOR_Y_BACKWARD_POS()&&(dir==MOTOR_DIR_BACKWARD))
  47.                                 ||(IS_MOTOR_Y_FORWARD_POS()&&(dir==MOTOR_DIR_FORWARD)))
  48.                         {
  49.                                 MOTOR_Y_DISABLE();
  50.                                 dir = MOTOR_DIR_NONE;
  51.                         }else
  52.                         {
  53.                                 MOTOR_Y_ENABLE();
  54.                                 MOTOR_Y_DIR_PIN = (dir==MOTOR_DIR_BACKWARD);
  55.                         }
  56.                 }
  57.                 y_last_dir = dir;
  58.         }else if(motor==MOTOR_CLAW)
  59.         {
  60.                 if(dir==MOTOR_DIR_NONE)
  61.                 {
  62.                         MOTOR_CLAW_RELEASE();
  63.                 }else
  64.                 {
  65.                         MOTOR_CLAW_HOLD();
  66.                 }
  67.         }
  68.         
  69. }
复制代码


3.爪子调力度,速度的代码(采用的是PWM)

  1. const u16 MOTOR_DUTY[MOTOR_TOTAL][MOTOR_SPEED_MAX+1] = {
  2.         {45+DUTY_OFFSET,60+DUTY_OFFSET,80+DUTY_OFFSET,110+DUTY_OFFSET,130+DUTY_OFFSET,160+DUTY_OFFSET,200+DUTY_OFFSET,250+DUTY_OFFSET,550+DUTY_OFFSET,TIM_ARR},//X
  3.         {45+DUTY_OFFSET,60+DUTY_OFFSET,80+DUTY_OFFSET,110+DUTY_OFFSET,130+DUTY_OFFSET,160+DUTY_OFFSET,200+DUTY_OFFSET,250+DUTY_OFFSET,550+DUTY_OFFSET,TIM_ARR},//Y
  4.         {45,60,80,110,130,160,200,250,550,TIM_ARR},//Z
  5.         {200,220,240,270,290,320,360,410,550,TIM_ARR}//爪子
  6. };



  7. void motor_set_speed(MOTOR motor,u8 speed)
  8. {
  9.         if(speed>MOTOR_SPEED_MAX)
  10.                 return;
  11.         
  12.         pwm_set_duty((PWM_CH)motor,MOTOR_DUTY[motor][speed]);
  13. }



  14. void motor_set_claw_strength_by_vol(float vol)
  15. {
  16.         #define CLAW_DUTY_MIN                        200
  17.         #define CLAW_DUTY_MAX                        TIM_ARR
  18.         u16 duty;
  19.         
  20.         vol = (float)(vol-QZLDY_MIN)/(QZLDY_MAX-QZLDY_MIN);
  21.         if(vol<0)
  22.                 vol = 0;
  23.         else if(vol>1)
  24.                 vol = 1;
  25.         duty = (u16)(vol*(CLAW_DUTY_MAX-CLAW_DUTY_MIN)+0.5f)+CLAW_DUTY_MIN;
  26.         
  27.         pwm_set_duty(PWM_CH_MOTOR_CLAW, duty);
  28. }
复制代码

4.厂家后台按键长按检测

  1. u8 key_check_long_press(KEY key,u32 time)
  2. {
  3.         while(1)
  4.         {
  5.                 if(!(KEY_Scan(1)&key))
  6.                         return 1;//失败
  7.                 if(time)
  8.                 {
  9.                         sys_delay_ms(1);
  10.                         time--;
  11.                         if(time==0)
  12.                                 return 0;//成功
  13.                 }
  14.         }
  15. }
复制代码



四、视频演示


















本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2025-3-28 21:11 , Processed in 0.034333 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表