搜索
bottom↓
回复: 228

激光鼠标传感器ADNS-9500采样源代码及遇到的问题

  [复制链接]

出0入0汤圆

发表于 2012-7-7 01:22:36 | 显示全部楼层 |阅读模式
Avago Technologies(安华高科技)2009年推出的激光鼠标传感器ADNS-9500是一款面向高端专业游戏应用的新高性能激光导航传感器产品。基于Avago LaserStream光学导航技术,ADNS-9500拥有功能强大的导航处理引擎,可以提供超高速移动检测和高分辨率,满足目前绝大多数主流游戏应用所需的精密跟踪功能。(摘自当年的新闻)
http://www.eet-china.com/article ... amp;encode=8a228ea8
如果将其与单片机连接,则可实现激光位置或速度检测。
搜索到一些源代码样本,虽然不全,但仍有参考价值。



弄到几个样品,试着与c8051f505单片机连接,还没有完全调通。卡在了下传固件步骤,传完之后就像没传一样,回读状态报告说,SROM没有运行。希望有接触过该传感器的人交流或指点一下。

本帖子中包含更多资源

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

x

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

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2012-8-17 00:14:48 | 显示全部楼层
二年前这个一出来就搞过, 40inch/m 当时的速度算是最快的了,
rom有官网有下载.  开机时spi烧一下 再设置一下CPI 就能.算出座标了.

出0入0汤圆

 楼主| 发表于 2012-8-20 06:05:38 | 显示全部楼层
f2k5 发表于 2012-8-17 00:14
二年前这个一出来就搞过, 40inch/m 当时的速度算是最快的了,
rom有官网有下载.  开机时spi烧一下 再设置一 ...

已经得到厂家的技术支持,问题已解决。
有两点不注意导致被卡住:
1。上电序列与SROM下载系列需要被看作两个独立的事件处理,需要分别使能cs并除能cs。而不能一次使能cs后,完成两个序列,才去除能cs。
2。laser_ctrl0(bit0)在进行SROM_CRC操作后会被除能。因此要先进行SROM_CRC操作,再做laser_ctrl0(bit0)使能。以保证以后的正常运行中laser_ctrl0(bit0)都保持使能状态。


出0入0汤圆

 楼主| 发表于 2012-8-20 06:09:54 | 显示全部楼层
ADNS-9500的速度是150inch/s。高端游戏鼠标都是这款控制器。

出0入0汤圆

 楼主| 发表于 2012-8-20 06:15:11 | 显示全部楼层
ADNS-9500已经更换主人,原厂家Avaga公司将全套技术及开发人员转移给Pixart公司。

出0入0汤圆

发表于 2012-8-22 00:25:20 | 显示全部楼层
上电序列是什么情况?   
开机后初始化过后, 可以读出PID和VID 和ROM版本, 把ROM版本变量和官网下载的最新的变量标识做判断, 不相同, 就可以执行下载ROM, 不会有冲突的呀.
CRC那个我也没管它,当时时只关心X和Y的座标.  
你是用来做表面测距吗.
跟表面材料有些关系的.

出0入0汤圆

 楼主| 发表于 2012-8-22 00:43:09 | 显示全部楼层
f2k5 发表于 2012-8-22 00:25
上电序列是什么情况?   
开机后初始化过后, 可以读出PID和VID 和ROM版本, 把ROM版本变量和官网下载的最新的 ...

上电序列就是开机初始化。我遵守以下文字描述:

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2012-8-22 00:56:00 | 显示全部楼层
注意到在第二步提到将cs置高又拉低后,再也没有关于cs拉高的要求。特别是在第5,6步之间,也就是下载SROM之前,没有提到关于cs的操作。实际上第5步之后必须将cs拉高,然后再拉低,才能开始下载SROM。而我的错误是从头到尾一直保持cs为低,直到完成所有步骤才将cs拉高。

后来看到新的例程,每个frame都出现一次cs拉高拉低的操作。也就是cs操作打包到底层函数中了,自然不存在下载SROM之前缺少cs操作问题。我的错误也间接证明,不是每个frame都需要cs操作,但是上电初始化之后,下载SROM之前的cs操作是必须的。

出0入0汤圆

 楼主| 发表于 2012-8-22 01:01:07 | 显示全部楼层
我的第二个错误是在第7步“Enable laser by setting Forced_Disable bit。。。。”之后自作主张加入了SROM CRC检验。结果将第7步已经打开的位又重新关闭。实际上SROM CRC检验只能在第6,7步之间加入。

出0入0汤圆

 楼主| 发表于 2012-8-22 01:06:00 | 显示全部楼层
我的应用不是测距,而是测速。小声说一句,是测量钞票在ATM机内的传送速度。

出0入0汤圆

发表于 2012-8-25 22:46:41 | 显示全部楼层
嗯, 现在没有问题了吧.
测表面的移动速度是没有问题的. 完全能满足.

出0入0汤圆

 楼主| 发表于 2012-8-26 00:42:53 | 显示全部楼层
速度测量结果会有5%的波动。还没搞明白是传送速度不稳,还是鼠标传感器测量不准。

出0入0汤圆

 楼主| 发表于 2013-1-28 21:36:19 | 显示全部楼层
结论是基本可用,精度在10%左右。

出0入0汤圆

发表于 2013-1-28 23:55:46 | 显示全部楼层
能不能买个模块给我

出0入0汤圆

 楼主| 发表于 2013-1-29 01:14:43 | 显示全部楼层
669911 发表于 2013-1-28 23:55
能不能买个模块给我

我只做项目,不卖模块。
你用它做什么呢?可以交流一下技术。

出0入0汤圆

 楼主| 发表于 2013-1-30 02:09:34 | 显示全部楼层
本帖最后由 xizi 于 2013-1-30 02:10 编辑

669911说:“说到底,这个也是个30*30像素的摄像头,8位单片机可以处理.我想做一个基于adns3060的简单机器视觉,这个项目qq详谈823475720 ”。

说得对,这是个30*30像素的摄像头。厂家留有指令接口,可以直接读出30x30=900字节图像数据。
没有用过ADNS-3060。与ADNS-9500对比了一下,ADNS-3060是低速光学传感器,而ADNS-9500是高速激光传感器。ADNS-3060的资料也很丰富,底层驱动应该可以搞定,但是后续的图像识别则不是我擅长的。
所以只能技术交流,无法承担你的整个项目。
另外我身在国外,qq交流不方便。而且站长也不提倡qq交流。

出0入0汤圆

发表于 2013-1-30 07:47:41 | 显示全部楼层
MARK MARK MARK

出0入0汤圆

 楼主| 发表于 2013-3-31 23:52:58 | 显示全部楼层
查了一下价格信息。1000片以下小批量,ADNS-9500和ADNS-3050都是15元一片。ADNS-3060没有查到信息。应该说ADNS-9500很超值。
http://detail.china.alibaba.com/offer/1195830726.html

出0入0汤圆

 楼主| 发表于 2013-4-1 18:46:13 | 显示全部楼层
网友669911问道:“你好,那么通过spi接口mcu可以读多少帧,我现在想用这个传感器开发一个简单的机器视觉,有60帧就够了 ”。
-------------------------------------------------------------------------------------------------
回答:
这还真得算一下。先列出几个已知数据:SPI接口速度是2MHz;每帧的字节数是900 byte,折算成位数是7200 bit;简单计算2000000/7200 = 278 帧/秒。这是理想情况,考虑额外消耗,100-200 帧/秒应该没问题。

出0入0汤圆

发表于 2013-4-29 20:07:07 | 显示全部楼层
ADNS9500的有8051mcu的源码码,能不能给发一个 qq mail :315221790@qq.com
多谢了!

出0入0汤圆

 楼主| 发表于 2013-4-30 00:58:32 | 显示全部楼层
本帖最后由 xizi 于 2013-4-30 00:59 编辑
dushuaihu 发表于 2013-4-29 20:07
ADNS9500的有8051mcu的源码码,能不能给发一个 qq mail :315221790@qq.com
多谢了!


楼主位的附件就是c8051f3xx单片机的源码。

出0入0汤圆

发表于 2013-5-1 09:57:04 | 显示全部楼层
xizi 发表于 2013-4-30 00:58
楼主位的附件就是c8051f3xx单片机的源码。

谢谢!最近也在研究ADNS9500,也遇到不少问题,这款芯片用普通的8051可以吗?在IO电平上是否能兼容?一个5v,一个3v?其中,我用普通8051模拟spi通信的时候,ADNS9500的MOSI引脚始终拉不下来,也就是说,这个引脚总是在2.4v左右,这个是否为电平不兼容引起的?多谢啦。。。

出0入0汤圆

 楼主| 发表于 2013-5-1 19:16:45 | 显示全部楼层
dushuaihu 发表于 2013-5-1 09:57
谢谢!最近也在研究ADNS9500,也遇到不少问题,这款芯片用普通的8051可以吗?在IO电平上是否能兼容?一个 ...

很有可能是电平不兼容。3v,5v混用要很小心。传个接口图上来会有助于分析。

出0入0汤圆

发表于 2013-5-2 13:51:37 | 显示全部楼层
本帖最后由 dushuaihu 于 2013-5-2 14:41 编辑
xizi 发表于 2013-5-1 19:16
很有可能是电平不兼容。3v,5v混用要很小心。传个接口图上来会有助于分析。 ...


现在基本可以正常读写了,不加载固件能用吗?

出0入0汤圆

 楼主| 发表于 2013-5-2 18:56:59 | 显示全部楼层
dushuaihu 发表于 2013-5-2 13:51
现在基本可以正常读写了,不加载固件能用吗?

如何做到正常读写的,请简单说一下。不论是心得,还是教训,都可供他人借鉴。
不加载固件估计不能用,也许某些个指令可用,但大部分指令都是由固件支持的。

出0入0汤圆

发表于 2013-5-2 19:33:16 | 显示全部楼层
xizi 发表于 2013-5-2 18:56
如何做到正常读写的,请简单说一下。不论是心得,还是教训,都可供他人借鉴。
不加载固件估计不能用,也 ...

是的,我现在正做固件的加载,但是不成功。。。有没有这个调试的方法可供参考呢?

出0入0汤圆

发表于 2013-5-2 19:39:08 | 显示全部楼层
正常读写很简单,就是51模拟spi口的操作,加电第一步就是要power reset,进行一下初始化,现在就卡在了第二步,就是加载固件了。。。。

出0入0汤圆

 楼主| 发表于 2013-5-2 19:43:22 | 显示全部楼层
dushuaihu 发表于 2013-5-2 19:33
是的,我现在正做固件的加载,但是不成功。。。有没有这个调试的方法可供参考呢? ...

技术手册是最好的参考。这是我用的手册:

注意看18页的SROM Download和21页的Power Up步骤。

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2013-5-2 19:56:14 | 显示全部楼层
我的手册跟你的一样的,page 21的第六步 加载固件之后,我就试着读出0x2a 的值  但是始终为0x00,就在关键的第六步了

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-5-2 20:04:18 | 显示全部楼层
dushuaihu 发表于 2013-5-2 19:56
我的手册跟你的一样的,page 21的第六步 加载固件之后,我就试着读出0x2a 的值  但是始终为0x00,就在关键的 ...

你遇到的问题与我最初遇到的一样。仔细看一下8楼的经验,或许会有帮助。
“注意到在第二步提到将cs置高又拉低后,再也没有关于cs拉高的要求。特别是在第5,6步之间,也就是下载SROM之前,没有提到关于cs的操作。实际上第5步之后必须将cs拉高,然后再拉低,才能开始下载SROM。而我的错误是从头到尾一直保持cs为低,直到完成所有步骤才将cs拉高。

后来看到新的例程,每个frame都出现一次cs拉高拉低的操作。也就是cs操作打包到底层函数中了,自然不存在下载SROM之前缺少cs操作问题。我的错误也间接证明,不是每个frame都需要cs操作,但是上电初始化之后,下载SROM之前的cs操作是必须的。

出0入0汤圆

发表于 2013-5-2 20:17:25 | 显示全部楼层
xizi 发表于 2013-5-2 20:04
你遇到的问题与我最初遇到的一样。仔细看一下8楼的经验,或许会有帮助。
“注意到在第二步提到将cs置高又 ...

这个贴子我仔细看过了,我也确实请注意到这一点了,但是,这一块有没有调试的技巧什么的,我这个就是根据你上面提供的例程改写过来的,crc校验什么的,还没做,固件加载后,在0x2a上就读不出预期的结果即0x91(固件版本)

出0入0汤圆

发表于 2013-5-2 20:18:39 | 显示全部楼层
dushuaihu 发表于 2013-5-2 20:17
这个贴子我仔细看过了,我也确实请注意到这一点了,但是,这一块有没有调试的技巧什么的,我这个就是根据 ...

我把源码给你看看?

出0入0汤圆

发表于 2013-5-2 20:20:48 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2013-5-2 20:26:18 | 显示全部楼层
dushuaihu 发表于 2013-5-2 20:18
我把源码给你看看?

我认为问题不在page 21的第六步,而是以前的步骤早已出错,只是在page 21的第六步反馈给你而已。
代码可以直接发到帖子中。

出0入0汤圆

发表于 2013-5-2 20:59:51 | 显示全部楼层
xizi 发表于 2013-5-2 20:26
我认为问题不在page 21的第六步,而是以前的步骤早已出错,只是在page 21的第六步反馈给你而已。
代码可 ...

void power_reset()
{       
        uint8 reg_it;
        SPI_CS = 1;
        SPI_CS = 0;
         // Write 0x5A to POWERUP register
        SPIWrite(0x3a,0x5a);
        delay(50000);
         // read register from 0x02 to 0x06
    for(reg_it=0x02; reg_it<=0x06; reg_it++)
    {
                SPIRead(reg_it);
                DelayUs(ADNS9500_TIMINGS_SRAD);               
    }
        SPI_CS = 1;
        UART_send_byte(SPIRead(ADNS9500_SPIREGISTER_PRODUCTID));
        UART_send_byte(SPIRead(ADNS9500_SPIREGISTER_INVPRODUCTID));
}

void upload_firmware()
{
        uint16 data_i;
        SPI_CS = 1;
    DelayUs(ADNS9500_TIMINGS_NCS_SCLK);
        SPI_CS = 0;
        DelayUs(ADNS9500_TIMINGS_NCS_SCLK);
  // Select the 3K bytes SROM size
//  adns9500_spi_send(ADNS9500_SPI_WRITE|ADNS9500_SPIREGISTER_CONFIGURATION4);
//  adns9500_spi_send(ADNS9500_CONFIGURATION4_LOAD1);
        SPIWrite(ADNS9500_SPIREGISTER_CONFIGURATION4,ADNS9500_CONFIGURATION4_LOAD1);
    DelayUs(ADNS9500_TIMINGS_SWW);
        UART_send_byte(SPIRead(ADNS9500_SPIREGISTER_CONFIGURATION4));//0x02
  // Write 0x1D to register SROMENABLE to initialize
//  adns9500_spi_send(ADNS9500_SPI_WRITE|ADNS9500_SPIREGISTER_SROMENABLE);
//  adns9500_spi_send(ADNS9500_SROMENABLE_LOAD1);
        SPIWrite(ADNS9500_SPIREGISTER_SROMENABLE,ADNS9500_SROMENABLE_LOAD1);
// Wait for one frame
//  adns9500_spi_cs(0);
//  _delay_us(ADNS9500_TIMINGS_FRAME_PERIOD);
//  _delay_us(ADNS9500_TIMINGS_FRAME_PERIOD);
//  adns9500_spi_cs(adns_i);
        SPI_CS = 1;
        DelayUs(ADNS9500_TIMINGS_FRAME_PERIOD);
        DelayUs(ADNS9500_TIMINGS_FRAME_PERIOD);
    SPI_CS = 0;
        UART_send_byte(SPIRead(ADNS9500_SPIREGISTER_SROMENABLE));//         0x1d
  // Write 0x18 to register SROMENABLE again to start SROM downloading
//  adns9500_spi_send(ADNS9500_SPI_WRITE|ADNS9500_SPIREGISTER_SROMENABLE);
//  adns9500_spi_send(ADNS9500_SROMENABLE_LOAD2);
        SPIWrite(ADNS9500_SPIREGISTER_SROMENABLE,ADNS9500_SROMENABLE_LOAD2);

//  adns9500_spi_cs(0);
//  _delay_us(ADNS9500_TIMINGS_SWW);
//  adns9500_spi_cs(adns_i);
        SPI_CS = 1;
        DelayUs(ADNS9500_TIMINGS_FRAME_PERIOD);
        SPI_CS = 0;
    DelayUs(ADNS9500_TIMINGS_NCS_SCLK);
  // Initiate PROM download burst mode
//  adns9500_spi_send(ADNS9500_SPI_WRITE|ADNS9500_SPIREGISTER_SROMLOAD);
//  _delay_us(ADNS9500_TIMINGS_LOAD);
        SPISend(ADNS9500_SPIREGISTER_SROMLOAD);
        DelayUs(ADNS9500_TIMINGS_LOAD);

  // For each firmware byte

  for(data_i=0;data_i<sizeof(adns9500_firmwareArray);data_i++)
  {
    // Read firmware from AVR FLASH, then write it
    uint8 byte = adns9500_firmwareArray[data_i];
    SPISend( byte );
    DelayUs(ADNS9500_TIMINGS_LOAD);
  }

  // Exit burst mode by pulling CS for FIRMWEND
//  adns9500_spi_cs(0);
        SPI_CS = 1;
}

出0入0汤圆

 楼主| 发表于 2013-5-2 22:05:44 | 显示全部楼层
