赠书 | 如何用 JavaScript 控制 Arduino?

0?wx_fmt=png


作者 | 赵英杰

微信公众号ID | csdn_iot


Arduino 运行 C 语言,而主控端运行 JavaScript,一次要编写和维护两种程序。既然浏览器和服务器都用 JavaScript,若 Arduino 也能用 JavaScript 控制,那岂不完美?


这就是 Rick Waldron 设计 Johnny-Five 库文件的原因。Johnny-Five 是1986 年上映的科幻电影“Short Circuit(直译为“短路”,译作“霹雳五号”)”当中的机器人主角的名字。电影中的机器人原本是人工智能军武,由于雷击造成短路,让它有了自我意识而开始一连串的故事。


霹雳五号:用 JavaScript 控制 Arduino


Johnny-Five(以下称“霹雳五号”)是在电脑或树莓派之类的高端控制板上运行的 Node.js 包,通过电脑上的 JavaScript 运行所有程序逻辑,而 Arduino 控制板只充当乖乖听话的“外设接口”。


实际的硬件接线如下,电脑或树莓派通过USB 接口( 或GPIO 串口引脚)与 Arduino 板控制相连。


0?wx_fmt=png


《完美图解Arduino 互动设计入门》的17-3 节提到,有一种在电脑软件和微处理器之间传递数据的通用消息格式,叫作 Firmata。“霹雳五号”的 JavaScript 代码和 Arduino 控制板就是用 Firmata 协议来沟通的。


Arduino IDE 提供了一个“StandardFirmata” 程序, 让 Arduino 控制板能收发 Firmata 消息。我们不需要了解 Firmata 的语法,霹雳五号的 JavaScript 程序会搞定一切。


除了霹雳五号,普遍用于儿童电脑教育的 Scratch,也是运用 Firmata 协议与 Arduino 控制板沟通的。


霹雳五号不仅支持 Arduino 控制板, 也支持 Raspberry Pi、 

BeagleBone Black、Intel Galileo、Edison 等控制板,详细的列表与说明,请参阅:http://johnny-five.io/platform-support/。


霹雳五号的基本结构


和 Arduino 的C 语言不同,霹雳五号程序至少包含三大要素:


  • 引用“johnny-five”库文件。

  • 创建 board 对象,通过它跟Arduino控制板的串口相连。

  • 创建连接回调函数。


基本程序架构如下:


0?wx_fmt=png


霹雳五号会自动查找连接在USB 串口的Arduino 控制板,也可以通过代码明确指定串口(若是通过树莓派的GPIO 串口连接Arduino 控制板的,就一定要设置串口名,否则会产生错误)。


如下是在不同的操作系统上指定USB 串口的方式,星号(*)代表串口编号:


// Windows 系统

var board = new five.Board({ port:"COM*"});

// Mac OS X 系统

var board = new five.Board({ port:"/dev/tty.usbmodem****"});

// Linux(Raspberry Pi) 系统

var board = new five.Board({ port:"/dev/ttyUSB*"});

// 树莓派GPIO 串口

var board = new five.Board({ port:"/dev/ttyAMA0"});


用霹雳五号指挥 Arduino 闪烁 LED


实验说明:学习霹雳五号的基本程序架构以及相关设置;编写JavaScript 代码令 Arduino 控制板的 13 脚闪烁。


实验材料:Arduino UNO 控制板,一片。


实验代码:请先添加一个存放Node 程序的文件夹,这里将此文件夹命名为blink。然后打开终端窗口,在blink 路径下运行下面的安装霹雳五号模块的指令:


> npm install johnny-five


安装完毕后,在此路径下添加一个index.js 文件,并输入闪烁LED 代码(请自行修改串口名)。


0?wx_fmt=png


Arduino 控制板要上传StandardFirmata 程序,请打开Arduino IDE 中的“文件”→“示例”→“Firmata”→“StandardFirmata”,并上传到Arduino 控制板。


