2018-6-11 17:09:23 [显示全部楼层]
14448浏览
查看: 14448|回复: 6

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机

[复制链接]
ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图1

先上视频:


它的初代原型机型号为Rombus3000,随后是RombusCT,然后才是最近流行的Tomy Turning Dashboard Outrun Arcade(实际上我将此款型号命名为RombusGT),但是这一次我采用了另一款经典的弹球机。因此我后面将向您介绍其具体情况——Rombus弹球机。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图2


硬件部分


硬件清单:

在项目初始阶段,我通常会着重考虑硬件的配置情况,因为我需要在设计时了解其具体尺寸。我的首个创意归功于Rasberry Pi,因为我对其非常熟悉,并且已经将其应用于其他街机游戏,但是等到它上线后我才发现在弹球仿真方面,这些运行在Linux系统上的迷你电脑未必是最佳选项。弹球仿真似乎都是基于Windows系统开发的。幸好我印象中曾经学习过一款名为LattePanda的开发板,因此我抱着试一试的想法,最终采用了这种方案。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图3

LattePanda的优势之一在于其内置Arduino Leonardo,非常适合处理多线程控制任务,并且支持多台显示器,这最终使得在线“背景屏幕”成为可能。
对屏幕本身而言,我采用官方的LattePanda 7英寸显示屏作为显示区域,并将低廉的5英寸HDMI显示屏作为其背景屏幕。其他关键硬件元素还包括一台 3.7W立体声l喇叭,以及一对Pimoroni 4ohm迷你音箱,最后我还从Arcade World(街机世界)官网以及众所周知的在线拍卖网站上购买了一系列的街机按钮。


结构设计

该设计方案都是通过InkScape软件手动完成的。决定机器尺寸的核心元件实际上是2台显示器。我从显示区域开始设计,留下一定的边框区域以及铝制边缘,然后计算出侧边尺寸以及整体结构的尺寸数据。按钮放置在适宜区域,随后我针对扬声器、电源插座、辅助按钮和风扇专门进行了布局设计,特别是风扇对于保证LattePanda不过热至关重要。


ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图4

然后我通过类似的方式制作了背部外壳,外壳与屏幕无缝衔接,并留出足够的区域空间,方便连接HDMI和迷你USB连接器。

原型机
由于这毕竟属于一次试水,所以我搭建了很多原型,因此严格意义上讲这并不是一次常规的系统设计和搭建方案,实际上我中间进行了多次推到和重建。
在首个原型机中,为了将屏幕固定到位,我采用了部分内置脚手架的设计方案。我希望减少螺钉的数量,因此我采用了部分内壁和梁将屏幕固定在所需位置,同时为布线和组件预留一定的内部空间。最终这种解决方案的运行效果非常理想,并且应用到我的最终版本中。当然我在最终版本中对其进行了一定的调整,以便能够在后来的侧滑轨增加一些固定螺母。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图5

随后我在主机上尝试打孔,并采用了不同的按钮连接方案。再次强调,我并不希望到处都是螺丝钉,所以我最终选择了榫卯结构和木胶。我的原型机采用激光方式进行制作,厚度为3mm,我原本将其作为最终版本的总配线架(MDF),因为我认为其太脆弱了,但是实际上当搭建完原型机后,我发现其硬度超高且质量轻便,所以实际上我将其应用于最终方案中。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图6

尽管在确定基础框架的过程中我打算拆除背板,但是当我发现所有外围部件都可以安装在背板时,我放弃了这个念头,而是选择将其安装到位,并嵌入显示屏幕区域,这样我就能在后台观察所有数据。最终证明这片区域的处理工作还是相当棘手的,所幸其处于可控范围内,因此我对其相当满意。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图7

基座的实体模型已经搭建完毕,接着就是定制侧面导轨和支脚的工作了。我最终选择了铝制角方案,并利用琢美(Dremel)电磨机工具进行了裁剪,这样就使其显得浑然一体。尽管这只是初步阶段方案,但是我确实需要考虑此元素,因为我知道我希望一劳永逸。我原本打算在侧导轨顶部安装“锁定杆”,但是实际效果并不理想,所以我最终在侧导轨上开槽,以保证整体的平齐和整洁。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图8

