Sei sulla pagina 1di 23

Gruppo n°2: Hao Chen, Wei Zheng, Luca Baldoni, Pietro Zingarlini

I.T.I.S. C.Zuccante

Classe 5aAA a.s. 2017/2018

Progetto:
Tiro al bersaglio laser
con torretta automatica
Sommario
Introduzione generale: .............................................................................................................. 3
Schema a blocchi: ..................................................................................................................... 4
Blocco A – Elegoo mega 2560 r3 ......................................................................................... 5
Blocco B, D – Sistema dei bersagli e visualizzazione punti con LCD ...................................... 9
Blocco C – Trasduttore segnale laser ................................................................................. 17
Blocco E – Arduino Uno...................................................................................................... 18
Blocco F – Visione artificiale .............................................................................................. 18
Blocco G – Torretta automatica .......................................................................................... 20
Conclusione:............................................................................................................................ 23

2
Introduzione generale:

Il progetto consiste in un gioco di tiro al bersaglio laser con una torretta automatica come
avversario del giocatore.
I bersagli sono posizionati sopra a una struttura in legno e mossi attraverso dei servo-motori; i
bersagli sono in totale 10, tra cui due finali che sono movibili in modo laterale per rendere il
gioco piùdifficile.
La torretta automatica, punta al bersaglio grazie alla visione artificiale mediante telecamera
VF0250 che gli indica le coordinate da seguire.
Il punteggio finale del robot e del giocatore verrà visualizzato infine su un display LCD.
Vince chi prima raggiunge i 10 punti!

3
Schema a blocchi:

4
Blocco A – Elegoo mega 2560 r3

Semplice spiegazione del blocco

Microcontrollore alimentato con trasformatore di 5V usato con shield progettato per il


controllo di servo motori, motori DC, fototransistor e display LCD.

Il microcontrollore Elegoo mega 2560 r3 è uguale all’Arduino mega 2560 Rev 3 con solo il
nome differente. Si è scelto di usare l’Elegoo e non l’Arduino Uno per la sua maggiore
quantitàdi pin digitali di cui abbiamo bisogno.

Shield per “Elegoo mega 2560 r3”

*schema elettrico e PCB allegato nelle pagine successiva

5
6
7
Visione dall’alto dello Shield per “Elegoo mega 2560 r3”

Visione dal basso dello Shield per “Elegoo mega 2560 r3”

8
Blocco B, D – Sistema dei bersagli e visualizzazione punti con LCD

Semplice spiegazione del blocco

Questo blocco viene controllato tutto dall’Elegoo mega 2560 r3; qui viene gestito tutta la
parte dei bersagli e del LCD del progetto.

I bersagli cambiano posizione da visibile a non visibile mediante dei servo motori, mentre i
bersagli mobili, oltre al servo, hanno anche motori DC che gli muovono da destra a sinistra e
viceversa.

Ogni bersaglio èdotato di due fototransistor e di una copertura per evitare i disturbi luminosi
dell’ambiente. [questa parte verràspiegata piùspecificatamente nel Blocco C]

Sul display LCD infine viene proiettato i punti guadagnati dal robot e giocatore, inoltre una
frase che dichiara il vincitore della partita.

Componenti

 Struttura base in legno;


 Coperchio del gioco in legno;
 Canaline ;
 Bersagli in legno con copertura da luce ambientale, verde per robot, rossi per
giocatore;
 Barra metallica con cuscinetto lineare;
 Cavetti per l’elettronica;
 Elegoo mega 2560 r3;
 Shield per “Elegoo mega 2560 r3”;
 Servo motori SG90 x10;
 Fototransistor bpw42 x20;
 Motori DC 12V con cinghia e pulegge per il scorrimento della cinghia x2;
 Finecorsa x4;
 Trasformatore 5V, 5A, 25W;
 Batteria 9V per alimentazione motori DC;

9
Foto del bersaglio

10
Struttura base in legno con canaline e bersagli

Struttura base con coperchio del gioco in legno

11
Codice per sistema di bersagli con lettura segnale laser e visualizzazione
punti con display LCD
#include <Servo.h> //Inserire la libreria Servo
#include "LiquidCrystal.h"

//Inizializzazione per il display LCD


const int rs = 42, en = 44, d4 = 46, d5 = 48, d6 = 50, d7 = 52;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

//inizializzazione dei servo motori per bersagli robot


Servo ServoR1;
Servo ServoR2;
Servo ServoR3;
Servo ServoR4;
Servo ServoR5;

//inizializzazione dei servo motori per bersagli giocatore


Servo ServoG1;
Servo ServoG2;
Servo ServoG3;
Servo ServoG4;
Servo ServoG5;

//pin per motore DC del robot


const int MotoreR1 = 5; // Pin 14 of L293
const int MotoreR2 = 6; // Pin 10 of L293

//pin per motore DC del giocatore


const int MotoreG1 = 4; // Pin 7 of L293
const int MotoreG2 = 3; // Pin 2 of L293

//pin per i fototransistor bersagli robot


int foto_transR1 = 22;
int foto_transR2 = 24;
int foto_transR3 = 26;
int foto_transR4 = 28;
int foto_transR5 = 30;

//pin per i fototransistor bersagli giocatore


int foto_transG1 = 32;
int foto_transG2 = 34;
int foto_transG3 = 36;
int foto_transG4 = 38;
int foto_transG5 = 40;

//pin per i finecorsa per i motori


int finecorsaR_dx = 47;
int finecorsaR_sx = 49;
int finecorsaG_dx = 53;
int finecorsaG_sx = 51;

//variabile per scelta salita bersagli


int n_bersaglio_robot;
int n_bersaglio_giocatore;

//variabile che ci dice se ci sono bersagli ON


int bersaglio_pronto = 0;

//variabile utile per controllo fototransistor


int fotocontrol = 0;

//variabile per i punti


int puntiR = 0;
int puntiG = 0;

12
//variabile per far partire i motori DC a destra
int i;

void setup() {

//settaggio pin per i fototransistor per bersagli robot


pinMode(foto_transR1, INPUT);
pinMode(foto_transR2, INPUT);
pinMode(foto_transR3, INPUT);
pinMode(foto_transR4, INPUT);
pinMode(foto_transR5, INPUT);

//settaggio pin per i fototransistor per bersagli robot


pinMode(foto_transG1, INPUT);
pinMode(foto_transG2, INPUT);
pinMode(foto_transG3, INPUT);
pinMode(foto_transG4, INPUT);
pinMode(foto_transG5, INPUT);

//settaggio per i servo motori per bersagli robot


ServoR1.attach (23);
ServoR2.attach (25);
ServoR3.attach (27);
ServoR4.attach (29);
ServoR5.attach (31);

//settaggio per i servo motori per bersagli giocatore


ServoG1.attach (33);
ServoG2.attach (35);
ServoG3.attach (37);
ServoG4.attach (39);
ServoG5.attach (41);

//settaggio per i motori DC per i bersagli movibili


pinMode(MotoreR1, OUTPUT);
pinMode(MotoreR2, OUTPUT);
pinMode(MotoreG1, OUTPUT);
pinMode(MotoreG2, OUTPUT);

//settaggio per i pin dei finecorsa


pinMode(finecorsaR_dx, INPUT);
pinMode(finecorsaR_sx, INPUT);
pinMode(finecorsaG_dx, INPUT);
pinMode(finecorsaG_sx, INPUT);

//inizializzo il display LCD


lcd.begin(16, 2);

void loop() {

//controllo se non ci sono bersagli ON, se non ci sono entro nel ciclo if
if (bersaglio_pronto == 0) {

//se i punti del robot e del giocatore sono inferiori a 11 entro nel ciclio if

//porto tutti i bersagli in posizione di riposo


ServoR1.write(0);
ServoR2.write(180);
ServoR3.write(180);
ServoR4.write(0);
ServoR5.write(0);
ServoG1.write(0);
ServoG2.write(0);
ServoG3.write(0);
ServoG4.write(0);

13
ServoG5.write(0);

if (puntiR < 10 && puntiG < 10) {


//mostro sul display LCD i punti del robot e del giocatore
lcd.setCursor(0, 0);
lcd.print("punti R = ");
lcd.setCursor(11, 0);
lcd.print(puntiR);
lcd.setCursor(0, 1);
lcd.print("punti G = ");
lcd.setCursor(11, 1);
lcd.print(puntiG);
}

//se il robot guadagna 10 punti, sul LCD viene scritto ROBOT VINCE e si rinizializza
//a 0 i punti sia del robot sia del giocatore e si attende 10s prima che il gioco
//ricominci
if (puntiR == 10) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ROBOT VINCE");
puntiR = 0;
puntiG = 0;
delay(10000);
lcd.clear();
}

//se il giocatore guadagna 10 punti, sul LCD viene scritto GIOCATORE VINCE
//e si rinizializza a 0 i punti sia del robot sia del giocatore e si attende
//10s prima che il gioco ricominci
if (puntiG == 10) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("GIOCATORE VINCE");
puntiR = 0;
puntiG = 0;
delay(10000);
lcd.clear();
}

//tempo di attesa di 2s dalla discesa-salita di un nuovo bersaglio


delay(2000);

//selezione di bersaglio in modo casuale, se esce il n5, cioe' il bersaglio mobile,


//allora per parita' di difficolta', tutti e due i bersagli che si alzeranno, saranno
//mobili
n_bersaglio_robot = random (1, 6);
n_bersaglio_giocatore = random(1, 6);
if (n_bersaglio_robot == 5 || n_bersaglio_giocatore == 5) {
n_bersaglio_robot = 5;
n_bersaglio_giocatore = 5;
}
}

