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

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条回答
669911
1楼-- · 2020-01-22 14:49
我不知道客户端程序怎么生成,请各位教诲
669911
2楼-- · 2020-01-22 17:57
光电鼠标拍摄

OK,所以最后决定让我的手在Arduino平台上,看到所有的嗡嗡声是真的。我必须说,我留下深刻的印象。这是迄今为止我所见过的大多数开发人员友好的开发平台。它的主要优点:

这很简单。硬件是非常简单的,并使用标准的,通常可用的组件。的软件IDE是基本的,但功能:编辑器窗口,状态窗口,集成了串行终端。就是这样。
这是相当强大的。Arduino的diecimilla,我用基于ATmega168微控制器时钟频率为16MHz。
它是基于开放源码硬件和软件(如果你省略了商标争议商标的Arduino)。电路板设计是公开的。这导致了创造的几个变种和的克隆(Freeduino)的平台的普及做出了贡献。
电源,固件更新和串行通信通过一个单一的USB电缆。
它的可扩展性。Arduino板的主要之上,可堆叠的“盾牌”的概念是天才:)作为一个事实上,一个小的原型盾的第一件事是我做了这个平台。
所以,前一段时间,我遇到了这个伟大的光电鼠标黑客雪碧。我决定,这将是巨大的做我的第一个Arduino的项目(超越“Blinky LED”的例子,那是。)

第一步,剥离的无线鼠标便宜的台风无线鼠标/键盘组合。


松开。寻找螺丝的底部垫和贴下。


我的模型来耦合的两个印刷电路板,采用了14引脚,两排头:


ADNS-2051光学传感器,中间是一个不寻常的芯片。该芯片持有一个16×16,64水平的灰度图像传感器和一个DSP计算从所捕获的图像的光流的变动:


下面的PCB是用镜头和LED准直光学集团:


的光学系统的更好的视图。制造由安捷伦技术或剥离Avago Technologies(安华高科技)技术:


Agilent / Avago Technologies(安华高科技)的大多数光学鼠标的光学部件,运动传感器和LED组件。这里的一切栈:


OK,所以走这远不是真有必要,我只是想看看事情是如何采取微距拍摄的:-)回去的ADNS-2051芯片的Arduino,你需要进行以下连接:


ADNS-2051针        Arduino的脚
1 SCLK        数字2
16 SDIO        数字3
15 PD        数字4
13 VDD        +5 V
12 GND        GND
所有其他引脚应该已经在所需的电路板,因此它们不需要被感动。然而,在我的情况下,我不得不连接的LED,因为它没有直接连接到VCC,但由控制器开启,也。这是因为它是建立了有线设计的芯片用于无线鼠标,所以他们不得不岔开位的参考设计。我很幸运,传感器板有一个女的头,我可以用线一切,所以我没有焊接什么。但你可能会的。


忽略的原型板的Arduino上,你可以直接到Arduino头接线一切。
您也可以下载的Arduino的脚本和下面的PC程序。该方案是在Java和需要安装的RXTX库。你需要得到使用,而Sun的CommAPI(命名空间gnu.io)“版本”RXTX 2.1。,截至2008年Java仍然没有原生支持的串行端口。它应该工作在Linux,Mac OS X和Windows,但我只测试了它在Windows下。

Arduino的脚本
客户端程序
客户端程序源代码
一旦RXTX已经安装,你可以运行jar文件,只需通过双击它,或在命令行中这样:

Java的JAR mousecam.jar的
该窗口会显示出来。只需选择你的Arduino板的串口相连,并单击“连接”。将被绘制在屏幕上的传感器数据的实时性。您可以增加或降低的行数,读取从所述传感器在每次运行。是有点慢,所以,如果你倾倒,你会得到一个完整的帧只有约5 fps的帧转储程序。如果你移动鼠标的同时,将严重的剪切文物和扫描将十分好看。在这种情况下,降低到2或3行捕捉窗口。


如果你移动鼠标在应用程序运行时,你可以在“扫描”下面的表面。正如你可以看到的质量是无与伦比的。扫描时,因为没有方法来检测旋转,你需要保持鼠标的方向完全一样的,这扭曲的捕捉更。

