原帖在
http://www.bidouille.org/hack/mousecam
光电鼠标拍摄
OK,所以最后决定让我的手在Arduino平台上,看到所有的嗡嗡声是真的。我必须说,我留下深刻的印象。这是迄今为止我所见过的大多数开发人员友好的开发平台。它的主要优点:
这很简单。硬件是非常简单的,并使用标准的,通常可用的组件。的软件IDE是基本的,但功能:编辑器窗口,状态窗口,集成了串行终端。就是这样。
这是相当强大的。Arduino的diecimilla,我用基于ATmega168微控制器时钟频率为16MHz。
它是基于开放源码硬件和软件(如果你省略了商标争议商标的Arduino)。电路板设计是公开的。这导致了创造的几个变种和的克隆(Freeduino)的平台的普及做出了贡献。
电源,固件更新和串行通信通过一个单一的USB电缆。
它的可扩展性。Arduino板的主要之上,可堆叠的“盾牌”的概念是天才:)作为一个事实上,一个小的原型盾的第一件事是我做了这个平台。
所以,前一段时间,我遇到了这个伟大的光电鼠标黑客雪碧。我决定,这将是巨大的做我的第一个Arduino的项目(超越“Blinky LED”的例子,那是。)
第一步,剥离的无线鼠标便宜的台风无线鼠标/键盘组合。
ADNS-2051针 Arduino的脚
1 SCLK 数字2
16 SDIO 数字3
15 PD 数字4
13 VDD +5 V
12 GND GND
#define SCLK 2
#define SDIO 3
#define PD 4
#define REG_PRODUCT_ID 0x00
#define REG_REVISION_ID 0x01
#define REG_MOTION 0x02
#define REG_DELTA_X 0x03
#define REG_DELTA_Y 0x04
#define REG_SQUAL 0x05
#define REG_AVERAGE_PIXEL 0x06
#define REG_MAXIMUM_PIXEL 0x07
#define REG_CONFIG_BITS 0x0A
#define REG_DATA_OUT_LOWER 0x0C
#define REG_DATA_OUT_UPPER 0x0D
#define REG_SHUTTER_LOWER 0x0E
#define REG_SHUTTER_UPPER 0x0F
#define REG_FRAME_PERIOD_LOWER 0x10
#define REG_FRAME_PERIOD_UPPER 0x11
int dumpWidth = 256; // Number of pixels to read for each frame.
byte frame[256];
void setup() {
Serial.begin(115200);
reset();
byte productId = readRegister(REG_PRODUCT_ID);
byte revisionId = readRegister(REG_REVISION_ID);
Serial.print("Found productId ");
Serial.print(productId, HEX);
Serial.print(", rev. ");
Serial.print(revisionId, HEX);
Serial.println(productId == 0x02 ? " OK." : " Unknown productID. Carry on.");
byte config = readRegister(REG_CONFIG_BITS);
config |= B00000001; // Don't sleep (LED always powered on).
writeRegister(REG_CONFIG_BITS, config);
}
void loop() {
// Allows to set the dump window by sending the number of lines to read via the serial port.
if(Serial.available() > 0) {
dumpWidth = 16 * Serial.read();
dumpWidth = constrain(dumpWidth, 0, 256);
}
readRegister(REG_MOTION); // Freezes DX and DY until they are read or MOTION is read again.
char dx = readRegister(REG_DELTA_X);
char dy = readRegister(REG_DELTA_Y);
Serial.print("DELTA:");
Serial.print(dx, DEC);
Serial.print(" ");
Serial.println(dy, DEC);
if( dumpWidth > 0 )
dumpFrame();
}
void dumpFrame() {
byte config = readRegister(REG_CONFIG_BITS);
config |= B00001000; // PixDump
writeRegister(REG_CONFIG_BITS, config);
int count = 0;
do {
byte data = readRegister(REG_DATA_OUT_LOWER);
if( (data & 0x80) == 0 ) { // Data is valid
frame[count++] = data;
}
}
while (count != dumpWidth);
config = readRegister(REG_CONFIG_BITS);
config &= B11110111;
writeRegister(REG_CONFIG_BITS, config);
Serial.print("FRAME:");
for(int i = 0; i < dumpWidth; i++) {
byte pix = frame
;
if( pix < 0x10 )
Serial.print("0");
Serial.print(pix, HEX);
}
Serial.println();
}
void reset() {
pinMode(SCLK, OUTPUT);
pinMode(SDIO, INPUT);
pinMode(PD, OUTPUT);
digitalWrite(SCLK, LOW);
digitalWrite(PD, HIGH);
delayMicroseconds(1);
digitalWrite(PD, LOW);
}
byte readRegister(byte address) {
pinMode (SDIO, OUTPUT);
for (byte i=128; i >0 ; i >>= 1) {
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, (address & i) != 0 ? HIGH : LOW);
digitalWrite (SCLK, HIGH);
}
pinMode (SDIO, INPUT);
delayMicroseconds(100); // tHOLD = 100us min.
byte res = 0;
for (byte i=128; i >0 ; i >>= 1) {
digitalWrite (SCLK, LOW);
digitalWrite (SCLK, HIGH);
if( digitalRead (SDIO) == HIGH )
res |= i;
}
return res;
}
void writeRegister(byte address, byte data) {
address |= 0x80; // MSB indicates write mode.
pinMode (SDIO, OUTPUT);
for (byte i = 128; i > 0 ; i >>= 1) {
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, (address & i) != 0 ? HIGH : LOW);
digitalWrite (SCLK, HIGH);
}
for (byte i = 128; i > 0 ; i >>= 1) {
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, (data & i) != 0 ? HIGH : LOW);
digitalWrite (SCLK, HIGH);
}
delayMicroseconds(100); // tSWW, tSWR = 100us min.
}
好吧,我来详细解释一下,可能不对,欢迎指正。
1,鼠标
从软件和硬件上,鼠标被复用了。它既是扫描(XY移动)的驱动器,也是图像采集采集器。
2,Arduino
它只完成图像采集后的传输,(编辑增加),说传输,不如说是截获,因为正常的鼠标功能,鼠标不需要把小图像传回PC,只告诉PC关于移动的信息。
软件结构是这样的,无论是Java还是什么语言,比如用最简单的excel VBA好了,如果他同时可以和Arduino接口的话(dll调用或者什么),整个过程和你写一个画图板程序没什么两样。
1,找到一个容器控件,能响应windows mouse move消息,通常一个对话窗,或者图片控件
2,添加响应windows mouse move的消息响应函数,此时的windows消息参数本身就包括我们需要绘图的中心点XY(当然你也可以认为是左上点,只要全局算法一致就行)
3,从Arduino读回像素点,然后把1维的线性数据,排成方阵,这个程序,就用逐点画就好了,不用建立内部的小16x16图片
4,检查下一个mouse move和当前的关系,比如,你X,Y都在8像素以外才开始画这也是循环操作的标准。(这句写得不好,不用看了)
一个个人观点,这个方案比较讨巧,用了无线鼠标,看上去,好像鼠标不工作了,其实,他没有破坏原有的鼠标功能,你用一个有线鼠标,也同样能完成。不过,你看到拖了2个数据线,你会觉得设计的没那么棒。
一周热门 更多>