|
使用开放式声音控制(OSC)协议建立Arduino和Web浏览器之间的通信。
本篇文章主要介绍了如何在Arduino开发板和Web浏览器之间建立双向的、开放式声音控制(OSC)的通信。我们将使用浏览器中的按钮将OSC消息发送到Processing。然后,Processing将消息转发给Arduino,Arduino控制LED并响应确认。
在本篇文章中使用Processing软件是非常必要的,因为只有一个Arduino无法从Web接收OSC消息。如果您不想使用Processing,那么可以使用以太网扩展板解决该问题。
OSC是允许计算机和其他多媒体设备之间通信的协议。这个简单但功能强大的工具提供了实时控制声音和其他媒体处理需求所需的一切 - 同时保持灵活且易于实施。它可以被认为是乐器数字接口(MIDI)的继承者。
所需的组件 ● Arduino开发板 ● Arduino IDE
先决条件 下载并安装node.js,然后通过将以下命令插入终端来安装socket.io库:npm install socket.io
浏览器说明 要通过浏览器接收OSC消息,我们需要使用'node.js'环境。它将通过WebSocket协议接收消息并将消息转发到浏览器,该协议充当两者之间的桥梁。
创建一个文件夹,在里面使用“.js”扩展名命名一个文件。在本篇文章中,我们使用'socketio.js'。然后,在文件中输入以下代码。 - var http = require('http'),
- socketio = require('socket.io'),
- fs = require('fs'),
- osc = require('osc-min'),
- dgram = require('dgram'),
- remote_osc_ip;
-
- var http_server = http.createServer(function(req, res) {
-
- fs.readFile(__dirname + '/socketio.html', function(err, data) {
-
- if(err) {
- res.writeHead(500);
- return res.end('Error loading socket.io.html');
- }
-
- res.writeHead(200);
- res.end(data);
-
- });
-
- });
-
- var io = socketio(http_server);
-
- var udp_server = dgram.createSocket('udp4', function(msg, rinfo) {
-
- var osc_message;
- try {
- osc_message = osc.fromBuffer(msg);
- } catch(err) {
- return console.log('Could not decode OSC message');
- }
-
- if(osc_message.address != '/socketio') {
- return console.log('Invalid OSC address');
- }
-
- remote_osc_ip = rinfo.address;
-
- io.emit('osc', {
- x: parseInt(osc_message.args[0].value) || 0
- });
-
- });
-
- io.on('connection', function(socket) {
-
- socket.on('browser', function(data) {
-
- if(! remote_osc_ip) {
- return;
- }
-
- var osc_msg = osc.toBuffer({
- oscType: 'message',
- address: '/socketio',
- args:[{
- type: 'integer',
- value: parseInt(data.x) || 0
- },
- {
- type: 'integer',
- value: parseInt(data.y) || 0
- }]
- });
-
- udp_server.send(osc_msg, 0, osc_msg.length, 9999, remote_osc_ip);
- console.log('Sent OSC message to %s:9999', remote_osc_ip);
-
- });
-
- });
-
- http_server.listen(8080);
- console.log('Starting HTTP server on TCP port 8080');
- udp_server.bind(9998);
- console.log('Starting UDP server on UDP port 9998');
复制代码
现在,运行'socketio.js'文件,该文件将允许发送和接收消息。 导航到CMD中的目录并输入命令:node socketio.js
CMD窗口显示'node socketio.js'代码输入。
接下来,在浏览器中打开一个网页。您将在节点脚本的输出部分中看到HTTP服务器设置为端口8080。此网页将发送OSC消息并在按下浏览器按钮后显示输出信息。
首先,将网页代码保存在HTML文件中,并将其命名为'socketio.html'。 然后,将其放在'socketio'文件夹中。 - <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>OSC Communication</title>
- <script src="/socket.io/socket.io.js"></script>
- </head>
- <body>
- <h2>OSC Communication between Arduino and Browser</h2>
- Buttons to control LED
- <button type="button" id="x" value="1" onclick="myFunction()" style="background-color:green;">ON</button>
- <button type="button" id="y" value="2" onclick="myFunction1()" style="background-color:red;">OFF</button>
- <h2>Output From Arduino:</h2>
- <span id="output"></span>
- <script>
- var socket = io.connect();
- socket.on('osc', function (data) {
- if (data.x == 1) {
- document.getElementById("output").innerHTML = "LED ON";
- }
- if (data.x == 2) {
- document.getElementById("output").innerHTML = "LED OFF";
- }
- });
- function myFunction() {
- socket.emit('browser', {
- x: 1 || 0
- });
- }
- function myFunction1() {
- socket.emit('browser', {
- x: 2 || 0
- });
- }
- </script>
- </body>
- </html>
复制代码
要打开网页,您需要Arduino的端口8080 IP地址。请遵循以下URL格式:http :: //x.x.x.x:8080。将“x.x.x.x”替换为您的系统IP地址。
显示Arduino和浏览器之间通信信息的网页。
Processing草图 此时,我们将安排从端口999的浏览器接收数据并将其转发到Arduino。下面的草图将允许Arduino中的数据传输到浏览器的端口9998。然后处理将与Arduino串口和COM端口通信。 请注意,双方的波特率是相同的。 - // Importing the library that will help us in sending and receiving the values from the Arduino
- // You always need to import the serial library in addition to the VSync library
- import vsync.*;
- import processing.serial.*;
- // Below libraries will connect and send, receive OSC messages
- import oscP5.*;
- import netP5.*;
- // Creating the instances to connect and send, receive OSC messages
- OscP5 oscP5;
- NetAddress dest;
- // We create a new ValueReceiver to receive values from the arduino and a new
- // ValueSender to send values to arduino
- ValueSender sender;
- ValueReceiver receiver;
- // The below variables will be syncronized with the Arduino and they should be same on the both sides.
- public int output;
- public int input = 2;
- void setup()
- {
- // Starting the serial communication, the baudrate and the com port should be same as on the Arduino side.
- Serial serial = new Serial(this, "COM6", 9600);
- // Ininialize the ValueReceiver and ValueSender with this (to hook it to your sketch)
- // and the serial interface you want to use.
- sender = new ValueSender(this, serial);
- receiver = new ValueReceiver(this, serial);
- // Synchronizing the variables as on the Arduino side. The order should be same.
- sender.observe("output");
- receiver.observe("input");
- // Starting the OSC Communication. listen on port 9999, return messages on port 9998
- oscP5 = new OscP5(this, 9999);
- dest = new NetAddress("127.0.0.1", 9998);
- }
- void draw() {
- if (input == 1) {
- sendOsc();
- }
- if (input == 2) {
- sendOsc();
- }
- print("input: ");
- println(input);
- }
- // Function to send OSC messages to browser
- void sendOsc() {
- OscMessage msg = new OscMessage("/socketio"); // tell the address
- msg.add((float)input); // add the message
- oscP5.send(msg, dest); //send the OSC message
- }
- // Recieve OSC messages from browser
- void oscEvent(OscMessage theOscMessage) {
- if (theOscMessage.checkAddrPattern("/socketio") == true) {
- // Receiving the output from browser
- output = theOscMessage.get(0).intValue();
- print("output: ");
- println(output);
- }
- }
复制代码
Arduino草图 一旦Arduino草图从Processing接收输出数据,它将触发LED信号。 如果输出为1,它将点亮LED。如果输出为2,它将关闭LED。 草图还会向Processing发送一条消息,确认LED是否亮起。
注意:在上传草图之前,请确保Processing没有运行,因为它将使用相同的端口并且会出现“port busy”错误。 - //Including the library that will help us in receiving and sending the values from processing
- #include <VSync.h>
- ValueReceiver<1> receiver; // Receiver Object
- ValueSender<1> sender; // Sender Object
- // The below variables will be syncronized with the Processing and they should be same on the both sides.
- int output;
- int input;
- int ledPin = 13; //LED Pin
- void setup()
- {
- /* Starting the serial communication because we are communicating with the
- Arduino through serial. The baudrate should be same as on the processing side. */
- Serial.begin(9600);
- pinMode(ledPin, OUTPUT);
- // Synchronizing the variables with the processing. The variables must be int type.
- receiver.observe(output);
- sender.observe(input);
- }
- void loop()
- {
- // Receiving the output from the processing.
- receiver.sync();
- // Matching the received output to light up LED
- if (output == 1)
- {
- digitalWrite(ledPin, HIGH);
- input = 1;
- }
- else if (output == 2)
- {
- digitalWrite(ledPin, LOW);
- input = 2;
- }
- sender.sync();
- }
复制代码
如何运行项目 首先,通过CMD运行'socketio.js'文件,它将创建一个服务器,帮助从Processing发送和接收数据。之后,在浏览器中输入您的PC IP地址,然后输入端口8080以打开网页。
在Arduino IDE中上传Arduino代码,然后在Processing中更改波特率和COM端口。 同样,两端的波特率和COM端口应该相同。
如果您按下网页按钮,作为响应,内置的Arduino LED将亮起或熄灭。 |