下面是如何被视为由传感器的白床单的纸张,织物从我的裤子和20欧元纸币上的小字:

   
好了,我们还有什么可以做这个很不错的传感器?在数据表的东西拨动了我的眼睛:在很宽的范围内的wavelenghts,从紫外到红外传感器是敏感的。那么,为什么不能取代标准的红 {MOD}LED的RGB LED吗?:-)

   
我跳过所有的血淋淋的细节,在这里是不那么令人印象深刻的结果:


我试图扫描一个细节的20欧元纸币。我有几个问题与传感器之间切换时,张铁军,王赟文,李世忠颜 {MOD}。该传感器将接近饱和或非常暗的帧的边界上。我解决了这个问题,通过增加100ms的延迟后,每种颜 {MOD}的变化,因此,该传感器能适应。另一个问题是,传感器,似乎要使用某种形式的自动光圈控制,这使得它无法取得平衡的颜 {MOD}。以下是相同的细节看起来与一个“真实”的相机。我们可以有点认识的蓝线:-)


如果你想复制这个惊人的结果(谁不喜欢呢?),你需要做到以下几点:

取出的红 {MOD}LED和RGB LED取代它。
LED阴极连接到引脚14(ADNS-2051 LED的需求是共阴极)。
数字引脚5上的Arduino连接红 {MOD}阳极。
数字引脚6上的Arduino连接绿 {MOD}的阳极。
将蓝 {MOD}阳极数字引脚7上的Arduino。
将这个脚本的Arduino。
这个可怕的破解版本以上的Java程序运行支持的颜 {MOD}。
更多信息:

ADNS-2051的功能。
了解光学小鼠。Avago Technologies(安华高科技)的白皮书。
同时测定光流。贝特霍尔德KP喇叭和Brian G. Schunck光流的理论文章。
Avago Technologies(安华高科技)网站上的光学导航传感器产品页面。
光电鼠标摄像头砍精灵MODS
OK,有足够的时间浪费在这了!:-)


评论

评论留下的乔恩·弗勒利希于2012年11月21日二十时32分14秒:
感谢发布。一位学生用这个想法,以帮助建立一个绳登山测量硬件原型:http://cmsc838f-f12.wikispaces.c ... _Cheng_Rope_Measure
评论留下的乔恩于2012年11月13日14点28分58秒:
卡亚Likha社会报MA nahi绫岭平衡凡是萨力NA RA SAL;
评论丹尼尔森MIKAEL于2012年9月28日19点29分25秒离开:
你从哪儿弄来的引脚的芯片吗?
评论留下的MIKAEL于2012年8月23日17时32分27秒:
对于所有那些想知道羯羊,你可能会使用,H2000芯片(HDNS-2000),我必须告诉你,这种芯片没有在这篇文章中提到的一个复杂的输出。HDNS-2000只有PS / 2和正交输出,因此所有的图像数据处理internall。可悲的。该芯片是很常见的,我已经打开了,许多老鼠都希望获得一个用于此目的的,但大多数的时候发现这个芯片。
评论留下的ashirviskas 2012-08-01十四时25分32秒:
我可以使用H2000传感器?
评论留下的伊萨克于2012年3月23日9点38分31秒:
我DNT有一个PD opition的A2610传感器的我能做些什么...开始用java,我不知道我是一个初学者需要帮助的。
评论留下的daianhtai2007@gmail.com于2011年11月27日8时59分53秒:
你能不能给我代码的Arduino的USB鼠标坐标x,y,如:
http://www.martijnthe.nl/2009/07 ... or-to-your-arduino/ 但我只有PAN3204你能写对我来说这IC库。非常感谢。


评论留下的Sylfranc 2011-07-28十三时28分58秒:
非常感谢您对本页面的其他信息:代码可以完美地与S2099的标记恢复从一个古老的罗技光电鼠标的传感器。唯一的区别是电源的3.3V和识别码传回03,而不是02。一个图片与评论 西尔万

yoyobbs
3楼-- · 2020-01-22 23:04
 精彩回答 2  元偷偷看……
i_kkyu
4楼-- · 2020-01-22 23:26
长长见识
sniper.q
5楼-- · 2020-01-23 00:45
软件翻译的吗?看着好吃力
669911
6楼-- · 2020-01-23 02:16
我自己顶顶

一周热门 更多>