在所有的部件安装方面,锁定杆将安装在实际前置屏幕上(同时夹住挡板切口),并将切口插入基座中。随后侧导轨将安全固定前置屏幕,并挡住定位槽口。如前所述,为了方便安装,我在屏幕支架上保留了部分固定螺母,这样在最后完工阶段时我可以将其固定到位,但是在此之前我没办法将其放置在准确的位置。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图9

这些支架被切割成合适的尺寸,然后通过钻床进行开孔,并利用小型夹具卡在合适的位置。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图10

在这方面,我很快就完成了相关的设计工作,并通过3D打印方式制作了部分小型支架,以免其刮伤表面。它们的影响可能微乎其微,但是其外观却非常精致。这都是一些很小的细节。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图11

原型机的最终元素是背景屏幕。最终我采用了前期的设计方案,即在显示屏周围预留了充裕的空间区域,尽管这些尺寸与预期完全不相符,但最终其减少了整个基础框架的尺寸。这就意味着显示器的HDMI/USB连接器内部排列非常紧凑,但是好在这种方式对运行未产生任何影响,所以我开心不已。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图12

同样的,在早期的设计方案中,我没有采用卡槽方式将屏幕/面板固定到两侧/顶部,但是随后我对这种方式进行了更改,即在前面创建了一种榫卯结构,然后将所有元素都卡入到位,这样就保证了整个侧面和顶部的干净整洁。为此我还采用了专门的显示器安装策略,为其创建了单独的背板,使其通过压铆螺母柱即可与外壳楔形结构紧密贴合,同时保证它和前置屏幕位置正确。这点同样卓有成效。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图13

最后一步是将后置屏幕外壳拆除,基于此我将其嵌至外壳顶部,然后利用一种源自Pimoroni网站的炫酷紧固系统(仅包含一个凹槽和O形环)完成拆卸工作。成本低廉,行之有效。完美!
ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图14


外观制作

我做的第一个贴花是硬币机械按钮。我在RombusCT 制作了类似的效果,所以我希望重复此项工作,因为它的外观看起来确实相当不错。这项工作是通过InkScape软件在部分醋酸盐制品上印刷完成的,随后我在中间嵌入了一个照明按钮。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图15

对于主机而言,我花了相当多的时间制作了具有一定复古气息的logo,并在其两侧布置了一种简单但是粗犷的条纹图案。此外我还为背景屏幕外壳设计了一种非常炫酷热门的弹球设计方案,这让其看起来充满活力。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图16


一旦我感受到设计带来的快感,那么后面的成果打印和原型机安装检查也将使我倍感兴奋。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图17

作为贴标的重要环节,我还通过激光切割方式整理两台显示器的边缘部分,最初这些切除的部分都显示为红色,但是很快它们就最终变为宽度为0.8mm的黑色塑料边缘。这些边缘遮挡了屏幕边缘,同时显得整个显示屏特别干净整洁。


搭建组装
随着原型和贴标最终磨合,现在是时候去对主机进行搭建了。这项工作我只花费了一天时间。首先我将所有的木片进行重新裁剪,然后利用木胶和胶枪将其粘在一起(木头胶起永久固定的作用,但是胶枪可以进行临时修复,这样我就无需等待木胶自动干固了)。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图18
ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图19

在这一点,我还专门绘制了部分边缘花纹。在之前的设计阶段中,贴花都是距离边缘1或2mm。这意味着我无需让它们完全对齐。为了不显示任何可见的木质边缘,我将所有可见区域都涂上黑色颜料。为此我使用了一支油性黑色马克笔。在RombusCT型号中,我花了好几个小时的时间完成这项涂覆工作,但是我后来发现这可以通过一种非常友好和快速的方式完成涂覆任务,并达到类似的效果。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图21

这种方法就是提前通过胶水和涂料刷在所有待组装的元件上并晾干,使用乙烯基贴纸进行打印并粘贴在贴花上,把黑色的塑料边框剪掉,将所有外设(扬声器、风扇、按钮等)都固定到支架上。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图20
ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图22

布线
在布线前,我首先将LattePanda安装在框架上。我在设计文件中小心地画出各个安装孔,并在其下方创建一个通风孔,以确保风扇打开时通风状况非常良好,从而保证LattePanda温度适宜,这点非常重要。不幸的是,LattePanda无任何外部电源开关引脚,因此我还不得不在基础框架上打孔,以便能够通过伸出手指接通电源。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图23