dushuaihu 发表于 2013-5-2 20:59
void power_reset()
{       
        uint8 reg_it;

我读代码比较慢,粗略看了两遍,还没看出问题。
先问一下,试没试过注释掉穿插代码中所有的UART_send_byte()结果如何?他们是否捣乱,未可知之。

出0入0汤圆

发表于 2013-5-2 22:13:04 | 显示全部楼层
xizi 发表于 2013-5-2 22:05
我读代码比较慢,粗略看了两遍,还没看出问题。
先问一下,试没试过注释掉穿插代码中所有的UART_send_byt ...

这个只是调试用的,现在可以加载固件了,但是又有新的问题了,问题是:我加载之后,也读出了0x2a的值了,这时候我没有进行crc的校验,此时,读不出任何Delta_X_L的值,而且,我确实把laser control registor 最低位置为0了,一定要进行一系列的校验吗?

出0入0汤圆

 楼主| 发表于 2013-5-2 22:20:38 | 显示全部楼层
dushuaihu 发表于 2013-5-2 22:13
这个只是调试用的,现在可以加载固件了,但是又有新的问题了,问题是:我加载之后,也读出了0x2a的值了, ...

我会自然地反问,为什么要省略校验呢?

出0入0汤圆

发表于 2013-5-2 22:28:59 | 显示全部楼层
xizi 发表于 2013-5-2 22:20
我会自然地反问,为什么要省略校验呢?

校验的作用是为了什么,不就是为了验证一下加载固件有没有问题吗?这个是个人的一些看法

出0入0汤圆

 楼主| 发表于 2013-5-2 22:57:44 | 显示全部楼层
dushuaihu 发表于 2013-5-2 22:28
校验的作用是为了什么,不就是为了验证一下加载固件有没有问题吗?这个是个人的一些看法 ...

问题就来了,能读出0x2a不代表校验能通过。二者都正确才代表加载固件没有问题。虽然你的情况可能是加载固件已经没有问题,但多方验证才放心。

出0入0汤圆

发表于 2013-5-3 12:49:15 | 显示全部楼层
xizi 发表于 2013-5-2 22:57
问题就来了,能读出0x2a不代表校验能通过。二者都正确才代表加载固件没有问题。虽然你的情况可能是加载固 ...

谢谢!我会继续试验,校验完就可买读Delta_X_L,Delta_X_H的值了吗?它这个激光灯怎么看不到亮呢?我已经把LASER_CTRL0置零了啊?你知道为什么吗?

出0入0汤圆

 楼主| 发表于 2013-5-5 07:12:45 | 显示全部楼层
dushuaihu 发表于 2013-5-3 12:49
谢谢!我会继续试验,校验完就可买读Delta_X_L,Delta_X_H的值了吗?它这个激光灯怎么看不到亮呢?我已经 ...

激光灯发出的是不可见光。

出0入0汤圆

发表于 2013-5-5 14:39:36 | 显示全部楼层
xizi 发表于 2013-5-5 07:12
激光灯发出的是不可见光。

现在又有新的问题了,测距离跟deltx 有什么关系?

出0入0汤圆

 楼主| 发表于 2013-5-5 21:32:48 | 显示全部楼层
本帖最后由 xizi 于 2013-5-5 21:34 编辑
dushuaihu 发表于 2013-5-5 14:39
现在又有新的问题了,测距离跟deltx 有什么关系?


deltax 本意就是∆x,也就是距离差值。每次读出deltax后,内部会将其清零。所以下次读到的deltax是上次读到这次读发生的距离差。

出0入0汤圆

发表于 2013-5-5 22:23:41 | 显示全部楼层
xizi 发表于 2013-5-5 21:32
deltax 本意就是∆x,也就是距离差值。每次读出deltax后,内部会将其清零。所以下次读到的deltax是上次读 ...

这个我也知道的,∆x代表多长啊?读出来的都是十六进制的数字 而且还不稳定,比如,我向左移动10cm,每次都不相同。。。有时还相差很大,是怎么回事?

出0入0汤圆

 楼主| 发表于 2013-5-6 06:35:37 | 显示全部楼层
dushuaihu 发表于 2013-5-5 22:23
这个我也知道的,∆x代表多长啊?读出来的都是十六进制的数字 而且还不稳定,比如,我向左移动10cm,每次 ...

看来你已经了解了很多,但也看出你看说明书不够仔细。你提问题由于是寥寥几语,不了解你的度,所以只能试探着回答。
请回去看说明书,第一页第三段。特别是我发上来的说明书版本,在第三段有我加上去的五条红框注释。然后有什么问题再交流。

出0入0汤圆

发表于 2013-5-6 08:30:23 | 显示全部楼层
xizi 发表于 2013-5-6 06:35
看来你已经了解了很多,但也看出你看说明书不够仔细。你提问题由于是寥寥几语,不了解你的度,所以只能试 ...

恩,谢谢,我再看看,您很热心,再次谢谢。。。

出0入0汤圆

发表于 2013-5-6 08:41:57 | 显示全部楼层
  1. /*
  2. * ADNS9500.hpp - Interface to access to Avago ADNS-9500 laser mouse sensors
  3. *
  4. *   Copyright 2012 Jesus Torres <jmtorres@ull.es>
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. *     http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */

  18. #include <fstream>
  19. #include <math.h>
  20. #include <mbed.h>
  21. #include <string>

  22. #include <ADNS9500.hpp>

  23. #define WAIT_TSRAD()        wait_us(100)
  24. #define WAIT_TSRWR()        wait_us(20)
  25. #define WAIT_TBEXIT()       wait_us(1)      // 500ns
  26. #define WAIT_TNCSSCLK()     wait_us(1)      // 120ns
  27. #define WAIT_TSCLKNCS()     wait_us(20)
  28. #define WAIT_TLOAD()        wait_us(15)

  29. #define DEFAULT_MAX_FPS             1958
  30. #define DEFAULT_MAX_FRAME_PERIOD    ceil(1.0e6 / DEFAULT_MAX_FPS)   // in us
  31. #define DEFAULT_X_CPI               1620
  32. #define DEFAULT_Y_CPI               1620
  33. #define CPI_CHANGE_UNIT             90

  34. #define SET_BIT(word, mask)         (word | mask)
  35. #define CLEAR_BIT(word, mask)       (word & (~mask))

  36. namespace adns9500 {

  37.     ADNS9500::ADNS9500(PinName mosi, PinName miso, PinName sclk, PinName ncs,
  38.         int spi_frequency, PinName motion)
  39.         : spi_(mosi, miso, sclk),
  40.           motion_(motion),
  41.           ncs_(ncs),
  42.           enabled_(false),
  43.           dx_(0), dy_(0),
  44.           xCpi_(DEFAULT_X_CPI), yCpi_(DEFAULT_Y_CPI)
  45.     {
  46.         motion_.fall(this, &ADNS9500::motionTrigger);
  47.     }

  48.     ADNS9500::~ADNS9500()
  49.     {
  50.         shutdown();
  51.     }

  52.     void ADNS9500::reset(const char* firmware)
  53.     {
  54.         // SPI port reset
  55.         ncs_.write(1);
  56.         WAIT_TNCSSCLK();
  57.         ncs_.write(0);
  58.         WAIT_TNCSSCLK();
  59.         
  60.         // send 0x3a to POWER_UP_RESET and wait for at least 50ms
  61.         spi_.write(POWER_UP_RESET);
  62.         WAIT_TSRAD();
  63.         spi_.write(0x5a);
  64.         wait_ms(50);
  65.         
  66.         // clear observation register. Only required to deassert shutdown mode.
  67.         spi_.write(OBSERVATION);
  68.         WAIT_TSRAD();
  69.         spi_.write(0x00);
  70.         wait_us(DEFAULT_MAX_FRAME_PERIOD);
  71.         
  72.         // check observation register bits [5:0]
  73.         spi_.write(OBSERVATION);
  74.         WAIT_TSRAD();
  75.         int observation = spi_.write(0x00);
  76.         WAIT_TSRAD();

  77.         if (! ADNS9500_IF_OBSERVATION_TEST(observation))
  78.             error("ADNS9500::reset : observation register test failed: 0x%x\n", observation);

  79.         // read motion data
  80.         spi_.write(MOTION);
  81.         WAIT_TSRAD();
  82.         spi_.write(DELTA_X_L);
  83.         WAIT_TSRAD();
  84.         spi_.write(DELTA_X_H);
  85.         WAIT_TSRAD();
  86.         spi_.write(DELTA_Y_L);
  87.         WAIT_TSRAD();
  88.         spi_.write(DELTA_Y_H);
  89.         WAIT_TSRAD();
  90.         
  91.         // read product and revision id to test the connection        
  92.         spi_.write(PRODUCT_ID);
  93.         WAIT_TSRAD();
  94.         int product_id = spi_.write(REVISION_ID);
  95.         WAIT_TSRAD();
  96.         int revision_id = spi_.write(0x00);
  97.         WAIT_TSCLKNCS();

  98.         ncs_.write(1);

  99.         if (product_id != 0x33) {
  100.             error("ADNS9500::reset : bad product ID: 0x%x\n", product_id);
  101.         }

  102.         if (revision_id != 0x03) {
  103.             error("ADNS9500::reset : bad revision ID: 0x%x\n", revision_id);
  104.         }

  105.         enabled_ = true;

  106.         if (firmware) {
  107.             sromDownload(firmware);
  108.             enableLaser();
  109.         }
  110.     }

  111.     void ADNS9500::shutdown()
  112.     {
  113.         if (! enabled_)
  114.             error("ADNS9500::shutdown : the sensor is not enabled\n");
  115.         
  116.         ncs_.write(0);
  117.         WAIT_TNCSSCLK();
  118.         
  119.         // send 0x3a to POWER_UP_RESET
  120.         spi_.write(POWER_UP_RESET);
  121.         WAIT_TSRAD();
  122.         spi_.write(0x5a);
  123.         WAIT_TSCLKNCS();
  124.         
  125.         ncs_.write(1);
  126.         
  127.         enabled_ = false;
  128.     }

  129.     int ADNS9500::read(Register lregister)
  130.     {
  131.         if (! enabled_)
  132.             error("ADNS9500::read : the sensor is not enabled\n");
  133.    
  134.         ncs_.write(0);
  135.         WAIT_TNCSSCLK();
  136.         
  137.         // send the command to read the register
  138.         spi_.write(lregister);
  139.         WAIT_TSRAD();
  140.         int value = spi_.write(0x00);
  141.         WAIT_TSCLKNCS();
  142.         
  143.         ncs_.write(1);
  144.         return value;
  145.     }

  146.     int ADNS9500::read(Register uregister, Register lregister)
  147.     {
  148.         if (! enabled_)
  149.             error("ADNS9500::read : the sensor is not enabled\n");

  150.         ncs_.write(0);
  151.         WAIT_TNCSSCLK();

  152.         // send the command to read the registers
  153.         spi_.write(lregister);
  154.         WAIT_TSRAD();
  155.         int lvalue = spi_.write(uregister);
  156.         WAIT_TSRAD();
  157.         int uvalue = spi_.write(0x00);
  158.         WAIT_TSCLKNCS();

  159.         ncs_.write(1);

  160.         return ADNS9500_UINT16(uvalue, lvalue);
  161.     }
  162.    
  163.     int ADNS9500::sromDownload(const char* filename)
  164.     {
  165.         if (! enabled_)
  166.             error("ADNS9500::sromDownload : the sensor is not enabled\n");
  167.    
  168.         ncs_.write(0);
  169.         WAIT_TNCSSCLK();

  170.         // SROM download
  171.         spi_.write(CONFIGURATION_IV);
  172.         WAIT_TSRAD();
  173.         spi_.write(ADNS9500_CONFIGURATION_IV_SROM_SIZE);
  174.         WAIT_TSRAD();
  175.         spi_.write(SROM_ENABLE);
  176.         WAIT_TSRAD();
  177.         spi_.write(0x1d);
  178.         wait_us(DEFAULT_MAX_FRAME_PERIOD);
  179.         spi_.write(SROM_ENABLE);
  180.         WAIT_TSRAD();
  181.         spi_.write(0x18);
  182.         WAIT_TSRAD();
  183.         spi_.write(SROM_LOAD_BURST);
  184.         
  185.         // TODO: Comprobar que pasa si el archivo no existe
  186.         ifstream ifs(filename, ifstream::in);
  187.         while(ifs.good()) {
  188.             WAIT_TLOAD();
  189.             spi_.write(ifs.get());
  190.         }
  191.         WAIT_TSCLKNCS();
  192.         ncs_.write(1);
  193.         WAIT_TBEXIT();

  194.         if (! ifs.eof())
  195.             error("ADNS9500::sromDownload : error reading from file: %s\n", filename);

  196.         // test if SROM was downloaded successfully
  197.         wait_us(160);
  198.         ncs_.write(0);
  199.         WAIT_TNCSSCLK();
  200.         spi_.write(SROM_ID);
  201.         WAIT_TSRAD();
  202.         int srom_id = spi_.write(0x00);
  203.         WAIT_TSCLKNCS();
  204.         ncs_.write(1);
  205.         
  206.         if (! srom_id)
  207.             error("ADNS9500::sromDownload : the firmware was not successful downloaded\n");

  208.         // test laser fault condition
  209.         ncs_.write(0);
  210.         WAIT_TNCSSCLK();
  211.         spi_.write(MOTION);
  212.         WAIT_TSRAD();
  213.         int motion = spi_.write(0x00);
  214.         WAIT_TSCLKNCS();
  215.         ncs_.write(1);
  216.         
  217.         if (ADNS9500_IF_LASER_FAULT(motion))
  218.             error("ADNS9500::sromDownload : laser fault condition detected\n");
  219.         
  220.         // return the SROM CRC value
  221.         ncs_.write(0);
  222.         WAIT_TNCSSCLK();
  223.         
  224.         spi_.write(SROM_ENABLE);
  225.         WAIT_TSRAD();
  226.         spi_.write(0x15);
  227.         wait_us(10);
  228.         spi_.write(DATA_OUT_LOWER);
  229.         WAIT_TSRAD();
  230.         int lcrc = spi_.write(DATA_OUT_UPPER);
  231.         WAIT_TSRAD();
  232.         int ucrc = spi_.write(0x00);
  233.         
  234.         WAIT_TSCLKNCS();
  235.         ncs_.write(1);
  236.         
  237.         return ADNS9500_UINT16(ucrc, lcrc);
  238.     }

  239.     void ADNS9500::enableLaser(bool enable)
  240.     {
  241.         if (! enabled_)
  242.             error("ADNS9500::enableLaser : the sensor is not enabled\n");
  243.    
  244.         ncs_.write(0);
  245.         WAIT_TNCSSCLK();

  246.         spi_.write(LASER_CTRL0);
  247.         WAIT_TSRAD();
  248.         if (enable) {
  249.             int laser_ctrl0 = CLEAR_BIT(0x00, ADNS9500_LASER_CTRL0_FORCE_DISABLED);
  250.             spi_.write(laser_ctrl0);
  251.         }
  252.         else {
  253.             int laser_ctrl0 = SET_BIT(0x00, ADNS9500_LASER_CTRL0_FORCE_DISABLED);
  254.             spi_.write(laser_ctrl0);
  255.         }        

  256.         WAIT_TSCLKNCS();
  257.         ncs_.write(1);
  258.     }

  259.     bool ADNS9500::getMotionDelta(int& dx, int& dy)
  260.     {
  261.         if (! enabled_)
  262.             error("ADNS9500::getMotionDelta : the sensor is not enabled\n");

  263.         ncs_.write(0);
  264.         WAIT_TNCSSCLK();
  265.    
  266.         spi_.write(MOTION);
  267.         WAIT_TSRAD();
  268.         int motion = spi_.write(DELTA_X_L);
  269.         WAIT_TSRAD();
  270.         
  271.         if (ADNS9500_IF_MOTION(motion)) {
  272.             int tmp = spi_.write(DELTA_X_L);
  273.             WAIT_TSRAD();
  274.             dx = ADNS9500_UINT16(spi_.write(DELTA_X_H), tmp);
  275.             WAIT_TSRAD();
  276.             tmp = spi_.write(DELTA_Y_L);
  277.             WAIT_TSRAD();
  278.             dy = ADNS9500_UINT16(spi_.write(DELTA_Y_H), tmp);
  279.             
  280.             dx_ = dx;
  281.             dy_ = dy;
  282.         }
  283.         else {
  284.             spi_.write(0x00);

  285.             dx = dx_;
  286.             dy = dy_;
  287.         }
  288.         
  289.         WAIT_TSCLKNCS();
  290.         ncs_.write(1);

  291.         return ADNS9500_IF_MOTION(motion);
  292.     }
  293.    
  294.     bool ADNS9500::getMotionDeltaMM(float& dx, float& dy)
  295.     {
  296.         int rawDx, rawDy;

  297.         bool motion = getMotionDelta(rawDx, rawDy);
  298.         dx = (float)rawDx / xCpi_ * 25.4;
  299.         dy = (float)rawDy / yCpi_ * 25.4;

  300.         return motion;
  301.     }

  302.     bool ADNS9500::getMotionData(MotionData& data)
  303.     {
  304.         if (! enabled_)
  305.             error("ADNS9500::getMotionData : the sensor is not enabled\n");
  306.    
  307.         ncs_.write(0);
  308.         WAIT_TNCSSCLK();
  309.         
  310.         // activate motion burst mode
  311.         spi_.write(MOTION_BURST);
  312.         WAIT_TSRAD();
  313.         spi_.write(0x50);
  314.         
  315.         // if in run mode, wait for 1 frame
  316.         wait_us(DEFAULT_MAX_FRAME_PERIOD);
  317.         
  318.         // read motion burst data
  319.         data.motion = spi_.write(0x00);
  320.         data.observation = spi_.write(0x00);
  321.         
  322.         int ldx = spi_.write(0x00);
  323.         data.dx = ADNS9500_UINT16(spi_.write(0x00), ldx);
  324.         
  325.         int ldy = spi_.write(0x00);
  326.         data.dy = ADNS9500_UINT16(spi_.write(0x00), ldy);
  327.         
  328.         data.squal = spi_.write(0x00);
  329.         data.pixelSum = spi_.write(0x00);
  330.         data.maximumPixel = spi_.write(0x00);
  331.         data.minimumPixel = spi_.write(0x00);
  332.         
  333.         int ushutter = spi_.write(0x00);
  334.         data.shutter = ADNS9500_UINT16(ushutter, spi_.write(0x00));
  335.         
  336.         int uframe_period = spi_.write(0x00);
  337.         data.framePeriod = ADNS9500_UINT16(uframe_period, spi_.write(0x00));

  338.         WAIT_TSCLKNCS();
  339.         ncs_.write(1);
  340.         WAIT_TBEXIT();
  341.         
  342.         return ADNS9500_IF_MOTION(data.motion);
  343.     }
  344.    
  345.     void ADNS9500::setResolution(Resolution xy_resolution)
  346.     {
  347.         if (! enabled_)
  348.             error("ADNS9500::setResolution : the sensor is not enabled\n");
  349.         
  350.         ncs_.write(0);
  351.         WAIT_TNCSSCLK();
  352.         
  353.         // enable XY axes CPI in sync mode
  354.         spi_.write(CONFIGURATION_II);
  355.         WAIT_TSRAD();
  356.         int rpt_mod = spi_.write(0x00);
  357.         WAIT_TSRAD();
  358.         spi_.write(CLEAR_BIT(rpt_mod, ADNS9500_CONFIGURATION_II_RPT_MOD));
  359.         WAIT_TSRAD();

  360.         // set resolution for X-axis and Y-axis
  361.         spi_.write(CONFIGURATION_I);
  362.         WAIT_TSRAD();
  363.         spi_.write(xy_resolution);

  364.         WAIT_TSCLKNCS();
  365.         ncs_.write(1);
  366.         
  367.         xCpi_ = xy_resolution * CPI_CHANGE_UNIT;
  368.         yCpi_ = xy_resolution * CPI_CHANGE_UNIT;
  369.     }
  370.    
  371.     void ADNS9500::setResolution(Resolution x_resolution, Resolution y_resolution)
  372.     {
  373.         if (! enabled_)
  374.             error("ADNS9500::setResolution : the sensor is not enabled\n");
  375.             
  376.         ncs_.write(0);
  377.         WAIT_TNCSSCLK();

  378.         // disable XY axes CPI in sync mode
  379.         spi_.write(CONFIGURATION_II);
  380.         WAIT_TSRAD();
  381.         int rpt_mod = spi_.write(0x00);
  382.         WAIT_TSRAD();
  383.         spi_.write(SET_BIT(rpt_mod, ADNS9500_CONFIGURATION_II_RPT_MOD));
  384.         WAIT_TSRAD();
  385.         
  386.         // set resolution for X-axis
  387.         spi_.write(CONFIGURATION_I);
  388.         WAIT_TSRAD();
  389.         spi_.write(x_resolution);
  390.         WAIT_TSRAD();
  391.                
  392.         // set resolution for Y-axis
  393.         spi_.write(CONFIGURATION_V);
  394.         WAIT_TSRAD();
  395.         spi_.write(y_resolution);

  396.         WAIT_TSCLKNCS();
  397.         ncs_.write(1);

  398.         xCpi_ = x_resolution * CPI_CHANGE_UNIT;
  399.         yCpi_ = y_resolution * CPI_CHANGE_UNIT;
  400.     }
  401.    
  402.     void ADNS9500::captureFrame(uint8_t pixels[NUMBER_OF_PIXELS_PER_FRAME])
  403.     {
  404.         if (! enabled_)
  405.             error("ADNS9500::captureFrame : the sensor is not enabled\n");
  406.             
  407.         ncs_.write(0);
  408.         WAIT_TNCSSCLK();
  409.         
  410.         spi_.write(FRAME_CAPTURE);
  411.         WAIT_TSRAD();
  412.         spi_.write(0x93);
  413.         WAIT_TSRAD();
  414.         spi_.write(FRAME_CAPTURE);
  415.         WAIT_TSRAD();
  416.         spi_.write(0xc5);
  417.         wait_us(DEFAULT_MAX_FRAME_PERIOD);
  418.         wait_us(DEFAULT_MAX_FRAME_PERIOD);
  419.         
  420.         // check for first pixel reading motion bit
  421.         spi_.write(MOTION);
  422.         while(true) {
  423.             WAIT_TSRAD();
  424.             int motion = spi_.write(MOTION);
  425.             if (ADNS9500_IF_MOTION(motion))
  426.                 break;
  427.         }
  428.         
  429.         // read pixel values
  430.         spi_.write(PIXEL_BURST);
  431.         WAIT_TSRAD();
  432.         for (uint8_t* p = pixels; p != pixels + sizeof(pixels); ++p) {
  433.             WAIT_TLOAD();
  434.             *p = spi_.write(PIXEL_BURST);
  435.         }

  436.         // burst exit        
  437.         WAIT_TSCLKNCS();
  438.         ncs_.write(1);
  439.         WAIT_TBEXIT();
  440.     }
  441. }
  442.             
复制代码

出0入0汤圆

发表于 2013-5-6 08:43:47 | 显示全部楼层
  1. #ifndef ADNS9500_HPP_
  2. #define ADNS9500_HPP_

  3. #include <mbed.h>
  4. #include <stdint.h>
  5. #include <string>

  6. #define ADNS9500_CONFIGURATION_II_RPT_MOD   (1 << 2)
  7. #define ADNS9500_CONFIGURATION_IV_SROM_SIZE (1 << 1)
  8. #define ADNS9500_LASER_CTRL0_FORCE_DISABLED (1 << 0)
  9. #define ADNS9500_OBSERVATION_CHECK_BITS     0x3f

  10. #define ADNS9500_HAS_MOTION_DETECTED(x)     (bool)(x & 0x80)
  11. #define ADNS9500_HAS_LASER_FAULT(x)         (bool)(x & 0x40)
  12. #define ADNS9500_IS_RUNNING_SROM_CODE(x)    (bool)(x & 0x80)
  13. #define ADNS9500_HAS_FIRST_PIXEL(x)         (bool)(x & 0x01)
  14. #define ADNS9500_PASS_OBSERVATION_TEST(x)   (bool)(x & ADNS9500_OBSERVATION_CHECK_BITS)
  15. #define ADNS9500_UINT16(ub, lb)             (uint16_t)(((ub & 0xff) << 8) | (lb & 0xff))
  16. #define ADNS9500_INT16(ub, lb)              (int16_t)(((ub & 0xff) << 8) | (lb & 0xff))

  17. namespace adns9500
  18. {
  19.     // Maximum SPI clock frequency supported by the sensor
  20.     const int MAX_SPI_FREQUENCY = 2000000;
  21.    
  22.     // Internal oscillator norminal frequency
  23.     const int INTERNAL_OSCILLATOR_FREQUENCY = 47000000;
  24.    
  25.     // Number of pixels per frame
  26.     const int NUMBER_OF_PIXELS_PER_FRAME = 900;
  27.    
  28.     // Maximum surface quality
  29.     const int MAX_SURFACE_QUALITY = 676;    // 169 * 4

  30.     //
  31.     // Sensor registers
  32.     //
  33.    
  34.     enum Register
  35.     {
  36.         PRODUCT_ID         = 0x00,
  37.         REVISION_ID        = 0x01,
  38.         MOTION             = 0x02,
  39.         DELTA_X_L          = 0x03,
  40.         DELTA_X_H          = 0x04,
  41.         DELTA_Y_L          = 0x05,
  42.         DELTA_Y_H          = 0x06,
  43.         SQUAL              = 0x07,
  44.         PIXEL_SUM          = 0x08,
  45.         MAXIMUM_PIXEL      = 0x09,
  46.         MINIMUM_PIXEL      = 0x0a,
  47.         SHUTTER_LOWER      = 0x0b,
  48.         SHUTTER_UPPER      = 0x0c,
  49.         FRAME_PERIOD_LOWER = 0x0d,
  50.         FRAME_PERIOD_UPPER = 0x0e,
  51.         CONFIGURATION_I    = 0x0f,
  52.         CONFIGURATION_II   = 0x10,
  53.         FRAME_CAPTURE      = 0x12,
  54.         SROM_ENABLE        = 0x13,
  55.         LASER_CTRL0        = 0x20,
  56.         DATA_OUT_LOWER     = 0x25,
  57.         DATA_OUT_UPPER     = 0x26,
  58.         SROM_ID            = 0x2a,
  59.         OBSERVATION        = 0x24,
  60.         CONFIGURATION_V    = 0x2f,
  61.         CONFIGURATION_IV   = 0x39,
  62.         POWER_UP_RESET     = 0x3a,
  63.         MOTION_BURST       = 0x50,
  64.         SROM_LOAD_BURST    = 0x62,
  65.         PIXEL_BURST        = 0x64
  66.     };

  67.     //
  68.     // Supported resolutions
  69.     //

  70.     enum Resolution
  71.     {
  72.         CPI_90   = 0x01,
  73.         CPI_1630 = 0x12,
  74.         CPI_3240 = 0x24,
  75.         CPI_5040 = 0x38
  76.     };
  77.    
  78.     //
  79.     // Motion burst data
  80.     //
  81.    
  82.     struct MotionData
  83.     {
  84.         MotionData()
  85.             : motion(0), observation(0), dx(0), dy(0), dxMM(0), dyMM(0),
  86.               surfaceQuality(0), averagePixel(0), maximumPixel(0),
  87.               minimumPixel(0), shutter(0), framePeriod(0)
  88.         {}
  89.    
  90.         int motion;
  91.         int observation;
  92.         int dx;
  93.         int dy;
  94.         float dxMM;
  95.         float dyMM;
  96.         int surfaceQuality;
  97.         float averagePixel;
  98.         int maximumPixel;
  99.         int minimumPixel;
  100.         int shutter;
  101.         int framePeriod;
  102.     };

  103.     //
  104.     // Interface to access to ADNS-9500 mouse sensor
  105.     //

  106.     class ADNS9500
  107.     {
  108.         public:
  109.         
  110.             //
  111.             // Create the sensor interface
  112.             //
  113.             // @param mosi MOSI pin for the SPI interface
  114.             // @param miso MISO pin for the SPI interface
  115.             // @param sclk SCLK pin for the SPI interface
  116.             // @param spi_frequency SPI clock frequency in Hz up to MAX_SPI_PORT_FREQUENCY
  117.             // @param ncs A digital active-low output pin for sensor chip select
  118.             // @param motion A digital active-low input pin activated by the sensor when motion
  119.             //               is detected
  120.             //
  121.             ADNS9500(PinName mosi, PinName miso, PinName sclk, PinName ncs,
  122.                 int spi_frequency = MAX_SPI_FREQUENCY, PinName motion = NC);

  123.             //
  124.             // Destroy de sensor interface
  125.             //
  126.             ~ADNS9500();

  127.             //
  128.             // Power up/reset the sensor
  129.             // Terminate with error if the connection can not be established
  130.             //
  131.             // @param firmware If the firmware has to be downloaded, C-string containing the name
  132.             //                 of the file where it is stored, or NULL in other case
  133.             //
  134.             void reset(const char* firmware = NULL);

  135.             //
  136.             // Shutdown the sensor
  137.             //
  138.             void shutdown();

  139.             //
  140.             // Read the value of a sensor register
  141.             //
  142.             // @param lregister The register which to read its value
  143.             // @return The value of the register
  144.             //
  145.             int read(Register lregister);
  146.             
  147.             //
  148.             // Read the values of sensor registers
  149.             //
  150.             // @param uregister The register which to read the upper byte
  151.             // @param lregister The register which to read the lower byte
  152.             // @return The values of registers as a 16-bit integer, putting the value
  153.             //         of uregister in the upper byte and the value of lregister in the
  154.             //         lower byte
  155.             //
  156.             int read(Register uregister, Register lregister);

  157.             //
  158.             // Get information about sensor status
  159.             //
  160.             // @return The value of MOTION register. It tells if motion or laser fault
  161.             //         conditions have ocurred, laser power setting status and operating
  162.             //         mode in current frame
  163.             //
  164.             int status()
  165.                 { return read(MOTION); }
  166.            
  167.             //
  168.             // Download the firmware to the sensor SROM
  169.             //
  170.             // @param filename The name of the file which contains the sensor firmware
  171.             // @return The SROM CRC value
  172.             //
  173.             int sromDownload(const char* filename);

  174.             //
  175.             // Enable the laser
  176.             //
  177.             // @param enable True if laser must be enabled, or false if laser must be disabled
  178.             //
  179.             void enableLaser(bool enable=true);

  180.             //
  181.             // Get motion deltas from sensor
  182.             //
  183.             // @param dx The component X of displacement
  184.             // @param dy The component Y of displacement
  185.             // @return True if motion was occurred since the last time the function was called,
  186.             //         or false in other case
  187.             //
  188.             bool getMotionDelta(int& dx, int& dy);

  189.             //
  190.             // Get motion deltas in mm. from sensor
  191.             //
  192.             // @param dx The component X of displacement in mm.
  193.             // @param dy The component Y of displacement in mm.
  194.             // @return True if motion was occurred since the last time the function was called,
  195.             //         or false in other case
  196.             //
  197.             bool getMotionDeltaMM(float& dx, float& dy);
  198.             
  199.             //
  200.             // Get all information about motion
  201.             //
  202.             // @param data The struct where sensor data will be stored
  203.             // @return True if motion was occurred since the last time the function was called,
  204.             //         or false in other case
  205.             //
  206.             bool getMotionData(MotionData& data);

  207.             //
  208.             // Set the resolution on XY axes together
  209.             //
  210.             // @param xy_resolution The resolution for X-axis and Y-axis
  211.             //
  212.             void setResolution(Resolution xy_resolution);

  213.             //
  214.             // Set the resolutions on X-axis and Y-axis
  215.             //
  216.             // @param x_resolution The resolution for X-axis
  217.             // @param y_resolution The resolution for Y-axis
  218.             //
  219.             void setResolution(Resolution x_resolution, Resolution y_resolution);

  220.             //
  221.             // Get a full array of pixel values from a single frame.
  222.             // This disables navigation and overwrites any donwloaded firmware,
  223.             // so call to reset() is needed to restore them
  224.             //
  225.             // @param pixels A pointer to the array where pixel values will be stored
  226.             //
  227.             void captureFrame(uint8_t* pixels);

  228.             //
  229.             // Member function invoked when motion has ocurred and if a motion pin
  230.             // was specified when the object constructor was called.
  231.             // By default it invokes the function specified by a previous call to attach()
  232.             //
  233.             virtual void motionTrigger()
  234.                 { motionTrigger_.call(); }

  235.             //
  236.             // Attach a function to call when a falling edge occurs on motion pin
  237.             //
  238.             // @param function A pointer to a function or 0 to set the attached function as none
  239.             //
  240.             void attach(void (*function)(void))
  241.                 { motionTrigger_.attach(function); }

  242.             //
  243.             // Attach a member function to call when a falling edge occurs on motion pin
  244.             //
  245.             // @param object A reference to the object to call the member function on
  246.             // @param function A pointer to the member function to be called
  247.             //
  248.             template<typename T>
  249.             void attach(T& object, void (T::*member)(void))
  250.                 { motionTrigger_.attach(object, member); }

  251.         private:
  252.             SPI spi_;
  253.             InterruptIn motion_;
  254.             DigitalOut ncs_;

  255.             bool enabled_;            
  256.             int xCpi_, yCpi_;
  257.             
  258.             FunctionPointer motionTrigger_;
  259.             
  260.             //
  261.             // Write a byte to the specified register
  262.             //
  263.             // @param address The register address
  264.             // @param value The value to be written to the register
  265.             //
  266.             void spiSend(Register address, int value);

  267.             //
  268.             // Read a byte from the specified register
  269.             //
  270.             // @param address The register address
  271.             // @return The value of the register
  272.             //
  273.             int spiReceive(Register address);
  274.     };
  275. }

  276. #endif /* ADNS9500_HPP_ */
  277.             
复制代码

出0入0汤圆

发表于 2013-5-6 08:44:59 | 显示全部楼层
网上查到了2个库文件,看看有没有用

出0入0汤圆

发表于 2013-5-6 09:43:09 | 显示全部楼层
xizi 发表于 2013-5-6 06:35
看来你已经了解了很多,但也看出你看说明书不够仔细。你提问题由于是寥寥几语,不了解你的度,所以只能试 ...

我再次仔细的看了一下你说的第三段,150ips就表示150 英寸每秒,是指一秒最大能捕获150英寸的变化量(或 150英寸的距离?) 附件中 x坐标中 motion 和 deltax 都表示的什么意思?现在并不是很清楚。。。?

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-5-6 11:00:42 | 显示全部楼层
dushuaihu 发表于 2013-5-6 09:43
我再次仔细的看了一下你说的第三段,150ips就表示150 英寸每秒,是指一秒最大能捕获150英寸的变化量(或  ...

还是不够细致。你解读了第一、二个注释。要想知道附件中 x坐标中 motion 和 deltax 都表示的什么意思,还需解读第四、五条注释。

出0入0汤圆

发表于 2013-5-6 13:21:53 | 显示全部楼层
xizi 发表于 2013-5-6 11:00
还是不够细致。你解读了第一、二个注释。要想知道附件中 x坐标中 motion 和 deltax 都表示的什么意思,还 ...

你直接给解释一下好吗?搞不懂什么意思,我主要是想得到deltax的实际移动距离,如何得到?

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2013-5-6 13:26:42 | 显示全部楼层
dushuaihu 发表于 2013-5-6 13:21
你直接给解释一下好吗?搞不懂什么意思,我主要是想得到deltax的实际移动距离,如何得到? ...

后三个,都表示什么意思?5670 cpi=223 cpmm 这个跟厘米 鼠标的移动距离有什么关系呢?

出0入0汤圆

发表于 2013-5-6 13:33:02 | 显示全部楼层
669911 发表于 2013-5-6 08:44
网上查到了2个库文件,看看有没有用

谢谢,多谢。。。。

出0入0汤圆

发表于 2013-5-6 13:39:13 | 显示全部楼层
669911 发表于 2013-5-6 08:44
网上查到了2个库文件,看看有没有用

春已浓,人将行,书如故

我再补充一句:春已浓,人将行,书如故,情依旧

出0入0汤圆

发表于 2013-5-6 19:54:06 | 显示全部楼层
669911 发表于 2013-5-6 08:43

在这个程序里,我没找到相关的测试x轴变化量的代码,请多指教,以c++的程序看起来有点力不从心了,如果有这方面的经验请告知一下,关于x轴左右移动的变化量跟左右移动的距离有什么关系?
我这边测出来的关于x的变化量与距离没有发现有什么相关的联系。。。期盼您的回答。。。多谢谢。。。。

出0入0汤圆

发表于 2013-5-6 20:45:01 | 显示全部楼层
我也不懂,应该不是绝对值,只是相对值。另外我感兴趣的是adns9500的图像功能,这几天我在打样

根据这个打的

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-5-6 20:50:30 | 显示全部楼层
dushuaihu 发表于 2013-5-6 13:26
后三个,都表示什么意思?5670 cpi=223 cpmm 这个跟厘米 鼠标的移动距离有什么关系呢? ...

cpi的意思是count per inch,也就是每英尺的移动距离产生多少个计数。5670cpi是说每英尺的移动距离会产生5670个计数值。
由于我们习惯国际制单位,所以需要换算成毫米。5670cpi = 223cpmm,也就是每毫米的移动距离会产生223个计数值。

附件中 x坐标中 motion 和 deltax 表示的是同一个东西,都是移动的距离,单位是计数值。只不过motion 给出了十进制表示,而deltax 给出的是十六进制表示。
那么你要将计数值换算成毫米,只需要把读得到的deltax 除以223。

当然,这223是在CPI设置为5670时使用的换算常数。如果你把CPI设置成其他值,换算常数需要重新调整。

出0入0汤圆

发表于 2013-5-6 21:07:30 | 显示全部楼层
xizi 发表于 2013-5-6 20:50
cpi的意思是count per inch,也就是每英尺的移动距离产生多少个计数。5670cpi是说每英尺的移动距离会产生 ...

这个是怎么算出来的:5670cpi = 223cpmm? 我设置的是5040cpi也就是在配制寄存器1中的配制。如何计算呢?

出0入0汤圆

发表于 2013-5-6 21:14:12 | 显示全部楼层
xizi 发表于 2013-5-6 20:50
cpi的意思是count per inch,也就是每英尺的移动距离产生多少个计数。5670cpi是说每英尺的移动距离会产生 ...

我现在的问题是deltax在鼠标移动10cm中多次测量读出来的值各不相同,这个就是最核心的问题。。。。这是我测量的数据 没有一点规则:我这里有一些我在10cm测量中读出的deltax高八位和低八位的数值:鼠标左移的值:03 42,02 35,00 FB,00 95,01 F5,01 BE,01 C3,01 EB,00 91,00 32,02 25,01 2B,04 DF.鼠标右移的值:
EA FA,E3 F6,C3 FC,DA F7,F1 F8,21 FC,74 FB,0B FE. 右移还好一点,但是左移的话就不行了,觉得偏差很大,不知从何做起。。。?另外,ADNS9500有很多工作模式,是否关这个有关?已经验证了多个猜想,但都是无果而终,总结了,所有的问题根源在于,deltax的值浮动太大,如何才能减少这个大的浮动?

出0入0汤圆

发表于 2013-5-6 21:16:03 | 显示全部楼层
669911 发表于 2013-5-6 20:45
我也不懂,应该不是绝对值,只是相对值。另外我感兴趣的是adns9500的图像功能,这几天我在打样

根据这个打 ...

不错,挺好看的,30*30的摄像功能有什么用处吗?

出0入0汤圆

发表于 2013-5-6 21:23:22 | 显示全部楼层
dushuaihu 发表于 2013-5-6 13:39
春已浓,人将行,书如故

我再补充一句:春已浓,人将行,书如故,情依旧  ...

你这两个库文件在哪里找的?我怎么就没找到类似的文件呢,网上相关的文件太少了。。。

出0入0汤圆

 楼主| 发表于 2013-5-6 21:37:23 | 显示全部楼层
dushuaihu 发表于 2013-5-6 21:07
这个是怎么算出来的:5670cpi = 223cpmm? 我设置的是5040cpi也就是在配制寄存器1中的配制。如何计算呢? ...

怎样把英尺换算成毫米,你最好还是利用一下google。敲入inch = ? mm。
5040 cpi 换算成cpmm,可以简单这样5040/5670*223 = 198.

出0入0汤圆

 楼主| 发表于 2013-5-6 21:46:51 | 显示全部楼层
dushuaihu 发表于 2013-5-6 21:14
我现在的问题是deltax在鼠标移动10cm中多次测量读出来的值各不相同,这个就是最核心的问题。。。。这是我 ...

这属于数据稳定问题。你不描述清楚你具体的操作过程,我也无法指出你的问题。但可以提示一点,就是z轴距离很关键。说明书中说最佳距离是4mm,否则数据不稳定。你可以观察一下你手中鼠标内部传感元件到鼠标垫的距离,应该是相仿的。

出0入0汤圆

发表于 2013-5-6 22:53:41 | 显示全部楼层
dushuaihu 发表于 2013-5-2 22:28
校验的作用是为了什么,不就是为了验证一下加载固件有没有问题吗?这个是个人的一些看法 ...

另外是不是需要读OX07的SQUAL数值,调整z距离使这个数值最大化,必要时更换透镜,使用另外的光源。看文档

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2013-5-7 14:27:13 | 显示全部楼层
xizi 发表于 2013-5-6 21:37
怎样把英尺换算成毫米,你最好还是利用一下google。敲入inch = ? mm。
5040 cpi 换算成cpmm,可以简单这 ...

这个值跟我算的也差不多,我的算法是:5040/25.4 约为198。425次计数每毫秒

出0入0汤圆

发表于 2013-5-7 14:28:40 | 显示全部楼层
669911 发表于 2013-5-6 22:53
另外是不是需要读OX07的SQUAL数值,调整z距离使这个数值最大化,必要时更换透镜,使用另外的光源。看文档 ...

这个有道理,我也试试

出0入0汤圆

发表于 2013-5-7 20:32:39 | 显示全部楼层
本帖最后由 dushuaihu 于 2013-5-7 20:35 编辑
xizi 发表于 2013-5-6 21:46
这属于数据稳定问题。你不描述清楚你具体的操作过程,我也无法指出你的问题。但可以提示一点,就是z轴距 ...


你所说的过程,是指的什么样的过程 呢?我这个程序的思想跟robortter的完全一样的,就是从上电复位,到整个的while死循环止 z距离应该不会有问题,虽然我不知道我这个的z距离的实际值,(这个鼠标完全是成品,能正常使用的),会不会跟while循环中延迟时间有关呢?上面提到的我所测的无规则数据是在while循环中我加了个按键功能,即按一下,我就读一次数据出来

        UART_init();
        power_reset();
        adns9500_check_firmware();
        upload_firmware();
        firmwareCRC();
        load_config();
        DelayUs(2000);
        KeyOut1 = 0;
        while (1)
        {
                key = 0;
                if(!keya)
                {       
                        delay(1000);
                        if(!keya)
                        {
                                vall = SPIRead(0x03);        //0x01
                                valh = SPIRead(0x04);        //0x01
                                UART_send_byte(valh); UART_send_byte(vall);
                                while(!keya);
                        }
                }
        }

出0入0汤圆

 楼主| 发表于 2013-5-7 21:39:51 | 显示全部楼层
dushuaihu 发表于 2013-5-7 14:27
这个值跟我算的也差不多,我的算法是:5040/25.4 约为198。425次计数每毫秒

解释一下425次计数每毫秒是怎么回事儿?

出0入0汤圆

 楼主| 发表于 2013-5-7 21:53:26 | 显示全部楼层
我所说的过程,是指尽可能多的细节。一个描述能做到让人身临其境才是好描述。比如到现在我才知道你是使用了现成的鼠标,我以为你是买来裸传感器自己做组装,那我可以怀疑组装有问题。
既然是现成的鼠标,你可以恢复到鼠标功能,然后连到电脑上用一下,看缓慢移动时屏幕上是否有断续的现象。

出0入0汤圆

发表于 2013-5-7 21:59:40 | 显示全部楼层
本帖最后由 dushuaihu 于 2013-5-7 22:01 编辑
xizi 发表于 2013-5-7 21:53
我所说的过程,是指尽可能多的细节。一个描述能做到让人身临其境才是好描述。比如到现在我才知道你是使用了 ...


没有断续的现象,现在我把里边的控制器取下来了,不然的话,是没法用的,也就是说,我不用它里边原来的mcu,而是换成我的51单片机来实现鼠标数据的读写,其它的电路都不变

出0入0汤圆

发表于 2013-5-7 22:05:12 | 显示全部楼层
本帖最后由 dushuaihu 于 2013-5-7 22:06 编辑

再看看这个东西

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-5-7 22:27:15 | 显示全部楼层
dushuaihu 发表于 2013-5-7 22:05
再看看这个东西

我的手册0x40--0x4f命令都是保留状态。不懂0x48,0x49干什么用。请把你的手册发上来。

出0入0汤圆

发表于 2013-5-7 22:31:05 | 显示全部楼层
关注一下 短距离测距  运动检测                                                                  

出0入0汤圆

发表于 2013-5-22 14:35:29 | 显示全部楼层
669911 发表于 2013-5-6 20:45
我也不懂,应该不是绝对值,只是相对值。另外我感兴趣的是adns9500的图像功能,这几天我在打样

根据这个打 ...

请问 图像功能探索的怎么样了?我也在探索图像功能,被卡住了

出0入0汤圆

发表于 2013-5-23 14:04:01 | 显示全部楼层
xizi 发表于 2012-8-22 00:56
注意到在第二步提到将cs置高又拉低后,再也没有关于cs拉高的要求。特别是在第5,6步之间,也就是下载SROM之 ...

请问哪里能下载到例程吗?能否传我一份?274495953@qq.com

出0入0汤圆

 楼主| 发表于 2013-5-23 21:44:41 | 显示全部楼层
hnbczzz 发表于 2013-5-23 14:04
请问哪里能下载到例程吗?能否传我一份?

回头去看1楼和21楼,你就知道例程在哪里。

出0入0汤圆

发表于 2013-5-25 15:59:18 | 显示全部楼层
xizi 发表于 2013-5-23 21:44
回头去看1楼和21楼,你就知道例程在哪里。

谢谢!

出0入0汤圆

发表于 2013-5-28 09:18:58 | 显示全部楼层
dushuaihu 发表于 2013-5-2 13:51
现在基本可以正常读写了,不加载固件能用吗?

您好,请问您使用软件模拟的SPI几口吗?我这里用硬件SPI怎么弄都不能进行正常的读写。

出0入0汤圆

发表于 2013-6-1 20:15:07 | 显示全部楼层
Kongweiming 发表于 2013-5-28 09:18
您好,请问您使用软件模拟的SPI几口吗?我这里用硬件SPI怎么弄都不能进行正常的读写。 ...

是的啊,我用的是stc89c52的51单片机。

出0入0汤圆

发表于 2013-6-3 07:52:02 | 显示全部楼层
dushuaihu 发表于 2013-6-1 20:15
是的啊,我用的是stc89c52的51单片机。

哦,谢谢。手册上说当Delta_X_L等几个寄存器出现数值的时候,MOTION寄存器中的MOT位会置位。我的问题是,MOT置位之后,在不读该寄存器的情况下Delta_X_L这个寄存器中的数值是否还会继续增加呢?

出0入0汤圆

发表于 2013-6-8 07:51:13 | 显示全部楼层
Kongweiming 发表于 2013-6-3 07:52
哦,谢谢。手册上说当Delta_X_L等几个寄存器出现数值的时候,MOTION寄存器中的MOT位会置位。我的问题是, ...

这个,你可以做个试验,来验证,应该会增加的

出0入0汤圆

发表于 2013-7-8 21:27:08 | 显示全部楼层
我在用ADNS-3080,不知道是spi通信问题,还是配置问题,就是固件下不进去,我发的请求贴在这里http://www.amobbs.com/forum.php? ... &highlight=ADNS,还请你看看我的代码,哪里有问题,谢谢!

出0入0汤圆

 楼主| 发表于 2013-7-8 22:52:44 | 显示全部楼层
kanglei79 发表于 2013-7-8 21:27
我在用ADNS-3080,不知道是spi通信问题,还是配置问题,就是固件下不进去,我发的请求贴在这里http://www.a ...

看不懂你的code,但是感觉 for(count=0;count<1986;count++) {} 问题很大。*data0 只运行一次,而取得的数据却被传送了1986次。有什么意义呢?

出0入0汤圆

发表于 2013-7-9 09:54:15 | 显示全部楼层
xizi 发表于 2013-7-8 22:52
看不懂你的code,但是感觉 for(count=0;count

恩,是我的错,那个1986是固件的字节数,今天我又改了改,单步调试了下,写操作应该是没有问题的,我就怕是配置问题,我知道你用过adns-9500,下面是3080下载SROM的时序图,右下角的那个 soonest to read SROM_ID和>100us是否是冲突的?

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-7-9 10:00:17 | 显示全部楼层
kanglei79 发表于 2013-7-9 09:54
恩,是我的错,那个1986是固件的字节数,今天我又改了改,单步调试了下,写操作应该是没有问题的,我就怕 ...


为什么说 soonest to read SROM_ID和>100us是冲突的?一回事儿。要求100us以后去读SROM_ID才会有正确结果。

出0入0汤圆

发表于 2013-7-9 10:35:07 | 显示全部楼层
xizi 发表于 2013-7-9 10:00
为什么说 soonest to read SROM_ID和>100us是冲突的?一回事儿。要求100us以后去读SROM_ID才会有正确结果 ...

我现在看datasheet都快看吐了,你说过你在驱动ADNS9500时得到过厂家的技术支持,有联系方式吗?我也想直接问问他们,谢了

出0入0汤圆

 楼主| 发表于 2013-7-9 10:49:19 | 显示全部楼层
kanglei79 发表于 2013-7-9 10:35
我现在看datasheet都快看吐了,你说过你在驱动ADNS9500时得到过厂家的技术支持,有联系方式吗?我也想直 ...

厂家在台湾
fae_service@pixart.com.tw

出0入0汤圆

发表于 2013-7-10 10:05:52 | 显示全部楼层
固件下载完然后CRC校验都过了后,采到的delta_x感觉好乱,这是我采到的100个数80 00 00 0F 2F 7F 0A 00 00 00 00 00 00 00 00 80 78 40 00 00 07 17 3F 05 00 00 00 00 00 00 00 00 C0 3C A0 00 00 03 0B 1F 02 00 00 00 00 00 00 00 00 60 1E D0 00 00 01 05 8F 81 00 00 00 00 00 00 00 00 30 0F 68 00 00 00 02 C7 40 00 00 00 00 00 00 00 00 18 07 34 00 00 00 81 E3 A0 00 00 00 00 00 00 00 00,为什么那么多0?

出0入0汤圆

发表于 2013-7-10 15:58:47 | 显示全部楼层
还有个问题就是,固件是写一次就行,还是每次下程序都要写一遍呢,为什么有时候能过CRC校验,有时候就过不去呢

出0入0汤圆

 楼主| 发表于 2013-7-10 18:23:58 | 显示全部楼层
kanglei79 发表于 2013-7-10 10:05
固件下载完然后CRC校验都过了后,采到的delta_x感觉好乱,这是我采到的100个数80 00 00 0F 2F 7F 0A 00 00  ...

1. 你这100个数只有100个,这在数量上就很奇怪。如果3080与9500格式一样,应该是每两个数一组,delta_x_L 和delta_x_H。采集100次会有200个数。
2. 每次采集后,delta_x在内部会被清零。delta是运动差值的意思,运动停下来了,下次差值就为0。不像A/D转换器,你加一个固定的电压,每次采集都是稳定值。

出0入0汤圆

 楼主| 发表于 2013-7-10 18:25:24 | 显示全部楼层
kanglei79 发表于 2013-7-10 15:58
还有个问题就是,固件是写一次就行,还是每次下程序都要写一遍呢,为什么有时候能过CRC校验,有时候就过不 ...

是的,固件掉电会丢失。每次都要下载。

出0入0汤圆

发表于 2013-7-10 18:45:34 | 显示全部楼层
xizi 发表于 2013-7-10 18:23
1. 你这100个数只有100个,这在数量上就很奇怪。如果3080与9500格式一样,应该是每两个数一组,delta_x_L ...

和9500格式不一样的,数据就一个字节,还有这100个数我是在传感器不移动的情况下测的,怎么会跳变这么严重呢

出0入0汤圆

发表于 2013-7-10 18:48:00 | 显示全部楼层
xizi 发表于 2013-7-10 18:25
是的,固件掉电会丢失。每次都要下载。

这是数据对应和利用采到的delta_x画的曲线图,传感器并未移动

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2013-7-10 20:13:09 | 显示全部楼层
kanglei79 发表于 2013-7-10 18:48
这是数据对应和利用采到的delta_x画的曲线图,传感器并未移动

1。检查一下反光面
2。除了CRC校验外,检查一下其它错误信息。比如9500就有srom_id,srom_crc,srom_run,motion_fault 等错误信息。

出0入0汤圆

发表于 2013-7-10 20:35:57 | 显示全部楼层
xizi 发表于 2013-7-10 20:13
1。检查一下反光面
2。除了CRC校验外,检查一下其它错误信息。比如9500就有srom_id,srom_crc,srom_run ...

3080包括srom_id和srom_crc两部分信息,id=0x28,crc得到的数据也是对的,我现在是把反光面部分装了个摄像机镜头,我最后想实现的功能其实是利用它来测量物体的移动距离

出0入0汤圆

 楼主| 发表于 2013-7-11 11:00:01 | 显示全部楼层
本帖最后由 xizi 于 2013-7-11 11:01 编辑
kanglei79 发表于 2013-7-10 20:35
3080包括srom_id和srom_crc两部分信息,id=0x28,crc得到的数据也是对的,我现在是把反光面部分装了个摄 ...


有可能是摄像机镜头捣乱。可以先回到鼠标的正常反光安装对比一下。不要指望一步到位。

出0入0汤圆

发表于 2013-10-7 12:16:47 | 显示全部楼层
xizi 发表于 2013-7-11 11:00
有可能是摄像机镜头捣乱。可以先回到鼠标的正常反光安装对比一下。不要指望一步到位。 ...


楼主你好,看到你的A9500已经开发的很成熟了,目前我也在尝试利用ADNS-9500来测定位移,有这样两个问题想请教您:
1. 坑爹的pixart在官网上没有放出SROM,不像以前Avago都挂在网上,我从网上找了好几个版本的例程,里面的Firmware都不一样,是有不同的版本吗?楼主是否拿到了官方的SROM文件可以分享一下哦?
2. 我看到A9500最大检测速度是150ips,不知道楼主有没有在高速条件下测试过这个芯片的稳定程度?超过150ips的使用有没有可能?

出0入0汤圆

 楼主| 发表于 2013-10-7 22:07:17 | 显示全部楼层
本帖最后由 xizi 于 2013-10-7 22:10 编辑
egomcray 发表于 2013-10-7 12:16
楼主你好,看到你的A9500已经开发的很成熟了,目前我也在尝试利用ADNS-9500来测定位移,有这样两个问题想 ...


1. Pixart 继续使用Avago 的srom. srom-91 或者srom-b1都可以用。我一直在用srom-91。
2. 高于150ips的情况没有测试过。倒是标准z轴距离2.4mm在我的设计中没有严格遵守,结果发现有些可以很好地工作,有些则不稳定。正为此发愁呢。预感到最后还得修改机械结构,严格限定z距离在2.4mm之内才有可能彻底稳定下来。

3. 附件是我使用中的srom-91,包含了我自己转换的c语言格式,可以作为单独文件直接使用。

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2024-9-28 11:03

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

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