Vier gewinnt auf dem U 64 LED Matrix Panel - AZ-Delivery

Mientras tanto, se ha un desarrollado un animado intercambio de información a través de correo electrónico con nuestro cliente, el Sr. Küster, a quien le debemos el Reloj de Arena Electrónico. Debido a una lesión, tiene mucho tiempo para programar su microcontrolador y esta vez me envió el juego "Conecta cuatro" para dos jugadores en la U 64 LED Matrix Panel CJMCU-8 * 8 con LEDS RGB. Contaba con todas las piezas en casa para el montaje experimental, así que lo probé de inmediato.

4 victorias

Hardware utilizado:

1

Nano V3.0 con chip FT232RL y ATmega328

O: Nano V3.0 con Atmega328 CH340

Alternativamente: Microcontrolador ATmega con 328P

1

U 64 LED Matrix Panel CJMCU-8 * 8 

Mini Breadboard (Breadboard), 3 Botones y Cable de puente (Jumper wire)


hardware

Para el conjunto terminado que se presenta en la imagen, todavía se necesita:

1

Caja

1

Paquete de baterías

1

LM2596S DC-DC Adaptador de fuente de alimentación


Aquí se presenta el diagrama de circuito:

diagrama de circuito
Como sucede a menudo, los programadores de la compañía de Nueva York Adafruit  se han dado el tiempo de librarnos a los usuarios de la parte más difícil de la programación relacionada con el hardware y han desarrollado una librería para la pantalla LED, la cual está a disposición en GitHub o mediante el gestor de librerías. Por lo tanto, se incluye al principio del sketch
#include <Adafruit_NeoPixel.h>. Si no lo ha hecho ya, por favor introduzca Neopixel en la ventana de búsqueda del administrador de la librería (a mí ya se me ha instalado).

administrador de la biblioteca

Como suele ocurrir, Neopixel es una librería para un gran número de pantallas RGBLEDs que tienen una cosa en común a pesar de una amplia variedad de diseños: Además de la fuente de alimentación, hay una sola línea de datos que controla los RGLEDs en serie. Con las líneas:

 En t número = 64;
 Adafruit_neaopixel banda(número, 6, Neo_grb + Neo_khz800);

Por lo tanto, creamos una instancia de nuestro módulo 8x8.

El campo de juego dispone de ocho columnas y siete filas, ya que la fila superior siempre es necesaria para colocar la próxima "Pieza de juego". Empieza el rojo. El LED superior izquierdo se ilumina en rojo y se puede mover en consecuencia con los dos botones para la izquierda (en GPIO9) y la derecha (en GPIO10). El movimiento se completa con el botón central (en GPIO8). El punto luminoso se desplaza hacia abajo hasta donde haya campos libres.

Después de la rutina de prueba para ver si un jugador ya ha alcanzado cuatro casillas del mismo color en horizontal, vertical o diagonal, aparece un LED verde en la parte superior izquierda y el segundo jugador realiza su movimiento de la misma manera. A continuación, vemos otro LED rojo en la parte superior izquierda, y así sucesivamente.

Si la rutina de prueba llega a un resultado positivo, primero los cuatro RGBLEDs parpadean en serie, y, a continuación, toda la pantalla parpadea con los colores del ganador. A continuación, el microcontrolador está listo para la siguiente ronda. Para terminar el juego antes de tiempo, presione simultáneamente los dos botones de dirección.