LattePanda本身安装了部分压铆螺母柱,并且其顶部包含一个定制切割的压克力面板,以放置音频放大器和配电区域界限。电源功率为5v 4A,通过壁挂式barrel jack安装在背后,并且其背板接线可以对所有不同的外设进行供电。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图24

需要注意的是,选择电源线应确保您使用的线规准确无误。起初我采用了部分价格低廉的barrel jack 跳线,并将其接至LattePanda,但是我发现电源出现严重的问题,设备也逐渐变为黄色。直到我把电线换成了22AWG的实心线(感谢Pimoroni帮忙解决了这个问题),这些问题立刻就迎刃而解。这个事情说明,电线的质量至关重要。
外围接线非常简单(只是过程略有些繁琐)。LattePanda引脚通过按钮接地。风扇直接连接到电源回路中。扬声器连接到放大器,然后通过螺丝接线端子连接到耳机插孔,并最终将音频馈入功放中。定制的micro USB适配器用于向后置屏幕显示器供电。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图25

大部分按钮都采用标准制式,但是柱塞除外。我原本希望其能够真正嵌进去,但是最终我决定采用仅具装饰作用的金属旋钮来代替柱塞,但是这却使其变成了一个触摸型电容。它不会弹出,但是它却可以实现同样的功能。为此,我采用了周围的一个廉价的电容式触摸模块。我用一点金属焊锡使得旋钮和紧固螺栓紧密粘连。老实说,这可能有点问题以及有点过于敏感(实际上您未接触到弹球就可能会把它烧坏),在大部分情况下,它已经足够完美了。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图26

最后需要连接的设备是显示器。背景屏幕显示器通过一根纤细的HDMI电缆接至底座的LattePandas HDMI插座上,主显示区域连接专用的板载插座。由于显示器电线很短,因此我在易趣网上额外买了一根柔性扁平排线和适配器,以延长电线长度并能够更容易地在不损坏任何电缆的情况下进行拆除。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图27
软件

ARDUINO控制按钮设置
如前所述,LattePanda的优势之一在于其配备了板载Arduino Leonardo。它能够与按钮控件实现无缝衔接。为了使按钮能够与模拟器协同工作,我需要将这些按钮转换为键盘按键。幸好Arduino Leonardo能够模拟键盘,这点简直太棒了。
如需做到这一点,我们需要通过草图将按钮映射到所需按键。这里我使用了一些巧妙的方法,改变了Picade草图的初衷意图,删除Picade电路板(实际上Arduino Leonardo位于其盖板下方)的冗余环节,并修改按键的映射关系,以与设置参数实现相互匹配。
该项目的所有脚本都能够在我的Rombus Pinball GitHub仓库中找到,我假设其位于LattePandas桌面的RombusPinball文件夹中。最关键的Arduino文件是RombusPinball.h和RombusPinball.ino(您可能还需要部分库文件,但是此处我不会逐一解释,您只需确保这些文件位于主脚本附近即可)。
RombusPinball.h文件只是简单地定义了部分变量,以引用我们的按钮和按钮状态。

[mw_shl_code=applescript,true]#include <arduino.h>
#include <Keyboard.h>

#define RP_BUTTON_COUNT 11

#define BTN_FLIPPER_LEFT 11 // Green
#define BTN_FLIPPER_RIGHT 5 // Purple
#define BTN_MAGNA_SAVE_LEFT 12 // Yellow
#define BTN_MAGNA_SAVE_RIGHT 4 // Grey
#define BTN_START 10 // Blue
#define BTN_COIN 13 // Brown
#define BTN_PLUNGER 6 // White

// Back buttons labelled as if looking
// directly at them with the back of
// the pinball machine facing you

#define BTN_BACK_LEFT_TOP A0 // Blue
#define BTN_BACK_LEFT_BOTTOM A1 // Orange
#define BTN_BACK_RIGHT_TOP A3 // Yellow
#define BTN_BACK_RIGHT_BOTTOM A4 // Green

typedef struct
{
uint8_t state; // what state was the input last in ( HIGH/LOW ) unsigned long last_change;
} button_state; [/mw_shl_code]

其中RombusPinball.ino文件包含处理和映射按钮点击过程的主例程。

[mw_shl_code=applescript,true]
/*
* Borrowed heavily from Pimoronis Picade sketch at https://github.com/pimoroni/Picade-Sketch/tree/master/Picade
*/

#include "RombusPinball.h"
#include "TimerOne.h"
#include <Keyboard.h>

#define DEBOUNCE_DELAY 25
const uint8_t rp_pins[] = { BTN_FLIPPER_LEFT, BTN_FLIPPER_RIGHT, BTN_MAGNA_SAVE_LEFT, BTN_MAGNA_SAVE_RIGHT, BTN_START, BTN_COIN, BTN_PLUNGER, BTN_BACK_LEFT_TOP, BTN_BACK_LEFT_BOTTOM, BTN_BACK_RIGHT_TOP, BTN_BACK_RIGHT_BOTTOM };
const uint8_t rp_keys[] = { KEY_LEFT_ARROW, KEY_RIGHT_ARROW, KEY_LEFT_CTRL, KEY_RIGHT_CTRL, '1', '5', KEY_RETURN, 'u', 'd', 'q', KEY_ESC };

static button_state button_states[RP_BUTTON_COUNT] = {};

void setup() {
Serial.begin(9600);
//while(!Serial);
Serial.setTimeout(100);

// Setup pins as input with pullup resistor
for ( uint8_t i = 0; i < RP_BUTTON_COUNT; i++ ) {
if (rp_pins == BTN_PLUNGER) {
pinMode(rp_pins, INPUT);
} else {
pinMode(rp_pins, INPUT_PULLUP);
}
}

Timer1.initialize(5000);
Timer1.attachInterrupt(update);
Timer1.start();
}

void update(void) {
for (int i = 0; i < RP_BUTTON_COUNT; i++)
{
uint8_t state;
state = !digitalRead(rp_pins);
if (state != button_states.state && (millis() - button_states.last_change) > DEBOUNCE_DELAY) // has this input changed state since the last time we checked?
{
button_states.state = state; // update our state map so we know what's happening with this key in future button_states.last_change = millis();
handle_key(i, state);
}
}
}
bool handle_key(uint8_t i, uint8_t state) {
uint8_t pin = rp_pins;
uint8_t key = rp_keys;

if (pin == BTN_PLUNGER) {
state = state ? LOW : HIGH;
}
if (state) {
Keyboard.press(key);
} else {
Keyboard.release(key);
}
}
void loop() {
// Do nothing...
}[/mw_shl_code]
这看起来似乎一目了然,但是实际上用户会发现按钮不断地点击/释放,并将这些动作都转换为键盘的点击按键/释放过程。唯一有点难以理解的是,帽式触摸传感器在高电平有效(您可以像其他按键那样设置其低电平有效,但是这一点我很晚才意识到),所以我们需要明确定义并设置HIGH和LOW值的切换点。
通过写入草图,我们的控制器设置参数可以通过板载Arduino IDE轻松上传,现在我们准备设置模拟器。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图28



模拟器设置

这是我在博客文章所提及的我一直有点害怕的环节。尽管在Rombus3000和RombusCT版本中,模拟器可以非常轻松地通过RetroPie进行设置,但是弹球仿真的场景则完全不同,并且极端分散。如果您打算自行解决弹球问题,我恐怕除了登录论坛并开展全面研究,没有其他捷径可走。根据我的研究结果,模拟器主要分为Visual Pinball和Future Pinball这两种方案,但是二者都需要其它模块才能与背景屏幕显示屏和DMD显示屏(点阵显示屏能够显示您的分值等)协同工作,然后您将能够通过表格选择器用户界面来使表格获得更佳的用户体验,这似乎也是两个最主要的选项,即Hyperspin或Pinball X。
在我的模型方案中,我决定采用Visual Pinball和Pinball X作为前端。
现在,我恐怕我没办法跟您讲解这部分的每个具体步骤,坦白来说,此过程需要您大胆尝试并勇于犯错,这样才能够准备就绪,我并不知道我采取的哪些步骤是必要的,并导致事情最终朝着目标的方向发展,所以我只能非常模糊地告诉您,这些都需要您自己独立摸索完成。
基本上您希望实现DirectB2S与Visual Pinball协同工作,后者是背景屏幕驱动器。VPForums论坛上应该有包含这二者的集成软件包,这将使安装过程变得更加简单。在运行安装程序前,您需要确保两个显示器都正常开启和设置,但是某些步骤可能是用于选择显示屏和背景屏幕的显示器。
您可能还希望从同一论坛下载部分表格,您可能会猜测此过程并不会一帆风顺。这里我需要提醒一下的是,您可以搜索“B2S”表格,因为这些表格对于我们设置的配置参数而言效果最为明显。
安装至少一个表格后,您应该能够对Visual Pinball进行测试,并确保配置符合您的需求(特别是Key配置能够在无控制器配置参数的情况下正常工作),并且一切都符合预期效果。如果没有,请务必查看论坛寻求帮助。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图29


