带你读《JavaScript机器人: 用Raspberry Pi、Arduino和BeagleBone构建NodeBots Make:JavaScript Robotics》之三:节点船

简介: 本书将向你展示用Raspberry Pi、Arduino和BeagleBone构建NodeBots Make以及如何使用它来编写你所制作的东西。让使用JavaScript控制硬件变得简单而有趣。

点击查看第一章
点击查看第二章
|第3章|

节点船

Sara Gorecki

在2014年举办的JS开发者大会上,节点船在一个全时工作室中开始。机器人+水=乐趣!这一天结束的时候,参与者们用他们的笔记本电脑控制他们的船在酒店的泳池中飞驰。活动中我有幸加入了一个四人小组,负责全程引导与会者设计出他们的小船。本章将介绍如何制作机器人小船,如图3-1所示。

image.png


图3-1 节点船

设计一艘船的挑战之一就是把它的硬件和你的电脑连接起来,毕竟你不希望带着你的电脑下水或是把你的船限制在USB线的长度范围之内。因此,我们将使用离线技术来控制我们的船,了解更多有关Spark核心板请见“Spark WiFi开发工具包”。
如你在图3-1中所见,船体采用塑料材质,并进行了密封防水,里面嵌有面包板和电池盒。图中的船体是用一个8.5英寸×5.5英寸×2.5英寸的塑料文具盒制成,顶部使用按扣开关(手工店里就可以买到),一次性的食品包装盒或者小的储物盒也可以。无论你用什么,记得在上面打个孔。
选择好了塑料容器之后,就可以确定泡沫板的尺寸了。图中的船使用的是两块2英寸×12英寸×4英寸的泡沫板,建议你多用点泡沫板,这样小船的安全系数能高一些,而且,泡沫板也很便宜,不是吗?
在组装的时候记得用硅胶把小船上打的孔封好,务必要确保胶的厚度和密封性。如果你手边没有硅胶,E6000速干胶的效果也是可以的。

3.1 材料清单

表3-1列出了构建船只所需的材料。

表3-1 物料清单


image.png

工具
制作小船所需工具:

  • Micro USB线(用于设置Spark核心板)
  • 剥线钳
  • 烙铁
  • 焊锡线轴
  • 英寸钻头的电钻
  • 热胶枪
  • 浴缸或儿童游泳池

3.2 潜艇电机吊舱

在制作小船的时候,务必注意电子设备的防水,防止短路。否则,项目只能提前结束了。不过如果不下水,小船又如何劈波斩浪呢?
下面隆重介绍田宫潜艇马达!它有一个通过锁扣扣紧的防水外罩,可以有效地保护电机。全封闭的外罩通过一个吸盘和船身相连,这使得电机无法从外部进行控制。因此在组装时我们需要对其进行改装从而通过Spark核心板驱动电机。
由于田宫潜艇使用双向电机,我们可以使用电机驱动器驱动电机进行双向运动。而且在改装马达和外罩,添加其他电子设备的接线后,部分电机驱动器,包括我们将使用的电机驱动器还支持对速度的控制。

3.2.1 为什么要使用电机驱动器

我们可以直接将大多数I / O零件(LED,伺服等)连接到微控制器上的相应引脚,然后它们就可以正常工作了(可能需要电容器或电阻器),然而电动机却不是这样。
你遇到的问题是电机消耗的电流过大。事实上,它所需要的电流比Arduino或Spark提供的电流更大,甚至可能会超出芯片的安全范围!因此如果直接将电机连上微控制器,电机非常小的话可能还好,不过很有可能会因电流过大把元件烧毁。
为解决这个问题,我们需要用到电机驱动器或一种称为H桥的芯片。这样,在实现芯片控制电流的同时还可能通过外部电源为电机供电。
使用驱动器或H桥也带来了额外的好处。一些电机驱动器,例如我们用来制造这种船的SparkFun驱动器(见图3-2),还包含一些额外的零件,可以实现对电机转速的控制。

image.png


图3-2 SparkFun 电机驱动器

3.2.2 电机吊舱零件

田宫潜艇马达设计为在吊舱内插入电池来使用,但我们改装它以使用外部电源,这样我们就可以在电脑上控制它的开关。因此,我们不需要子工具包中的所有零件。我们所需要的是外壳,一些蓝色塑料冲孔零件,黑色胶圈,小管润滑脂和电机。
由于潜艇吊舱中包含的方向舵太小,无法有效操纵小船。因此后面我们将另外制作方向舵,所以吊舱中所附带的大部分蓝色塑料零件已经没有用了,不过有两个零件是必不可少的,一个是推进器,另一个是夹在电机吊舱上的一端扁平的小环,如图3-3所示。
田宫改进型
这些都是黄色田宫马达的改进型,红色的迷你田宫马达不过是外形上做了点改变且底盘小了点。

