鼠标传感器改造成扫描器,谁能根据描述给我给一个教程

2020-01-22 12:01发布

原帖在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.
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
18条回答
Argee
1楼-- · 2020-01-23 21:49
 精彩回答 2  元偷偷看……
plumlee
2楼-- · 2020-01-24 01:25
这个真正在用的时候,鼠标不能抬起吧。要不然,就会OFFSET了。软件里还是检测这个。
yesjustme1
3楼-- · 2020-01-24 03:00
You can download the Arduino script and the PC program below. The program is in java and requires the RXTX library to be installed. You need to get the "RXTX 2.1 for use withOUT Sun's CommAPI (namespace gnu.io)" version. No, as of 2008 java still does not natively support the serial port. It should work with Linux, Mac OS X and Windows, but I only tested it under Windows.

xiaole01
4楼-- · 2020-01-24 06:31
灰常强大呀
weimas
5楼-- · 2020-01-24 08:38
楼主牛X,不过不知道干什么用,应该是纯粹的技术吧
jinshaopu
6楼-- · 2020-01-24 12:04
 精彩回答 2  元偷偷看……

一周热门 更多>