Веб-камера из оптической мыши

от автора

Для отслеживания перемещений в оптической мыши используется небольшая камера-сенсор. В этой статье я покажу как можно вывести изображение с этой камеры в браузер.

Для эксперимента я использовал старый манипулятор Logitech RX 250 с чипом ADNS-5020. Этот сенсор может записывать серые изображения с разрешением 15×15 точек, а также рассчитывать перемещения по осям X-Y.

Для эксперимента понадобятся:
— микроконтроллер arduino
— ethernet шилд
— оптическая мышь с сенсором ADNS-5020
— резистор 10 кОм

Собираем схему

Отсоедините от печатной платы мыши следующие выводы ADNS-5020: NRESET(3), NCS(4), SDIO(1), SCLK(8) при помощи паяльника или обычными кусачками.

Припаяйте резистор 10 кОм между выводами NRESET и +5В. К выводам NCS, DSIO, SCLK, +5V, GND припаяйте провода необходимой длины (20 см).
В результате мы получим такую схему соединений:

Подсоедините Ethernet шилд к контроллеру arduino и подсоедините его к сети.
Затем соедините сенор с arduino как указано ниже:
+5V — Arduino +5V
GND — Arduino GND
NCS — Arduino digital pin 7
SDIO — Arduino digital pin 6
SCLK — Arduino digital pin 5

Скетч для Arduino

Замените в этом скетче IP адрес (192.168.1.102) на адрес вашего компьютера.
Загрузите скетч в arduino.

#include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h>  byte arduinoMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress arduinoIP(192, 168, 1, 177); // desired IP for Arduino unsigned int arduinoPort = 8888;      // port of Arduino  IPAddress receiverIP(192, 168, 1, 102); // IP of udp packets receiver unsigned int receiverPort = 6000;      // port to listen on my PC  EthernetUDP Udp;  int SCLK = 5; int SDIO = 6; int NCS  = 7;  void setup() {   Serial.begin(9600);   Ethernet.begin(arduinoMac,arduinoIP);   Udp.begin(arduinoPort);      pinMode(SCLK, OUTPUT);   pinMode(SDIO, OUTPUT);   pinMode(NCS, OUTPUT);      mouse_reset();   delay(10); }  void loop() {   char img[225];   for (int i=0;i<225;i++){       img[i]=readLoc(0x0b);       img[i] &= 0x7F;       img[i]+=1;//if there is 0 value, part of udp package is lost       Serial.print(img[i], DEC);       Serial.print(",");       delay(2);   }     Serial.println();   Udp.beginPacket(receiverIP, receiverPort); //start udp packet   Udp.write(img); //write mouse data to udp packet   Udp.endPacket(); // end packet    delay(500); }  void mouse_reset(){   // Initiate chip reset   digitalWrite(NCS, LOW);   pushbyte(0x3a);   pushbyte(0x5a);   digitalWrite(NCS, HIGH);   delay(10);   // Set 1000cpi resolution   digitalWrite(NCS, LOW);   pushbyte(0x0d);   pushbyte(0x01);   digitalWrite(NCS, HIGH); }  unsigned int readLoc(uint8_t addr){   unsigned int ret=0;   digitalWrite(NCS, LOW);   pushbyte(addr);   ret=pullbyte();   digitalWrite(NCS, HIGH);   return(ret); }  void pushbyte(uint8_t c){   pinMode(SDIO, OUTPUT);   for(unsigned int i=0x80;i;i=i>>1){     digitalWrite(SCLK, LOW);     digitalWrite(SDIO, c & i);     digitalWrite(SCLK, HIGH);   } }  unsigned int pullbyte(){   unsigned int ret=0;   pinMode(SDIO, INPUT);   for(unsigned int i=0x80; i>0; i>>=1) {     digitalWrite(SCLK, LOW);     ret |= i*digitalRead(SDIO);     digitalWrite(SCLK, HIGH);   }   pinMode(SDIO, OUTPUT);   return(ret); } 

Открыв окно последовательного интерфейса можно увидеть данные приходящие от мыши:

Установите библиотеки Node.js и Socket.IO

Для показа данных в браузере мы должны установить на компьютер библиотеки node.js и socket.io. Установите node.js отсюда: nodejs.org и наберите в командной строке:
npm install socket.io

Код для вебсайта Node.js

В следующей программе мы получаем данные по udp от arduino и посылаем их в браузер используя простой web сервер.

var dgram = require("dgram"); var server = dgram.createSocket("udp4");  var io = require('socket.io').listen(8000); // server listens for socket.io communication at port 8000 io.set('log level', 1); // disables debugging. this is optional. you may remove it if desired.  server.on("message", function (msg, rinfo) { //every time new data arrives do this:   //console.log("server got: " + msg + " from " + rinfo.address + ":" + rinfo.port);    //console.log("server got:" + msg);    io.sockets.emit('message', msg); });  server.on("listening", function () {   var address = server.address();   console.log("server listening " + address.address + ":" + address.port); });  server.bind(6000); //listen to udp traffic on port 6000  var http = require("http"),     url = require("url"),     path = require("path"),     fs = require("fs")     port = process.argv[2] || 8888;  http.createServer(function(request, response) {    var uri = url.parse(request.url).pathname     , filename = path.join(process.cwd(), uri);    var contentTypesByExtension = {     '.html': "text/html",     '.css':  "text/css",     '.js':   "text/javascript"   };    fs.exists(filename, function(exists) {    	if(!exists) {       response.writeHead(404, {"Content-Type": "text/plain"});       response.write("404 Not Found\n");       response.end();       return;     } 	     if (fs.statSync(filename).isDirectory()) filename += '/index.html';      fs.readFile(filename, "binary", function(err, file) {       var headers = {};       var contentType = contentTypesByExtension[path.extname(filename)];       if (contentType) headers["Content-Type"] = contentType;       response.writeHead(200, headers);       response.write(file, "binary");       response.end();     });   }); }).listen(parseInt(port, 10));  console.log("Static file server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown"); 

Просто сохраните программу в файл: code.js

Теперь создадим веб страницу преобразующую данные из socket.io в картинку 15×15:

<html> <head> 	<style> 		#wrapper { width:300px; height:300px; } 		div div { width:20px; height:20px; float:left; } 	</style> 	<script type="text/javascript" src="//localhost:8000/socket.io/socket.io.js"></script> 	<script> 		var socket = io.connect('http://localhost:8000'); 		socket.on('connect', function () { 			socket.on('message', function (msg) { 				document.getElementById('wrapper').innerHTML = ''; 				for (var i = 0; i < 225; i++) { 					pixDraw(Math.round((msg[i])*2.4)); 				} 			}); 		});	 		function pixDraw(clr) { 			var pixDiv = document.createElement('div'); 			pixDiv.style.backgroundColor = "rgb("+clr+","+clr+","+clr+")"; 			document.getElementById("wrapper").appendChild(pixDiv); 		} 	</script> </head> <body> 	<div id="wrapper"></div> </body> </html> 

Сохраните как index.html

Запустите программу!

Для windows вы можете скачать архив download.zip по ссылке внизу и запустить runme.bat. В linux наберите команду node code.js в окне терминала.
В поле адрес браузера введите http://localhost:8888/ и увидите изображение поступающее в реальном времени от сенсора мыши:

Franci Kapel
mousecamera.zip

ссылка на оригинал статьи http://habrahabr.ru/post/207484/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *