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 板控制相连。

《完美图解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控制板的串口相连。
  • 创建连接回调函数。

基本程序架构如下:

霹雳五号会自动查找连接在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 代码(请自行修改串口名)。

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

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

若运行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 闪烁,因为霹雳五号把一些常用的电子元器件控制模式都写成对象(参阅下文),我们无须理会背后的运作细节。

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

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

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

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

通过REPL 模式操控Arduino

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

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

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

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

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

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

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

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

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

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

    • 数字输入:Pin.INPUT
    • 数字输出:Pin.OUTPUT
    • 模拟输入:Pin.ANALOG
    • PWM 输出:Pin.PWM
    • 舵机信号:Pin.SERVO
  • digitalWrite(引脚 , 信号 ):输出数字信号,可能值为 0 或 1。

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

  • 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 脚的输出状态:

完整的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() 函数来设置要延后运行的语句

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

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

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

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


作者:赵英杰,网昱多媒体技术总监,美国密歇根 S.V. 州立大学传播与多媒体硕士,开源硬件技术达人。专长为 Arduino、Flash、Dreamweaver 等,在台湾大学、台湾科技大学等大专院校及教育训练单位担任讲师、并著有《超图解Arduino 互动设计入门》、《超图解物联网IoT 实作入门》、 《Dreamweaver CS6 教学范本(适用SiliconStone 认证考试教材)等多本相关书籍。 《超图解 Arduino 互动设计入门》 已授权 Arduino 原厂发行多国语言版本,为华文世界 Arduino 教材首例! 
本文选自《完美图解物联网IoT实操:使用JavaScript,Node.JS,Arduino,Raspberry Pi》第 5 章。

如何用 JavaScript 控制 Arduino?的更多相关文章

  1. 如何用 async 控制流程

    来自: http://larry850806.github.io/2016/05/31/async/ [Javascript] 如何用 async 控制流程 (一) 31 May 2016 async ...

  2. 控制Arduino的利器-Windows Remote Arduino

    1. 概述 相信很多朋友已经在玩 Arduino了,而且一般都是使用官方的Arduino IDE来写程序控制Arduino硬件.为了能够实现更加方便的控制,微软在Windows IoT计划中推出了Wi ...

  3. [转] 控制Arduino的利器-Windows Remote Arduino

    原文地址:控制Arduino的利器-Windows Remote Arduino 1. 概述 相信很多朋友已经在玩 Arduino了,而且一般都是使用官方的Arduino IDE来写程序控制Ardui ...

  4. HTML5 - 使用JavaScript控制<audio>音频的播放

    有时我们需要使用js来控制播放器实现音乐的播放,暂停.或者使用js播放一些音效.   1,通过JavaScript控制页面上的播放器 比如把页面上添加一个<audio>用来播放背景音乐(由 ...

  5. 如何用Javascript检测到所有的IE版本

    如何用Javascript检测到所有的IE版本 function GetIEVersion() { var sAgent = window.navigator.userAgent; var Idx = ...

  6. [转] JavaScript控制浏览器全屏及各种浏览器全屏模式的方法、属性和事件

    [From] http://www.jb51.net/article/76695.htm HTML 5中的full screen,目前可以在除IE和opera外的浏览器中使用 ,有的时候用来做全屏AP ...

  7. 如何用JavaScript实现2+2=5?

    我大学毕业找工作时,经常做一些稀奇古怪的面试题.这不,给大家分享一道整蛊的面试题,它其实不能算一道正式的面试题,大家可以用它来捉弄你们那些程序员朋友. 题目:如何用JavaScript实现2+2=5? ...

  8. 一步一步学Silverlight 2系列(22):在Silverlight中如何用JavaScript调用.NET代码

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  9. javascript控制流程语句

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. Unity 编辑器扩展 场景视图内控制对象

    http://blog.csdn.net/akof1314/article/details/38129031 假设有一个敌人生成器类,其中有个属性range用来表示敌人生成的范围区域大小,那么可以用O ...

  2. 【BIEE】15_时间维度建立

    时间维度的建立 1.环境准备 ①新建时间维度表:TIME_DIMENSION 建立时间维度表并插入数据 ---------------创建时间维度表 create table TIME_DIMENSI ...

  3. Azure Storage Blob Go SDK示例

    简介 前面一篇博客介绍了关于Azure ManagerAPI Go SDK的使用,本篇继续介绍使用Blob Go SDK 操作中国区Azure Blob. SDK下载: go get github.c ...

  4. C语言学习笔记(二) 基础知识

    数据类型 C语言数据可以分为两大类: 基本类型数据和复合类型数据: 基本类型数据 整数 整型   (int)  ——占4字节 短整型(short int)  ——占2字节    长整型(long in ...

  5. android-gradle-深入浅出-五:build type

    默认情况下,Android插件自动为项目构建一个debug和一个release版本的应用.这两个版本的不同主要体现在在非开发机上的调试功能以及APK的签名方式.debug版本使用一个用公开的name/ ...

  6. MTU的概念,什么是路径MTU? MTU发现机制,TraceRoute(了解)

    1.MTU的概念      MTU即Maximum Transmission Unit 最大传输单元.它是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位). 2.路径MTU     ...

  7. linux 自启动

    使用chkconfig命令可以查看在不同启动级别下课自动启动的服务(或是程序),命令格式如下:chkconfig --list可能输出如下:openvpn 0:关闭 1:开启 ...... 6:关闭 ...

  8. Subversion和TortoiseSVN安装与配置(转)

    Subversion为版本控制软件的服务器端. TortoiseSVN为版本控制软件的客户端. 1.下载Subversion与TortoiseSVN. Subversion的地址:http://sub ...

  9. RabbitMQ基础概念

    转至:http://blog.csdn.net/whycold/article/details/41119807 RabbitMQ简介 AMQP,即Advanced Message Queuing P ...

  10. mysql存在就更新,不存在就新增

    INSERT INTO newest_log_operation(    ACTION, OPERATION, KEY_VALUE, BUS_KEY, CONTENT, USER_ID, VERSIO ...