image.png


图3-3 随附的塑料套件

将螺旋桨和夹子打出并将它们放在一边,直到完成焊接。

3.2.3 修改电机

接下来就需要焊接电机的控制线路了,首先将两根电线焊接到电机上。然后,将这些电线连接到船内的Spark核心板。电机吊舱内空间有限,必须选择柔软的细电线。事实证明,标准的跳线是不二之选。以下是具体的步骤:
1.拿两根最长的跳线。如果你的跨接线具有较粗的端头,请使用剪线钳将其剪掉,然后剥去两端的橡胶绝缘层,如图3-4所示。切记不要切断里面的金属线。
2.在马达上。你会看到一侧有两个小金属环伸出来。这些是用于为电机供电的正极和负极接线柱,我们要把跳线焊接到接线柱上。

image.png


图3-4 剥线跳线

3.将剥好的跳线穿过电机上的金属环,以确保将它们固定到位。
4.定位电线,使其长端靠在电机主体上,向后指向电机的主轴/螺旋桨端。也可以将电线连接到电机主体上,以便在焊接时将它们固定到位。
5.将跳线焊到电动机接线柱上,如图3-5所示,保持跳线朝向线圈的外边。没必要焊得非常完美,但是要保证能够装上我们之前留在电机尾部的蓝色塑料夹。

image.png


图3-5 将电线焊接到电机上

确保长跳线末端的裸露金属不会接触电机的金属主体。这可能会导致电路短路并使电机无法工作。为避免这种情况发生,我们可以在可能有接触的电机周围缠上一些胶带。

3.2.4 测试电机

现在,检查下电机焊接的焊接效果如何。我们可以将焊接到电机上的两根电线与一节AA电池的正负极相连。如果电机开始旋转,我们就可以进入下一步了。如果没有,请检查焊点,确保焊接良好,并且电路没有短路;或者,换节电池试试。

3.2.5 完成电机

完成焊接并检查之后,在装入电机盒之前还需要做几项准备工作(需要之前准备好的蓝色塑料环、黑色橡胶圈和小管润滑脂):
1.将蓝色塑料环卡在电机的白色端,确保夹子在电线的一侧。夹子应紧贴在电机侧面的凸起上,如图3-6所示。

image.png


图3-6 将环卡在电机上(附彩图)


在电机套件中,该塑料环是用来将接线柱和电池的接线固定在一起。在我们的项目中,它将有助于将电机固定在吊舱后部,并在关闭时保持电机与螺旋桨的连接。
2.在橡胶圈的平端涂抹润滑脂。这将有助于密封,以防止你的电机进水。(适量即可,在后面我们还会用到润滑脂。)
3.将橡胶圈平的一面朝向电机,穿到电机的主轴上,如图3-7所示。
在电机主体和橡胶圈之间填满润滑脂。如果有明显的间隙,则继续加添润滑脂。

image.png


图3-7 绝缘橡胶圈

3.2.6 插入电机

现在可以将电机插入吊舱了!
1.首先是吊舱的后半部分。它的后端应该有一个洞。
从洞里可以看到里面向吊舱内凸出的塑料垫片(见图3-8)。当插入电机时,我们要注意这些塑料垫片的位置,这些塑料垫片可能会卡住电线。

image.png


图3-8 吊舱内部

2.将马达上的接线向内弯转,使它们并拢,指向远离电机主轴的方向并将它们靠在电机的主体上。两根电线应并拢,向着电动机的中心,如图3-9所示。

image.png


图3-9 弯转导线

3.将电线固定到位,将电机插入吊舱的后半部分,如图3-10所示。

image.png


图3-10 插入电机

在插入电机时,注意不要把电线夹进去,蓝色塑料环上有一个小间隙,可以穿过它们,始终保持电线是伸出吊舱的。
4.将电机推入吊舱到底,并使主轴从吊舱的后端伸出。
5.将之前准备好的螺旋桨安装到电机主轴上,如图3-11所示。现在后半部分的安装就完成了。

image.png


图3-11 螺旋桨

3.2.7 打孔

我们需要在吊舱上打几个孔以将电线伸出来。在决定钻孔的位置时,记住以下几点:
在吊舱的前部有很多空间可供使用,但空间越向前越窄;钻的孔越向前,穿线的难度越大,而且在靠前的位置钻孔也会浪费电线的长度。
在吊舱内部,有一条用于固定电池座的一部分的凸边。这个位置的吊舱壁更厚,尽量避免在这个位置打孔。最后一点,注意电线是朝向小船的方向伸出来的,应避开电机吊舱外部的凸起部分。一切准备好后,请按照以下步骤操作:
1.将吊舱的前半部分和后半部分对齐,如图3-12所示。按照下面的步骤钻孔。

