内容简介:
当前,嵌入式系统和网络已经密不可分,我们使用的手机会联网获取资讯,家电(如空调或热水器等)会联网接受远程控制,户外监控摄像头和各种传感器通过网络将数据传回监控中心,我们所处的世界正在走向万物互联,从而形成万维物联网WoT(Web of Things)。本文借助树莓派3B Linux单板机及少量的电子元件,详细介绍Node.js与树莓派物联网控制与接口技术,以此为基础,我们还可结合当代人工智能及机器学习算法构建出丰富多彩的智能物联网或智能万维网应用平台及应用产品原型系统。
文章目录
一、Node.js简介
二、树莓派Node.js升级及构建基本的HTTP服务器测试程序
1.树莓派Node.js升级安装
2.用Node构建一个基本的树莓派HTTP服务器测试程序
三、运用Node.js编制Web服务器程序控制树莓派GPIO接口-以树莓派LED发光控制为例
1.树莓派GPIO引脚与LED连接
2.安装 onoff 模块和socket.io库
3.创建Web服务器文件和HTML文件
一、Node.js简介
简单来说,Node.js就是运行在服务端的JavaScript。Node.js是一种事件驱动I/O服务端JavaScript环境、基于Google的V8引擎而建立的一个平台。Node.js 使用事件驱动、非阻塞式 I/O 的模型,使用它可以方便、快速地构建可扩展的物联网Web应用平台。Node目前有两个活跃版本:长期支持版(LTS)和当前版,由 Node.js基金会进行管理并提供支持。自从 2009年 Node.js问世以来,JavaScript渐渐变成了能开发所有软件的语言,其地位也越来越重要,它不再是只能勉强在浏览器上使用的鸡肋语言。这里有 ECMAScript 2015的功劳,因为它解决了之前那些ECMAScript标准中遗留下来的几个关键问题。Node所用的Google V8引擎就是基于ECMAScript 2015而开发的。ECMAScript 2015是 ECMAScript标准的第6个版本,所以有时也被称为 ES6。Node、React和 Electron等技术创新成果让 JavaScript无处不在:从服务器到浏览器,再到原生的移动端应用程序。甚至像微软这样的大公司都对JavaScript敞开了怀抱,也为Node的成功应用起到了推波助澜的作用。
Node和JavaScript的优势之一是它们的单线程编程模型。多个线程一般会引入 Bug,尽管一些新的编程语言,包括 Go和 Rust,试图提供更加安全的并发工具,但 Node仍然保留了JavaScript在浏览器中所用的模型。在为浏览器编写代码时,我们写的指令序列一次执行一条,代码非并行执行。然而对于用户界面来说这是不合理的,没有哪个用户想在浏览器执行网络访问或文件获取这样的低速操作时干等。为了解决该问题,在浏览器中引入事件处理机制:当你点击按钮时,就有一个事件被触发,还有一个之前定义的函数会跑起来。这种机制能规避一些在线程编程中经常出现的问题,如资源死锁及竞态条件等。
二、树莓派Node.js升级及构建基本的HTTP服务器测试程序
1.树莓派Node.js升级安装
网上提供了较简单的树莓派Node.js升级两步安装法。以Raspberry PI 3B为例,在RPi Linux终端升级安装node.js v10.22.0版本步骤如下:
~$ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
~$ sudo apt-get install -y nodejs
升级安装是否成功,可以输入以下命令进行测试:
~$ node -v
v10.22.0
~$ nodejs
v10.22.0
~$ npm -v
6.14.6
从上面输入命令及显示,我们可以看出RPi已成功安装node v10.22.0和npm 6.14.6,并且node和nodejs两种命令方式都可以使用。
2.用Node构建一个基本的树莓派HTTP服务器测试程序
下面我们使用Raspberry Pi的nano编辑器创建一个基本的HTTP服务器测试程序(见图1),程序清单如下:
//Filename: nodetest.js
//导入http模块
var http = require(‘http’);
//调用http.createServer()方法创建服务器
http.createServer(function (request, response) {
//通过response.writeHead()方法写http文件头
response.writeHead(200, {‘Content-Type’: ‘text/plain’});
//通过response.end()方法发送响应状态码,并通知服务器完成消息
response.end(‘Hello Node.js!\n’);
}).listen(3000);//监听3000端口号
// TODO: console log - server info
console.log(‘Server running at http://192.168.199.106:3000/’);
图1 一个基本的HTTP服务器测试程序
程序最后一句使用console.log()方法显示’Server running at http://192.168.199.106:3000/'字符串。其中,192.168.199.106是所用树莓派的IP地址。
保存程序,输入node命令并运行:
$ node testserver.js
在浏览器输入http://192.168.199.106:3000,我们可以看到“Hello Node.js!”输出结果,故node.js运行成功。
三、运用Node.js编制Web服务器程序控制树莓派GPIO接口-以树莓派LED发光控制为例
1.树莓派GPIO引脚与LED连接
这里以WiFi方式,即同一WiFi路由器下的局域网,通过单击Web页面的按钮,控制连接到树莓派GPIO.4引脚的LED。树莓派GPIO引脚排列可通过gpio readall命令获得(见图2)。
图2 树莓派GPIO引脚排列及编号对照
下面对图2的GPIO引脚及编号进行说明,树莓派GPIO引脚是数字引脚,可以将它的输出设为高电平或低电平,或者通过它读取输入的高低电平。如果想读取模拟输入设备的值,需要外接ADC芯片。树莓派GPIO引脚编码有三种方式:(1) BOARD编码:是根据板子上引脚的位置进行编号,自上而下,从左到右,依次进行编号,也称为物理引脚(Physical pins)。(2) BCM编码:是Broadcom提供的一种编码规则,它和Broadcom ARM SoC片上系统中的信道编号相对应,这些编码看起来没有什么规律,是Python等GPIO编程常用的引脚编码方式;(3) wiringPi编码:是GNU gcc/g++等GPIO编程常用的引脚编码方式,简称wPi。
图3 树莓派GPIO引脚与LED连接原理图及实物图
树莓派GPIO引脚与LED连接原理图及实物图见图3所示。图3左侧为原理图,右侧为树莓派GPIO与LED连接实物图,这里树莓派GPIO使用Pin16物理引脚,其对应wiringPi编码为4、BCM编码为23。发光二极管选用直径为5mm的红色LED,其正向导通电压一般在1.7V~2.2V之间,LED发光亮度可根据GPIO引脚驱动电流公式I≈(VH-1.8V)/R近似选取,式中 VH ≈3.3V为GPIO引脚高电平电压,1.8V为LED正向导通时的额定电压,注意树莓派GPIO引脚最大驱动电流不要超过16mA;R为限流电阻,其值越小LED亮度越暗,这里限流电阻选用了1kΩ电阻,如果想增大LED亮度还可选用680Ω、220Ω等标称电阻。树莓派Pin16物理引脚(BCM GPIO 23)、Pin6物理引脚(GND)与1kΩ限流电阻及LED通过三根杜邦线连接,此处使用了两端为母插头的杜邦线,这样可以省掉面包板。
2.安装 onoff 模块和socket.io库
这里使用Node.js、socket.io编制Web服务器程序控制树莓派的GPIO 接口。通过在Web页面创建两个开关按钮来远程控制连接到树莓派GPIO接口上的LED 点的点亮或熄灭。
Socket.io是一个WebSocket库,它包括客户端的JavaScript和服务器端的Nodejs,其目标是构建能在不同浏览器、嵌入式设备及移动设备上使用的实时应用。它会自动根据浏览器从WebSocket、Ajax长轮询、Iframe流标签等方式中选择最佳方式实现网络实时应用。
前面已安装了树莓派Node.js,接下来安装 onoff 模块、socket.io库:
(1)安装 onoff 模块
~$ npm install onoff
(2)安装socket.io库
~$ npm install socket.io –save
安装好Node.js、onoff模块、socket.io库后,我们就能从浏览器网页控制Raspberry Pi的GPIO 接口了。
3.创建Web服务器文件和HTML文件
我们已经安装了所有必需的包,现在可以创建Web服务器程序和HTML文件了,建议将这些文件放在同一目录中。
首先创建一个HTML文件,通过键入~$ nano index.html 命令来创建一个名为index.html文件,输入代码如下:
<!--Filename: index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html" charset="UTF-8">
<title>树莓派GPIO接口的Web远程控制</title>
</head>
<body>
<h3>控制BCM编码23引脚</h3>
<button type="button" id="state" onclick="LEDOn()" style="background-color:green;"> LED灯点亮 </button>
<button type="button" id="state" onclick="LEDOff()" style="background-color:red;"> LED灯熄灭 </button>
<script src="https://cdn.bootcss.com/socket.io/2.0.3/socket.io.js"></script>
<script> var socket = io.connect(); //load socket.io-client and connect to the host function LEDOn(){ socket.emit("state", 1); //发送button打开LED状态 } function LEDOff(){ socket.emit("state", 0); //发送button关闭LED状态 } </script>
</html>
</body>
</html>
接着,我们再创建一个Web服务器文件。Node.js文件将打开请求并返回文件的内容,如果出现错误,它将返回404。通过键入~$ nano ledonoff_webserver.js命令创建一个名为名为ledonoff_webserver.js 的服务器文件,输入代码如下:
//Filename: ledonoff_webserver.js
var Gpio = require('onoff').Gpio; //Require onoff to control GPIO
var LEDPin = new Gpio(23, 'out'); //Declare BCM Coding GPIO 23 an output
var fs = require('fs'); //Require filesystem to read html files
var http = require('http').createServer(function handler(req, res) { //Create server
fs.readFile(__dirname + '/index.html', function (err, data) { //Read html file
if (err) {
res.writeHead(500);
return res.end('Error loading socket.io.html');
}
res.writeHead(200);
res.end(data);
});
});
var io = require('socket.io')(http) //Require socket.io module and pass the http object
http.listen(3000); //Listen to port 3000
io.sockets.on('connection', function (socket) { // WebSocket Connection
var buttonState = 0; //Variable to store button state
socket.on('state', function (data) { //Get button state from client
buttonState = data;
if (buttonState != LEDPin.readSync()) { //Change LED state if button state is changed
LEDPin.writeSync(buttonState); //Turn LED on or off
}
});
});
注意,对于图3中的LED连接到GPIO.4(Pin16)引脚,要使用对应于图2中的BCM编码23引脚号。这样我们就成功创建了Web服务器和HTML文件,接下来,我们就可以运行Web服务器并通过Web页面控制Raspberry Pi的GPIO 接口了。
在命令终端输入以下命令启动web服务器:
~$ node ledonoff_webserver.js
然后,我们可用连接WiFi的手机打开浏览器,使用“树莓派的IP地址:3000”打开网页。我使用的树莓派IP地址是192.168.199.106,在手机浏览器中键入:http://192.168.199.106:3000,应该会在浏览器上看到 “LED灯点亮”和“LED灯熄灭”两个按钮(见图4)。当按下手机浏览器中的“LED灯点亮”按钮时,连接到树莓派GPIO引脚的LED就会点亮(见图5);当按下 “LED灯熄灭”按钮时,连接到树莓派GPIO引脚的LED就会熄灭。
图4 手机浏览器远程控制LED灯亮灭的操作界面
图5 按下图4的 “LED灯点亮”按钮,连接树莓派的LED灯被点亮
在此基础上,我们还可结合当代人工智能及机器学习算法构建出丰富多彩的智能物联网或智能万维网应用平台及应用产品原型系统,如利用树莓派PWM(脉宽调制)信号和当代智能控制算法开发电动机、机械臂的远程智能控制创新应用等。
(作者Email联系:yuanzywhu@163.com)
发布日期:2020年9月10日