最近,因为一些不可描述的原因,我踩了个巨坑——JS控制单片机

先上效果吧,由于不知道掘金怎么上传录像,就放微博啦,链接地址:

正文

作为一名端茶倒水、递烟递酒、擦窗扫地无所不能的全干打杂工,我是一点想法都没有,毕竟作为一名前端都算不上合格,更不用讲硬件这块了。

单片机的开发一般都是C++或者C开发者去搞的,甚至可能还要用到汇编。因此开发者在我脑海的印象一般是这样的:


看了下自己的发际线。。。。嗯,看样子我不适合这个职业。

但万事不绝对,在坚持不懈的努力下,我找到了个神器——Cylon.js

这是个Node控制单片机开源库,据说是为了解决如何处理多个单片机而生的库,不得不说这个库真的很强大,内置了相当多的驱动以及很多想不到的功能,比如控制一个灯的开和关。

首先简单介绍一下今天的主角:arduino。这是一款开源硬件,有着相当惊人的能力和出色的社区。当然,价格也是相当诱人的。(我绝对不会说是因为便宜才买的它)在某宝上,一块arduino配上各种零件大约200+左右,并且它的开发也非常简单,在B站还有各种大佬进行DIY,上次还看到了利用超声波制作雷达装置,对大佬的敬仰如同涛涛江水连绵不绝。

废话说完了,下面就开始正题了。摆在最开头的是准备工作,我们一步一步往下走。

准备

  1. Node环境:这里默认大家都装好了
  2. 驱动:正常来讲,板子一插上就能正常操作,但不排除无法识别需要装驱动。驱动安装详细步骤在这里:www.arduino.cc/en/Guide/Wi…
  3. 开发环境:单单只有Node环境是不够的,这里详细介绍如何安装
  4. arduino开发版一块,面包板一块,连接线一根,电阻、导线、led小灯若干

这里就从第三点开始讲,开发环境,这里因为我用的是arduino+windows,因此我准备的arduino开发环境是适合windows操作系统的,至于其他的应该类似,就不详谈(因为我也不会呀,流下了没技术的泪水)。顺便说一下,官方文档非常神奇,安装指令的顺序有时候会变~



首先需要下载gort,下载地址是:gort.io/documentati…

386版本代表32位系统,amd64代表64位系统,各位看官可以自行选择。不过在这里我推荐使用386版本,因为amd64位在之后的操作中一直连不上驱动更新服务器(已经使用科学上网小工具)

下载完成后,就可以把它解压到任何地方了。我解压的位置是 E:\gort。这时候文件夹内会有三个文件。



这时候,右击开始菜单,打开具有管理员权限的命令提示符(CMD),输入:gort arduino install

这时候将会安装一个开发工具,不用管它,一路下一步就好了。安装完成后,关闭命令提示符窗口,重新再打开一个有管理员权限的命令提示符,然后将arduino连接到电脑,此时可以执行gort scan serial命令,理论上能看到arduino连接的端口,但很不幸我换了几台电脑,都是执行完命令后没任何输出。

还好,windows自带了设备管理器,能查看硬件端口。只需要右击此电脑,选择属性,选择设备管理器,选择查看端口(COM和LPT),应该会看到一个名为“Arduino Uno(COMxx)”的开放端口。若不存在COM和LPT部分,查看“其他设备”中的“未知设备”项,当然,这也是表明你需要安装驱动,或者你运气不好买了个废板子。

记住刚查看的端口号,我的是COM3

这时候,在命令行中输入gort arduino upload firmata <COMX>,这里的COMX则用你们查看到的端口号代替。如果执行比较顺利,那么恭喜你,开发环境已经搭建完毕,这时候就可以开始上手撸代码了,没错,撸JS代码!

撸码时间

先上个简单的,比如说让led灯每秒闪闪

首先安装依赖

npm install cylon cylon-firmata cylon-gpio cylon-i2c复制代码
var Cylon = require('cylon');

Cylon.robot({
  connections: {
    arduino: { adaptor: 'firmata', port: 'COM3' }
  },

  devices: {
    led1: { driver: 'led', pin: 13 }
  },

  work: function(arduino) {
    setInterval(function(){
    	arduino.led1.toggle()
    }, 1000)
  }
}).start();复制代码

然后运行这段程序,你就会发现led小灯开始一闪一闪啦!是不是非常简单!

于是,野心慢慢变大,既然能让小灯一闪一闪,那是不是就能用电脑去控制小灯开关?比如我点击开,然后小灯就开了,那还不是美滋滋!

说干就干,一番琢磨发现了一个MQTT协议,这玩意能用于arduino和电脑通信,能够在使用电脑向arduino发送指令。在之前的基础之上,稍加修改就能做到了。

let Cylon = require('cylon');

Cylon.robot({
  name: 'cybot',
  connections: {
    arduino: { adaptor: 'firmata', port: "COM3" }
  },

  devices: {
    led1: {driver: 'led', pin: 8},
    led2: {driver: 'led', pin: 9},
  },

  work: function(bord) {

  },
});

Cylon.api(
  'mqtt',
  {broker: 'mqtt://test.mosquitto.org'}
);

Cylon.start();
复制代码



但这还没完,这段代码运行后,arduino就处于接收指令状态,但本身因为没有任何操作,因此这时候的板子是没任何反应的,它在傻傻的等你下命令呢!

所以再新建个文件,用于发送指令吧!

const mqtt = require('mqtt');
let client = mqtt.connect('mqtt://test.mosquitto.org');

var payload = JSON.stringify({
    sender: 'self',
    param1: 'uno'
});

client.subscribe('/api/robots');
client.subscribe('/api/robots/cybot/devices/led1/commands/toggle');

setInterval(function(){
	client.publish('/api/robots/cybot/devices/led1/commands/toggle');
}, 1000)
复制代码



这是个非常简单的发指令操作,我来解释下:

连接url:'mqtt://test.mosquitto.org',这个是上一个代码中自定义的连接url

subscribe():注册指令,一旦使用这个方法,那么在调用publish方法的时候会触发message事件,获取板子中由括号内指令产生的数据。

publish():发送指令,能够将具体指令发送至arduino让其执行。

指令url,/api/robots/cybot/devices/led1/commands/toggle,其中,cybot是上一个代码中name值,表示操作哪块板子,led1表示上一个代码中的叫做led1的设备,toggle则表示led1的具体操作指令(toggle表示切换状态,如果灯是亮着,执行后就变成熄灭状态,反之则变成灯亮状态)。详细指令在官方文档中能够查询。

好了,再次运行,你就会发现你的led又开始一闪一闪起来,只不过和刚才不同,刚才是arduino中的程序控制灯的亮暗,而这次是你发送指令让arduino开关灯。因此,似乎骚操作从我脑海里跳了出来,既然能控制灯的亮暗,那么我写个界面去控制灯的开关如何?利用前端知识和后端知识配合Cylon是不是能做出什么惊天动地的骚操作?比如定时炸弹。。。。不不不,定时开关。

留在最后

至于为什么视频录制会是某音,我也很绝望啊。。。本来想上传优酷,发现账号密码忘了,上传微博似乎也不错?但等了一万年没等到验证码。。。至于B站,有个十秒限制,上传不上去,所以。。。。大家都是社会人,就不要辣么在意细节啦!!


小白第一次上手硬件,有什么不对请看官指出,谢谢大家花时间看完我这篇水文啦!

最后,我还是忍不住想发这张图