Ciao a tutti,
un mio amico mi ha chiesto se è possibile realizzare il gioco del tris nel seguente modo:
- n°1 scatola con 9 led bi-colore collegati ad arduino
- n°2 pulsantiere separate (una per giocatore); anche queste gestite da arduino
Quello che si vorrebbe realizzare è il seguente:
-se il giocatore uno accende il primo led in alto per esempio (colore rosso), al secondo giocatore venga negata la possibilità di accendere tale led di verde (si otterrebbe così un colore arancione essendo i led bi-colore)
-questo meccanismo ripetuto per tutti e 9 i led
-quando un giocatore realizza un tris. fare lampeggiare i 3 led del tris e avviare una nuova partita dopo un certo tempo
-salvare il punteggio dei due giocatori su due display 7 segmenti differenti
Secondo voi è fattibile come cosa?
sto cercando di dividere il problema in semblici blocchi, e il primo dubbio che mi sorge è come memorizzare che un led è acceso per esempio di verde e impedire all'avversario di accendere lo stesso led.
Devo utilizzare degli array per caso?
grazie a tutti 
ciao
fiodavid
fiodavid:
il primo dubbio che mi sorge è come memorizzare che un led è acceso per esempio di verde e impedire all'avversario di accendere lo stesso led.
Crea una matrice 3x3, "byte myMatrix[3,3];"se la cella contiene 0 è libera, se contiene 1 è verde, se contiene 2 è rosso, prima di aggiornare lo stato della cella controlli che valore contiene, solo se è 0 puoi settare il colore a seconda del giocatore.
per astrobeed: ti ringrazio. Potresti postarmi un codice di esempio per capire meglio la sintassi che dovrei usare? non ho mai gestito matrici con arduino (oppure se puoi passarmi qualche link dove posso trovare degli esempi di tale utilizzo)
grazie mille
ciao
fiodavid
Ti basta guardare nel refernce che trovi su Learning - Reference menu in alto.
Poi la gestisci come la battaglia navale, ogni casella ha le sue coordinata, attenzione che parti da 0 quindi la prima sarà [0,0].
Se hai difficoltà con la matrice a due indici, potresti anche farne una ad un solo indice di 9 elementi e numerare ad una ad una le caselle ma ti verrà più difficile la parte... complicata, ovvero capire quando hai fatto tris.
Ciao a tutti,
al momento sto provando a scrivere il codice che se premo il pulsante per accendere il led verde si accende il led verde e resta acceso,mentre se premo il led rosso non si accende il led rosso.
Voglio che si accenda un led alla volta e fino a quando il primo led che ho acceso non si spegne, il secondo led non si può accendere.
Secondo voi questo codice può funzionare:
#define LED_VERDE 13
#define LED_ROSSO 12
#define LED_VERDE_ON 10
#define LED_ROSSO_ON 11
#define LED_VERDE_OFF 12
#define LED_ROSSO_OFF 13
#define ALL_LED_OFF 20
#define PULSANTE_VERDE 3
#define PULSANTE_ROSSO 4
int statoPrecedentePulsante=0;
int stateLED_VERDE=0;
int stateLED_ROSSO=0;
int countPULSANTE=0;
char led=0;
char statePULSANTE=0; //lavoro a bit
char stateLED=0; //lavoro a bit
int gestioneLED(int led){
switch(led) {
case LED_VERDE_ON:
digitalWrite(LED_VERDE,HIGH);
break;
case LED_ROSSO_ON:
digitalWrite(LED_ROSSO,HIGH);
break;
case LED_VERDE_OFF:
digitalWrite(LED_VERDE,LOW);
break;
case LED_ROSSO_OFF:
digitalWrite(LED_ROSSO,LOW);
break;
case ALL_LED_OFF:
digitalWrite(LED_VERDE,LOW);
digitalWrite(LED_ROSSO,LOW);
break;
}
}
void setup() {
// put your setup code here, to run once:
pinMode(LED_VERDE,OUTPUT);
pinMode(LED_ROSSO,OUTPUT);
pinMode(PULSANTE_VERDE,INPUT);
pinMode(PULSANTE_ROSSO,INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int statoPulsante=0;
int statoLED=0;
statoPulsante=digitalRead(PULSANTE_VERDE);
if (statoPulsante==HIGH){
statePULSANTE|=0x01 ; //pulsante LED VERDE
}
statoPulsante=digitalRead(PULSANTE_ROSSO);
if (statoPulsante==HIGH){
statePULSANTE|=0x02; //PULSANTE LED ROSSO
}
statoLED=digitalRead(LED_VERDE);
if(statoLED==HIGH){
stateLED|=0x01; //LED VERDE ON
}
statoLED=digitalRead(LED_ROSSO);
if(statoLED==HIGH){
stateLED|=0x02; //LED ROSSSO ON
}
if(statoPulsante!=statoPrecedentePulsante){
if (statePULSANTE==0x01){
gestioneLED(LED_VERDE_ON);
}
if (statePULSANTE==0x02){
gestioneLED(LED_ROSSO_ON);
}
if (statePULSANTE==0x01 && statePULSANTE==0x02){
gestioneLED(ALL_LED_OFF);
}
}
}
Grazie a tutti
Ciao
fiodavid
Lavori presso l'UCCS (Ufficio Complicazione Cose Semplici) ?
per paulus1969: no :), solo che come mi dicevi di fare tu, non ho trovato esempi
e allora ho provato a fare diversamente 
paulus1969:
Lavori presso l'UCCS (Ufficio Complicazione Cose Semplici) ?
Forse lavora presso l'UCCAS (Ufficio Centrale Complicazione Affari Semplici). 
può essere 
A parte gli scherzi
, riusciresti a passarmi un esempio?
byte map[9] ={0};
byte inlut[9] = {0,1,2,3,4,5,6,7,8};// pin input
byte oulut[2][9]={{10,11,12,13,14,15,16,17,18},
{19,20,21,22,23,24,25,26,27}};//pin output
byte player = 0;
...
...
void loop()
{
while (1)
{
for ( i = 0; i < 9, ++i )
if ( digitalRead(lut[i]) ) break;
delay(150);
if ( i < 9 && digitalRead(inlut[i]) && map[i] == 0 ) break;
}
map[i] = player;
digitalWrite(oulut[player][i],1);
player = !player;
}
l'ho scritto dal phone e non con la presunzione di postare codice funzionante ma per darti una dritta.
se invece di usare una matrice usi un vettore allora l'indice del pulsante premuto corrisponderà all'indice dell 'output che corrisponderà alla mappa.
Ora va adattato al tuo circuito con i dovuti accorgimenti.
per vbextreme: ti ringrazio per il codice di esempio, provo a lavorarci su. 
scusa la domanda: quando scrivi nel codice if ( digitalRead(lut*) ) break;[/b], "lut" non l'hai definito come array, non devi definirlo?*
scusa la mia ignoranza con gli array 
ciao
fiodavid
scusa, ma dal phone mi è scappato l'in, ovvero quella deve essere "inlut" e non "lut".
ma come colleghi i led?
9 per giocatore sono 18 led....non li attacchi tutti uno a uno vero?
c'è poi la matrice di pulsanti, come l'hai fatta? come la vuoi gestire?
senza nessun integrato extra la soluzione piu elementare è questa:
d0#-----\
d1#-----|---\
d2#-----|---|----\
| | |
d3#-----L1---L1---L1
L2---L2---L2-----#d6
d4#-----L1---L1---L1
L2---L2---L2-----#d7
d5#-----L1---L1---L1
L2---L2---L2-----#d8
d9 #-----\
d10#-----|---\
d11#-----|---|---\
| | |
d12#-----P---P---P
d13#-----P---P---P
a0 #-----P---P---P
[code]
per vbextreme ti spiego la mia idea:
-i led sono 9 perchè sono bi-colore (fanno verde e rosso); i led hanno 3 pin (ma forse li trovo anche a 2 pin); se sono a 3 pin collego il comune a massa con relativa resistenza e gli altri 2 pin a due pin digitalI/O differenti di arduino
-le pulsantiere sono due (una per giocatore) i pulsanti li collego agli ingressi analogici di arduino,tramite dei partitori di tensione, così in base al valore di tensione letto, so quale tasto ho premuto
-la mia idea è quella di utilizzare un arduino mega in modo che gli ingressi analogici li uso per le 2 pulsantiere (18 pulsanti totali, e pensavo di collegarne almeno 3 per ingresso analogico tramite partitore di tensione) e i 9 led bi-colore collegarli alle digital I/O
-2 ulteriori led (uno rosso e uno verde) che si accendono random in base alla pressione di un pulsante (per decidere chi inizia la partita)
-quando un giocatore realizza un tris, vorrei fare lampeggiare i 3 led del relativo tris e far suonare un buzzer
-in aggiunto, ma devo vedere se mi bastano i pin, vorrei aggiungere 2 display 7 segmenti per salvare il punteggio realizzato da ogni singolo giocatore
Pultroppo al momento non ho ancora fatto lo schema, ma conto di farlo appena possibile
Secondo te può funzionare la cosa?
Grazie per le dritte e per i consigli
Ciao
fiodavid
Si può fare.
Verrebbe più facile con un touch-screen, ma sarebbe diverso.
Vuoi mettere una tastiera per ognuno (ne basterebbe una sola, tanto si agisce a turni, ma se ne vuoi due...), una tastiera la gestisci anche con una porta analogica quindi 2 porte analogiche per le tastiere.
Poi ti serve il buzzer, una porta digitale.
Quindi i LED. Sono bicolore, quindi due porte digitali per ogni LED, 18 porte digitali a meno di usare cose più complicate ma tanto se usi la Mega ne hai una cinquantina. Più un'altra porta per un altro LED bicolore che indica il turno (ed anche chi inizia e volendo anche chi ha vinto).
Lasciamo perdere al momento il calcolo della corrente necessaria per accendere 10 LED, in teoria dovresti farlo per vedere se andare direttamente dalle I/O o mettere dei transistor, per buona abitudine si fa sempre.
Siamo a 20 porte digitali e 2 porte analogiche.
Rimangono i display a segmenti per il punteggio.
Ti conviene mettere un display LCD.
Più semplice, più flessibile, più bello.
Certo, con quanto ti costa, ne compri di matite per fare il tris normale
ma vuoi mettere la soddisfazione... e poi se dopo un po' vuoi fare altro, recuperi praticamente tutto l'hardware.
Veniamo al software.
Piccola sfida....
te la sentiresti di fare un programma che consente anche una modalità allenamento per una sola persona?
Se lo scrivi bene, te ne accorgi dal fatto che pareggia sempre (o vince se sbaglia l'umano). Casomai puoi mettere il "livello facile" a scopo didattico per i giovanissimi...
penso che il collegamento diretto alla board sia un po eccessivo.
come mostrato nello schema postato sopra bastano 3+3 pin x matrice usata e questa è una configurazione semplice e molto utile da imparare.
Certo si potrebbe usare anche il tristate dei pin ma forse sarebbe eccessivo.
in quella configurazione ti servono 6+3+6+3 pin in totale 18 per 2 matrici da 3*3 e 2 matrici di pulsanti.
ti rimane parecchio per extra, rimango dell'idea di percorrere un passo alla volta.
Prima fase connettere la matrice di led e creare una funzione che legga la matrice e la visualizziamo.
Seconda fase leggere lo stato dei pin e visualizzarli a "monitor" (matrice).
Terza fase espandere il tutto * 2
quarta fase si inizia col gioco.
Non è un progetto semplice, io ho letto un intero libro sul gioco del tris, non dedicato ad Arduino ma agli algoritmi in generale.
Siamo qua, facci sapere se hai bisogno
dimenticato, con lo schema sopra si potrebbe fare:
byte map[3][3]={0};
byte lx[3]={0,1,2};
byte ly[3]={3,4,5};
byte ix[3]={9,10,11};
byte iy[3]={12,13,14};
void refresh()
{
byte y,x;
for( y=0; y<3; ++y)
{
for(x=0; x<3; ++x)
{
digitalWrite(lx[x],map[y][x]);
digitalWrite(ly[y],!map[y][x]);
}
}
}
byte pulsantiera(byte* ry, byte* rx)
{
byte y,x,b;
for( y=0; y<3; ++y)
{
for(x=0; x<3; ++x)
{
b=0;
BOUNCE:
digitalWrite(ix[x],1);
if ( digitalRead(iy[y])
{
delay(10);
if(!b++) goto BOUNCE;
digitalWrite(ix[x],0);
*ry = y;
*rx = x;
return 1;
}
digitalWrite(ix[x],0);
}
}
return 0;
}
... setup ...
for pin in lx = output = 0
for pin in ly = output = 1
for pin in ix = output = 0
for pin in iy = input
void loop()
{
byte y,x;
if ( pulsantiera( &y,&x) )
map[y][x] = !map[y][x];
refresh();
}
come detto sopra questo vuole solo essere un esempio, essendo scritto dal phone non soffermati sui puntini ma cerca di capirne la logica.
Tale argomento sarebbe da approfondire con una semplice ricerca quale "Arduino matrice di led"
questo è quello che ho fatto al momento senza usare le matrici però, ma solo con 2 led separati (lo avevo già scritto prima che mi rispondavate)
#define LED_VERDE 13
#define LED_ROSSO 12
#define LED_VERDE_ON 10
#define LED_ROSSO_ON 11
#define LED_VERDE_OFF 12
#define LED_ROSSO_OFF 13
#define ALL_LED_OFF 20
#define PULSANTE_VERDE 3
#define PULSANTE_ROSSO 4
int statePrecedentePulsante=0;
int stateLED_VERDE=0;
int stateLED_ROSSO=0;
int countPULSANTE=0;
char led=0;
char statePULSANTE=0; //lavoro a bit
char stateLED=0; //lavoro a bit
int gestioneLED(char led){
if (led & 0x01) { // led verde acceso
digitalWrite(LED_VERDE,HIGH);
}else{
digitalWrite(LED_VERDE,LOW);
}
if (led & 0x02) { // led rosso acceso
digitalWrite(LED_ROSSO,HIGH);
}else{
digitalWrite(LED_ROSSO,LOW);
}
}
void setup() {
// put your setup code here, to run once:
pinMode(LED_VERDE,OUTPUT);
pinMode(LED_ROSSO,OUTPUT);
pinMode(PULSANTE_VERDE,INPUT);
pinMode(PULSANTE_ROSSO,INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int statoPulsante;
statoPulsante=digitalRead(PULSANTE_VERDE);
if (statoPulsante==HIGH){
statePULSANTE|=0x01 ; //pulsante LED VERDE
}
statoPulsante=digitalRead(PULSANTE_ROSSO);
if (statoPulsante==HIGH){
statePULSANTE|=0x02; //PULSANTE LED ROSSO
}
if(statePULSANTE!=statePrecedentePulsante){ // è cambiato qualcosa nei tasti
if (statePULSANTE==0x01){ // solo verde
if (!(stateLED & 0x02)){ // se rosso spento
stateLED ^= 0x01; // commuta il verde
}
}
if (statePULSANTE==0x02){ // solo rosso
if (!(stateLED & 0x01)){ // se verde spento
stateLED ^= 0x02; // commuta il rosso
}
}
gestioneLED(stateLED);
statePrecedentePulsante = statePULSANTE;
}
}
}
e funziona correttamente. Vorrei aggiungere un pulsante per fare il reset e ricominciare con i controlli e ho aggiunto il seguente codice dopo la riga statePrecedentePulsante = statePULSANTE; :
statoPulsante=digitalRead(PULSANTE_RESET);
if (statoPulsante==HIGH){
digitalWrite(LED_VERDE,LOW);
digitalWrite(LED_ROSSO,LOW);
}
ma non funziona; sapete dirmi dove sbaglio?
Per passare a realizzare il tutto con la matrice, pensavo di realizzare lo schema elettrico per capire meglio il funzionamento. Appena ho l'ho buttato giù, lo posto così mi dite se può andare 
Ciao
fiodavid
è un po contorto!
#define LED_VERDE 13
#define LED_ROSSO 14
#define PULSANTE_VERDE 3
#define PULSANTE_ROSSO 4
#define PULSANTE_RESET 5
byte led=0;
void gestioneLED(byte l)
{
led = l;
if (led)
{
digitalWrite(led,HIGH);
return;
}
digitalWrite(LED_VERDE,LOW);
digitalWrite(LED_ROSSO,LOW);
}
byte buttonPress(byte pin)
{
if ( !digitlRead(pin) ) return 0;
delay(150);
return digitalRead(pin);
}
void setup() {
// put your setup code here, to run once:
pinMode(LED_VERDE,OUTPUT);
pinMode(LED_ROSSO,OUTPUT);
pinMode(PULSANTE_VERDE,INPUT);
pinMode(PULSANTE_ROSSO,INPUT);
pinMode(PULSANTE_RESET,INPUT);
}
void loop()
{
if ( led )
{
if ( buttonPress(PULSANTE_RESET))
led = 0;
gestioneLED(0);
return;
}
if ( buttonPress(PULSANTE_VERDE) )
{
gestioneLED(LED_VERDE);
return;
}
if ( buttonPress(PULSANTE_ROSSO) )
gestioneLED(LED_ROSSO);
}
ho cercato di ripulire il codice senza ottimizzare niente in modo che rimanga comprensibile
per vbextreme: ti ringrazio per il codice; l'ho provato e il comportamento è il seguente:
-premo pulsante led rosso si accende led rosso
-premo pulsante led verde si accende led verde
- premo prima pulsante led rosso e tenendo premuto tale pulsante, premo pulsante led verde: si accende il led verde e si spegne quello rosso
-premo prima pulsante led verde e tenendo premuto tale pulsante, premo pulsante led rosso:resta acceso led verde
-premo reset e non succede niente.
Quello che deve fare è:
-se premo pulsante led verde resta acceso led verde ma se premo pulsante led rosso, non succede niente
-premo reset e si resatta tutto
-se premo pulsante led rossoresta acceso led rosso ma se premo pulsante led verde, non succede niente
Ti faccio sapere cosa riesco a fare sistemando il tuo codice
Intanto ti allego al post lo schema della matrice led con le connessioni ad arduino
Grazie mille 
ciao
fiodavid
tris_V1.0.pdf (13.3 KB)
#define LED_VERDE 13
#define LED_ROSSO 14
#define PULSANTE_VERDE 3
#define PULSANTE_ROSSO 4
#define PULSANTE_RESET 5
byte led=0;
void gestioneLED(byte l)
{
led = l;
if (led)
{
digitalWrite(led,HIGH);
return;
}
digitalWrite(LED_VERDE,LOW);
digitalWrite(LED_ROSSO,LOW);
}
byte buttonPress(byte pin)
{
if ( !digitlRead(pin) ) return 0;
delay(150);
return digitalRead(pin);
}
void setup() {
// put your setup code here, to run once:
pinMode(LED_VERDE,OUTPUT);
pinMode(LED_ROSSO,OUTPUT);
pinMode(PULSANTE_VERDE,INPUT);
pinMode(PULSANTE_ROSSO,INPUT);
pinMode(PULSANTE_RESET,INPUT);
}
void loop()
{
if ( led )
{
if ( buttonPress(PULSANTE_RESET))
{
led = 0;
gestioneLED(0);
}
return;
}
if ( buttonPress(PULSANTE_VERDE) )
{
gestioneLED(LED_VERDE);
return;
}
if ( buttonPress(PULSANTE_ROSSO) )
gestioneLED(LED_ROSSO);
}
scusa mi era scappata una graffa, cosi dovrebbe andare, controlla che la define PULSANTE_RESET corrisponda al tuo pin del pulsante io ho messo 5 a caso