一板网电子技术论坛

风筝
发表于: 2019-3-5 10:52:25 | 显示全部楼层

使用开放式声音控制(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'。然后,在文件中输入以下代码。

  1. var http = require('http'),
  2.     socketio = require('socket.io'),
  3.     fs = require('fs'),
  4.     osc = require('osc-min'),
  5.     dgram = require('dgram'),
  6.     remote_osc_ip;

  7. var http_server = http.createServer(function(req, res) {

  8.   fs.readFile(__dirname + '/socketio.html', function(err, data) {

  9.     if(err) {
  10.       res.writeHead(500);
  11.       return res.end('Error loading socket.io.html');
  12.     }

  13.     res.writeHead(200);
  14.     res.end(data);

  15.   });

  16. });

  17. var io = socketio(http_server);

  18. var udp_server = dgram.createSocket('udp4', function(msg, rinfo) {

  19.   var osc_message;
  20.   try {
  21.     osc_message = osc.fromBuffer(msg);
  22.   } catch(err) {
  23.     return console.log('Could not decode OSC message');
  24.   }

  25.   if(osc_message.address != '/socketio') {
  26.     return console.log('Invalid OSC address');
  27.   }

  28.   remote_osc_ip = rinfo.address;

  29.   io.emit('osc', {
  30.     x: parseInt(osc_message.args[0].value) || 0
  31.   });

  32. });

  33. io.on('connection', function(socket) {

  34.   socket.on('browser', function(data) {

  35.     if(! remote_osc_ip) {
  36.       return;
  37.     }

  38.     var osc_msg = osc.toBuffer({
  39.       oscType: 'message',
  40.       address: '/socketio',
  41.       args:[{
  42.         type: 'integer',
  43.         value: parseInt(data.x) || 0
  44.       },
  45.       {
  46.         type: 'integer',
  47.         value: parseInt(data.y) || 0
  48.       }]
  49.     });

  50.     udp_server.send(osc_msg, 0, osc_msg.length, 9999, remote_osc_ip);
  51.     console.log('Sent OSC message to %s:9999', remote_osc_ip);

  52.   });

  53. });

  54. http_server.listen(8080);
  55. console.log('Starting HTTP server on TCP port 8080');
  56. udp_server.bind(9998);
  57. console.log('Starting UDP server on UDP port 9998');
复制代码

现在,运行'socketio.js'文件,该文件将允许发送和接收消息。 导航到CMD中的目录并输入命令:node socketio.js

CMD window.png

CMD窗口显示'node socketio.js'代码输入。


接下来,在浏览器中打开一个网页。您将在节点脚本的输出部分中看到HTTP服务器设置为端口8080。此网页将发送OSC消息并在按下浏览器按钮后显示输出信息。


首先,将网页代码保存在HTML文件中,并将其命名为'socketio.html'。 然后,将其放在'socketio'文件夹中。

  1. <!DOCTYPE html>
  2. <html lang="en">


  3. <head>
  4.   <meta charset="utf-8">
  5.   <title>OSC Communication</title>
  6.   <script src="/socket.io/socket.io.js"></script>
  7. </head>


  8. <body>
  9.   <h2>OSC Communication between Arduino and Browser</h2>
  10.   Buttons to control LED
  11.   <button type="button" id="x" value="1" onclick="myFunction()" style="background-color:green;">ON</button>
  12.   <button type="button" id="y" value="2" onclick="myFunction1()" style="background-color:red;">OFF</button>
  13.   <h2>Output From Arduino:</h2>
  14.   <span id="output"></span>


  15.   <script>
  16.     var socket = io.connect();


  17.     socket.on('osc', function (data) {
  18.       if (data.x == 1) {
  19.         document.getElementById("output").innerHTML = "LED ON";
  20.       }
  21.       if (data.x == 2) {
  22.         document.getElementById("output").innerHTML = "LED OFF";
  23.       }
  24.     });


  25.     function myFunction() {
  26.       socket.emit('browser', {
  27.         x: 1 || 0
  28.       });
  29.     }


  30.     function myFunction1() {
  31.       socket.emit('browser', {
  32.         x: 2 || 0
  33.       });
  34.     }
  35.   </script>
  36. </body>


  37. </html>
复制代码

要打开网页,您需要Arduino的端口8080 IP地址。请遵循以下URL格式:http :: //x.x.x.x:8080。将“x.x.x.x”替换为您的系统IP地址。

webpage.png

显示Arduino和浏览器之间通信信息的网页。


Processing草图

此时,我们将安排从端口999的浏览器接收数据并将其转发到Arduino。下面的草图将允许Arduino中的数据传输到浏览器的端口9998。然后处理将与Arduino串口和COM端口通信。

请注意,双方的波特率是相同的。

  1. // Importing the library that will help us in sending and receiving the values from the Arduino
  2. // You always need to import the serial library in addition to the VSync library
  3. import vsync.*;
  4. import processing.serial.*;  

  5. // Below libraries will connect and send, receive OSC messages
  6. import oscP5.*;  
  7. import netP5.*;

  8. // Creating the instances to connect and send, receive OSC messages
  9. OscP5 oscP5;
  10. NetAddress dest;

  11. //  We create a new ValueReceiver to receive values from the arduino and a new
  12. // ValueSender to send values to arduino
  13. ValueSender sender;
  14. ValueReceiver receiver;

  15. // The below variables will be syncronized with the Arduino and they should be same on the both sides.
  16. public int output;
  17. public int input = 2;

  18. void setup()
  19. {
  20.   // Starting the serial communication, the baudrate and the com port should be same as on the Arduino side.
  21.   Serial serial = new Serial(this, "COM6", 9600);

  22.   //  Ininialize the ValueReceiver and ValueSender with this (to hook it to your sketch)
  23.   //  and the serial interface you want to use.
  24.   sender = new ValueSender(this, serial);
  25.   receiver = new ValueReceiver(this, serial);

  26.   // Synchronizing the variables as on the Arduino side. The order should be same.
  27.   sender.observe("output");
  28.   receiver.observe("input");

  29.   // Starting the OSC Communication. listen on port 9999, return messages on port 9998
  30.   oscP5 = new OscP5(this, 9999);
  31.   dest = new NetAddress("127.0.0.1", 9998);
  32. }

  33. void draw() {
  34.   if (input == 1) {
  35.     sendOsc();
  36.   }
  37.   if (input == 2) {
  38.     sendOsc();
  39.   }
  40.   print("input: ");
  41.   println(input);
  42. }

  43. // Function to send OSC messages to browser
  44. void sendOsc() {
  45.   OscMessage msg = new OscMessage("/socketio");  // tell the address
  46.   msg.add((float)input); // add the message
  47.   oscP5.send(msg, dest); //send the OSC message
  48. }

  49. // Recieve OSC messages from browser
  50. void oscEvent(OscMessage theOscMessage) {
  51.   if (theOscMessage.checkAddrPattern("/socketio") == true) {
  52.     // Receiving the output from browser
  53.     output = theOscMessage.get(0).intValue();  

  54.     print("output: ");
  55.     println(output);
  56.   }
  57. }
复制代码

Arduino草图

一旦Arduino草图从Processing接收输出数据,它将触发LED信号。

如果输出为1,它将点亮LED。如果输出为2,它将关闭LED。

草图还会向Processing发送一条消息,确认LED是否亮起。


注意:在上传草图之前,请确保Processing没有运行,因为它将使用相同的端口并且会出现“port busy”错误。

  1. //Including the library that will help us in receiving and sending the values from processing
  2. #include <VSync.h>
  3. ValueReceiver<1> receiver;  // Receiver Object
  4. ValueSender<1> sender;      // Sender Object

  5. // The below variables will be syncronized with the Processing and they should be same on the both sides.
  6. int output;
  7. int input;

  8. int ledPin = 13; //LED Pin

  9. void setup()
  10. {
  11.   /* Starting the serial communication because we are communicating with the
  12.     Arduino through serial. The baudrate should be same as on the processing side. */
  13.   Serial.begin(9600);
  14.   pinMode(ledPin, OUTPUT);

  15.   // Synchronizing the variables with the processing. The variables must be int type.
  16.   receiver.observe(output);
  17.   sender.observe(input);
  18. }

  19. void loop()
  20. {
  21.   // Receiving the output from the processing.
  22.   receiver.sync();

  23.   // Matching the received output to light up LED
  24.   if (output == 1)
  25.   {
  26.     digitalWrite(ledPin, HIGH);
  27.     input = 1;
  28.   }
  29.   else if (output == 2)
  30.   {
  31.     digitalWrite(ledPin, LOW);
  32.     input = 2;
  33.   }
  34.   sender.sync();
  35. }
复制代码

如何运行项目

首先,通过CMD运行'socketio.js'文件,它将创建一个服务器,帮助从Processing发送和接收数据。之后,在浏览器中输入您的PC IP地址,然后输入端口8080以打开网页。


在Arduino IDE中上传Arduino代码,然后在Processing中更改波特率和COM端口。 同样,两端的波特率和COM端口应该相同。


如果您按下网页按钮,作为响应,内置的Arduino LED将亮起或熄灭。

跳转到指定楼层
回复

使用道具 举报

我吃大西瓜
发表于: 2019-4-16 10:19:42 | 显示全部楼层

如何将Arduino传感器的数据传输显示在网页上啊?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 288 | 回复: 503



Archiver|手机版|小黑屋|

GMT+8, 2019-5-24 17:40 , Processed in 0.078125 second(s), 31 queries . Powered by Discuz! X3.4

YiBoard一板网 © 2015-2018 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表