Lightgun wifi Samco modificata

Guide, richieste e tutto ciò che c'è da sapere sui controlli del cab
Avatar utente
roberone
Newbie
Newbie
Messaggi: 29
Iscritto il: 11/10/2020, 18:36
Città: Livorno
Grazie Inviati: 8 volte
Grazie Ricevuti: 4 volte

Lightgun wifi Samco modificata

Messaggio da roberone »

Salve,
volevo condividere con voi, i risultati ottenuti modificando il codice del progetto Samco.

Per il momento mi sono dedicato alla versione con 2 led perché comunque funziona molto bene.
La prima modifica che ho apportato è stata al sistema di calibrazione.
L'originale prevede diverse fasi, ma non sempre si riesce a capire la fase corrente.
Inoltre prevede di acquisire la posizione di punti determinati per rapportare i dati rilevati dalla camera, alla risoluzione dello schermo/posizione sensori.
Questo sarebbe ottimo, se non fosse per il fatto, che se non si è estremamente precisi, il puntatore impazzisce. In sostanza per riuscire a calibrare occorrono diversi tentativi, in cui bisogna riattraversare le varie fasi di funzionamento.

Per questo motivo ho optato per una soluzione diversa.
Ho registrato i dati di una calibrazione ottimale, che permette di far funzionare la pistola da subito. Successivamente (se necessaio) si possono scorrere dei preset che permettono di adattare il movimento alla risoluzione.

Inoltre mi avanzavano delle schede radio nRF24L01 da un progetto precedente (costano comunque pochi euro) perciò ho provato ad implementare la trasmissione/ricezione nel codice della pistola.
Ovviamente per questo sono serviti due arduino, uno in trasmissione (sulla pistola) che si occupa dell'acquisizione dei dati della camera, e uno in ricezione (collegato al device arcade) che gestisce la ricezione e l'emulazione mouse.


qui trovate come collegare la scheda nrf24l01 (il collegamento è lo stesso per RX e TX)
http://www.meccanicaeautomazione.it/com ... -nrf24l01/

qui come collegare la camera
https://create.arduino.cc/projecthub/sa ... use-05d110


Buon divertimento!



Codice modulo TX (pistola)

Codice: Seleziona tutto

int positionX[4];               // RAW Sensor Values
int positionY[4];

int oneY = 0;                   // Re-mapped so left sensor is always read first
int oneX = 0;
int twoY = 0;
int twoX = 0;

int finalX = 0;                 // Values after tilt correction
int finalY = 0;

int xLeft = 0;                  // Stored calibration points
int yTop = 0;
int xRight = 0;
int yBottom = 0;

int MoveXAxis = 0;              // Unconstrained mouse postion
int MoveYAxis = 0;

int conMoveXAxis = 0;           // Constrained mouse postion
int conMoveYAxis = 0;

int count = 4;                  // Set intial count

int _tigger = 7;               // Label Pin to buttons
int _up = 11;
//int _down = 9;
//int _left = 10;
int _right = 12;
int _A = A1;
int _B = A0;
int _start = A2;
int _select = A3;
int _reload = 8;
int _pedal = 5;


int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;
int buttonState6 = 0;
int buttonState7 = 0;
int buttonState8 = 0;
int buttonState9 = 0;
int buttonState10 = 0;

int oldbuttonState7 = 0;
int oldbuttonState8 = 0;


#include <DFRobotIRPosition.h>
DFRobotIRPosition myDFRobotIRPosition;



#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#define MIRF_PAYLOAD 32
byte rxData[MIRF_PAYLOAD + 1];
byte txData[MIRF_PAYLOAD + 1];
char msg[50];
int msgIndex = 0;




String stringa;


int res_x = 1920;
int res_y = 1080;
int ritardo = 10;

void setup() {

  memset(rxData, 0, sizeof(rxData));
  memset(txData, 0, sizeof(txData));
  Serial.begin(9600);
  Mirf.cePin = 9;
  Mirf.csnPin = 10;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte*)"clie1");
  Mirf.payload = MIRF_PAYLOAD;
  Mirf.channel = 10;
  Mirf.config();




  pinMode(_tigger, INPUT_PULLUP);         // Set pin modes
  pinMode(_up, INPUT_PULLUP);
  // pinMode(_down, INPUT_PULLUP);
  // pinMode(_left, INPUT_PULLUP);
  pinMode(_right, INPUT_PULLUP);
  pinMode(_A, INPUT_PULLUP);
  pinMode(_B, INPUT_PULLUP);
  pinMode(_start, INPUT_PULLUP);
  pinMode(_select, INPUT_PULLUP);
  pinMode(_reload, INPUT_PULLUP);

  myDFRobotIRPosition.begin();            // Start IR Camera



  delay(500);

}