Aquí está el sketch completo y en forma de descarga:

 # include 
 En t número = 64;
 Adafruit_neaopixel banda(número, 6, Neo_grb + Neo_khz800);
 
 largo rojo = banda.Color(5, 0, 0); largo verde = banda.Color(0, 5, 0); largo color = 0;
 byte zw1 = 0; En t ZW2 = 0; // se utilizan en "Salida Spielfeld"
 byte ZW3 = 0; // se utiliza en la reducción de los juegos de piedras
 byte zw4 = 0; // campo de inicio cuando la prueba
 byte ZW5 = 0; // Zaelwert Inner Loop, ensayos 4 campos
 byte ZW6 = 0; // zaelwert bucle medio, pone a prueba una columna
 byte zw7 = 0; // valor Zael del lazo externo, pone a prueba todas las columnas
 byte zw8 = 0; // piedras caídas
 byte Zwart = 0; // el color ganador edición
 byte ZW10 = 0; // Loeschen Pantalla y campo de juego
 byte SW11 = 0; // parpadear piedras ganadores
 largo COLOR_1 = 0; largo COLOR_2 = 0; // color de ganar
 byte posición 1 = 0; byte Position_2 = 0; byte Position_3 = 0; byte Position_4 = 0; // ganadores de posición
 
 // 0 -> No se utiliza; 1 -> rojo; 2 -> verde
 byte matchfield [64] = {
   1, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0
 };
 
 byte derecho = 10; byte Izquierda = 9; byte abajo = 8; // Número de las cantidad puertos necesarios
 
 byte dirección = 0 ; // 1 -> derecha; 2 -> izquierda; 3 -> abajo
 byte status_start = 1; // 1 -> Red; 2 -> verde
 byte status_spiel = 1 ; // 1 -> Red; 2 -> verde
 byte position_0 = 0; // puntero para el campo
 byte test_rot = 0; byte test_gruen = 0; byte ganador = 0; // Requiere para determinar el ganador
 
 vacío configurar() {
 
   De serie.comenzar(9600);
 
   banda.comenzar();
   banda.show(); // Inicializar todos los píxeles a 'off'
 
   pinMode(derecho, APORTE); digitalWrite (derecho, ELEVADO);
   pinMode(Izquierda, APORTE); digitalWrite (Izquierda, ELEVADO);
   pinMode(abajo, APORTE); digitalWrite (abajo, ELEVADO);
 
   ausgabe_spielfeld ();
 }
 
 vacío lazo() {
 
   // Teclado consulta y saltar en el programa correspondiente
   hacer {
     
     Si (lectura digital de(derecho) == BAJO && lectura digital de(Izquierda) == BAJO) {
       zw8 = 56;
       test_spielende ();
    };
     Si ( lectura digital de(derecho) == BAJO) {
       dirección = 1; rechts_0 ();
    }
     Si ( lectura digital de(Izquierda) == BAJO) {
       dirección = 2; links_0 ();
    }
     Si ( lectura digital de(abajo) == BAJO) {
       Si (matchfield [position_0 + 8] == 0) {
         dirección = 3;
         runter_0 (); zw8 ++; // Número Durchlaeufe + 1
         test_spielende ();
      };
    }
  }
   tiempo ( dirección == 0);
   dirección = 0; // dirección Loesch Ender
 
 
   ausgabe_spielfeld ();
   demora(300);
 }
 
 // ------------- prueba si hay un ganador ------------------
 // ---------- programa se llama después de bajar una piedra
 vacío test_spielende () {
 
   // ----------- ------------ prueba en diagonal por encima de
   // ---------- ---------- 3 verschaltelte ciclos
 
   zw4 = 32; // campo de inicio cuando la prueba
   ganador = 0; zw7 = 0;
 
   hacer {
     ZW6 = 0;
 
     hacer {
       ZW5 = 0; // Zaelschleife
       test_rot = 0; test_gruen = 0;
 
       // Prueba 4 células diegonal anteriormente
       hacer {
         Si ( matchfield [zw4] == 1) {
           test_rot ++;
        };
         Si ( matchfield [zw4] == 2) {
           test_gruen ++;
        };
 
         // Tenga en cuenta la posición de la victoria
         Si (ganador == 0) {
           Si (ZW5 == 0) {
             posición 1 = zw4;
          };
           Si (ZW5 == 1) {
             Position_2 = zw4;
          };
           Si (ZW5 == 2) {
             Position_3 = zw4;
          };
           Si (ZW5 == 3) {
             Position_4 = zw4;
          };
        };
 
         zw4 = zw4 - 7; ZW5++;
      }
       tiempo (ZW5 != 4);
 
       Si (test_rot == 4) {
         ganador = 1;
      } demás {
         test_rot = 0;
      };
       Si (test_gruen == 4) {
         ganador = 2;
      } demás {
         test_gruen = 0;
      };
       zw4 = zw4 + 36; ZW6++;
       Si (ganador != 0) {
         ZW6 = 4;
      };
    }
     tiempo ( ZW6 != 4);
 
     zw4 = zw4 - 31; zw7++;
     Si (ganador != 0) {
       zw7 = 5;
    };
  }
   tiempo (zw7 != 5);
 
   // ----------- ----------- prueba diagonal hacia abajo
   // ---------- ---------- 3 ciclos anidados
 
   zw4 = 8; // campo de inicio cuando la prueba
   zw7 = 0;
 
   hacer {
     ZW6 = 0;
 
     hacer {
       ZW5 = 0; // bucle de conteo
       test_rot = 0; test_gruen = 0;
 
       // células de prueba 4 en diagonal hacia abajo
       hacer {
         Si ( matchfield [zw4] == 1) {
           test_rot ++;
        };
         Si ( matchfield [zw4] == 2) {
           test_gruen ++;
        };
 
         // Tenga en cuenta la posición de la victoria
         Si (ganador == 0) {
           Si (ZW5 == 0) {
             posición 1 = zw4;
          };
           Si (ZW5 == 1) {
             Position_2 = zw4;
          };
           Si (ZW5 == 2) {
             Position_3 = zw4;
          };
           Si (ZW5 == 3) {
             Position_4 = zw4;
          };
        };
 
         zw4 = zw4 + 9; ZW5++;
      }
       tiempo (ZW5 != 4);
 
       Si (test_rot == 4) {
         ganador = 1;
      } demás {
         test_rot = 0;
      };
       Si (test_gruen == 4) {
         ganador = 2;
      } demás {
         test_gruen = 0;
      };
       zw4 = zw4 - 28; ZW6++;
       Si (ganador != 0) {
         ZW6 = 4;
      };
    }
     tiempo ( ZW6 != 4);
 
     zw4 = zw4 - 31; zw7++;
     Si (ganador != 0) {
       zw7 = 5;
    };
  }
   tiempo (zw7 != 5);
 
   // ------------ perpendicular prueba ---------------
   // ---------- ---------- 3 verschaltelte ciclos
 
   zw4 = 8; // campo de inicio cuando la prueba
   zw7 = 0;
   hacer {
     ZW6 = 0;
 
     hacer {
       ZW5 = 0; // zaelschleife
       test_rot = 0; test_gruen = 0;
 
       // prueba 4 células perpendicular
       hacer {
         Si ( matchfield [zw4] == 1) {
           test_rot ++;
        };
         Si ( matchfield [zw4] == 2) {
           test_gruen ++;
        };
 
         // Tenga en cuenta la posición de la victoria
         Si (ganador == 0) {
           Si (ZW5 == 0) {
             posición 1 = zw4;
          };
           Si (ZW5 == 1) {
             Position_2 = zw4;
          };
           Si (ZW5 == 2) {
             Position_3 = zw4;
          };
           Si (ZW5 == 3) {
             Position_4 = zw4;
          };
        };
 
         zw4 = zw4 + 8; ZW5++;
      }
       tiempo (ZW5 != 4);
 
       Si (test_rot == 4) {
         ganador = 1;
      } demás {
         test_rot = 0;
      };
       Si (test_gruen == 4) {
         ganador = 2;
      } demás {
         test_gruen = 0;
      };
       zw4 = zw4 - 24; ZW6++;
       Si (ganador != 0) {
         ZW6 = 4;
      };
    }
     tiempo ( ZW6 != 4);
 
     zw4 = zw4 - 31; zw7++;
     Si (ganador != 0) {
       zw7 = 8;
    };
  }
   tiempo (zw7 != 8);
 
   // ------------- -------------- Nivel de prueba
   // ---------- ---------- 3 ciclos anidados
   zw4 = 8; // campo de inicio cuando la prueba
   zw7 = 0;
   hacer {
     ZW6 = 0;
 
     hacer {
       ZW5 = 0;
       test_rot = 0; Test_gruen = 0;
 
       // test 4 celdas horizontalmente
       hacer {
         SI ( matchfield [zw4] == 1) {
           test_rot ++;
        };
         SI ( matchfield [zw4] == 2) {
           Test_gruen ++;
        };
 
         // nota de la posición en la victoria
         SI (ganador == 0) {
           SI (ZW5 == 0) {
             posición 1 = zw4;
          };
           SI (ZW5 == 1) {
             Position_2 = zw4;
          };
           SI (ZW5 == 2) {
             Position_3 = zw4;
          };
           SI (ZW5 == 3) {
             Position_4 = zw4;
          };
        };
 
         zw4++; ZW5++;
      }
       Tiempo (ZW5 != 4);
 
       SI (test_rot == 4) {
         ganador = 1;
      } Demás {
         test_rot = 0;
      };
       SI (Test_gruen == 4) {
         ganador = 2;
      } Demás {
         Test_gruen = 0;
      };
       zw4 = zw4 + 4; ZW6++;
       SI (ganador != 0) {
         ZW6 = 7;
      };
    }
     Tiempo ( ZW6 != 7);
 
     zw4 = zw4 - 55; zw7++;
     SI (ganador != 0) {
       zw7 = 5;
    };
  }
   Tiempo (zw7 != 5);
 
   // colores ganador Conjunto
   SI (ganador == 1) {
     COLOR_1 = rojo;
     COLOR_2 = rojo;
     El fin (); // edición ganador de color rojo
  };
   SI (ganador == 2) {
     COLOR_1 = verde;
     COLOR_2 = verde;
     El fin (); // edición ganador de color verde
  };
   SI (zw8 == 56 ) {
     COLOR_1 = verde;
     COLOR_2 = rojo;
     El fin (); // sorteo edición
  };
 
   posición 1 = 0; Position_2 = 0; Position_3 = 0; Position_4 = 0;
   test_rot = 0; Test_gruen = 0;
 }
 
 // ---------- ----------- edición de color ganador
 
 vacío El fin () {
   SW11 = 0;
 
   SI (zw8 != 56 ) {
     hacer {
       banda.SetpixelColor ( posición 1, 0, 0, 0);
       banda.Setpixelcolor ( Position_2, 0, 0, 0);
       banda.SetpixelColor ( Position_3, 0, 0, 0);
       banda.SetpixelColor ( Position_4, 0, 0, 0);
       banda.show(); demora(200);
       banda.Setpixelcolor ( posición 1, COLOR_1);
       banda.Setpixelcolor ( Position_2, COLOR_1);
       banda.SetpixelColor ( Position_3, COLOR_1);
       banda.SetpixelColor ( Position_4, COLOR_1);
       banda.show(); demora(200);
       SW11++;
    }
     Tiempo ( SW11 != 5);
  }
 
   Zwart = 0;
   hacer {
     banda.SetpixelColor ( Zwart, COLOR_1); Zwart++;
     banda.SetpixelColor ( Zwart, COLOR_2); Zwart++;
  }
   Tiempo (Zwart != 64);
   banda.show();
 
   demora(2000);
 
   // Preparación ---------- ----------- nuevo comienzo
 
   ZW10 = 0;
   hacer {
     banda.SetpixelColor ( ZW10, 0, 0, 0); matchfield [ZW10] = 0;
     ZW10++;
  }
   Tiempo ( ZW10 != 64);
   banda.show();
 
   matchfield [0] = 1; edition_spielfeld ();
   zw1 = 0; ZW2 = 0; ZW3 = 0; zw4 = 0; ZW5 = 0; ZW6 = 0; zw7 = 0; zw8 = 0; Zwart = 0; ZW10 = 0;
   posición 1 = 0; Position_2 = 0; Position_3 = 0; Position_4 = 0;
   Position_0 = 0;
 
   // cambia de color inicio del juego
   COLOR_1 = 0; COLOR_2 = 0; ganador = 0;  
 
   SI (Status_start == 1) {
     color = verde; Status_spiel = 2;Status_start=2;
     matchfield [0] = 2;
  } Demás {
     color = rojo;
     matchfield [0] = 1; Status_piel = 1;Status_start=1;
  };
   
   edition_spielfeld ();
 }
 
 // ---------- un paso a la izquierda ------------------
 vacío left_0 () {
   SI (Position_0 != 0) {
     matchfield [Position_0] = 0;
     Position_0--;
     matchfield [ Position_0 ] = Status_spiel;
  };
 }
 
 // ---------- un paso a la derecha -----------
 vacío right_0 () {
   SI (Position_0 != 7) {
     matchfield [Position_0] = 0;
     Position_0++;
     matchfield [ Position_0 ] = Status_spiel;
  };
 }
 
 // ---------- hundimiento de la Piedra juego -----------
 vacío Runter_0 () {
   ZW3 = 0;
   hacer {
     SI (matchfield [Position_0 + 8] == 0 ) {
       matchfield [Position_0] = 0; Position_0 = Position_0 + 8; matchfield [Position_0] = Status_piel;
       ZW3++;
       edition_spielfeld (); demora(200);
    }
     Demás {
       ZW3 = 7;
    }
  }
   Tiempo (ZW3 != 7) ;
   dirección = 0; Position_0 = 0;
   SI (Status_spiel == 1 ) {
     Status_piel = 2;
     matchfield [Position_0] = 2;
  } Demás {
     Status_piel = 1;
     matchfield [Position_0] = 1;
  };
   edition_spielfeld ();
 }
 
 // ---------- ----------- campo de juego edición
 vacío edition_spielfeld () {
   zw1 = 0;
 
   hacer {
     ZW2 = matchfield [zw1];
     SI (ZW2 == 0) {
       banda.SetpixelColor ( zw1, 0, 0, 0);
    };
     SI (ZW2 == 1) {
       banda.SetpixelColor ( zw1, rojo);
    };
     SI (ZW2 == 2) {
       banda.SetpixelColor ( zw1, verde);
    };
     zw1++;
  }
   Tiempo (zw1 != 64);
   banda.show();
 }
 
 // huk cuatro gewinnt_4.4 27.07.2021