//ciclo switch case per selezionare quale bersaglio robot deve andare ON
switch (n_bersaglio_robot) {
case 1:
bersaglio_pronto = 1;
ServoR1.write(75);
fotocontrol = 1;
break;
case 2:
bersaglio_pronto = 1;
ServoR2.write(90);

14
fotocontrol = 1;
break;
case 3:
bersaglio_pronto = 1;
ServoR3.write(90);
fotocontrol = 1;
break;
case 4:
bersaglio_pronto = 1;
ServoR4.write(75);
fotocontrol = 1;
break;
case 5:
bersaglio_pronto = 1;
ServoR5.write(90);
digitalWrite(MotoreR1, HIGH);
digitalWrite(MotoreR2, LOW);
fotocontrol = 2;
break;
}

//ciclo switch case per selezionare quale bersaglio giocatore deve andare ON
switch (n_bersaglio_giocatore) {
case 1:
bersaglio_pronto = 1;
ServoG1.write(75);
fotocontrol = 1;
break;
case 2:
bersaglio_pronto = 1;
ServoG2.write(75);
fotocontrol = 1;
break;
case 3:
bersaglio_pronto = 1;
ServoG3.write(75);
fotocontrol = 1;
break;
case 4:
bersaglio_pronto = 1;
ServoG4.write(75);
fotocontrol = 1;
break;
case 5:
bersaglio_pronto = 1;
ServoG5.write(110);
digitalWrite(MotoreG1, HIGH);
digitalWrite(MotoreG2, LOW);
fotocontrol = 2;
break;
}

//ciclo while quando viene selezionato un bersaglio non mobile


while (fotocontrol == 1) {

//quando viene beccato un bersaglio col laser, i bersagli si abbassano e se era del robot, verra' aggiunto un punto
al robot
//mentre se era del giocatore, viene aggiunto un punto al giocatore
if (digitalRead(foto_transR1) == 0 || digitalRead(foto_transR2) == 0 || digitalRead(foto_transR3) == 0 ||
digitalRead(foto_transR4) == 0) {
puntiR = puntiR + 1;
bersaglio_pronto = 0;
fotocontrol = 0;
}
if (digitalRead(foto_transG1) == 0 || digitalRead(foto_transG2) == 0 || digitalRead(foto_transG3) == 0 ||
digitalRead(foto_transG4) == 0) {
puntiG = puntiG + 1;

15
bersaglio_pronto = 0;
fotocontrol = 0;
}
}

//ciclo while quando viene selezionato un bersaglio mobile, vengono attivati i motori DC
while (fotocontrol == 2) {

//cicli if quando viene beccato un bersaglio mobile, dipendentemente dal robot o giocatore
//viene assegnato un punto
if (digitalRead(foto_transR5) == 0) {
digitalWrite(MotoreR1, LOW);
digitalWrite(MotoreR2, LOW);
digitalWrite(MotoreG2, LOW);
digitalWrite(MotoreG1, LOW);
puntiR = puntiR + 1;
bersaglio_pronto = 0;
fotocontrol = 0;
}
if (digitalRead(foto_transG5) == 0) {
digitalWrite(MotoreR1, LOW);
digitalWrite(MotoreR2, LOW);
digitalWrite(MotoreG2, LOW);
digitalWrite(MotoreG1, LOW);
puntiG = puntiG + 1;
bersaglio_pronto = 0;
fotocontrol = 0;
}

//ciclo if per far andare destra e sinistra i motori DC con i finecorsa fintanto
//che non vengono beccati i bersagli mobili
if (digitalRead(foto_transR5) == 1 && digitalRead(foto_transG5) == 1) {
if (digitalRead(finecorsaR_sx) == 0) {
digitalWrite(MotoreR1, HIGH);
digitalWrite(MotoreR2, LOW);
}
if (digitalRead(finecorsaR_dx) == 0) {
digitalWrite(MotoreR2, HIGH);
digitalWrite(MotoreR1, LOW);
}
if (digitalRead(finecorsaG_sx) == 0) {
digitalWrite(MotoreG1, HIGH);
digitalWrite(MotoreG2, LOW);
}
if (digitalRead(finecorsaG_dx) == 0) {
digitalWrite(MotoreG2, HIGH);
digitalWrite(MotoreG1, LOW);
}
}
}
}

16
Blocco C – Trasduttore segnale laser

Semplice spiegazione del blocco

Blocco in cui il segnale del puntatore laser della torretta automatica viene trasportato da
valore luminoso a valore elettronico per il Elegoo mega mediante due foto-transistor collegati
ad ogni bersaglio.

Circuito

Calcoli

Sapendo che la corrente e con luminositàpari a 0 , prediamo una


corrente che non sia troppo bassa per evitare di non poter mandare in saturazione il foto-
transistor e ne' troppo alta a causa dei disturbi luminosi dell'ambiente. Perciò scegliamo una
corrente di .

Perciò prendiamo una . Inoltre per facilitare la cattura del segnale laser dal
nostro foto-transistor, aumentiamo l’area utile al ricevimento del laser ed il conseguente
innesco del componente mettendo due foto-transistor in parallelo. Il calcolo rimane invariato.

17
Blocco E – Arduino Uno

Semplice spiegazione del blocco

Microcontrollore usato per controllare la torretta automatica e ricevere dati dalla visione
artificiale tramite il Processing per muovere la torretta in una data coordinata.

Blocco F – Visione artificiale

Semplice spiegazione del blocco

Attraverso l’utilizzo della telecamera VF0250, viene visualizzato la posizione del bersaglio
attraverso il suo colore verde, la coordinata della sua posizione viene inviata ad Arduino
mediante il programma Processing .

Codice per la visione artificiale – localizzazione e spedizione coordinata


di un colore verde visualizzato con fotocamera
import processing.serial.*;
import processing.video.*;
Serial myPort;
// variabile capture video
Capture video;

// variabile del colore e le coordinate


color trackColor;
int x;
int y;
int mouse=0;
int controlloB=0;
byte sendx;
byte sendy;
byte out[] = new byte[2];

18
void setup() {
size(400, 460); //dimensione della finestra
String[] cameras = Capture.list();
printArray(cameras);
video = new Capture(this, cameras[13]); //imposto che telecamera utilizzare
video.start();
//inizia
trackColor = color(204, 0, 0);
//colore da cercare
String portName = Serial.list()[0]; //decido che port del USB usare
myPort = new Serial(this, portName, 9600);
}

void captureEvent(Capture video) {


video.read();
//legge immagine dal "video"
}

void draw() {
video.loadPixels();
image(video, 0, 0);

// Before we begin searching, the "world record" for closest color is set to a high number that is easy for the first
pixel to beat.
float worldRecord = 500;

// coordinate del colore piu vicino


int closestX = 0;
int closestY = 0;

// inizia il loop che passera su tutti i pixel


for (x = 0; x < video.width; x++ ) {
for (y = 0; y < video.height; y++ ) {
int loc = x + y * video.width;
// per decidere che colore èquello attuale
color currentColor = video.pixels[loc];
float r1 = red(currentColor);
float g1 = green(currentColor);
float b1 = blue(currentColor);
float r2 = red(trackColor);
float g2 = green(trackColor);
float b2 = blue(trackColor);

float d = dist(r1, g1, b1, r2, g2, b2); // compariamo il colore voluto con colore attuale

if (d < worldRecord) { //se il pixel analizzato èabbastanza vicino al colore scelto viene salvato le
coordinate
worldRecord = d;
closestX = x;
closestY = y;
}
}
}

if (worldRecord < 10) {


// fa un cerchio attorno al colore trovato.
fill(trackColor);
strokeWeight(4.0);
stroke(0);
ellipse(closestX, closestY, 16, 16);
out[0] = byte(map(0-closestX, 0, 400, 0, 255)); // manda fuori le due coordinate in serie.
out[1] = byte(map(0-closestY, 0, 460, 0, 255));
myPort.write(out);
}

19
}

