LightGunDiyer 光枪爱好者
github方案移植 步骤二 方案的代码部分 单片机主程序 - 可打印的版本

+- LightGunDiyer 光枪爱好者 (http://www.wukongxuetang.com/bbs)
+-- 版块: 光枪原理与光枪DIY (http://www.wukongxuetang.com/bbs/forumdisplay.php?fid=1)
+--- 版块: 光枪-创意设计 (http://www.wukongxuetang.com/bbs/forumdisplay.php?fid=6)
+--- 主题: github方案移植 步骤二 方案的代码部分 单片机主程序 (/showthread.php?tid=32)



github方案移植 步骤二 方案的代码部分 单片机主程序 - wukong - 04-29-2024

#include "Arduino.h"
#include "Transformation.h"
#include "AbsMouse.h"
#include <Keyboard.h>
#include "Wire.h"

#define triggerA 2
#define triggerB 3
#define mag 9
#define lid 8
#define fireLED 4
#define warningLED 15

//采集模块实例化
#include <wukongM700.h>
//设置第一个参数为cs引脚,第二个参数为单片机采集时光枪的编号
PointsTracking irtracker(4, 1);
int irPoints[8];
bool PointFound[4];

int positionX[] = {1023, 1023, 1023, 1023};
int positionY[] = {1023, 1023, 1023, 1023};
int cornersX[] = {1023, 1023, 1023, 1023};
int cornersY[] = {1023, 1023, 1023, 1023};
boolean dataComplete = false;
int button_triggerA = 0;
int button_triggerB = 0;
int button_mag = 0;
int button_lid = 0;
int warningLEDState = 0;

//声明屏幕分辨率为1920*1080
int screenW = 1920;
int screenH = 1080;
//中心点偏移参考点
int gunCenterX = 595;
int gunCenterY = 325;

void setup() {
  pinMode(fireLED, OUTPUT);
  pinMode(warningLED, OUTPUT);
  pinMode(triggerA, INPUT_PULLUP);
  pinMode(triggerB, INPUT_PULLUP);
  pinMode(mag, INPUT_PULLUP);
  pinMode(lid, INPUT_PULLUP);
  Serial.begin(19200);
  AbsMouse.init(screenW, screenH);
  camera.begin();
  Keyboard.begin();
  digitalWrite(fireLED, LOW);
  digitalWrite(warningLED, LOW);
  irtracker.DeviceInit();
  if (irtracker.deviceIsOk) {
    Serial.println("point tracting device is ok");
    camx = irtracker.get_xpixel();
    camy = irtracker.get_ypixel();
    Serial.print("x:"); Serial.print(camx); Serial.print(" y:"); Serial.println(camy);
  }
  else {
    Serial.println("pleas check point tracting device' spi setting");
  }
}

void loop() {
  handleButtons();
  getCameraData();
}

//按键的监听与驱动
void handleButtons() {
  int triggerA_now = digitalRead(triggerA);
  int triggerB_now = digitalRead(triggerB);
  int mag_now = digitalRead(mag);
  int lid_now = digitalRead(lid);
  if (triggerA_now != button_triggerA)
  {
    button_triggerA = triggerA_now;
    if (button_triggerA == 0)
    {
      AbsMouse.press(MOUSE_LEFT);
      digitalWrite(fireLED, HIGH);
    }
    else {
      AbsMouse.release(MOUSE_LEFT);
      digitalWrite(fireLED, LOW);
    }
  }
  if (triggerB_now != button_triggerB)
  {
    button_triggerB = triggerB_now;
    if (button_triggerB == 0) {
      AbsMouse.press(MOUSE_RIGHT);
    }
    else {
      AbsMouse.release(MOUSE_RIGHT);
    }
  }
  if (lid_now != button_lid) {
    button_lid = lid_now;
    if (button_lid == 0) {
      AbsMouse.press(MOUSE_MIDDLE);
    }
    else {
      AbsMouse.release(MOUSE_MIDDLE);
    }
  }
  if (mag_now != button_mag) {
    button_mag = mag_now;
    if (button_mag == 0) {
      Keyboard.press(KEY_RETURN);
    }
  }
  else {
    Keyboard.release(KEY_RETURN);
  }
}

//获取模组光点采集
void getCameraData() {
  if (irtracker.deviceIsOk) {
    irtracker.get_mot_data(irPoints);
    for (int i = 0; i < 4; i++)
    {
      if (irPoints[2 * i] < 0 || irPoints[2 * i + 1] < 0) {
        PointFound[i] = false;
      }
      else {
        PointFound[i] = true;
      }
    }   
  }
  if (PointFound[0] && PointFound[1] && PointFound[2] && PointFound[3]) {
    for (uint t = 0; t < 4; t++) {
      positionX[t] = irPoints[2 * t];
      positionY[t] = irPoints[2 * t + 1];
    }
    int orderedX[] = {0, 1, 2, 3};
    for (int i = 0; i < 3 ; i++) {
      for (int j = i + 1; j < 4; j++) {
        if (positionX[orderedX[i]] < positionX[orderedX[j]]) {
          int temp = orderedX[i];
          orderedX[i] = orderedX[j];
          orderedX[j] = temp;
        }
      }
    }
    if (positionY[orderedX[0]] < positionY[orderedX[1]]) {
      cornersX[0] = positionX[orderedX[0]];
      cornersY[0] = positionY[orderedX[0]];
      cornersX[2] = positionX[orderedX[1]];
      cornersY[2] = positionY[orderedX[1]];
    } else {
      cornersX[0] = positionX[orderedX[1]];
      cornersY[0] = positionY[orderedX[1]];
      cornersX[2] = positionX[orderedX[0]];
      cornersY[2] = positionY[orderedX[0]];
    }

    if (positionY[orderedX[2]] < positionY[orderedX[3]]) {
      cornersX[1] = positionX[orderedX[2]];
      cornersY[1] = positionY[orderedX[2]];
      cornersX[3] = positionX[orderedX[3]];
      cornersY[3] = positionY[orderedX[3]];
    } else {
      cornersX[1] = positionX[orderedX[3]];
      cornersY[1] = positionY[orderedX[3]];
      cornersX[3] = positionX[orderedX[2]];
      cornersY[3] = positionY[orderedX[2]];
    }

    Transformation trans(cornersX, cornersY, screenW, screenH, gunCenterX, gunCenterY);
    AbsMouse.move(trans.u(), trans.v());
    setWarningLED(0);
  } else {
    setWarningLED(1);
  }
}

void setWarningLED(int x) {
  if (x == 1) {
    digitalWrite(warningLED, HIGH);
  }
  else {
    digitalWrite(warningLED, LOW);
  }
}