Como alternativa, también puede jugar "Cuatro Victorias" en el Set de Carcasa de Pared AZ-Touch. Jörn Weise había presentado esta alternativa en su Blog el 3 de julio 2021.

Las dos versiones presentadas están diseñadas para dos jugadores y, además de la estupenda pantalla, ofrecen la posibilidad de comprobar si un jugador ya ha ganado. Para aquellos que quieran jugar contra un ordenador con un juego fuerte, se recomienda la versión de Al Sweigart en la Raspberry Pi. Para mi vergüenza, tengo que admitir que pierdo de vez en cuando. Entonces, ¿prefiere jugar contra mi nieta con el sketch del Sr. Küster en el U 64 LED Matrix Panel CJMCU-8 * 8?


Diviértase construyendo y jugando.

DisplaysFür arduinoProjekte für anfänger

9 comentarios

Andreas Wolter

Andreas Wolter

@mircemk: you have to change the order in the array “byte spielfeld 64”. But it’s difficult to change that. The odd rows (if start with 1) should be the same and the even rows are mirrored. Sorry but you hav to search the parts by yourself step by step.

If you find a solution please tell us.

Best regards,
Andreas Wolter
AZ-Delivery Blog

mircemk

mircemk

Hello,
My matrix is slightly different from yours ie. the diodes light up one by one in a zig zag pattern, and with yours each new row starts on the left. What code modification do I need to do. Do you have an idea?
Thank you

Andreas Wolter

Andreas Wolter

@René: Wenn auch mit den Testsketches die LED nicht eingeschaltet wird, gehe ich davon aus, dass in dem Modul etwas nicht korrekt verlötet ist. SIe könnten versuchen, einen Testsketch so anzupassen, dass genau diese LED eingeschaltet wird. Wenn diese nicht leuchtet, müssen Sie den Support kontaktieren und das Modul austauschen lassen.

Grüße,
Andreas Wolter
AZ-Delivery Blog

René

René

Hi,
also auch mit einem Test-Sketch/Beispiel Sketch aus der Neopixel Bibliothek bleibt die erste LED dunkel. Keine Ahnung warum das so ist.
Wenn man das 4-Gewinnt Programm startet, dann ist es ja auch so, dass die erste LED dunkel ist und man eben direkt bei der zweiten startet. Also entweder ist das Modul defekt oder irgendein anderer Fehler ist vorhanden.
Habe beides, Board und Matrix bei euch bezogen.

Andreas Wolter

Andreas Wolter

@Renè: haben Sie am Programm änderungen vorgenommen?
Wenn nicht, empfehle ich, ein Testprogramm auf den MC zu laden, um zu sehen, ob die LEDs alle ordnungsgemäß angesprochen werden.

Unser Blogautor Bernd Albrecht hat den Sketch nochmal getestet und er funktioniert so wie er soll.
Ich denke aber, dass wir den Fehler finden werden.

Grüße,
Andreas Wolter
AZ-Delivery Blog

René

René

Ich habe jetzt einen Fehler im Programm:
Beim Start des Arduinos wird nicht das ganz oben, ganz links befindliche LED rot aktiviert sondert immer ganz oben und eins nach rechts.
Hab versucht das zu finden, aber kann es sein, dass die LED Matrix falsch initialisiert wird?

René

René

Super, vielen Dank.

Andreas Wolter

Andreas Wolter

Wir haben den Link zum Gehäuse ergänzt. Es ist kein 3D-Modell für den Drucker.

Außerdem hat uns Herr Küster ein Update zur Verfügung gestellt, das Sie jetzt ebenfalls im Beitrag finden.

Mit freundlichen Grüßen,
Andreas Wolter
AZ-Delivery Blog

René

René

Cooles Projekt, würde ich gern nachbauen aber den Hinweis zum Gehäuse finde ich sehr lustig ;)
Könntet ihr vielleicht erwähnen welches ihr dazu genutzt habt?
Oder noch besser wäre, wenn das eine stl für einen 3D-Druck wäre ;)

Deja un comentario

Todos los comentarios son moderados antes de ser publicados