void loop() {

  Mirf.setTADDR((byte*)"serv1");
  memcpy(txData, msg + msgIndex, MIRF_PAYLOAD);
  Mirf.send(txData);
  while (Mirf.isSending()) {
  }
  delay(ritardo);

  mouseButtons();
  getPosition();
 

}


/*        -----------------------------------------------        */
/* --------------------------- METHODS ------------------------- */
/*        -----------------------------------------------        */


void getPosition() {    // Get tilt adjusted position from IR postioning camera

  myDFRobotIRPosition.requestPosition();

  if (myDFRobotIRPosition.available()) {
    for (int i = 0; i < 4; i++) {
      positionX[i] = myDFRobotIRPosition.readX(i);
      positionY[i] = myDFRobotIRPosition.readY(i);
    }

    if (positionX[0] > positionX[1]) {
      oneY = positionY[0];
      oneX = positionX[0];
      twoY = positionY[1];
      twoX = positionX[1];
    }
    else if (positionX[0] < positionX[1]) {
      oneY = positionY[1];
      oneX = positionX[1];
      twoY = positionY[0];
      twoX = positionX[0];
    }
    else {

      oneY = res_y;
      oneX = 0;
      twoY = res_y;
      twoX = 0;
    }



    finalX = (res_x / 2) + cos(atan2(twoY - oneY, twoX - oneX) * -1) * (((oneX - twoX) / 2 + twoX) - (res_x / 2)) - sin(atan2(twoY - oneY, twoX - oneX) * -1) * (((oneY - twoY) / 2 + twoY) - (res_y / 2));
    finalY = (res_y / 2) + sin(atan2(twoY - oneY, twoX - oneX) * -1) * (((oneX - twoX) / 2 + twoX) - (res_x / 2)) + cos(atan2(twoY - oneY, twoX - oneX) * -1) * (((oneY - twoY) / 2 + twoY) - (res_y / 2));

   
    stringa = String("-5-") + String(finalX) + String("-") + String(finalY) + String("-") + String(buttonState2) + String("-") + String(buttonState9) + String("-") + String(buttonState8) + String("-") + String(buttonState7) + String("-") + String(buttonState1) ;
    stringa.toCharArray(msg, 50) ;

  }

  else {
    Serial.println("Device not available!");
  }

}



void mouseButtons() {    // Setup Left, Right & Middle Mouse buttons

  buttonState2 = digitalRead(_tigger);
  buttonState3 = digitalRead(_up);
  //  buttonState4 = digitalRead(_down);
  //  buttonState5 = digitalRead(_left);
  buttonState6 = digitalRead(_right);

  buttonState9 = digitalRead(_start);
  buttonState10 = digitalRead(_select);
  buttonState1 = digitalRead(_reload);

  buttonState7 = digitalRead(_A);
  buttonState8 = digitalRead(_B);


}






Codice modulo RX

Codice: Seleziona tutto


#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#define MIRF_PAYLOAD 32
byte rxData[MIRF_PAYLOAD + 1];
byte txData[MIRF_PAYLOAD + 1];


int finalX = 0;                 // Values after tilt correction
int finalY = 0;

int MoveXAxis = 0;              // Unconstrained mouse postion
int MoveYAxis = 0;

int conMoveXAxis = 0;           // Constrained mouse postion
int conMoveYAxis = 0;

int count = 4;                  // Set intial count


int buttonState1 = 0;
int lastButtonState1 = 0;
int buttonState2 = 0;
int lastButtonState2 = 0;
int buttonState3 = 0;
int lastButtonState3 = 0;
int buttonState4 = 0;
int lastButtonState4 = 0;
int buttonState5 = 0;
int lastButtonState5 = 0;
int buttonState6 = 0;
int lastButtonState6 = 0;
int buttonState7 = 0;
int lastButtonState7 = 0;
int buttonState8 = 0;
int lastButtonState8 = 0;
int buttonState9 = 0;
int lastButtonState9 = 0;
int buttonState10 = 0;
int lastButtonState10 = 0;

int correzzione = 0;
int offset_x = 0; //300
int offset_y = 0; //200
int barra = 0;

#include <HID.h>                // Load libraries
#include <Wire.h>
#include <Keyboard.h>
#include <AbsMouse.h>
//#include <DFRobotIRPosition.h>

//DFRobotIRPosition myDFRobotIRPosition;

int res_x = 1920;         // Put your screen resolution width here
int res_y = 1080;            // Put your screen resolution height here


String ricevuto;
char *lettura[10];
byte c_lettura = 0;
char charBuf[50];

void setup() {
  memset(rxData, 0, sizeof(rxData));
  memset(txData, 0, sizeof(txData));
  Serial.begin(9600);
  Mirf.cePin = 9;
  Mirf.csnPin = 10;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte*)"serv1");
  Mirf.payload = MIRF_PAYLOAD;
  Mirf.channel = 10;
  Mirf.config();


  AbsMouse.init(res_x, res_y);
  AbsMouse.move((res_x / 2), (res_y / 2));          // Set mouse position to centre of the screen

  delay(500);



}
void loop() {
  c_lettura = 0;
  memset(rxData, 0, sizeof(rxData));
  if (!Mirf.isSending() && Mirf.dataReady()) {
    Mirf.getData(rxData);
    if (count == 4)count = 0;

    lettura[c_lettura] = strtok((const char*)rxData, "-");
    while ( c_lettura < 9)
    {

      lettura[c_lettura] = strtok(NULL, "-");


      ++c_lettura;
    }

    finalX = atoi(lettura[0]);
    finalY = atoi(lettura[1]);


    buttonState2 = atoi(lettura[2]);
    buttonState9 = atoi(lettura[3]);
    buttonState8 =  atoi(lettura[4]);
    buttonState7 = atoi(lettura[5]);
    buttonState1 = atoi(lettura[6]);

    Serial.print(count);
    Serial.print("|");
    Serial.print(offset_x);
    Serial.print("|");
    Serial.print(offset_y);
    Serial.print("|");
    Serial.print(buttonState2);
    Serial.print("|");
    Serial.print(buttonState9);
    Serial.print("|");
    Serial.print( buttonState8);
    Serial.print("|");
    Serial.print(buttonState7);
    Serial.print("|");
    Serial.println(buttonState1);


    Mirf.setTADDR((byte*)"clie1");
    for (unsigned i = 0; i != MIRF_PAYLOAD; ++i) {
      txData[i] = rxData[i] + 1;
    }
    Mirf.send(txData);
  } else {
    if (count == 0)count = 4;


  }


  if (count == 4) {

   
    mouseButtons();
    go();

  }

  /* ------------------ START/PAUSE MOUSE ---------------------- */


  else if (count == 3 ) {

    reset();
    mouseCount();
    mouseButtons();
  

  }

  /* -------------------- Calibrazione -------------------------- */


  else if (count == 2 ) {
if (barra == 0){
    AbsMouse.move(offset_x + correzzione, offset_y + correzzione);
    delay(20);
    AbsMouse.move((res_x - (offset_x + correzzione)), offset_y + correzzione);
    delay(20);
}else{
    AbsMouse.move((res_x - (offset_x + correzzione)), (res_y - (offset_y + correzzione)));
    delay(20);
    AbsMouse.move(offset_x + correzzione, (res_y - (offset_y + correzzione)));
    delay(20);
}   
    mouseCount();
    reset();

    /* ---------------------------------------------- */

  }

  


  else {

    AbsMouse.move(conMoveXAxis, conMoveYAxis);

    mouseButtons();

    MoveXAxis = map (finalX, 1600, 1200, offset_x, (res_x - offset_x));
    MoveYAxis = map (finalY, 700-barra, 1000-barra, offset_y, (res_y - offset_y));

    conMoveXAxis = constrain (MoveXAxis, 0, res_x);
    conMoveYAxis = constrain (MoveYAxis, 0, res_y);


    reset();

  }

}



/*        -----------------------------------------------        */
/* --------------------------- METHODS ------------------------- */
/*        -----------------------------------------------        */




void go() {    // Setup Start Calibration Button

  //  buttonState1 = digitalRead(_reload);

  if (buttonState1 != lastButtonState1) {

    
    if (buttonState1 == LOW) {
      count == 3;
    }
    else { // do nothing
    }
    delay(50);
  }
  lastButtonState1 = buttonState1;
}



