JS `IoT` (物联网) 设备上的 JavaScript 运行时:`Espruino`, `Johnny-Five`

各位观众老爷,大家好!今天咱们来聊聊一个挺有意思的话题:如何在“万物互联”的 IoT 设备上玩转 JavaScript。别害怕,不是要你焊电路板,咱们主要讲讲两个给力的 JavaScript 运行时:Espruino 和 Johnny-Five。

第一幕:JavaScript,你的新玩具!

话说 JavaScript,这门前端语言,现在可不只是在浏览器里蹦跶了。它已经渗透到各个角落,包括你的智能灯泡、智能插座,甚至你的冰箱(如果它够聪明的话)。为啥?因为 JavaScript 简单易学,社区庞大,工具链完善,而且…程序员多啊!

想象一下,你可以用你熟悉的 JavaScript 代码来控制你的家电,是不是感觉很酷?这可不是幻想,Espruino 和 Johnny-Five 就是帮你实现梦想的工具。

第二幕:Espruino,硬件界的瑞士军刀

Espruino,严格来说,它既是一个 JavaScript 解释器,也是一个运行它的硬件平台(当然你也可以把它刷到其他硬件上)。它的特点是:

  • 轻量级: 非常省资源,可以在资源有限的 IoT 设备上运行。
  • 实时性: 能够快速响应外部事件,控制硬件。
  • 易用性: 提供 Web IDE,可以通过浏览器直接编写和上传代码。
  • JavaScript 语法: 使用标准的 JavaScript 语法,方便前端工程师上手。
  • 社区支持: 拥有活跃的社区,可以找到各种示例和库。

Espruino 的硬件核心通常是 STM32 系列的微控制器,你可以把它看作是一个迷你的 Arduino,但是运行的是 JavaScript。

Espruino 的初体验:点亮 LED

咱们先来个简单的例子,用 Espruino 点亮一个 LED。假设你已经有一个 Espruino 板子,并连接了一个 LED 到板子的某个引脚(比如 A1)。

// 设置 A1 引脚为输出模式
pinMode(A1, "output");

// 点亮 LED
digitalWrite(A1, 1); // 1 代表高电平,点亮 LED

// 稍等 1 秒
setTimeout(function() {
  // 关闭 LED
  digitalWrite(A1, 0); // 0 代表低电平,关闭 LED
}, 1000);

这段代码很简单,先用 pinMode 函数设置 A1 引脚为输出模式,然后用 digitalWrite 函数控制引脚的电平。1 代表高电平,0 代表低电平。setTimeout 函数用于延迟 1 秒后关闭 LED。

你可以通过 Espruino Web IDE 将这段代码上传到你的 Espruino 板子上,然后你就会看到 LED 亮起 1 秒钟后熄灭。

Espruino 的进阶玩法:读取传感器数据

除了控制 LED,Espruino 还可以读取各种传感器的数据。比如,我们可以读取一个温度传感器(比如 DS18B20)的数据。

// 引入 OneWire 和 DS18B20 库
var ow = require("OneWire");
var sensor = require("DS18B20");

// 创建 OneWire 对象,并连接到 A1 引脚
var oneWire = new ow(A1);

// 函数:读取温度
function getTemperature() {
  sensor.search(oneWire, function(devices) {
    if (devices.length > 0) {
      sensor.getTemp(oneWire, devices[0], function(temp) {
        console.log("温度: " + temp + "°C");
      });
    } else {
      console.log("未找到 DS18B20 传感器");
    }
  });
}

// 每隔 5 秒读取一次温度
setInterval(getTemperature, 5000);

这段代码首先引入了 OneWireDS18B20 库,这两个库封装了与 DS18B20 传感器通信的细节。然后,我们创建了一个 OneWire 对象,并连接到 A1 引脚。getTemperature 函数用于读取温度,并将其打印到控制台。setInterval 函数用于每隔 5 秒调用一次 getTemperature 函数。

Espruino 的高级技巧:事件驱动编程

Espruino 支持事件驱动编程,这意味着你可以编写代码来响应外部事件,比如按钮按下、传感器数据变化等。