当Visual Pinball工作后,您随后可能会希望安装Pinball X。虽然我觉得非常遗憾,但是我不得不说的是,恐怕事情没有您想象的那么简单。您需要安装并通过配置向导进行自定义设置。设置完毕后,您需要找到并下载VP安装的各种表格媒体包。安装这些软件后,您可以在前端用户界面选择它们,随后Visual Pinball将会启动。

ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图30

正如我所说,这看起来有点复杂,并且显得整个过程过于简化,但是至少我希望它能够帮助到您,前提是您希望自行尝试处理整个架构过程。
HACKS和TWEAKS
在这方面,我希望一切进展顺利,然而我不得不对其它一些事情做出调整。
首先,由于某些未知原因,LattePanda偶尔会擦除Arduino绘制的所有图形,导致最终我不得不编写单独的批处理脚本,以便在Pinball X UI启动时刷新Arduino固件(友情提示,Pinball X设置中有个选项能够让您配置的脚本在应用程序启动前运行)。
其次,我还碰到过一个问题,即Visual Pinball窗口无法以正确顺序打开,更重要的是,主显示区域并没有成为活动窗口,这意味着它没有做出任何响应,除非您通过数遍点击窗口。然而这起不到任何作用,所以我最终不得不使用一个名为AutoHotKey的应用程序来保证显示区域始终为活动窗口。我在背景屏幕后方的DMD窗口也碰到过类似的问题,我试图用同样的方法进行修复,但是我没有成功,所以这种方式还是有点问题。如需启动时激活此脚本,请在C:\Users\LattePanda\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup文件夹中创建脚本快捷方式。
上述两个脚本都可以在我的Rombus Pinball GitHub仓库中找到。



结论

我涉足该项目并简单地认为这将是另外一项非常好的模拟器项目,跟我以前做过的项目类似,但是实际上弹球模拟器工作比我预想的要困难得多。这最终迫使我不得不做出一些妥协,但最终我仍然认为自己制作的成果相当炫酷而且特别。我并不认为它真的具备了能够与真正专用的PC弹球模拟器一争高下的实力,因为专业人士都开始尝试制作4K显示屏了,但是对于像我这样的休闲玩家来说,这却是一个非常有趣的小东西,无需占用太多空间,因此它完美地满足了我的各种需求。

作者:
ROMBUS PINBALL——用LattePanda制作一款最新的迷你弹球机图31


DFB1_4Kx5Yz  见习技师

发表于 2018-6-12 16:10:12

楼主,贴花是咋做的啊?太6了
回复

使用道具 举报

ddplys  高级技师

发表于 2018-6-12 17:57:24

学习一下,panda太贵了,只能用树莓派研究看看
回复

使用道具 举报

luna  初级技神
 楼主|

发表于 2018-6-13 14:12:33

DFB1_4Kx5Yz 发表于 2018-6-12 16:10
楼主,贴花是咋做的啊?太6了

这个项目用的是:乙烯基贴纸,自己设计好图案,找印刷店打印一下就可以了
回复

使用道具 举报

luna  初级技神
 楼主|

发表于 2018-6-13 14:22:16

ddplys 发表于 2018-6-12 17:57
学习一下,panda太贵了,只能用树莓派研究看看

这个项目作者有做过Rasberry Pi版本的,如果你是用Linux系统上跑程序,我觉得可以看一下作者设计的Rombus3000:https://circuitbeard.co.uk/page2/,机型有点不一样。如果是玩windows系统开发,那我还是推荐LattePanda,性价比高的不要不要的~
回复

使用道具 举报

DFB1_4Kx5Yz  见习技师

发表于 2018-6-13 15:43:42

luna 发表于 2018-6-13 14:12
这个项目用的是:乙烯基贴纸,自己设计好图案,找印刷店打印一下就可以了  ...

谢谢了
回复

使用道具 举报

1973742214  高级技师

发表于 2018-6-18 16:14:34

厉害厉害,游戏高手
回复

使用道具 举报

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

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail