您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何利用Arduino+Nodejs做一個(gè)手勢(shì)識(shí)別的交互系統(tǒng),內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
接觸Arduino也有些日子了,就想著做一個(gè)小玩意兒檢驗(yàn)一下哈。不恰當(dāng)?shù)牡胤綒g迎交流一下。。。
本次接到命令要做一個(gè)智能手勢(shì)識(shí)別交互的系統(tǒng)產(chǎn)品。主要用到的硬件模塊有SeeedStudio也就是矽遞科技公司開發(fā)一款A(yù)rduino Uno開發(fā)板圖1、一款PAJ傳感器圖2。軟件方面就主要是Arduino IDE和Nodejs架設(shè)的Web服務(wù)器。目標(biāo)產(chǎn)品的預(yù)想是通過手勢(shì)動(dòng)作控制Web界面的滾動(dòng)與切換。
圖1:
圖2:
介紹完所需材料模塊,那就開始進(jìn)行積木搭建咯。。
因?yàn)槟K比較少,就省去了擴(kuò)展板
下面是Arduino IDE程序:
代碼在這里:
//調(diào)用兩個(gè)庫函數(shù) #include <Wire.h> #include "paj7620.h" #define GES_REACTION_TIME 800 #define GES_QUIT_TIME 1000 //定義一個(gè)LED輸出引腳,用來進(jìn)行握手測(cè)試 const int ledPin = 13; //定義一個(gè)初始狀態(tài)字符 String ledStatus = "off"; // 用來從Nodejs客戶端獲取信息 String inputString = ""; boolean stringComplete = false; /** * * arduino board setup * */ void setup() { // 設(shè)置波特率 Serial.begin(115200); //定義LED引腳 pinMode(ledPin, OUTPUT); //PAJ uint8_t error = 0; Serial.println("\nPAJ7620U2 TEST DEMO: Recognize 15 gestures."); error = paj7620Init(); // initialize Paj7620 registers if (error) { Serial.print("INIT ERROR,CODE:"); Serial.println(error); } else { Serial.println("INIT OK"); } Serial.println("Please input your gestures:"); } /** * * Default arduino loop function * it runs over and over again * */ void loop() { uint8_t data = 0, data1 = 0, error; error = paj7620ReadReg(0x43, 1, &data); // Read Bank_0_Reg_0x43/0x44 for gesture result. if (!error) { switch (data) { case GES_RIGHT_FLAG: delay(GES_REACTION_TIME); paj7620ReadReg(0x43, 1, &data); if(data == GES_LEFT_FLAG) { Serial.println("<section class=\"Right-Left\">"); Serial.println("</section>"); } else if(data == GES_FORWARD_FLAG) { Serial.println("<section class=\"Forward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else if(data == GES_BACKWARD_FLAG) { Serial.println("<section class=\"Backward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else { Serial.println("<section class=\"Right\">"); Serial.println("</section>"); } break; case GES_LEFT_FLAG: delay(GES_REACTION_TIME); paj7620ReadReg(0x43, 1, &data); if(data == GES_RIGHT_FLAG) { Serial.println("<section class=\"Left-Right\">"); Serial.println("</section>"); } else if(data == GES_FORWARD_FLAG) { Serial.println("<section class=\"Forward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else if(data == GES_BACKWARD_FLAG) { Serial.println("<section class=\"Backward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else { Serial.println("<section class=\"Left\">"); Serial.println("</section>"); } break; break; case GES_UP_FLAG: delay(GES_REACTION_TIME); paj7620ReadReg(0x43, 1, &data); if(data == GES_DOWN_FLAG) { Serial.println("<section class=\"Up-Down\">"); Serial.println("</section>"); } else if(data == GES_FORWARD_FLAG) { Serial.println("<section class=\"Forward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else if(data == GES_BACKWARD_FLAG) { Serial.println("<section class=\"Backward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else { Serial.println("<section class=\"Up\">"); Serial.println("</section>"); } break; case GES_DOWN_FLAG: delay(GES_REACTION_TIME); paj7620ReadReg(0x43, 1, &data); if(data == GES_UP_FLAG) { Serial.println("<section class=\"Down-Up\">"); Serial.println("</section>"); } else if(data == GES_FORWARD_FLAG) { Serial.println("<section class=\"Forward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else if(data == GES_BACKWARD_FLAG) { Serial.println("<section class=\"Backward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else { Serial.println("<section class=\"Down\">"); Serial.println("</section>"); } break; case GES_FORWARD_FLAG: delay(GES_REACTION_TIME); paj7620ReadReg(0x43, 1, &data); if(data == GES_BACKWARD_FLAG) { Serial.println("<section class=\"Forward-Backward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else { Serial.println("<section class=\"Forward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } break; case GES_BACKWARD_FLAG: delay(GES_REACTION_TIME); paj7620ReadReg(0x43, 1, &data); if(data == GES_FORWARD_FLAG) { Serial.println("<section class=\"Backward-Forward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } else { Serial.println("<section class=\"Backward\">"); Serial.println("</section>"); delay(GES_QUIT_TIME); } break; case GES_CLOCKWISE_FLAG: Serial.println("<section class=\"Clockwise\">"); Serial.println("</section>"); break; case GES_COUNT_CLOCKWISE_FLAG: Serial.println("<section class=\"anti-clockwise\">"); Serial.println("</section>"); break; default: paj7620ReadReg(0x44, 1, &data1); if (data1 == GES_WAVE_FLAG) { Serial.println("<section class=\"wave\">"); Serial.println("</section>"); } break; } } delay(100); updateLedStatus(); } void updateLedStatus() { //檢測(cè)LED狀態(tài)是否被完整接收 if (stringComplete) { if (inputString == "on\r") { ledStatus = "on"; } if (inputString == "off\r") { ledStatus = "off"; } //把LED狀態(tài)發(fā)送到服務(wù)器 Serial.println(ledStatus); inputString = ""; stringComplete = false; } // 通過當(dāng)時(shí)狀態(tài)判斷行為動(dòng)作狀態(tài) digitalWrite(ledPin, ledStatus == "on" ? HIGH : LOW); } void serialEvent() { while (Serial.available()) { // 接收新字節(jié) char inChar = (char)Serial.read(); inputString += inChar; // 如果接收到換行符則中斷 if (inChar == '\r') { stringComplete = true; } } }
接著是Web服務(wù)器的搭建,使用的是Nodejs。
其中server.js文件:
var app = require('http').createServer(handler), io = require('socket.io').listen(app), fs = require('fs'), url = require('url'), SerialPort = require('serialport').SerialPort, // initialize serialport using the COM5 serial port // remember to change this string if your arduino is using a different serial port sp = new SerialPort('COM5', { baudRate: 115200 }), // this var will contain the message string dispatched by arduino arduinoMessage = '', /** * helper function to load any app file required by client.html * @param { String } pathname: path of the file requested to the nodejs server * @param { Object } res: http://nodejs.org/api/http.html#http_class_http_serverresponse */ readFile = function(pathname, res) { // an empty path returns client.html if (pathname === '/') pathname = 'client.html'; fs.readFile('htmlarduino/client/' + pathname, function(err, data) { if (err) { console.log(err); res.writeHead(500); return res.end('Error loading client.html'); } res.writeHead(200); res.end(data); }); }, /** * * This function is used as proxy to print the arduino messages into the nodejs console and on the page * @param { Buffer } buffer: buffer data sent via serialport * @param { Object } socket: it's the socket.io instance managing the connections with the client.html page * */ sendMessage = function(buffer, socket) { // concatenating the string buffers sent via usb port arduinoMessage += buffer.toString(); // detecting the end of the string if (arduinoMessage.indexOf('\r') >= 0) { // log the message into the terminal // console.log(arduinoMessage); // send the message to the client socket.volatile.emit('notification', arduinoMessage); // reset the output string to an empty value arduinoMessage = ''; } }; // creating a new websocket io.sockets.on('connection', function(socket) { // listen all the serial port messages sent from arduino and passing them to the proxy function sendMessage sp.on('data', function(data) { sendMessage(data, socket); }); // listen all the websocket "lightStatus" messages coming from the client.html page socket.on('lightStatus', function(lightStatus) { sp.write(lightStatus + '\r', function() { // log the light status into the terminal console.log('the light should be: ' + lightStatus); }); }); }); // just some debug listeners sp.on('close', function(err) { console.log('Port closed!'); }); sp.on('error', function(err) { console.error('error', err); }); sp.on('open', function() { console.log('Port opened!'); }); // L3T'S R0CK!!! // creating the server ( localhost:8000 ) app.listen(8000); // server handler function handler(req, res) { readFile(url.parse(req.url).pathname, res); }
其中還有用到Nodejs的socket.io模塊進(jìn)行前后臺(tái)數(shù)據(jù)調(diào)用。serialport模塊進(jìn)行跟Arduino串口匹配通信。通過npm命令就可以安裝
Web頁面就比較簡(jiǎn)單了:
<html> <head> <title>手勢(shì)識(shí)別控制Web</title> <style> center { font-size: 100px; font-family:arial; background:rgba(20,20,20,0.5); width:500px; margin:auto; } section{background:#333;margin:10px;width:100px;height:100px;} </style> </head> <body> <button> Turn the light <span>on</span> </button> <script src="socket.io/socket.io.js"></script> <script src="http://code.jquery.com/jquery-latest.min.js"></script> <script src="js/app.js"></script> </body> </html>
上述內(nèi)容就是如何利用Arduino+Nodejs做一個(gè)手勢(shì)識(shí)別的交互系統(tǒng),你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。