arduino平台读取鼠标光电传感器

鼠标坏掉了,大抵是修不好了。(全剧终---)

但是爱动手的小明不会浪费这个鼠标,确认外观没有明显烧毁痕迹后,尝试从电路板上利用光电传感器进行位移的测量,光电传感器(型号:FCT3065)找不到datasheet,但查到内核仿的是PAW3205, 因此只需要参考后者的datasheet即可。

通过电路板的led找到LED引脚,确定引脚信息,开始操作

首先去掉鼠标主控芯片,然后飞线将vdd连接到电源正极,注意供电不能高于3.6v,再焊接4根杜邦线,引出SDIO、SCLK、电源正负极即可,盖上盖子,测试!

复制代码
/*
   Program to interface FCT3065-XY Optical Mouse
   Sensor with Arduino.

   This code detects when mouse is moved and also
   prints the change in x direction and change in y
   direction in the serial monitor.

   Author: Vineet Sukhthanker
   Date: 6 October 2020


*/

//Register Addresses from datasheet
#define PROD_ID1 0x00
#define PROD_ID2 0x01
#define MOTION_STATUS 0X02
#define DEL_X 0x03
#define DEL_Y 0x04
#define OP_MODE 0x05
#define CONF 0x06
#define IMG_QUALITY 0x07
#define OP_STATE 0x08
#define W_PROTECT 0x09
#define SLEEP1_SET 0x0A
#define ENTER_TIME 0x0B
#define SLEEP2_SET 0x0C
#define IMG_THRESHOLD 0x0D
#define IMG_RECOG 0x0E

const int SCLK = 13;
const int SDIO = 12;

byte noSleep = 0xA0;

int i = 0;
void setup() {
  Serial.begin(115200);
  pinMode (SCLK, OUTPUT);
  mouseInit();

  byte prodId1 = readRegister(PROD_ID1);
  Serial.print((prodId1 == 0x31) ? "\nDevice OK" : "\nUnknown Device"); // checks for product ID
  Serial.print(prodId1);
}

void loop() {
  int motion = readRegister(MOTION_STATUS); // read motion status register
  // if(motion==0x81){
  Serial.print("\nMoved!");
  Serial.print(motion);
  int8_t delta_x = readRegister(DEL_X); // read delta x register
  int8_t delta_y = readRegister(DEL_Y); // read delta y register
  Serial.print("\nX:");

  Serial.print(delta_x);

  Serial.print(" Y:");

  Serial.print(delta_y);
  //}
  delay(1000);
}

void mouseInit(void) // function to initialize optical sensor.
{
  digitalWrite(SCLK, HIGH);
  digitalWrite(SCLK, LOW);
  delayMicroseconds(1); // tRESYNC = 1us (mentioned in datasheet)
  digitalWrite(SCLK, HIGH);
  delay(320); // tSIWTT = 320ms (mentioned in datasheet)
  digitalWrite(SCLK, LOW);
  writeRegister(OP_MODE, noSleep); // disable sleep mode
}

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(3); // tHOLD = 3us (mentioned in datasheet)

  byte res = 0;
  for (byte i = 128; i > 0 ; i >>= 1) {
    digitalWrite (SCLK, LOW);
    digitalWrite (SCLK, HIGH);
    if ( digitalRead (SDIO) == HIGH )
      res |= i;
  }

  delayMicroseconds(3); // tHOLD = 3us min. (mentioned in datasheet)

  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);
}

效果如图,x和y坐标分别向下向右为正,寄存器补码形式存储8位位移量

大合照(或许旋转编码器还再可以玩一玩)

参考

如何优雅的DIY鼠标?

FCT3065-XY_MouseSensor

相关推荐
点灯小铭3 小时前
基于单片机的多模式自动洗衣机设计与实现
数据库·单片机·嵌入式硬件·毕业设计·课程设计
La Pulga4 小时前
【STM32】RTC实时时钟
c语言·stm32·单片机·嵌入式硬件·mcu·实时音视频
m0_555762904 小时前
STM32产品程序测试完整指南
stm32·单片机·嵌入式硬件
普中科技4 小时前
【普中Hi3861开发攻略--基于鸿蒙OS】-- 第 26 章 WIFI实验-AP 建立网络
单片机·嵌入式硬件·wifi·liteos·hi3861·普中科技
普中科技5 小时前
【普中Hi3861开发攻略--基于鸿蒙OS】-- 第 24 章 OLED液晶显示实验
单片机·嵌入式硬件·oled·liteos·hi3861·普中科技
冻结的鱼5 小时前
STM32H5 的 PB14 引脚被意外拉低的问题解析
stm32·单片机·嵌入式硬件
小莞尔6 小时前
【51单片机】【protues仿真】基于51单片机彩灯控制器系统
单片机·嵌入式硬件
文火冰糖的硅基工坊6 小时前
[嵌入式系统-146]:五次工业革命对应的机器人形态的演进、主要功能的演进以及操作系统的演进
前端·网络·人工智能·嵌入式硬件·机器人
老六哥_AI助理指南6 小时前
为什么AI会改变单片机的未来?
人工智能·单片机·嵌入式硬件
点灯小铭6 小时前
基于单片机的智能家居多参数环境监测与联动报警系统设计
单片机·mongodb·毕业设计·智能家居·课程设计·期末大作业