image.png


图3-12 潜艇吊舱预装配

在吊舱的前半部分标记好电线伸出的位置。
2.使用1/8英寸钻头在标记的位置打孔。确保孔的大小能够同时穿过两根导线。
3.孔打好后,将电线从孔中依次穿出,如图3-13所示。

image.png


图3-13 修改接线后的吊舱

3.2.8 关闭电机吊舱

电机接线完成后,我们就可以合上电机吊舱并密封潜水艇上的孔了。
1.在接头的接缝处涂上之前剩下的润滑脂会使密封效果更好。
2.将吊舱的两半对接上,并把接头处挤出的润滑脂擦干净。
3.把电线拉直,但要注意不要用力过大以免拉断接头。将硅胶或胶水密封剂涂在钻出的孔上,把孔密封好。
4.将吊舱放好,等它干燥即可。如果你有让它快速干燥的配方,应该只需要几分钟就干燥到可以移动了。
这些胶水需要一天才能完全凝固,但如果赶时间的话,不必等这么久。几个小时就可以了。这也是为什么我们要先进行船体改装。

3.2.9 电线的防水

如果你在焊好电线组装好电机吊舱之后发现电线有点短;或者后面想要改变电机吊舱的位置,需要延长电线的话,务必做好电线的防水工作。
热缩管可以保证焊接处的密封性。你可以购买热风枪来收缩管子,但是一些收缩包装可以用一个好的吹风机加热。确保购买与你可用工具兼容的收缩包装。
然后:
1.在焊接两根电线之前,将一根适当直径的管子套到其中一根电线上。
2.将两根导线焊接在一起。
3.把热缩管套在两根电线的焊接点处。
4.加热热缩管直至其收缩到足以在电线上形成良好的密封。
5.如果担心热缩管的密封性,可以用一些硅胶或防水胶将热缩管两端密封。
这样电线的防水问题就解决了。

3.3 安装Spark核心板

现在我们已经完成了吊舱的改装,接下来我们将对Spark核心板(见图3-14)进行声明,并连接硬件实现用计算机对其进行控制。如果你还没有做完这些,检查你的“Spark WiFi 开发套件”。我们将引导你完成整个过程。

image.png


图3-14 Spark核心板

部分Spark核心板芯片有一个芯片天线,而另一些则有一个光纤连接器。光纤连接器版本上装有板载天线。如果你的Spark核心板有光纤连接器,需要接一个外接天线,可连接柔性天线或“鸭”天线。在连接WiFi之前,检查下你的天线是否安装好了。
我们可以在智能手机App上通过WiFi声明Spark,但如果有许多WiFi设备或任何其他设备时,通过USB连接Spark并使用Spark CLI命令行工具进行声明会更便捷,而且还可以避免意外地声明其他人的设备。
因为你将基于当前的WiFi网络配置Spark,请记住,如果你将船带到另一个不同WiFi网络的位置,你将不得不重新配置!组装船时请切记这一点。你不需要为了配置Spark的WiFi凭证而把整个船拆掉。
在配置过程中,如果Spark有异常情况出现,闪烁别的颜色,请查询相关文件以获取更多信息。
在运行你的船的代码之前,你还必须用VoodooSpark替换Spark的存储固件。“Spark WiFi开发套件”中也对此进行了概述。
测试Spark
在进行下一步之前,将Spark连接到电池组并对其进行测试,以确保其工作正常并可以正常接收计算机的命令:
1.将Spark插入面包板,并确保它横跨面包板中间的分隔板。
2.将电池组的红线连接到Spark标记VIN的引脚上。
3.将电池组的黑线连接到Spark上的GND引脚。VIN和GND都位于电路板的左上方(当USB端口朝上时)。图3-15显示了应该如何接线。
4.将四节AA电池装入电池座。Spark将开始工作,闪烁绿色表示它正连接到WiFi,连接成功后就变成了青色的呼吸灯(缓慢淡入和淡出光线而不是稳定闪烁)。

image.png


图3-15 线路布置

3.4 第一个Spark项目

现在,我们可以创建一个简单的测试程序,以确保你的Spark可以通过WiFi正确接收命令。就是如图 3-16所示的闪烁的LED灯,Spark有一个与引脚D7共享连接的板载LED,下面我们将编写一个简单的程序来使这个LED灯闪烁。
现在,你可能已经完成了基本的Johnny-Five设置,然后按照下列步骤操作

image.png


图3-16 运行Spark测试程序