// 连接按钮到 B1 引脚
// 当按钮按下时,执行以下代码
setWatch(function(e) {
  console.log("按钮被按下了!");
  // 你可以在这里添加其他操作,比如控制 LED
}, B1, { edge: "rising", debounce: 50, repeat: true });

这段代码使用 setWatch 函数来监听 B1 引脚的上升沿(即按钮按下)。当按钮按下时,setWatch 函数会调用回调函数,回调函数会将 "按钮被按下了!" 打印到控制台。edge: "rising" 指定监听上升沿,debounce: 50 指定防抖时间为 50 毫秒,repeat: true 指定重复监听。

第三幕:Johnny-Five,Node.js 的硬件盟友

Johnny-Five 是一个 Node.js 的框架,专门用于控制硬件。它的特点是:

  • 基于 Node.js: 可以利用 Node.js 强大的生态系统。
  • 跨平台: 支持多种硬件平台,包括 Arduino、Raspberry Pi 等。
  • 易用性: 提供简洁的 API,方便控制硬件。
  • 模块化: 提供丰富的模块,可以方便地控制各种传感器和执行器。
  • 社区支持: 拥有活跃的社区,可以找到各种示例和库。

Johnny-Five 需要运行在 Node.js 环境中,这意味着你需要一个可以运行 Node.js 的设备,比如 Raspberry Pi。然后,你可以通过 USB 连接 Arduino 到 Raspberry Pi,并使用 Johnny-Five 来控制 Arduino。

Johnny-Five 的初体验:闪烁 LED

咱们先来个简单的例子,用 Johnny-Five 控制 Arduino 上的 LED 闪烁。

// 引入 johnny-five 库
const { Board, Led } = require("johnny-five");

// 创建一个 Board 对象,代表 Arduino 板子
const board = new Board();

// 当板子准备好后,执行以下代码
board.on("ready", () => {
  console.log("Arduino 板子准备好了!");

  // 创建一个 Led 对象,连接到 13 号引脚
  const led = new Led(13);

  // 让 LED 闪烁
  led.blink(500); // 500 毫秒闪烁一次
});

这段代码首先引入了 johnny-five 库,然后创建了一个 Board 对象,代表 Arduino 板子。board.on("ready", ...) 用于在板子准备好后执行回调函数。在回调函数中,我们创建了一个 Led 对象,连接到 13 号引脚。led.blink(500) 用于让 LED 闪烁,闪烁频率为 500 毫秒。

Johnny-Five 的进阶玩法:控制舵机

除了控制 LED,Johnny-Five 还可以控制各种执行器,比如舵机。

// 引入 johnny-five 库
const { Board, Servo } = require("johnny-five");

// 创建一个 Board 对象,代表 Arduino 板子
const board = new Board();

// 当板子准备好后,执行以下代码
board.on("ready", () => {
  console.log("Arduino 板子准备好了!");

  // 创建一个 Servo 对象,连接到 9 号引脚
  const servo = new Servo(9);

  // 让舵机转动到 90 度
  servo.to(90);

  // 稍等 2 秒
  board.wait(2000, () => {
    // 让舵机转动到 0 度
    servo.to(0);
  });
});

这段代码首先引入了 johnny-five 库,然后创建了一个 Board 对象,代表 Arduino 板子。board.on("ready", ...) 用于在板子准备好后执行回调函数。在回调函数中,我们创建了一个 Servo 对象,连接到 9 号引脚。servo.to(90) 用于让舵机转动到 90 度。board.wait(2000, ...) 用于延迟 2 秒后执行回调函数,回调函数用于让舵机转动到 0 度。

Johnny-Five 的高级技巧:使用 Firmata 协议

Johnny-Five 通过 Firmata 协议与 Arduino 通信。Firmata 是一个通用的协议,用于在软件和硬件之间进行通信。你可以通过 Arduino IDE 将 Firmata 固件上传到 Arduino 板子上,然后就可以使用 Johnny-Five 来控制 Arduino 了。

第四幕:Espruino vs Johnny-Five:谁更适合你?

Espruino 和 Johnny-Five 都是很棒的 JavaScript IoT 运行时,但是它们各有优缺点。

