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.
Hardware utilizado:
1 |
Nano V3.0 con chip FT232RL y ATmega328 O: Nano V3.0 con Atmega328 CH340 Alternativamente: Microcontrolador ATmega con 328P |
|
1 |
||
Mini Breadboard (Breadboard), 3 Botones y Cable de puente (Jumper wire) |
Para el conjunto terminado que se presenta en la imagen, todavía se necesita:
1 |
Caja |
|
1 |
Paquete de baterías |
|
1 |
Aquí se presenta el 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).
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:
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.
9 comentarios
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
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
@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é
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
@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é
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é
Super, vielen Dank.
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é
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 ;)