void mouseButtons() {    // Setup Left, Right & Middle Mouse buttons


  if (buttonState2 != lastButtonState2) {
    if (buttonState2 == LOW) {
      AbsMouse.press(MOUSE_LEFT);
    }
    else {
      AbsMouse.release(MOUSE_LEFT);
    }
    
  }

  if (buttonState3 != lastButtonState3) {
    if (buttonState3 == LOW) {
      Keyboard.press(KEY_UP_ARROW);
      delay(100);
      Keyboard.releaseAll();
    }
    else {

    }

  }

  if (buttonState4 != lastButtonState4) {
    if (buttonState4 == LOW) {
      Keyboard.press(KEY_DOWN_ARROW);
      delay(100);
      Keyboard.releaseAll();
    }
    else {

    }

  }

  if (buttonState5 != lastButtonState5) {
    if (buttonState5 == LOW) {
      Keyboard.press(KEY_LEFT_ARROW);
      delay(100);
      Keyboard.releaseAll();
    }
    else {

    }

  }

  if (buttonState6 != lastButtonState6) {
    if (buttonState6 == LOW) {
      Keyboard.press(KEY_RIGHT_ARROW);
      delay(100);
      Keyboard.releaseAll();
    }
    else {

    }

  }

  if (buttonState7 != lastButtonState7) {
    if (buttonState7 == LOW) {
      AbsMouse.press(MOUSE_RIGHT);
    }
    else {
      AbsMouse.release(MOUSE_RIGHT);
    }

  }

  if (buttonState8 != lastButtonState8) {
    if (buttonState8 == LOW) {
      AbsMouse.press(MOUSE_MIDDLE);
    }
    else {
      AbsMouse.release(MOUSE_MIDDLE);
    }

  }
  if (buttonState9 != lastButtonState9) {
    if (buttonState9 == LOW) {
      Keyboard.press(KEY_BACKSPACE);
      delay(100);
      Keyboard.releaseAll();
    }
    else {

    }

  }

  if (buttonState10 != lastButtonState10) {
    if (buttonState10 == LOW) {
      Keyboard.press(KEY_RETURN);
      delay(100);
      Keyboard.releaseAll();
    }
    else {

    }

  }

  lastButtonState2 = buttonState2;
  lastButtonState3 = buttonState3;
  lastButtonState4 = buttonState4;
  lastButtonState5 = buttonState5;
  lastButtonState6 = buttonState6;
  lastButtonState7 = buttonState7;
  lastButtonState8 = buttonState8;
  lastButtonState9 = buttonState9;
  lastButtonState10 = buttonState10;
}


void mouseCount() {    // Set count down on trigger

  if (buttonState2 != lastButtonState2) {
    if (buttonState2 == LOW) {
      if (count == 3) {
        count--;
      } else if (count == 2) {
        if (offset_x < 500) {
          offset_x = offset_x + 100;
          offset_y = offset_y + 80;
        } else {
          offset_x = 0;
          offset_y = 0;
        }
      }
      else { // do nothing
      }
      //   delay(10);
    }

    lastButtonState2 = buttonState2;
  }

 if (buttonState7 != lastButtonState7) {
  if (buttonState7 == LOW) {
    if (barra==0) {
        barra = 300;
      } else {
        barra = 0;
      }
  }
  lastButtonState7 = buttonState7l;
 }


  
}

  void reset() {    // Pause/Re-calibrate button



    if (buttonState1 != lastButtonState1) {
      if (buttonState1 == LOW) {
      
        if (count == 0) {
          count = 3;
        } else {
          count = 0;
        }
        delay(50);
      }
      else { // do nothing
      }
      delay(50);
    }
    lastButtonState1 = buttonState1;
  }
Ultima modifica di roberone il 07/11/2020, 13:03, modificato 1 volta in totale.
Avatar utente
CONSOLEMAN
God of Arcade
God of Arcade
Messaggi: 3385
Iscritto il: 26/08/2015, 0:01
Città: ARCADIA
Grazie Inviati: 111 volte
Grazie Ricevuti: 90 volte

Re: Lightgun wifi Samco modificata

Messaggio da CONSOLEMAN »

Grazie
Avatar utente
Tox Nox Fox

BanHammer Silver Medal Donatore
Moderatore
Moderatore
Messaggi: 11785
Iscritto il: 14/01/2007, 23:35
Medaglie: 3
Grazie Inviati: 160 volte
Grazie Ricevuti: 275 volte

Re: Lightgun wifi Samco modificata

Messaggio da Tox Nox Fox »

Questo lo leggo con calma questa sera
WP.ARCADEITALIA.NET
La Guida al MameCab
Avatar utente
roberone
Newbie
Newbie
Messaggi: 29
Iscritto il: 11/10/2020, 18:36
Città: Livorno
Grazie Inviati: 8 volte
Grazie Ricevuti: 4 volte

Re: Lightgun wifi Samco modificata

Messaggio da roberone »

Ho realizzato un prototipo molto rudimentale, ma utile per testare vari aspetti.

Immagine

Infatti mi sono reso conto di aver sottostimato il volume dei cavi e sono stato costretto a mettere esterno quello dell'alimentazione.

Testando su vari dispositivi e schermi ho verificato che la calibrazione non è necessaria quindi la toglierò questa funzione.

Spero di riuscire a realizzare presto un nuovo prototipo con il software aggiornato.
Avatar utente
roberone
Newbie
Newbie
Messaggi: 29
Iscritto il: 11/10/2020, 18:36
Città: Livorno
Grazie Inviati: 8 volte
Grazie Ricevuti: 4 volte

Re: Lightgun wifi Samco modificata

Messaggio da roberone »

Anche se non ha suscitato grande interesse, aggiorno con la nuova realizzazione.

Immagine
Rispondi

Torna a “Controlli (joystick, pulsanti, trackball, spinner, volanti, ecc...)”