特性 Espruino Johnny-Five
运行环境 单片机 Node.js
资源消耗
实时性 相对较低
学习曲线 简单,JavaScript 语法 相对复杂,需要了解 Node.js
硬件支持 Espruino 板子,部分其他 STM32 板子 Arduino, Raspberry Pi, BeagleBone 等
适用场景 资源有限的设备,实时性要求高的场景 资源充足的设备,需要利用 Node.js 生态系统的场景
开发方式 Web IDE,命令行 Node.js 开发环境
是否需要额外硬件 硬件本身就是一个完整的板子,有时不需要 需要额外的运行 Node.js 的设备(如树莓派)

总结一下:

  • 如果你想快速上手,而且你的设备资源有限,或者你需要很高的实时性,那么 Espruino 可能是更好的选择。
  • 如果你已经熟悉 Node.js,而且你的设备资源充足,或者你需要利用 Node.js 强大的生态系统,那么 Johnny-Five 可能是更好的选择。

第五幕:实战项目:智能家居控制系统

咱们来个实战项目,用 Espruino 或 Johnny-Five 构建一个智能家居控制系统。这个系统可以控制灯光、温度、湿度等,并可以通过 Web 界面进行控制。

1. 硬件准备:

  • Espruino 板子 或 Arduino + Raspberry Pi
  • LED
  • 温度传感器 (DHT11/DHT22)
  • 继电器 (用于控制灯光等)
  • Web 服务器 (可以用 Node.js 搭建)

2. 软件架构:

  • 硬件层: Espruino 或 Arduino 代码,用于控制硬件。
  • 通信层: 使用 MQTT 协议进行通信。
  • 服务器层: Node.js 服务器,用于接收和发送数据。
  • Web 界面: HTML/CSS/JavaScript,用于控制硬件。

3. 代码实现(简化版,仅供参考):

Espruino 端代码:

// 引入 DHT11 库
var dht = require("DHT11");

// 连接 DHT11 传感器到 A1 引脚
var sensor = dht.connect(A1);

// 函数:读取温度和湿度
function getTemperatureAndHumidity() {
  sensor.read(function(a) {
    if (a.temp !== undefined) {
      console.log("温度: " + a.temp + "°C, 湿度: " + a.rhum + "%");
      // 在这里可以将数据通过 MQTT 发送到服务器
    } else {
      console.log("读取 DHT11 传感器数据失败");
    }
  });
}

// 每隔 5 秒读取一次温度和湿度
setInterval(getTemperatureAndHumidity, 5000);

Node.js 服务器端代码:

// 引入 MQTT 库
const mqtt = require('mqtt');

// 连接到 MQTT 服务器
const client  = mqtt.connect('mqtt://your_mqtt_broker');

// 订阅主题
client.subscribe('temperature');
client.subscribe('humidity');

// 监听消息
client.on('message', function (topic, message) {
  // message is Buffer
  console.log(topic + ": " + message.toString());
  // 在这里可以将数据存储到数据库,或者发送到 Web 界面
});

Web 界面代码:

<!DOCTYPE html>
<html>
<head>
  <title>智能家居控制系统</title>
</head>
<body>
  <h1>温度: <span id="temperature">--</span> °C</h1>
  <h1>湿度: <span id="humidity">--</span> %</h1>

  <script>
    // 使用 WebSocket 连接到服务器
    const socket = new WebSocket('ws://your_web_server');

    // 监听消息
    socket.onmessage = function (event) {
      const data = JSON.parse(event.data);
      document.getElementById('temperature').textContent = data.temperature;
      document.getElementById('humidity').textContent = data.humidity;
    };
  </script>
</body>
</html>

这个项目只是一个简单的示例,你可以根据自己的需求进行扩展。比如,你可以添加更多的传感器和执行器,或者使用更复杂的算法来控制硬件。

第六幕:总结与展望

JavaScript 在 IoT 领域的应用前景非常广阔。Espruino 和 Johnny-Five 都是很棒的工具,可以帮助你快速构建 IoT 应用。随着 JavaScript 技术的不断发展,相信未来会有更多的 JavaScript IoT 运行时出现,让我们可以更加方便地控制硬件,创造更加智能的世界。

今天的讲座就到这里,感谢大家的观看!希望大家能够从今天的讲座中有所收获,并能够动手尝试用 JavaScript 控制你的硬件!下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注