搜索
bottom↓
回复: 18

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

[复制链接]

出0入0汤圆

发表于 2013-2-6 21:23:53 | 显示全部楼层 |阅读模式
原帖在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.
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-2-6 21:25:38 | 显示全部楼层
我不知道客户端程序怎么生成,请各位教诲

出0入0汤圆

 楼主| 发表于 2013-2-6 21:34:31 | 显示全部楼层
光电鼠标拍摄

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,从紫外到红外传感器是敏感的。那么,为什么不能取代标准的红色LED的RGB LED吗?:-)

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


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


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

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

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。一个图片与评论 西尔万

出0入0汤圆

发表于 2013-2-6 21:42:09 | 显示全部楼层
强大........

出0入0汤圆

发表于 2013-2-6 21:44:08 | 显示全部楼层
长长见识

出0入4汤圆

发表于 2013-2-6 22:09:32 | 显示全部楼层
软件翻译的吗?看着好吃力

出0入0汤圆

 楼主| 发表于 2013-2-7 09:35:16 | 显示全部楼层
我自己顶顶

出0入0汤圆

发表于 2013-2-8 03:22:12 | 显示全部楼层
这是个比较好玩儿的过程,其实你也可以用单点的图像和成理解(允许我这么说吧,我说事总是很拗口,表达能力不好)
相当于鼠标还是正常工作,不过在光学部件的输出,并联了另外一个采样器——Arduino。
鼠标的移动,被java程序捕获,你就得到了XY,而光学输出,被Arduino采样,并解析数据桢,就可以在那个点画个16x16的小图,你的鼠标不停移动,就完成了扫描。如果图片很大,你想象下,用个反射的光对管,粘在鼠标上,移动的同时,采样光对管的输出,你也可以画个图出来。调个焦,光斑足够小,移动足够慢,也许,画出来的图不必他差:1个点,就不存在扭动的偏差了。
供你参考。

出0入0汤圆

 楼主| 发表于 2013-2-8 10:00:56 | 显示全部楼层
Argee 发表于 2013-2-8 03:22
这是个比较好玩儿的过程,其实你也可以用单点的图像和成理解(允许我这么说吧,我说事总是很拗口,表达能力 ...

而光学输出,被Arduino采样,并解析数据桢,就可以在那个点画个16x16的小图




我现在卡在这一步,那个软件不知道怎么搞

出0入0汤圆

发表于 2013-2-8 12:05:28 | 显示全部楼层
好高级呀 学习啦

出0入0汤圆

发表于 2013-2-8 16:58:37 | 显示全部楼层
光电鼠标的芯片,本身就是个高帧率的摄像芯片,有些芯片能查到说明书。 不过楼主的问题答不上来。

出0入0汤圆

发表于 2013-2-18 03:57:54 | 显示全部楼层
本帖最后由 Argee 于 2013-2-18 04:03 编辑

好吧,我来详细解释一下,可能不对,欢迎指正。
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个数据线,你会觉得设计的没那么棒。

出0入0汤圆

发表于 2013-2-18 04:37:38 | 显示全部楼层
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function Ellipse Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)


Private Sub UserForm_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Dim hdc As Long, i As Single
   
    hdc = GetDC(FindWindow(vbNullString, Me.Caption))
    If Button > 0 Then
        Ellipse hdc, X, Y, X + 1, Y + 1
    End If
End Sub

出0入0汤圆

发表于 2013-2-18 04:42:29 | 显示全部楼层
这是用的excel增加了个VBA的userform,因为VBA不支持Pset画点了,不得已到网上抄了段椭圆的,其实把椭圆的换成Arduino取数据,然后描点,就可以了。凑合着看吧。

这个excel的程序还有个问题,就是要针对屏幕的分辨率,其实还要做下缩放,否则返回的XY其实不是正好的点的位置。只是提供个思路,所以不具体的弄代码了。

出0入0汤圆

发表于 2013-3-1 15:33:17 | 显示全部楼层
这个真正在用的时候,鼠标不能抬起吧。要不然,就会OFFSET了。软件里还是检测这个。

出0入0汤圆

发表于 2013-3-3 16:10:55 | 显示全部楼层
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.

出0入0汤圆

发表于 2014-10-23 20:13:57 | 显示全部楼层
灰常强大呀

出0入0汤圆

发表于 2014-10-28 09:06:10 | 显示全部楼层
楼主牛X,不过不知道干什么用,应该是纯粹的技术吧

出0入0汤圆

发表于 2014-10-28 09:18:22 | 显示全部楼层
mark  高大上啊
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 12:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表