ADNS3080光流传感器的arduino编程测试

· 更新于

adns3080arduino光流传感器

一,准备

  • cjmcu 光流传感器 ADNS3080 一个
  • arduino nano开发板一个(NANO默认SPI:10(SS),11(MOSI),12(MISO),13(SCK)))
  • arduino ide 2.0
  • processing 4.0

参考链接:https://github.com/ThomasVandenabeele/rp-adns3080

二,图像代码

1,arduino代码

``#include "SPI.h"  #include <SoftwareSerial.h>  SoftwareSerial mySerial(6, 7); // RX, TX   #define PIN_SS        10 #define PIN_MISO      12 #define PIN_MOSI      11 #define PIN_SCK       13  #define PIN_MOUSECAM_RESET     9 #define PIN_MOUSECAM_CS        10  #define ADNS3080_PIXELS_X                 30 #define ADNS3080_PIXELS_Y                 30  #define ADNS3080_PRODUCT_ID            0x00 #define ADNS3080_REVISION_ID           0x01 #define ADNS3080_MOTION                0x02 #define ADNS3080_DELTA_X               0x03 #define ADNS3080_DELTA_Y               0x04 #define ADNS3080_SQUAL                 0x05 #define ADNS3080_PIXEL_SUM             0x06 #define ADNS3080_MAXIMUM_PIXEL         0x07 #define ADNS3080_CONFIGURATION_BITS    0x0a #define ADNS3080_EXTENDED_CONFIG       0x0b #define ADNS3080_DATA_OUT_LOWER        0x0c #define ADNS3080_DATA_OUT_UPPER        0x0d #define ADNS3080_SHUTTER_LOWER         0x0e #define ADNS3080_SHUTTER_UPPER         0x0f #define ADNS3080_FRAME_PERIOD_LOWER    0x10 #define ADNS3080_FRAME_PERIOD_UPPER    0x11 #define ADNS3080_MOTION_CLEAR          0x12 #define ADNS3080_FRAME_CAPTURE         0x13 #define ADNS3080_SROM_ENABLE           0x14 #define ADNS3080_FRAME_PERIOD_MAX_BOUND_LOWER      0x19 #define ADNS3080_FRAME_PERIOD_MAX_BOUND_UPPER      0x1a #define ADNS3080_FRAME_PERIOD_MIN_BOUND_LOWER      0x1b #define ADNS3080_FRAME_PERIOD_MIN_BOUND_UPPER      0x1c #define ADNS3080_SHUTTER_MAX_BOUND_LOWER           0x1e #define ADNS3080_SHUTTER_MAX_BOUND_UPPER           0x1e #define ADNS3080_SROM_ID               0x1f #define ADNS3080_OBSERVATION           0x3d #define ADNS3080_INVERSE_PRODUCT_ID    0x3f #define ADNS3080_PIXEL_BURST           0x40 #define ADNS3080_MOTION_BURST          0x50 #define ADNS3080_SROM_LOAD             0x60  #define ADNS3080_PRODUCT_ID_VAL        0x17  void mousecam_reset() {   digitalWrite(PIN_MOUSECAM_RESET,HIGH);   delay(1); // reset pulse >10us   digitalWrite(PIN_MOUSECAM_RESET,LOW);   delay(35); // 35ms from reset to functional }  int mousecam_init() {   pinMode(PIN_MOUSECAM_RESET,OUTPUT);   pinMode(PIN_MOUSECAM_CS,OUTPUT);      digitalWrite(PIN_MOUSECAM_CS,HIGH);      mousecam_reset();      int pid = mousecam_read_reg(ADNS3080_PRODUCT_ID);   if(pid != ADNS3080_PRODUCT_ID_VAL)     return -1;    // turn on sensitive mode   mousecam_write_reg(ADNS3080_CONFIGURATION_BITS, 0x19);    return 0; }  void mousecam_write_reg(int reg, int val) {   digitalWrite(PIN_MOUSECAM_CS, LOW);   SPI.transfer(reg | 0x80);   SPI.transfer(val);   digitalWrite(PIN_MOUSECAM_CS,HIGH);   delayMicroseconds(50); }  int mousecam_read_reg(int reg) {   digitalWrite(PIN_MOUSECAM_CS, LOW);   SPI.transfer(reg);   delayMicroseconds(75);   int ret = SPI.transfer(0xff);   digitalWrite(PIN_MOUSECAM_CS,HIGH);    delayMicroseconds(1);   return ret; }  struct MD {  byte motion;  char dx, dy;  byte squal;  word shutter;  byte max_pix; };  void mousecam_read_motion(struct MD *p) {   digitalWrite(PIN_MOUSECAM_CS, LOW);   SPI.transfer(ADNS3080_MOTION_BURST);   delayMicroseconds(75);   p->motion =  SPI.transfer(0xff);   p->dx =  SPI.transfer(0xff);   p->dy =  SPI.transfer(0xff);   p->squal =  SPI.transfer(0xff);   p->shutter =  SPI.transfer(0xff)<<8;   p->shutter |=  SPI.transfer(0xff);   p->max_pix =  SPI.transfer(0xff);   digitalWrite(PIN_MOUSECAM_CS,HIGH);    delayMicroseconds(5); }  // pdata must point to an array of size ADNS3080_PIXELS_X x ADNS3080_PIXELS_Y // you must call mousecam_reset() after this if you want to go back to normal operation int mousecam_frame_capture(byte *pdata) {   mousecam_write_reg(ADNS3080_FRAME_CAPTURE,0x83);      digitalWrite(PIN_MOUSECAM_CS, LOW);      SPI.transfer(ADNS3080_PIXEL_BURST);   delayMicroseconds(50);      int pix;   byte started = 0;   int count;   int timeout = 0;   int ret = 0;   for(count = 0; count < ADNS3080_PIXELS_X * ADNS3080_PIXELS_Y; )   {     pix = SPI.transfer(0xff);     delayMicroseconds(10);     if(started==0)     {       if(pix&0x40)         started = 1;       else       {         timeout++;         if(timeout==100)         {           ret = -1;           break;         }       }     }     if(started==1)     {       pdata[count++] = (pix & 0x3f)<<2; // scale to normal grayscale byte range     }   }    digitalWrite(PIN_MOUSECAM_CS,HIGH);    delayMicroseconds(14);      return ret; }  void setup()  {   pinMode(PIN_SS,OUTPUT);   pinMode(PIN_MISO,INPUT);   pinMode(PIN_MOSI,OUTPUT);   pinMode(PIN_SCK,OUTPUT);      SPI.begin();   SPI.setClockDivider(SPI_CLOCK_DIV32);   SPI.setDataMode(SPI_MODE3);   SPI.setBitOrder(MSBFIRST);      Serial.begin(115200);    if(mousecam_init()==-1)   {     Serial.println("Mouse cam failed to init");     while(1);   } }  char asciiart(int k) {   static char foo[] = "WX86*3I>!;~:,`. ";   return foo[k>>4];     Serial.begin(9600); }  byte frame[ADNS3080_PIXELS_X * ADNS3080_PIXELS_Y];  void loop()  {   //#if 1      // if enabled this section grabs frames and outputs them as ascii art      if(mousecam_frame_capture(frame)==0)   {     int i,j,k;     Serial.print("S");     Serial.println();     for(i=0, k=0; i<ADNS3080_PIXELS_Y; i++)      {       for(j=0; j<ADNS3080_PIXELS_X; j++, k++)        {         Serial.print(frame[k]);//asciiart(frame[k]));         Serial.print('-');       }       Serial.println();     }   }   //Serial.print("E");   //Serial.println();   ////Serial.println();   delay(100);         //#else      // if enabled this section produces a bar graph of the surface quality that can be used to focus the camera   // also drawn is the average pixel value 0-63 and the shutter speed and the motion dx,dy.      //int val = mousecam_read_reg(ADNS3080_PIXEL_SUM);   //MD md;      //mousecam_read_motion(&md);   /*   for(int i=0; i<md.squal/4; i++)     Serial.print('*');   Serial.print(' ');   Serial.print((val*100)/351);   Serial.print(' ');   */   //Serial.print(md.shutter); Serial.print(" (");   //Serial.print("I");      /*int X = (int)md.dx;   int Y = (int)md.dy;   if(X > -1) Serial.print("+");   if(X < 0) Serial.print("-");   if(abs(X) < 10) Serial.print("0");   Serial.print(abs(X));   Serial.print(',');   if(Y > -1) Serial.print("+");   if(Y < 0) Serial.print("-");   if(abs(Y) < 10) Serial.print("0");   Serial.println(abs(Y));   /*   Serial.print((int)md.dx); Serial.print(',');   Serial.println((int)md.dy); //Serial.println(')');   // Serial.println(md.max_pix);   */   //delay(20);   //*/   //#endif }``

2,processing

注意要在插件管理里面安装javafx

`import processing.javafx.*;  import processing.serial.*;  Serial myPort; String myRawString = "";   int[][] image = new int[30][30]; int row = 0; int col = 0;  int driftX = 0; int driftY = 0;  void setup() {   size(300, 330, FX2D);   pixelDensity(2);   myPort = new Serial(this, "COM4", 115200);//这里写自己arduino nano的串口号 }  void draw() {      fill(255, 0, 0);   rect(0, 0, 300, 30);    fill(255, 255, 0);   textSize(15);   text("Ling & Thomas", 10, 20);        while (myPort.available() > 0) {     myRawString = myPort.readStringUntil('\n');     if (myRawString != null) {              if(myRawString.charAt(0) == 'S' | myRawString.charAt(0) == 'E'){         row = 0;         col = 0;       }       if(myRawString.charAt(0) == 'I'){         String strX = myRawString.substring(1, 4);         String strY = myRawString.substring(5, 8);                driftX = parseInt(strX)*-1;         driftY = parseInt(strY);                //println("X: "+ driftX);         //println("Y: "+ driftY);                  fill(255, 255, 0);         textSize(15);         text(driftX, 210, 20);         text(driftY, 280, 20);       }       else{         int[] line = int(split(myRawString, "-"));         if(line.length > 30 && row < 30){           for (int i = 0; i < 30; i = i+1) {             image[i][row] = line[i];                          stroke(image[i][row]);             fill(image[i][row]);             rect(i*10, row*10+30, 10, 10);           }                      row++;         }       }      }   }  }`

3,如图

三,数据代码

直接在arduino的库里面搜索3080,然后就看到了该传感器库,安装后有例程。