如果你像我一样,你喜欢弹球,但没有钱购买或空间适合全尺寸游戏。那么为什么不建立自己的呢?
在这里,我们将介绍如何创建由Arduino驱动的自定义弹球游戏。游戏中有灯光,声音,真实的弹球部分,包括保险杠,掉落目标和弹弓,甚至还有一个坡道。
该项目需要大量不同的材料,因此请参阅后续章节,了解完成每个步骤所需的新材料。首先,如果您可以使用激光切割机或CNC路由器以及基本的电子和硬件工具包,这将非常有用。
作者注:这个instructable最近刚发布,并非所有的设计和软件文件都已完全组织完成。如果计划使用我们的文件,请发表评论,以便我们确保所有内容都处于最新状态。
供应:
第1步:设计
上图是Solidfield设计的运动场和支撑组件。该场地纯粹是定制的,但是射门线(例如后循环射击的曲线)是基于真正的弹球机设计的,以确保顺畅的比赛。这里的一个难点是,由于它们的复杂性,实际的弹球部件(例如保险杠和下落目标)没有建模,但仍需要注意确保一切都适合在运动场下 - 部件要大得多低于上面。
这些文件包含在存储库中,因此您可以根据自己的喜好调整设计。
设计的一些亮点:
比赛场地为42英寸×20.25英寸,与1980年代的Bally式比赛相当。它由½“胶合板制成,这是标准的,不应该改变,因为弹球部件组件是为这个厚度设计的。这里的墙壁由¼“层顶部的1/2”层组成。在第一个原型中,仅包括1/2英寸的墙壁,但事实证明这些墙壁太短,并且可以在特别坚固的镜头上将弹球弹到空中。其次,这种设计允许略微凸起的射击线(如上图所示),允许球稍微落入游戏区,但不会倒退。
坡道采用透明丙烯酸和3D打印支撑设计。它穿过了比赛场地,这样玩家就有机会从左脚蹼连续多次击中坡道。因此,使用透明丙烯酸树脂不会妨碍玩家对桌子的看法:
最后,场地由四个角落的短墙支撑,使得比赛场地保持标准的6.5度坡度。后壁有一个底部“架子”,可以拆下并用于安装电子设备。这导致具有全尺寸游戏场的游戏,但是比典型游戏更紧凑并且可以由一个人手动携带。但是,由于运动场是标准尺寸,如果您想将运动场放入标准弹球柜中,可以移除这些支撑。为此,您可能需要考虑添加一个球返回组件,该组件不包含在此设计中。
第2步:切割木材
为了切割游戏场的各层,我们使用了激光切割机。然而,一个强大到足以切割½“胶合板的激光切割机很难找到,需要高质量的胶合板,如果你不小心可能会引发火灾。使用CNC路由器切割典型的比赛场地 - 虽然一些角落可能不那么清晰,但你仍然应该取得不错的效果。为简单起见,下面的步骤假设您可以使用我们所做的相同激光切割机。有些人只使用钻头和拼图得到了不错的结果,但如果你走这条路,你必须非常小心并且非常耐心。
创建游戏区的第一步是将设计转换为可以送入激光切割机的.DXF文件。例如,playfield .DXF文件如下图所示。此项目中使用的文件包含在我们的存储库中。
使用激光切割机,我们切出了游戏场的形状,¼“中间层(我们使用duron,更便宜的木质原型材料,但¼”胶合板也可以使用),½“顶层,½”支持。
所需材料:
- ½“胶合板为playfield和基地
- 中间墙层的¼“胶合板或duron
- ½“,¾”和1“木螺钉
- 访问CNC路由器或激光切割机
第3步:组装Playfield
首先将¼“duron层的碎片夹在各自位置的胶合板上。使用手钻,首先使用3/32“钻头钻孔导孔,然后使用平头¾”木螺钉将¼“层连接到游乐场从上到下执行此操作非常重要(即因此,螺钉首先穿过¼“层,然后进入½”基座,因为¼“部分小而薄,如果沿相反方向钻孔,将弯曲远离基层。确保螺钉头与¼“层齐平并且不提供任何额外厚度也很重要。
最后要注意的是:这些螺丝几乎可以放在任何地方,因为一旦组装了运动场,这个层对玩家来说几乎是不可见的。但是有一个例外 - 不要将螺钉放入射手车道。 (我们最初犯了这个错误)。
接下来,连接侧壁,并使用最长的木螺钉从板的顶部钻入它们,再次使螺钉头与顶部齐平。完成后,将½“层片夹在斗牛上方,并像以前一样将它们拧入,除非这次使用1”螺丝从底部拧入。由于顶层厚度为1/2“,因此不太可能弯曲远离底座,从底部拧紧,确保螺丝对玩家不可见。
最后,使用2个螺丝从底部拧入,将射击块(如上图所示,用射击器)连接起来,这样块就不容易扭曲。射击块有一个“U”形槽,适合射手,可以通过拧紧另一侧的螺母来安装。您可能还必须使用润滑剂来减少射杆和球之间的摩擦。
此时可能需要对设计进行一些调整。例如,在我们的设计中,下落目标的切割太窄,必须使用dremel进行扩展。如果将我们的文件用作参考文件,请尝试联系可能提供更新文件的作者。对任何粗糙区域进行打磨也是一个好主意,特别是在两块木块相遇的地方。
在大多数情况下,这归结于木工,我们可以转向组装。
所需材料:
- 3/4“平头木螺钉
- 射手组装
- 更长(~1.5“)的木螺钉
- 手钻3/32“位
- 润滑油
- 1“平头木螺钉
- 文件和/或dremel和砂纸
第4步:添加组件
在设计阶段的这一点上,您应该大致了解确保所有组件实际适合在游戏区域下方所需的方向。 (如果使用我们的设计,请参考上表下方的图片)。
首先,通过将½“木螺钉穿过组件中的安装孔,安装下落目标,直立目标和弹弓组件。对弹出式保险杠也一样,但要确保先拆下盖子,否则组件将无法插入其孔中!
其次,安装鳍状肢组件。确保它们以正确的方向旋转。当发射时,螺线管将销钉压入线圈,这应该使轴旋转,使得鳍状板朝向运动场向上旋转。安装了鳍状肢组件后,将鳍状肢蝙蝠从另一侧安装。使用组件中的锁紧螺母上的扳手将它们拧紧到位,然后使用组件随附的弹簧确保在不发射时将鳍状物向下鼓起。
同样,使用1/2英寸螺钉安装所有侧翻开关,确保它们可以轻松地从顶部压入并弹回原位。使用6-32螺栓,也可以将门开关安装在左上角我们的设计。这个门开关也可以作为一个单向开口,允许从右侧和射击者射入保险杠。这是一个设计方面,导致镜头进入右斜坡和右回路进入不同的地方,增加了游戏的多样性。
要安装灯,首先将塑料插件插入孔中。这些刀片厚约1/4英寸。如果使用CNC路由器,安装这些路由器的正确方法是切割比插入孔略大的1/4“层。在我们的设计中,由于激光切割机不能切割局部层,我们采用3D打印支架来支撑插件。使用环氧树脂将刀片固定到位(首先使边缘粗糙)和砂纸,以确保刀片与运动场保持水平。
接下来,将LED插入并扭转到位,将LEDS插入支架。然后,将支架拧入到位,使这些LED直接位于每个插件下方。下面连接的灯架非常薄,实际上足够薄,以至于1/2“螺丝可以刺穿桌子的顶部。使用几个垫圈,这样就不会发生这种情况。
playfield柱子使用6-32螺栓安装。安装完成后,将橡胶套件周围的橡胶包起来制作被动保险杠。如果设计完全是胶合板,这些给桌子带来了更多的“生命”。使用相同的螺栓,将导板导轨安装在鳍状肢上方。还将游戏结束时的开关粘合到位。
请注意,大多数游戏都有专门的球返回组件,如此处。然而,这不包括在此设计中,主要是由于成本。当然,权衡的是玩家现在负责将球放回射手路。不过,我们确实有一个射击游戏,如前图所示。
通过将脚蹼按钮和启动按钮放入孔中并使用榫头锁定到位来安装它们。使用6-32螺栓将挡板按钮叶片开关用螺栓固定在按钮内,按下按钮时将关闭开关电路。
此时,你的运动场(从上面)就像一个几乎完整的弹球桌!所有缺失的是斜坡。在你的朋友们之间尽情享受关于它看起来多么棒的感觉,同时私下里害怕有多少接线和焊接要做。
所需材料(大多数是从PinballLife.com购买的,只需搜索下面的条款即可找到)。
- 1个3库下降目标组件
- 3x pop保险杠总成
- 1左脚蹼组件
- 1右脚蹼组件
- 2个鳍状肢蝙蝠
- 2个鳍状肢按钮
- 2个鳍状板按钮
- 1个开始按钮
- 1个橡胶圈套装
- ~30个Playfield明星帖子,(1 1/16“使用)
- 2车道指南
- 2个鳍状按钮叶片开关
- 2个弹弓组件
- 1站立目标
- 10个翻转开关
- 8个LED#44卡口式灯
- 8个卡口式灯架(带有长安装支架的微型卡口式底座2引线插座)
- 5 1-1 / 2“x 13/16”蓝色箭头插入
- 3 1“x 3/4”透明子弹插入
- 6-32个螺栓(2.5“,以及一些较小的尺寸),螺母和垫圈
- ~2“宽门开关(就像这里的一个,这可能很难找到,我们从ebay上购买的旧破坏的弹球坡道上取消了我们)
第5步:构建斜坡
要制作坡道,请使用¼“丙烯酸树脂作为基础件,使用⅛”丙烯酸作为侧壁。透明的丙烯酸树脂将提供漂亮,干净的外观,同时不会阻挡玩家的游戏场景。使用彩色丙烯酸也可能是一个不错的选择,但不建议使用完全不透明的材料,如木材。
斜坡的支撑使用makerbot进行3D打印,并使用相同的6-32螺栓用螺栓固定在游乐场和塑料上。
这里的丙烯酸片使用丙烯酸水泥粘合在一起,丙烯酸水泥是一种基本上熔化并将塑料焊接在一起的溶剂。确保少量使用,它会产生一种几乎看不见的强力粘合。
在斜坡的入口处,我们包括了一个如上图所示的斜坡翻板。这是一块薄薄的金属片,可以提供从滑道到坡道塑料的非常平滑的过渡,而不是让弹球必须“跳”到塑料的1/4“厚度。你可以从弹球专卖店或Ebay(我们做过)便宜地购买其中一种,或者用钣金制作你自己的一种。在商业游戏中,这些是铆接的,因此螺栓不会粘在一起并妨碍球。由于我们没有适当的设备,我们确保使用平头螺钉并在塑料和金属中适当地倒角孔以达到相同的效果。
在斜坡的右前角有一个狭窄的门开关连接到3D支架上,在那里它转过场地。此开关是在击中成功的斜坡拍摄时记录的内容。
所需材料:
- 1/4“透明丙烯酸(12x24”板)
- 1/2“透明丙烯酸(12x24”板材)
- 丙烯酸水泥
- 访问3D打印机和激光切割机
- 斜坡翻板
- 用于斜面翻板的平头6-32螺栓
- 腔室钻头或手动工具
- 窄门开关
步骤6:规划电子模块和引脚布局
(作者的更新:通过长时间使用,48V可以在此配置中烧掉一些晶体管。我建议使用35V或更低电压,或使用更专业的控制板资源,如下所示:http:// pinballmakers .COM /维基/的index.php /建筑)
该机器有3个电压等级:电磁阀电源为48V,LED为6.3V,逻辑和声音为5V。为了提供这些电压水平,我们使用了用于48V的CNC电源和现成的DC适配器来提供6.3V和5V。 (有可能只使用6.3V,因为Arduino下调其5V输出引脚的电源电压,但我们保持这些电源隔离)。 48V是一个高电压,虽然本身不致命,但可能会损坏部件,如果电路出现任何问题,可能会导致元件过热。在主48V电源的输入和输出上使用5-A慢熔保险丝,以避免在任何晶体管短路时引发火灾。
在Arduino屏蔽上,我们连接了带有Molex连接器的电线,这些连接器的设计符合三个子板中每个子板的输入和输出要求:电磁阀驱动板,灯/声音驱动板和输入板。
在我们的设计中,我们有以下引脚分配。当然,这非常灵活。引脚0保持打开状态。 (Instructables不允许我们以0开头的数字列表。)
- 打开
- 打开
- 中断/输入有效引脚
- 编码输入引脚
- 编码输入引脚
- 编码输入引脚
- 编码输入引脚
- 编码输入引脚
- 右保险杠输出
- 中保险杠输出
- 左保险杠输出
- 丢弃目标输出
- 翻转主开关输出
- 主灯开关输出
- 光输出引脚
- 光输出引脚
- 光输出引脚
- 声音输出引脚
- 打开
虽然我们的设计没有实现,但SCL和SDA引脚可用于显示,其余引脚可用于额外控制,例如添加功能(回球)或更多照明组合。
所需材料:
- 48V CNC电源(像这样)
- 现成的6.3V和5V电源(像这样)
- 5A缓慢熔断保险丝和保险丝座,以及用于连接的热缩管
- Molex连接器
- Arduino原型盾板
- 大量的22AWG电线,焊料和耐心
第7步:制作驱动板
驱动板负责将来自Arduino,脚踏板按钮和弹弓开关的输入转为点火线圈。由于信号处于5V电平且电磁阀处于48V,因此需要高功率MOSFET来中继信号。本设计中使用的晶体管是Mouser的这些100V额定MOSFET。
上图为三个示意图,包括鳍状肢,弹弓和保险杠/跌落目标。每个都有不同的要求,但在所有这些要求中,当给晶体管提供5V信号时,电磁阀的电流路径打开,并且5-8安培被推过线圈以产生强大的冲击力。这是很多潮流!实际上,如果晶体管保持导通超过非常短暂的脉冲,那么这么大的电流会烧坏元件。在使用软件或其他方法测试此电路时,确保永远不会为螺线管完全供电超过一秒钟。
上述电路中的主要问题是感应冲击。电磁阀是功能强大的电感器,如您所知,电感器中的电流不能瞬间改变。因此,当晶体管关闭时,仍有一个短暂的时刻,5-8安培流过螺线管,所有这些电流都需要去的地方。如果没有给出接地路径,该电流将驱动晶体管漏极电压高达数百伏并破坏晶体管。此外,当晶体管被破坏时,它会使所有三个端子短路,这会导致连续电流的电流流动,如果没有安装适当的保险丝,可能会损坏电磁阀。 (我们在发现中销毁了8个晶体管并试图解决这个问题,但幸运的是没有螺线管,因为我们总是快速手动断开电源)。
有两种方法可以防止感应冲击:首先,每个弹球组件应该带有一个二极管,指示从晶体管漏回到电源。理论上,这应该防止晶体管漏极不会超过电源电压,因为一旦发生这种情况,二极管将导通并从电感器中消耗所有剩余的能量。不幸的是,实际上这些二极管本身并不能足够快地开启以足以抑制感应冲击。
为了解决这个问题,我们增加了一个RC'缓冲'电路。该电路具有与电阻串联的电容器。电容器从电感器吸收足够的电流,使二极管有时间导通并执行其功能。有关RC缓冲电路的更多信息,请点击此处。
保险杠/ droptarget螺线管驱动电路非常简单,只有晶体管,电磁阀,缓冲器和接收Arduino输入的连接。在此电路板和后续电路板中,确保为电磁阀接线,使二极管(原理图中未显示)指向高压侧。
由于三个原因,鳍状肢驱动器电路有点复杂。首先,为了在按钮按下和鳍状肢动作之间产生快速反应,建议直接在电路中创建响应,而不是由Arduino处理的单独输入和输出。由Arduino引起的延迟很小,但是经验丰富的玩家将能够立即分辨,并且会因缺乏控制而感到沮丧。
其次,脚蹼具有两个不同的线圈(低功率线圈和高功率线圈),一个行程末端开关,当脚蹼高时触发。这个开关具有重要的功能,允许高功率线圈最初点火以提供强大的行程,但切换到低功率线圈(~130欧姆对4欧姆),提供足够的功率以保持脚蹼保持“向上”只要放置按钮,但不会消耗太多电流以烧坏电磁阀。在下图中,EOS开关通常是闭合的,但我们的组件有一个常开开关,需要另一个晶体管将其转换为常闭信号。
第三,虽然我们希望按钮直接控制脚蹼,但我们还包括来自Arduino的“主”开关信号,可根据球是否在比赛中激活或停用脚蹼。这导致在电路中使用第三晶体管。
同样,弹弓板也有其自身的复杂性。虽然它只使用一个晶体管,但它和脚蹼一样,应该由输入开关(我们串联连接)直接控制,以实现快速响应,并且不需要Arduino上的额外输出引脚。不幸的是,如果晶体管的栅极直接连接到开关,则响应速度太快,不能超过几乎没有明显的反应,因为开关不会长时间保持闭合状态。为了获得更强大的冲击力(即让弹弓螺线管“跟进”),我们在晶体管的栅极添加了一个二极管和一个大电阻,这样可以实现快速响应,但会产生很大的电压衰减时间常数在该节点处,即使在重新打开弹弓开关之后,栅极仍然接近5V(并且晶体管导通)足够长以具有明显的踢动。另一个复杂因素是将此输入发送到Arduino,作为输入板(我们将在后面看到)需要 低 输入,当输入被推高时弹弓操作。为了解决这个问题,我们提供了第三个晶体管,当输入变为高电平时它会关闭,因此可以像播放场上的任何其他输入开关一样对待
驱动板(实际上是两块板)由两个鳍状驱动器,两个弹弓驱动器和四个用于剩余螺线管的单开关驱动器组成。我们使用0.1“molex连接器将电路板连接到电磁阀,电源和开关,而不是直接焊接,因此可以更轻松地进行任何维修或调整。
我们在设计中使用了可焊接面包板,但设计具有这些功能的实际PCB可以获得更清晰的结果,并有助于减轻这些机器不可避免的电线混乱。
材料:
- 12个100V额定功率晶体管
- 10-50 uF电容(如果可能,非极性)
- 300,5k和500k,以及3M电阻器
- 1个较小的晶体管用于弹弓开关
- 几个1N4004二极管
- 原型可焊面包板(或者更好的是,设计自己的PCB)
步骤8:制作传感器输入板
由于我们只使用Arduino,因此我们仅限于20个数字引脚。然而,弹球机有几十个独特的开关输入,更不用说灯,声音和驱动电磁阀所需的输出。为了缓解这个问题,我们假设不会同时触发两个输入(从而限制我们仅使用1个球)。这个假设允许我们通过将开关输入转换为带有第6个引脚的5位二进制寄存器来“编码”开关输入,只要接收到有效的开关输入,就会触发中断。为实现这一目标,我们使用了一个8至3编码器的级联,使用此编码器在上图所示的布局中制作24到5编码器。
这是该项目最重要的发展之一,因为它允许我们从最初只有脚蹼,保险杠和一个或两个目标的计划中大大增加我们机器的复杂性。
第二块原型板用于放置24个公Molex连接器;在运动场上的每个开关都会在插入该板的长线末端有一个母连接器。放置目标是一个独特的案例,可以通过多种方式处理。我们所做的是将每个降落目标开关串联连接,以便当输入全部关闭时输入关闭,并允许Arduino向螺线管发送信号以向后发射掉落目标。
材料:
- 4个3态输出优先级8到3编码器
步骤9:制作灯光/声音/得分外围板
为了以与编码器类似的方式保存引脚,我们使用3到8解码器来控制我们的灯。这为我们提供了限制,即我们在任何时候都不能点亮一个以上的灯,但这是一个可以接受的权衡,以释放其他元素的引脚。我们还包括第四个“主”光输出,可以同时控制所有灯。例如,这可以让我们在首次开启游戏时多次闪烁所有灯光(强烈表明玩家在按下开始按钮时实际发生了某些事情,否则很难没有球槽或彩色显示器)。
上面的示意图以类似于驱动器的晶体管电路为特征,但更简单,因为较低的电压(对于灯为6.3V)需要较小的晶体管并且不需要那么多的保护电路。我们使用二极管“或”门来为晶体管隔离主开关信号和单独的光信号。这允许我们每个光只使用一个晶体管而不是两个晶体管,并防止Arduino和编码器芯片“对抗”来源或吸收电流。
虽然我们为每个场地灯(插入物下面的灯)使用了低电流LED,但是开始按钮和3个弹出式保险杠每个都带有白炽灯泡,每个灯泡吸收约250mA。晶体管的额定电流为530mA连续电流,所以为了不超过这个,我们确保只有两个白炽灯经过一个晶体管。
我们还安装了一个无源5V压电蜂鸣器,可以让我们为这块电路板播放基本的声音。
可以使用light_sequence + sound_sequence功能或通过弹球语言界面对自定义灯光和声音序列进行编程。
- 10个照明晶体管(我们使用这些)
- 5V压电蜂鸣器
第10步:第11步:设计您的游戏规则
有两种选择来定义弹球游戏的规则。您可以使用可自定义的弹球文档或硬编码游戏规则与游戏进行交互。硬编码的游戏规则允许更多的灵活性,包括连续镜头和定时奖励,而使用弹球文档/解析器系统允许更灵活,但更简单的规则。我们将从可配置游戏的界面开始,然后详细介绍一些硬编码的游戏规则,以便您可以选择自己的弹球游戏所需的配置。
有关此项目中引用的文件,请参阅此处的github存储库。
第1部分。设计游戏规则
图片中提供了弹球游戏的默认状态机。
这在默认启动码中提供。现在你有两个选择 - 要么为机器编写自己的代码,要么使用弹球游戏的指定格式。
步骤11:选项1.编写自己的Pinball.txt文件
在弹球文本文档中,您将找到三个部分:一个用于部分,一个用于“状态”,一个用于“操作”。在这里,您可以为每个组件定义特定操作。对于大多数组件,您可能希望坚持使用单状态状态机。例如,如果每次击中保险杠,则玩家应该得到100多个点,点亮斜坡灯,并获得100分,然后状态图将如图1所示,并带有相应的代码。如果你想让一个组件拥有一个多状态状态机,比如说你想要一个灯在碰到碰撞器时打开,然后在再次碰到它时关闭,你的状态图/相应的状态将如图2所示。我们的特定机器提供了结构,如图3所示,您可以为其定义规则。它们的名称,内部编码宏(您不必担心,但如果您决定研究源代码可能会有用)和中断代码如图3所示。图4将这些名称连接到playfield组件。
写弹球游戏的提示
由于游戏组件与特定中断(由“pos”字段表示)相关联,而这些中断又是由硬件定义的,因此我们不建议在“状态”字段之外过多地修改“部分”部分。我们建议保留状态0和动作0,用于对评分没有影响的组件,例如开始按钮和游戏开关。我们的代码如图5所示。
第12步:定义光和声音序列
如前所述,使用3至8解码器+一个主开关来控制板上的八个灯。通过将对应于零件代码的二进制编码版本的引脚写入高电平,可以点亮特定的灯。 light_sequence辅助函数为用户提供了一个界面,用于指定他/她想要点亮的灯,并在state_machine_headers.h文档中定义宏。为了方便您的编程,我们再次提供了一个表格。至于Sound,我们使用Arduino音色库为各种游戏事件编写短音序列。我们有四种预先制作的声音供你选择(使用executeSound(<你想要的声音>))。这些声音对应于长长的,愉快的序列,短暂的快乐序列,短暂的悲伤序列和长长的悲伤序列。如果您想编写自己的声音,可以在这里查看如何操作(pitch.h已包含在存储库中):http://www.arduino.cc/en/Reference/Tone
步骤13:将Pinball.txt文件加载到Arduino
一旦你完成了FSM的编写,这里就是如何将你的游戏加载到你的Arduino上(假设你使用的是Mac)。所有文件都可以在github存储库中找到。
- 解压缩arduino-serial zip文件。
- 导航到arduino-serial文件,并在此处保存您的游戏配置文件。 “Pinball.txt”提供了一个可以使用的示例模板。
- 打开Arduino。上传弹球游戏草图。
- 打开终端,然后键入以下命令:
- 使
- ./arduino-serial -b 9600 -p pinball.txt
- 现在,我们应该在Arduino的内存中读取和存储数据。如果有任何格式错误的行,Arduino将打印一条错误消息,您可以选择重新发送该文件。
- 当您使用终端上传代码时,例如当Arduino打印出“完成”消息时,您可以打开Arduino Serial来读取正在进行的游戏中的消息。
软件游戏的常见问题/优化
- 硬编码与可配置游戏 - 我们注意到硬编码游戏中的中断响应比可定制游戏中的中断更准确。这可能是因为可定制游戏有很多通用功能需要条件语句。这减慢了循环的读取速度,这导致我们错过了几次中断并影响了游戏的整体运行速度。为了解决这个问题,我们减少了配置文件游戏的一些可自定义性,以便在电路中实现可接受的响应时间。我们最初担心Arduino的RAM容量以及它可以存储多少游戏规则,但事实证明这不是最初预期的问题,而且循环的速度是更大的限制因素。
- 消除中断 - 由于弹球游戏的快速动作,我们有几种情况,在这种情况下,中断引脚接收到几个中断,弹球只击中一个游戏组件。另外,因为在编码器有时间正确读取所有输入之前接收到这些中断,所以中断将链接到不正确的组件。为了解决这个问题,我们使用了一个外部去抖动库,它在接收到第一个中断后1ms响应,在游戏读取输入代码之前为编码器引脚提供时间达到高电平。
- 显示 - 虽然串行显示允许游戏打印出详细信息,但玩家在玩快节奏的弹球游戏时很难读取输出信息。对于玩家必须使用附带的计算机玩游戏来说,这也很笨重。在未来,我们希望实现一种数字显示器,可以在用户可以轻松看到的显示器中显示得分和其他游戏信息,例如LED矩阵或7段显示器。
第14步:选项2:对自己的游戏进行硬编码的建议
首先 - 阅读state_machine_headers.h文档以了解存储有关状态机信息的全局数据结构。在加载到Arduino代码之前,您应该将这些数据结构初始化为Arduino IDE中的游戏规则。提供以下数据结构:
游戏结构用于保存有关每个部分状态的信息以保存有关状态转换的信息保存有关要执行的操作的信息的动作这些结构由读取文件填充。定义所有引脚的输入/输出。中断引脚应定义为INPUT引脚。
在主循环中,检查每个循环以查看是否已为每个游戏组件触发中断。在switch语句中定义每个游戏组件。
辅助函数executeState更新部件的当前状态,并根据编码内信息执行操作。
可以在文件“simplepinballgame.ino”中找到游戏代码的硬编码第一版。
第15步:连接一切
为了将Arduino与我们的驱动板接口,我们使用了一个protoshield来更容易地访问其他板上的引脚。有很多电线,所以要小心!按照电子引脚和布局中给出的布局将Arduino插座连接到相应的引脚。 Molex连接器应该有助于确定哪些连接器与哪些连接器连接。
这是一个简短的故障排除常见问题解答,以防您遇到我们遇到的任何常见问题:
输入编码器的特性是Arduino有6个输入引脚:5个共同显示触发了哪个输入,第6个引脚在触发任何单个输入时变为高电平。写入的代码仅检测此第六个引脚从低电平变为高电平的时间。因此,如果Arduino没有接收任何输入,并且您确定所有或至少大多数开关都工作,请检查是否有任何开关被卡住。例如,如果所有丢弃目标都已关闭且尚未被重新启动,那么这是一个关闭的开关并阻止Arduino接收任何其他输入。
检查确保固定射击器的螺母是否已完全拧紧,或射击器块是否松动。或者,给射手杆加油。
如果将开关置于太宽的通道中,允许球绕过它们,这可能是机械/设计问题。否则,它可能是代码中某处延迟太长的结果。例如,如果您正忙着使用音色库和delay()语句播放音调,那么Arduino将无法在此期间接收输入。我们使用的一个解决方法是仅播放斜坡拍摄,站立目标,开始按钮和游戏结束切换的声音,因为我们知道在新输入可能被触发之前我们将在这些镜头之后有多少时间。
不可否认,我们没有为特定灯或特定螺线管分配特定的接头,这意味着第一次插入所有内容时(或者如果不以某种方式标记它们,后续时间),输出引脚(或输出光编码)连接在一起任意顺序。使用反复试验来确定哪个引脚对应哪个输出并相应地调整代码。对于灯和保险杠来说,这并不是那么糟糕 - 但是肯定标记所有输入并记下哪个,因为该过程最多可以有24个值,并且需要更长的时间进行校准。
在5个编码器引脚完全解析其值之前,编码器有时会将指示器引脚拉高,这是不幸的。对于我们来说,我们知道当按下开关的数量是一个接一个时发生了这种情况,但它可能会以不同的方式显示出来。我们通过使用去抖动库来解决这个问题,在我们注意到切换发生变化和记录哪个开关之间会产生一点点延迟。但是要小心,因为太多的延迟(超过15-20mS)会导致您完全错过输入。
对不起,但我们还没有找到一个很好的解决方案。