最近,因为一些不可描述的原因,我踩了个巨坑——JS控制单片机
先上效果吧,由于不知道掘金怎么上传录像,就放微博啦,链接地址:
正文
作为一名端茶倒水、递烟递酒、擦窗扫地无所不能的全干打杂工,我是一点想法都没有,毕竟作为一名前端都算不上合格,更不用讲硬件这块了。
单片机的开发一般都是C++或者C开发者去搞的,甚至可能还要用到汇编。因此开发者在我脑海的印象一般是这样的:
看了下自己的发际线。。。。嗯,看样子我不适合这个职业。
但万事不绝对,在坚持不懈的努力下,我找到了个神器——Cylon.js
这是个Node控制单片机开源库,据说是为了解决如何处理多个单片机而生的库,不得不说这个库真的很强大,内置了相当多的驱动以及很多想不到的功能,比如控制一个灯的开和关。
首先简单介绍一下今天的主角:arduino。这是一款开源硬件,有着相当惊人的能力和出色的社区。当然,价格也是相当诱人的。(我绝对不会说是因为便宜才买的它)在某宝上,一块arduino配上各种零件大约200+左右,并且它的开发也非常简单,在B站还有各种大佬进行DIY,上次还看到了利用超声波制作雷达装置,对大佬的敬仰如同涛涛江水连绵不绝。
废话说完了,下面就开始正题了。摆在最开头的是准备工作,我们一步一步往下走。
准备
- Node环境:这里默认大家都装好了
- 驱动:正常来讲,板子一插上就能正常操作,但不排除无法识别需要装驱动。驱动安装详细步骤在这里:www.arduino.cc/en/Guide/Wi…
- 开发环境:单单只有Node环境是不够的,这里详细介绍如何安装
- 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站,有个十秒限制,上传不上去,所以。。。。大家都是社会人,就不要辣么在意细节啦!!
小白第一次上手硬件,有什么不对请看官指出,谢谢大家花时间看完我这篇水文啦!
最后,我还是忍不住想发这张图