如何用 JavaScript 控制 Arduino?

attitude
发布于 2020-11-17 18:47
浏览
0收藏

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

如何用 JavaScript 控制 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控制板的串口相连。
  ◆  创建连接回调函数。
基本程序架构如下:

如何用 JavaScript 控制 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 代码(请自行修改串口名)。

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

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

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

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

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

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

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

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

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区
通过REPL 模式操控Arduino


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

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

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

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

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

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

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

 

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

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

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

若程序不需要使用REPL 模式,则可以在创建Board 对象时取消。取消之后,程序里的REPL 相关代码将无法运行(会报错)。 
如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区
霹雳五号的方法与内置对象


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

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

 ● 数字输入:Pin.INPUT
 ● 数字输出:Pin.OUTPUT
 ● 模拟输入:Pin.ANALOG
 ● PWM 输出:Pin.PWM
 ● 舵机信号:Pin.SERVO
  ◆  digitalWrite(引脚 , 信号 ):输出数字信号,可能值为 0 或 1。
  ◆  digitalRead(引脚 , 处理函数 ( 值 )):读取数字输入信号。如下代码将读取数字 2 脚,武汉试管婴儿并将其值显示在终端窗口中:
如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

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

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

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

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

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

如何用 JavaScript 控制 Arduino?-鸿蒙开发者社区

JavaScript 也没有Arduino 的millis() 指令,JavaScript 提供的是 getTime() 函数和Date(日期)对象。
millis() 可返回从Arduino 开机到现在所经过的毫秒数。

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

标签
已于2020-11-17 18:47:43修改
收藏
回复
举报
回复
    相关推荐