1.在编程之前,你需要为项目创建一个文件夹并将目录更改为它。
进入项目目录后,可以通过使用命令npm init创建pack-age.json文件来开始项目。这将引导你完成创建项目的package.json的步骤,该文件将存储代码依赖项列表。
2.由于在此项目中所使用的是Spark而不是Arduino,所以我们需要使用Spark-IO模块作为Johnny-Five的插件。在项目目录中安装Johnny-Five和Spark-IO并添加--save标志以自动将这些模块添加到package.json文件中:
image.png
接下来创建一个名为test.js的新文件。这是你编写代码来控制Spark的地方,如例3-1所示。
例3-1 Johnny-Five的Spark测试本
image.png
image.png
①在此文件中,你应首先调用Johnny-Five和Spark-IO模块,并将它们设置为变量。这样就可以访问此文件中的Johnny-Five和Spark-IO模块。
②初始化一个新的Johnny-Five板。执行此操作时,你可以传入JavaScript对象作为参数。由于我们正在使用Spark,并且将使用Spark的输入/输出而不是Arduino,我们将指定输入输出并将其设置为新的Spark()。
③现在程序已经知道要查找Spark了,但它仍然不知道如何识别你的Spark。为此,你需要将JavaScript对象作为参数传递给新的Spark对象。在配置Spark时注意指定token(令牌)和deviceId(设备ID)。
“最好把访问令牌和设备ID作为环境变量存储从而可以把它们从源代码中去掉。”——《Spark WiFi开发零件》
将此代码保存在test.js 文件中后,继续使用命令node test.js运行它。Spark核心板上星星符号旁边的蓝色LED小灯(如图3-16所示)开始有规律地闪烁。现在你的Spark就全部设置好了!切记,如果你遇到任何问题,可以查看《Spark故障排除指南》。
注意:运行几分钟后Spark上的芯片会变得非常热!
现在请拔下电池组,因为要稍微修改一下电池组的走线。

3.5 焊接电机驱动器

现在,在继续组装船之前,还需要进行一点焊接。现在SparkFun电机驱动器上没有插脚,无法将其插入面包板,需要进行焊接:
1.电机驱动器有两排孔。将芯片朝上准备好。
从插针上面扣掉两排八个的引脚。将这两排插针对正驱动器两排孔的下面。插头引脚的短端应穿过驱动器中的孔。当两侧都装配到位时,电机驱动器能够像桌子一样立住。
2.从电机驱动器的顶部将插针接头焊接到位,如图3-17所示。注意不要将两个引脚焊接在一起。这会使驱动器短路并导致其发生故障。

image.png


图3-17 焊接电机驱动器

3.6 给小船接线

在船上有三个主要零件。第一是电机驱动器;第二是Spark核心板;第三是电池座。这三个都将插到面包板并彼此联通。

  1. 将Spark核心板和电机驱动器插入面包板。它们应该很好地贴合在一起。并注意使Spark核心板和电机驱动器都横跨面包板中心的分隔线,如图3-18所示。

    image.png


图3-18 Spark核心板和电机驱动器

注意在放置Spark核心板的时候USB接口应该朝向面包板的外侧,这样后面连接的时候会方便很多。
2.将电池座连接到面包板,如图3-19所示。将电池座的红线插入面包板的有“+”标记的接线柱上(正极)。现在将黑色电线插入面包板的有“-”标记的接线柱上(负极)。无论何时需要接通电源、Spark核心板、电机驱动器或是电机、我们都可以连接到面包板上的这些线路。

  1. 将陶瓷电容器安装到面包板中。陶瓷电容器可以任意方向与电源正负极相连,而其他类型电容器则有正负极性的要求。你可以将电容器理解为一种备用电源,如果用电器需要的电能超过电池可以提供的功率,电容器可以临时充当一下能量来。

    image.png


图3-19 将电池座连接到面包板上(附彩图)

Spark 核心板可以由3.6~6.0V的外接电源供电。每节AA电池提供1.5V电压,因此四节AA 电池组刚刚好。如果使用可充电电池的话注意一节可充电电池在电量充满的情况下也只有 1.2V的电压。

  1. 电容器安装好之后,就可以将电源与Spark核心板相连。在连接的时候无须从电池组上引线,用跳线将面包板的正负极连接到Spark上的VIN和GND引脚即可。Fritzing电路图如图3-19所示。

3.6.1 给电机驱动器供电

现在可以连接电机驱动器了。驱动板的每个引脚都印有标签,不过它们印在电路板的下面。如果你从顶部看,芯片朝上,则引脚的设置如图3-20所示。

image.png


图3-20 电机驱动器引脚图

给电机驱动器供电,我们需要两个电源——一个是电池,另一个是Spark。
1.找到电机驱动器上的VM引脚。使用跳线将电池的正极连接到此引脚。然后,找到GND引脚,并以相同方式将其与电池负极相连。
2.在电机驱动器的VM和GND引脚之间还有另一个标记为VCC的引脚。将另一个电源连接到此,但注意此引脚仅能接入2.7~5.5V的电压。
电池组要向整个电路提供电力,那么如何保证能够获得足够的电力?
解决方案是使用Spark核心板。如果你看一下Spark,就会发现一个标有3V3的引脚,它可以提供3.3V电压!你可以直接用跳线连接Spark的3V3引脚和电机驱动器的VCC引脚。
Spark有两个3.3V引脚。一个标记为3V3,另一个标记为3V3 *。(打印出的星标非常小,所以它看起来更像是一个点。)接线的时候务必使用没有星标的引脚!星标表示这是一个低噪声稳压电源轨,可能无法提供足够电力。

3.6.2 连接Spark核心板和电机驱动器

我们使用的电机驱动器可以支持两个电机,但我们在船上只使用一个。我们要使用的电机输入的电机驱动器上的三个引脚是PWMA、AIN1和AIN2。要连接Spark和电机驱动程序,请按照下列步骤操作:
1.使用跳线将电机驱动器上的PWMA连接到Spark上的A0位置。这是Spark的PWM引脚之一。PWM代表脉冲宽度调制。这样就可以调整电机旋转的速度了。
2.将电机驱动器上的AIN1和AIN2的引脚连接到D0和D1上。两个输入引脚各自对应电机的不同旋转方向。图 3-21为接线的Fritzing电路图。
脉冲宽度调制引脚
并非所有引脚都是PWM引脚。在Spark上,脉冲宽度引脚为A0、A1、A4、A5、A6、A7、D0和D1。
PWM引脚的什么特别之处呢?大多数引脚都可以设置为打开或关闭两种状态。而PWM引脚的不同在于,它们可以非常快速地打开和关闭。你基本上选择引脚的占空比,这允许对零件进行更多级别的控制。
以LED为例。如果将它连接到非PWM引脚,它只能处于打开或关闭两种状态。如果连接到PWM引脚,LED会以极快的速度闪烁,就像不断地打开和关闭一样。根据引脚开启的时间百分比,这会让人感觉它变得更亮或更暗。

image.png


图3-21 电机驱动器接线图

3.6.3 连接电机

现在电机驱动器已经接好电源,并能够从Spark核心板接收指令了,接下来就可以连接我们密封在吊舱内的电机了。

  1. 从电机吊舱中取出一根电线,并将其连接到电机驱动器上的A1。将另一根电机线连接到A2。注意这是一个双向电机,所以电线和引脚之间的对应关系无关紧要。
    在本例中,我们只使用一个电机吊舱为船提供动力,后面我们还会添加一个伺服系统驱动方向舵。不过,我们所使用的电机驱动器可以驱动两个电机,你可以为你的船再加一个电机吊舱。如果你有这个打算的话,第二个电机吊舱应该接到驱动板的B01和B02引脚,控制方向的引脚为BIN1和BIN2,控制速度的引脚为PWMB。

使用两个电机可以获得更快的速度,如果你把两个电机安装在船的两侧,还可以通过控制两个电机的不同速度和方向来控制船的行进。
2.为确保电机正常工作,还需要进行布线。你会注意到电机驱动器有一个标有STBY的引脚。在未通电的时候,此引脚将阻止电机开启。这个功能并不影响我们的船正常工作,因此你可以通过将此引脚连接到Spark的3V3引脚来有效地关闭此功能,以便始终接收电压。图3-22展示了Spark核心板和电机的最终布线。

image.png


图3-22 Spark核心板和电机的完整布线

3.7 电机的控制:代码

现在船上的电机线路连接工作已经完成,让我们开始编码。
本书中示例的所有源代码都可以在GitHub上找到。
1.在项目中创建一个名为boat.js的新文件。类似于你之前创建的test.js,需要用到Johnny-Five和Spark-IO。但是,这一次,在你准备好的事件中,你将需要实例化一个新的电机对象而不是一个新的LED。
2.创建新电机时,将JavaScript对象作为参数传递。该对象将指定我们连接到电机驱动器上的三个Spark引脚。你需要指定哪个是脉冲宽度模块(pwm),哪个是正向(dir),哪个是反向(cdir)。本书中默认的接口分别是A0、D0和D1:
image.png
3.为了更方便地测试电机并从终端控制它,你还可以在boat.js文件中添加REPL:
image.png
请记住,实例化电机并将其添加到REPL应该都在你准备好的事件中进行。
4.连接电池组并插入电池,以便测试电机。
等待Spark连接到WiFi,青色呼吸灯闪烁。然后使用node boat.js运行你的程序。
终端显示出“Repl Initialized”时,Spark核心板就可以接收命令了。没什么问题的话,现在你应该能够控制电机的方向和速度!
5.你可以在终端运行m.forward()和m.reverse()以使电机在一个方向或另一个方向上旋转。m.stop()将停止电机。而且,通过这个电机驱动器,你还可以控制电机的速度!
为此,你可以传递一个0~255的数字作为正向和反向函数的参数。0相当于停止,255是最高速度!
在测试电机的时候,可以通过把手放在螺旋桨后感受气流的方向来判断电机的转向。如果电机反转,有许多种办法解决。最简单的方法是,转换你的代码中的Spark核心板的dir 和cdir 引脚。(本书中所使用的是D0 和D1引脚。)如果你想通过物理方法解决,你可以代替重新将两根电线插入到电机驱动器的 A01和A02 引脚。

3.7.1 添加按键事件

现在你可以通过终端的REPL来操纵你的船,但是如果能够使用方向键来控制它会更好。为此,请使用节点的keypress模块:
image.png
按键模块可以获取按键事件,你可以指定要监控的按键。它还为你的键提供了方便的名称,比如,你可以通过查找key.name ===“up”来监听up键上的按键:

  1. 在代码中需要“keypress”,并确保process.stdin将发出keypress事件。
    2.在按键事件中,指定不同按键按下时所需要进行的动作。比如,“up”应该调用motor.forward(255),“down”应该调用motor.reverse(255),如例3-2所示。

例3-2 节点按键事件
image.png
3.按键模块不会检测按键弹起事件,因此使用此代码,你的船将永远无法停止。你需要添加另一个键作为制动器。空格键就不错:
image.png

3.7.2 记录按键状态

使用按键模块时遇到的一个问题是,如果按住某个键,则会一直调用与该键相关联的功能,直到该键被释放。这可能会导致Spark出现错误并使其崩溃。为了避免这种情况,你可以将按键的状态存储在对象中,并且只在第一次按下该键时调用该函数:
1.创建一个对象并将其设置为等于变量state(状态)。键将是向上和向下,并将两者的值设置为false。
2.当你在代码中检测到按键事件时,调整函数使motor.forward()和motor.reverse()函数只有在相关的向上或向下状态值为false时才会调用。同样,当up或down状态为true时,你只需要调用motor.stop()。
3.当motor.forward()、motor. reverse(),或motor.stop()被调用时,你要确保你调整的是相应的按键状态。
简单的前进功能可以参考例3-3。
例3-3 通过键盘事件控制电机
image.png
image.png

3.8 船体装配

现在我们已经完成了船只的动力安装并完成内部零件的安装接线,现在可以进一步完成船的物理构建。
1.取事先准备好的两块泡沫塑料,并使用热胶枪连接到船的两侧,如图3-23所示。当你安装定位时,注意要使电机吊舱完全浸入水中,但确保你的船顶位于水面之上。

image.png


图3-23 装配船体

粘贴泡沫时还要注意:任何电子设备,包括稍后将装配到船顶的伺服电机,都必须与水隔离,否则会进水短路,你的船也将无法正常工作。你还需要确保泡沫的定位不会阻止盖子关闭。
2.将面包板和电池组放入作为船体的容器内,并确定要放置零件的位置。确定后,标记你希望电机吊架的电线进入船体的位置。
现在可以从船上拆下电子元件。
现在我们可以把零件都装到船体内,或者使用重量相当的东西代替,然后检测船体的浮力。
3.在你标记的位置钻一个洞。根据你的船的设计,孔可以不是中心,但请记住孔的位置将会对马达吊舱的位置有所影响。而马达吊舱的位置必须居中,否则你的船可能会偏航。
同之前电机吊舱上钻孔一样,在这里钻的孔也要尽可能小,同时确保电机两端的电线可以穿过它。
4.断开电机吊舱与电机驱动器的连接,然后将电线穿过你在船底钻出的孔。
5.将船倒置并将电机吊架放置在中心位置,使其朝向正确的方向。为了使电机吊舱稳定,你需要将其放置在船底部,如
图 3-24所示。
6.将电机吊架固定到位,用硅胶或胶水密封船上的孔,确保船体完全密封。你也可以使用硅胶或胶水来固定电机,稍后你还可以进行加固。将船放在一边静置,等待密封胶干燥。

image.png


图3-24 放置电机吊舱

7.硅胶或胶水干燥到足以使其固定时,将船正面翻转并从内部密封孔。
一旦干燥,如果你的电机吊舱仍在移动,请在电机吊舱和船之间添加一些热胶以稳定它。
8.将面包板和电池固定器放回船内,然后将电机重新连接到电机驱动器上。
恭喜你!现在可以测试你的船了。但是你还没有完成。现在你的船只能前进和后退。接下来我们将添加一个方向舵来对船进行控制。
注意:在平静的水中(如浴缸或儿童游泳池)对你的船只进行测试!以免船只出现问题时无法及时抢救。

3.9 伺服系统

为了控制船的方向舵,我们将使用伺服系统。伺服系统是一种可以控制移动角度的电机,从0°到180°。这非常适合驱动方向舵!
我们将在船上使用标准伺服系统。注意不是连续旋转伺服(continuous-rotation servo)。连续旋转伺服可以360°旋转,而且所控制的不是其旋转的角度而是旋转的速度。
1.你的伺服电机应连接三根电线。这些电线的颜色可能因伺服而异,但黑色或棕色的电线为负极端。使用跳线将此电线连接到面包板上的负极端。
2.伺服的中间导线应为红色或橙色。通过面包板将此电线连接到电池电源正极。伺服电机需要很大的功率,因此通常可以用外部电池电源供电。对于这艘船而言,只要你的电池是新的,四节AA电池应足以为伺服电机、电机和Spark供电。
3.伺服系统上的第三根电线是从Spark接收输入的线。为了使伺服系统正常工作,需要将其连接到PWM引脚。
注意,Spark上的PWM引脚是A0、A1、A4、A5、A6、A7、D0和D1。A0是正在使用的电动机。我们将使用A4作为伺服,如图3-25所示。

image.png


图3-25 最终接线,带伺服系统(附彩图)

由于电机连接到 A0,因此无法将伺服连接到A1。这是因为,A0 和 A1 连接到相同的内部零件,而且输出相同频率的脉冲宽度。电机和伺服系统正常工作的频率不同,所以你需要将伺服系统接到A4引脚,以避免该冲突。如果你的船用了两个伺服,可以将一个接到A0另一个接到A1。

3.9.1 伺服系统编程

现在我们已经将伺服连接到你的船上,接下来将它添加到你的代码中。
1.在定义电机后,使用new five.Servo()函数初始化伺服。
2.将伺服作为参数传递给对象,将引脚设置为A4,因为这是伺服连接到Spark上的引脚。
将startAt设置为90,这将确保你的伺服在程序启动时自动居中。如果伺服偏离中心位置,你可以稍微调整一下。
你还可以添加一个范围来定义伺服可以转向的最小角度和最大角度。这样可以确保方向舵不会碰到船体,定义伺服转向的角度时调用min()函数和max()函数。本书中将角度范围设置为45-135,如下代码所示:
image.png
3.在存储向上和向下按键状态的状态对象中,你还要添加向右和向左的状态。在按键事件中,你就可以监测这些按键,并调用servo.min()函数和servo.max()函数控制伺服机构左右偏转(见例 3-4)。
例3-4 通过键盘事件控制伺服
image.png
image.png
现在我们的程序已经可以通过按键控制船的左右偏航,但由于按键监测模块无法检测到的按键抬起,所以船会一直转向。正常来讲我们不需要按其他的按键来使船恢复直行。你将使用时间模块来控制按键时长,如例3-5所示。
例3-5 时态队列
image.png
4.初始化timeOfDirection变量,并在按键事件中,每当按下右方向键或左方向键时,将其更新为Date.now()。这将允许我们查看已经过了多长时间,并且如果不再按下键,则使伺服居中。
5.因为我们所使用的是Temporal模块,所以在终端中键入npm install --save temporal来安装模块并将其保存到package.json文件中。
6.在就绪事件中调用temporal.queue()。这需要一个数组,并允许你指定任务何时运行以及它们是否循环。在我们的设计中,将重复一个函数,并且每100毫秒循环一次。
7.在此函数中,将timeOfDirection的值与当前时间进行比较。如果超过500毫秒,就可以确定按键不再被按下,并且可以使伺服中立。每当按下向右键或向左键时,确保将timeOfDirection重置为当前时间。

3.9.2 安装方向舵

现在我们已经完成伺服系统的安装和程序!但是,伺服系统不是方向舵。我们需要用冰棍棒改装一个并将它连接到我们的服务器上。
1.取两根冰棒棍,将它们切成两半并排成一行,使四个半部分接触,形成正方形或矩形。这将是方向舵底部的鳍。
2.用四个半冰棍棒将你制作的鳍黏到一个全长冰棍棒的底部。这就是你的方向舵。
3.将没有翅片的方向舵的末端黏合到伺服旋转件的末端上。你的伺服可能带有多个附件。建议使用较长的一个,这样可以使方向舵远离船只,如图 3-26所示。
4.方向舵连接到伺服系统之后,将伺服系统安装在船体后部外侧。根据容器盖子的紧密程度,你可以直接将盖子盖在从船的内部硬件通向伺服的导线上。但是,如果电线挡住了盖子,那么要在船舱盖上钻一洞。
5.使用热胶枪将伺服系统固定到船上。根据你使用的容器类型和船的设计外形,你可以选择将其连接到主船体,盖子的边缘或将盖子固定到位的夹子上。

image.png


图3-26 方向舵和伺服

固定伺服系统时,注意确保船只漂浮后,方向舵的主要部分要完全浸没在水中。还要确保方向舵居中,否则会很控制船。
注意,伺服不具备防水能力!做好防水工作,否则伺服系统将会失灵。许多伺服都贴有标签。固定黏接伺服系统时,注意尽可能避开标签。否则,伺服可能会在你最不期望的时候在标签贴纸处脱落!

3.10 启航

现在方向舵已经安装好了,船可以下水了!把它放在游泳池里,或者仅仅放在浴缸中,然后让它前行!
你也随意装饰你的船,让它拥有百变的造型,见图3-27。

image.png


图3-27 成品船

3.11 进一步探索

现在你有一个完整的船,你可以添加更多的功能或尝试其他方法来控制它!
比如,你可以尝试以下任何一个或全部:
在船底添加一个水传感器,进水时就会发出预警信号。
使用带有加速度计的装置(例如Sphero)操纵船只。
安装第二个电机吊舱并通过调节两个吊舱之间的速度来转向。
编程来控制更精细的转弯。
添加加速和减速功能。
添加声呐实现自动驾驶。
安装可以用程序控制的LED彩灯,发送不同的命令彩灯将呈现不同的颜色。
创意有无限的可能,而每一个创意都是独一无二的,我们期待着你的作品,可以将你的作品照片发送到我们的推特@NodeBoats(http://twitter.com/nodeboats),祝你玩得开心!

相关文章
|
1月前
|
前端开发 JavaScript
使用JavaScript实现复杂功能:构建一个自定义的拖拽功能
使用JavaScript实现复杂功能:构建一个自定义的拖拽功能
|
14天前
|
JavaScript 前端开发 持续交付
【专栏】Vue.js和Node.js如何结合构建现代Web应用
【4月更文挑战第27天】本文探讨了Vue.js和Node.js如何结合构建现代Web应用。Vue.js作为轻量级前端框架,以其简洁易懂、组件化开发、双向数据绑定和虚拟DOM等特点受到青睐;而Node.js是高性能后端平台,具备事件驱动、非阻塞I/O、丰富生态系统和跨平台优势。两者结合实现前后端分离,高效通信,并支持热更新、持续集成、跨平台和多端适配,为开发高性能、易维护的Web应用提供强有力的支持。
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【AIGC】基于大语言模型构建多语种聊天机器人(基于Bloom大语言模型)
【5月更文挑战第8天】基于大语言模型Bloom构建多语种聊天机器人
|
3天前
|
传感器 机器人 Java
使用Java构建机器人应用
使用Java构建机器人应用
6 0
|
11天前
|
JavaScript 前端开发 API
如何利用JavaScript和Electron构建具有丰富功能的桌面应用
【4月更文挑战第30天】如何利用JavaScript和Electron构建具有丰富功能的桌面应用
5 0
|
11天前
|
缓存 监控 JavaScript
Node.js中构建RESTful API的最佳实践
【4月更文挑战第30天】本文介绍了在Node.js中构建RESTful API的最佳实践:选择合适的框架(如Express、Koa)、设计清晰的API接口(遵循HTTP动词和资源路径)、实现认证授权(JWT、OAuth 2.0)、错误处理、限流缓存、编写文档和测试,以及监控性能优化。这些实践有助于创建健壮、可维护和易用的API。
|
11天前
|
消息中间件 监控 JavaScript
Node.js中的微服务架构:构建与实践
【4月更文挑战第30天】本文探讨了在Node.js中构建微服务的实践,包括定义服务边界、选择框架(如Express、Koa或NestJS)、设计RESTful API、实现服务间通信(HTTP、gRPC、消息队列)、错误处理、服务发现与负载均衡,以及监控和日志记录。微服务架构能提升应用的可伸缩性、灵活性和可维护性。
|
20天前
|
资源调度 JavaScript 搜索推荐
服务端渲染:使用Nuxt.js构建Vue SSR应用
【4月更文挑战第22天】本文介绍了如何使用Nuxt.js创建Vue SSR应用。首先确保安装Node.js和npm/yarn,然后全局安装Create Nuxt App,创建项目并选择配置。Nuxt.js提供清晰的项目结构,如`pages/`存放Vue页面。编写简单SSR页面后,启动开发服务器预览。完成开发,使用Nuxt.js命令部署到静态文件托管服务,实现首屏加载优化和SEO提升。Nuxt.js简化了SSR开发,助力高效构建高性能Vue应用。
|
1月前
|
JavaScript 前端开发 API
Vue.js:构建高效且灵活的Web应用的利器
Vue.js:构建高效且灵活的Web应用的利器
|
1月前
|
前端开发 JavaScript 数据可视化
使用JavaScript实现复杂功能:动态数据可视化的构建
使用JavaScript实现复杂功能:动态数据可视化的构建

热门文章

最新文章