Project

Nitendon Switch Tetris Bot

Switch Bot开发日记系列


今天主要优化了通信部分

首先是usb hub(adapter)到了,测试了一下非常给力,能够完美模拟手柄上的按键。不过有个之前没有考虑到的缺点就是需要使用ctrl+2组合键 来激活。所以要将下位机原有的部分逻辑重写。

一开始的逻辑是这样的:上位机Serial通过rx tx给下位机发送字节,下位机读取成字符串并根据keyPrefix与suffix分析指令内容。内容由 “command+splitter+commandNumber”组成。举个例子,比如需要依次按下”ab123”这几个键时,上位机发送的raw data就是”@ab123,1“的字节码。 由于传输时可能会有其他因素干扰,这里字符@作为keyPrefix,作为suffix,下位机只提取中间的内容。并依次对command遍历执行按下松开操作。

但问题来了,当需要按组合键的时候,这个方法就不太行得通了。虽然可以改变设计,使上位机发送过来的command更具体,但是这里我们是想让传输 的数据越少越好,从而减小延迟。所以上位机的程序还是保持原来的结构,在下位机获取到指令后做出一些改变。

下位机在遍历每个Command字符时只会遍历一个,如果我们想按F1键,若上位机传入”@f1“那么下位机会将”f1”两个按键打出来。在switch bot这个 应用里,我们会既有打印”f和1”两个按键的需求,也有打印F1键的需求。所以使用了”@f-1“作为F1的指令(因为没有打印”f-1”的需求)。传入下位机 中下位机就可以根据该字段进行判断。这里是把command.replace(“f-1”, “!”);(因为不需要打印!) 后面ctrl+2的命令也是按这种方法以此类推。


解决了另一个通信上很麻烦的问题:switch手柄按键响应速度要比pc慢,导致三次握手协议的传输速率不尽人意

在pc上实验时,每次按下和松开之间的延迟都是10ms,每行命令都能够被迅速的执行。这种情况下,使用握手协议虽然保证数据通信但是限制了传输速度(接收到命令后需要返回 给上位机commandNumber,上位机要把接收到的状态传回下位机,由于它们都是单线程执行,都要在此过程中等待另一线程的结果)

所以这里改成了单方向(上位机到下位机,下位机只执行收到的指令不返回状态)传输的方法,上位机计算按下command对应键位所需的时间再加上额外的的transferTime,只有在这 延迟之后才能对下位机发送下一条命令。测试了一下虽然感觉很不靠谱但是每条命令都能准确迅速地执行。


在Tetris99中,如果想开始新游戏或者返回主菜单需要长按A/B键,这一点还没有实现不过可能会用和上面F1按键实现相似的解决方案(比如”@a+3b+4”就是长按a键三秒后长按b键4秒之类的)。