Для отслеживания перемещений в оптической мыши используется небольшая камера-сенсор. В этой статье я покажу как можно вывести изображение с этой камеры в браузер.
Для эксперимента я использовал старый манипулятор Logitech RX 250 с чипом ADNS-5020. Этот сенсор может записывать серые изображения с разрешением 15x15 точек, а также рассчитывать перемещения по осям 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 Foundn");
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 atn => http://localhost:" + port + "/nCTRL + C to shutdown");
Просто сохраните программу в файл: code.js
Теперь создадим веб страницу преобразующую данные из socket.io в картинку 15x15:
<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
Автор: xDimus