0?wx_fmt=png


实验结果:在终端窗口中输入“node index.js”指令,Node 将响应连接状况并且初始化一个REPL 环境(参阅下文说明),紧接着,操控Arduino 的程序将开始运行,让13 脚的LED 开始闪烁。


0?wx_fmt=png


若运行Node 程序时,终端窗口中出现类似于下面的错误消息,则代表无法跟Arduino 控制板连接:


1440865565684 Connected /dev/ttyAMA0

1440865575745 Device or Firmware Error A timeout occurred while

connecting to the Board.

Please check that you've properly flashed the board with the correct firmware.


请检查代码里的USB 端口名是否正确, 以及Arduino 控制板是否上传了 StandardFirmata 程序。


霹雳五号与Arduino 的C 语言代码架构比较


Arduino 的编程语言是简化版的C/C++,它提供了许多标准C语言所没有的指令,例如setup()、loop()、delay()、digitalRead() 等。同样地,霹雳五号也向Arduino 看齐, 提供了在标准JavaScript 语言中不存在,但是简单易懂的指令和对象,方便我们操控微电脑。


通过比较使用Arduino 的C 语言和霹雳五号的JavaScript 代码来控制LED,霹雳五号不需要事先设置Arduino 引脚的模式(即:输入或输出),也不需要通过循环控制 LED 闪烁,因为霹雳五号把一些常用的电子元器件控制模式都写成对象(参阅下文),我们无须理会背后的运作细节。


0?wx_fmt=png


Arduino 的C 语言程序经过编译之后,保存在微控器里面运行。霹雳五号的 JavaScript 程序则是在电脑上运行的,Arduino 无法独立运作。换句话说,如果电脑关机或者拔除USB 连接,霹雳五号程序和Arduino 控制板就没有作用了……看到这里,读者一定感到疑惑,这种运作模式好吗?


视情况而定。若只为了闪烁LED,当然不好。但若是在电脑上运行Node 网站服务器或者复杂的运算,同时需要与外界环境交互时,那就不失为一种良好的解决方案。


此外,树莓派和其他高端微控制板,甚至是能安装Windows 或Linux 系统的电视棒,也能运行Node 与霹雳五号,不一定要使用耗电量较高的电脑。


0?wx_fmt=png

可安装与运行Linux 系统的Android 电视棒,能通过USB 接口连接Arduino 控制板


通过REPL 模式操控Arduino


霹雳五号会在运行阶段自动设置一种REPL 操作模式,也就是让我们在终端窗口中直接输入JavaScript 语句来操控Arduino。至于要开放哪些指令在终端窗口中操作,由 repl 对象的inject() 方法设置:


0?wx_fmt=png


如下程序将提供Led 对象给REPL 模式操作,请将此程序文件命名为index.js,保存在上一节的blink 文件夹中:


0?wx_fmt=png


运行此node.js 程序后,即可在终端窗口中测试上文提到的led 对象方法,例如led.on() 将点亮LED。


0?wx_fmt=png


接着输入led.blink(500) 或led.strobe(500),LED 将以500ms 时间间隔闪烁(默认间隔时间为100ms),直到输入led.stop() 为止。测试完毕后,按两次“Ctrl+C”快捷键退出程序。


repl 对象也能包含自定义函数,方便我们运行一连串事先定义好的语句。如下代码注入名为“on”和“off”的自定义函数,分别运行点亮和关闭LED 的方法。


0?wx_fmt=png


运行此程序进入REPL 模式后,输入on() 可点亮LED ;输入off() 则关闭LED。


若程序不需要使用REPL 模式,则可以在创建Board 对象时取消。取消之后,程序里的REPL 相关代码将无法运行(会报错)。 

0?wx_fmt=png


霹雳五号的方法与内置对象


霹雳五号提供的数字和模拟引脚控制指令,都刻意设计成和Arduino 的C 语言指令同名。例如:


  • pinMode(引脚 , 模式 ):设置引脚模式。“模式”的可能值如下 :


  • 数字输入:Pin.INPUT

  • 数字输出:Pin.OUTPUT

  • 模拟输入:Pin.ANALOG

  • PWM 输出:Pin.PWM

  • 舵机信号:Pin.SERVO


  • digitalWrite(引脚 , 信号 ):输出数字信号,可能值为 0 或 1。


  • digitalRead(引脚 , 处理函数 ( 值 )):读取数字输入信号。如下代码将读取数字 2 脚,并将其值显示在终端窗口中:


0?wx_fmt=png


  • analogWrite(引脚 , 值 ):输出 0~255 的 PWM 值。

  • analogRead(引脚 , 处理函数 (值 )):读取模拟输入信号,可能值为 0~1023。如下程序片段,将读取A0 引脚的模拟输入值:


board.on("ready", function() {

this.pinMode(0, five.Pin.ANALOG); // A0 引脚设置成模拟输入

this.analogRead(0, function(value) { // 持续读取A0 引脚值

console.log(value);

});

});


  • loop(毫秒, 处理函数):相当于Arduino的loop()循环函数,也是JavaScript的setInterval() 方法的简化版。如下代码将每隔0.5 秒变换一次13 脚的输出状态:


0?wx_fmt=png


完整的API 指令列表, 请参阅霹雳五号官网的Board 类的API 单元(http://johnny-five.io/api/board/#api)。


霹雳五号也内置了常用的控制对象(Component Class,组件类),有助于精简代码。


  • Button:读取开关或按钮的状态,支持上拉电阻设置。

  • Led :控制普通的发光二极管。

  • Led.Matrix :控制矩阵 LED显示器,内置 ASCII字符集。

  • LCD :支持并列连接或者用 I2C 接口串联的HD44780 液晶显示器。

  • Sensor :传感器,泛指读取所有模拟输入元器件的输入值。

  • Servo :控制普通或者 360°旋转的舵机。

  • Motor :控制碳刷电机,支持 H 桥式电路和 PWM 速度与转向控制。

  • Ping:读取超音波测距模块的返回值。

  • IR.Reflect.Array :读取连接在模拟脚的数个反射或遮光型光电传感器。

  • ShiftRegister :控制并输出数据给 74HC595 位移寄存器。

  • Thermometer :读取温度值。


完整的控制对象列表和示例代码,请参阅霹雳五号官网的API 单元(http://johnny-five.io/api/)。


JavaScript 程序和霹雳五号并没有Arduino 的delay(延迟或暂停)指令,JavaScript 采用setTimeout() 函数来设置要延后运行的语句


0?wx_fmt=png


或者,使用霹雳五号board 对象的wait() 方法(代表“等待”)。例如,如下程序一开始点亮13 脚的LED,经过3 秒之后,将它关闭:


0?wx_fmt=png


JavaScript 也没有Arduino 的millis() 指令,JavaScript 提供的是 getTime() 函数和Date(日期)对象。


millis() 可返回从Arduino 开机到现在所经过的毫秒数。


getTime() 可返回从1970 年1 月1 日零时到现在所经过的毫秒数。




本文选自《完美图解物联网IoT实操:使用JavaScript,Node.JS,Arduino,Raspberry Pi》第 5 章。 

0?wx_fmt=jpeg


赠书规则


  • 如果你对本书感兴趣,可以在本文下方留言,说出自己申请理由,我会把有价值的评论放出,根据评论点赞数+申请理由挑选出 5 位参与的小伙伴。

  • 截止时间:10 月 2 日 12:00。


如果有迫不及待的宝宝们想要即刻阅读这本书,点击下方【阅读原文】,即可订购哟,感谢博文视点的技术图书支持~~


最后祝各位小伙伴们国庆中秋双节快乐,玩得开心!


0?wx_fmt=jpeg


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值