void mousePressed() {
// Salva il colore dove il mouse ha cliccato come colore da cercare
int loc = mouseX + mouseY*video.width;
trackColor = video.pixels[loc];
mouse=1;
}

Blocco G – Torretta automatica

Semplice spiegazione del blocco

[manca immagine della torretta automatica] (da sistemare esteticamente)

La torretta automatica èformato da due servo motori che hanno scopo di spostare il puntatore
laser nello spazio mediante le coordinate x ed y ricevuti tramite la visione artificiale.

Componenti

 Piattaforma di posizionamento telecamera, torretta automatica e giocatore;


 Servo motore SG90 x2;
 Arduino Uno;
 Diodo laser 5V;
 Webcam VF0250;
 Computer.

20
Piattaforma di posizionamento telecamera, torretta automatica e
giocatore

Codice per torretta automatica – ricezione coordinate dalla visione


artificiale e puntamento del bersaglio in tale coordinata
int Laser = 9; //inizializzo il pin9 per il laser
int values[] = {0, 0}; //variabile stringa di lunghezza 2
int currentValue = 0;
#include <Servo.h> //Inserisco la libreria Servo

Servo Servox; //Inizializzo il servo con nome Servox


Servo Servoy; //Inizializzo il servo con nome Servoy

void setup()
{
pinMode(Laser, OUTPUT);
//Il Servox e' collegato al pin digitale 3 che comanda le coordinate X
Servox.attach (3);
// Il Servoy e' collegato al pin digitale 6 che comanda le coordinate Y
Servoy.attach(6);
digitalWrite(Laser, 1);
}
void loop()
{
if (Serial.available() > 0) {
int incomingValue = Serial.read();

values[currentValue] = incomingValue;

21
currentValue++;
if (currentValue > 1) {

currentValue = 0;
Servox.write (map(values[0], 0, 255, 68, 95));
//muove il motore Servox in funzione del valore ricevuto
Servoy.write (map(values[1], 0, 255, 119, 146));
//muove il motore Servoy in funzione del valore ricevuto
delay(3);
Servox.write (map(values[0], 0, 255, 68, 95));
Servoy.write (map(values[1], 0, 255, 119, 146) + 1);
delay(3);
Servox.write (map(values[0], 0, 255, 68, 95));/
Servoy.write (map(values[1], 0, 255, 119, 146) - 1);
delay(3);
//Ampliamente del range di puntamento del nostro laser per rimediare l’errore dovuta dal non idealita’ del
webcame con la torreta
}
}
}

22
Conclusione:

Il progetto funziona come inizialmente ideato.

Si sono riscontrati molte problematiche sulla parte hardware del progetto, per esempio la
luce ambientale che attivava i fototransistor in modo non voluto, per risolvere questo
problema abbiamo abbassato la resistenza da 10kΩ iniziali a 1,8kΩ e inoltre si è aggiunto
una protezione da luce ambientale sul bersaglio.

Si sono riscontrati anche vari problemi sull’installazione delle cinghie per far muovere a
destra e sinistra i bersagli visto che le torri di sostegno non riescono a rimanere fisse.

Inoltre è difficile calibrare bene le coordinate che si riceve dalla webcam con la direzione che
deve puntare il laser, in quanto la webcam e la piattaforma di posizionamento non
rimangono in una posizione fissa.

Per il giocatore è stato costruito una pistola con puntatore laser:

In allegato link con video del progetto funzionante:

https://drive.google.com/open?id=1jpRAaI1MnlYqr8n9EuF60630awDXLr5s

23

Potrebbero piacerti anche