Arduino Snake Game con strip ws2812

Ciao a tutti. Ho visto diversi tutorial su internet su come creare questo gioco, e li ho anche provati, ma nessuno mi ha dato come risultato il gioco funzionante.
Molti sketch che si trovano su internet hanno tutto: codice, video dimostrativo, spiegazioni, ma... Non ti danno i collegamenti.
Io ho trovato un codice su internet, molto interessante, che potrebbe servirmi (sto cercando di creare questo progetto non per me, ma per i bambini del mio oratorio estivo in cui vado)
L'unico problema di quello sketch è che... Non va. Non va con i miei led, e non ne so il motivo.
Lui usa una matrice led 16x16, mentre io ne uso una 10x10.
Ho provato a modificare il codice (cambiando i numeri di dichiarazione) ma niente di niente, non va.

Inoltre, l'altra differenza, è che lui ha una vera e propria matrice led 16x16 prefabbricata, mentre io uso una strip led con chip ws2812, tagliata ogni 10 led e saldata correttamente come se avessi ancora la strip intatta. (in questo modo ottengo un quadrato 10x10)

Ora, forse i collegamenti tra i led della matrice prefabbricata e la mia sono differenti, non lo so... Fatto sta che non funziona niente, e vorrei chiedere il vostro aiuto.
Vi lascio il link del video, dove nella descrizione potete trovare il codice e il circuito in file fritzing.

Grazie in anticipo a chi proverà ad aiutarmi

Ale

diciamo che il concetto è parecchio diverso...

nell'esempio che segui, hai una matrice di led indirizzabile da una coppia di coordinate x e y che identificano un punto, nella tua soluzione i led sono tutti in serie uno all'altro quindi pur non essendo impossibile, la gestione di un programma come lo snake diventa piuttosto elaborata...

Riusciresti ad aiutarmi...? Per favore..
Ci tengo a questo progetto
Altrimenti se avessi lo schema di collegamento della matrice, forse si potrebbe replicare.
Riusciresti ad aiutarmi?

Lui usa le strip, però non riesco a farlo andare:

Cosa vuol dire "non riesco a farlo andare"?
Posta il tuo codice

Il mio codice è quello lì. Ho solo modificato i numeri che dichiarano la grandezza della matrice, ma non funziona

il problema è che io uso una strip led e non una matrice, e non so come far andare il gioco, perchè con gli sketch che trovo su internet non ne va neanche uno

ESEMPIO:

#include <Snake.h>
#include "FastLED.h"

#define NUM_LEDS 135
#define LEDS_PER_ROW 15
#define DATA_PIN 6

Snake snakeGame(15,9,10);//initialize the snake field with x=15, y=9, delay=10 ticks 
CRGB leds[NUM_LEDS];

void setup() {
 snakeGame.setBodyColor(255,0,255);//optionally set the color of the snakeparts
 snakeGame.setFoodColor(0,60,125);//optionally set the color of the food
 snakeGame.setHeadColor(225,20,60);//optionally set the color of the snakeparts

 delay(2000);
 FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
 Serial.begin(9600);
}

byte setPixel(byte x, byte y, byte r, byte g, byte b)
{
 byte ledID = NUM_LEDS - (y * LEDS_PER_ROW) - x - 1 ;
 leds[ledID].setRGB(r,g,b);
 return ledID;
}

void changeRGBtoGBR()
{
 for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed++)
 {
 leds[whiteLed].setRGB(leds[whiteLed].g , leds[whiteLed].b, leds[whiteLed].r);
 }
}

void clearScreen()
{
 for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed++)
 {
 leds[whiteLed].setRGB( 3, 3, 3);
 }
}

void loop() 
{ 
 Snake::pixel* snakeLimbs=snakeGame.getSnakeLimbs();//this needs to be updated every frame
 Snake::pixel* snakeFood = snakeGame.getFoodPositions();//this needs to be updated every frame
 clearScreen();
 setPixel(snakeFood[0].posX,8-snakeFood[0].posY,snakeFood[0].pixelColor.r,snakeFood[0].pixelColor.g,snakeFood[0].pixelColor.b); // display the food
 for(int i=0; i<snakeGame.getSnakeLenght(); i++)
 {
 //display the snake, my setpixel method has x=0, y=0 at the top left, but the library has it at bottom left, so I invert the Y-Axis:
 setPixel(snakeLimbs[i].posX,8-snakeLimbs[i].posY,snakeLimbs[i].pixelColor.r,snakeLimbs[i].pixelColor.g,snakeLimbs[i].pixelColor.b);
 }
 FastLED.show();
 snakeGame.tick();//main loop for the snake library
 if(snakeGame.wasGameReset())// if the snake bit itself or the wall, flash a little
 {
 for(int i=0; i<30; i++)
 {
 changeRGBtoGBR();
 FastLED.show();
 delay(40);
 }
 }
 else
 delay(30);

}

byte incomingByte=0;
void serialEvent() {
 while (Serial.available()) 
 {
 incomingByte = Serial.read();
 Serial.write(incomingByte);
 }
 switch(incomingByte)
 {
 case 'a':
 snakeGame.goLeft(); //snake will go left on the next move
 break;
 case 'd':
 snakeGame.goRight(); //snake will go right on the next move
 break;
 case 's':
 snakeGame.goDown(); //snake will go down on the next move
 break;
 case 'w':
 snakeGame.goUp(); //snake will go up on the next move
 break;
 case '1': //cheat!
 snakeGame.increaseSize();
 break;
 case '2': //whaaaaaa
 snakeGame.setDelay(4);//set speed (actually you set the delay time)
 break;
 }
}

questo codice usa strip led ma... NON dice dove viene collegato il controller, nè come si fa.
Potete aiutarmi?

(Snake Game with arduino and custom LED display on Vimeo)

Quello che non ti è chiaro e che @Patrick_M ha provato a spiegarti è che il codice che stai usando NON può funzionare con le strip led ma solo con le matrici led questo perché una matrice non è composta da n strip collegate in cascata o su più pin ma viene indirizzata con due coordinate ad esempio per accedenre il primo led in altro la coordinata è 0,0 mentre il led della prima colonna seconda riga sarà 0,1.
Tu usando strip led collegate in cascata il led della seconda riga prima colonna colonna non è 0,1 ma 11 non è impossibile fare ciò che vuoi ma devi riscrivere il codice quasi da zero poiché stai usando HARDWARE differente.
O ti doti di hardware uguale (ovvero una matrice di neopixel) o cambi il software ma non è una passeggiata farlo serve buona conoscenza e esperienza perché tra l'altro i neopixel necessitano di timing ben precisi per funzionare

fabpolli:
Quello che non ti è chiaro e che @Patrick_M ha provato a spiegarti è che il codice che stai usando NON può funzionare con le strip led ma solo con le matrici led questo perché una matrice non è composta da n strip collegate in cascata o su più pin ma viene indirizzata con due coordinate ad esempio per accedenre il primo led in altro la coordinata è 0,0 mentre il led della prima colonna seconda riga sarà 0,1.
Tu usando strip led collegate in cascata il led della seconda riga prima colonna colonna non è 0,1 ma 11 non è impossibile fare ciò che vuoi ma devi riscrivere il codice quasi da zero poiché stai usando HARDWARE differente.
O ti doti di hardware uguale (ovvero una matrice di neopixel) o cambi il software ma non è una passeggiata farlo serve buona conoscenza e esperienza perché tra l'altro i neopixel necessitano di timing ben precisi per funzionare

lo so cosa intendeva, infatti sto chiedendo aiuto a voi perchè io non sono in grado di fare ciò che dite... Inoltre l'ultimo sketch che ho messo, con il link, usa STRIP LED ws2812, cioè le stesse mie...
In alternativa, se sapessi come è fatta la matrice led 8x8, potrei replicarla, ma non so come vengono collegati i led... per questo sto chiedendo aiuto a voi

In questo link sembra che ci sia una persona che ha replicato la matrice 8x8 e, se si osserva bene il circuito, si nota che i pin "DATA IN" e "DATA OUT" sono collegati "in serie", ovvero tali e quali alle strip led... Quindi, teoricamente, non cambia proprio niente.

Nel link che hai postato con le strip, se guardi bene, i pezzi di strip sono collegati a zig-zag, non e' che tu li hai collegati diversamente ? ... poi cosa significa che non sai dove collegare il controller ? ... con le strip di WS2812 il controller puoi collegarlo solo al DIN, e da nessun'altra parte (ed ovviamente, anche le parti di strip che tagli, quando le riunisci vanno collegate con il DOUT del primo pezzo al DIN del secondo, e cosi via)

O intendi qualcos'altro ?

Etemenanki:
Nel link che hai postato con le strip, se guardi bene, i pezzi di strip sono collegati a zig-zag, non e' che tu li hai collegati diversamente ? ... poi cosa significa che non sai dove collegare il controller ? ... con le strip di WS2812 il controller puoi collegarlo solo al DIN, e da nessun'altra parte (ed ovviamente, anche le parti di strip che tagli, quando le riunisci vanno collegate con il DOUT del primo pezzo al DIN del secondo, e cosi via)

O intendi qualcos'altro ?

Sono a zig zag perchè, se guardi i pin del diodo led in sè (led 5050), in alto a sinistra trovi "DATA OUT", in basso a destra "DATA IN". per questo sono a zig zag, ma se guardi bene il collegamento è tale e quale alle strip led.
Con "non so dove collegare il controller" intendo dire non la strip led, ma il controller per giocare al gioco Snake

AGGIORNAMENTO:
Il codice che metterò qua di seguito l'ho trovato su internet e permetteva di giocare a snake con una matrice 8x8, dichiarata da voi diversa dalle strip led ws2812 che però, almeno teoricamente, in base alla mia scoperta, risultano uguali e identiche.
Fatto sta che, comunque, ho modificato il codice qua di seguito per farlo funzionare con una matrice 10x10.. Ma ora funziona perfettamente solo con una 8x8, lasciando quindi gli altri led spenti.
Idee?

#include <Adafruit_NeoPixel.h>


#define PIN 2           //Output Pin
#define MAX_LED 100       //Quantity of bead
uint32_t c;
int a = 0 , number;
unsigned char huan = 0, ci = 0;
unsigned char  u = 40; //The font size of word group
unsigned char x = 0;
unsigned char Colour[3];
unsigned char go[] = {2, 3, 4, 5, 9, 14, 17, 20, 22, 26, 27, 29, 34, 35, 36, 37, 41, 46, 49, 54, 58, 59, 60, 61}; //24
unsigned char light[10][10] = {
  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
  {19, 18, 17, 16, 15, 14, 13, 12, 11, 10},
  {20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
  {39, 38, 37, 36, 35, 34, 33, 32, 31, 30},
  {40, 41, 42, 43, 44, 45, 46, 47, 48, 49},
  {59, 58, 57, 56, 55, 54, 53, 52, 51, 50},
  {60, 61, 62, 63, 64, 65, 66, 67, 68, 69},
  {79, 78, 77, 76, 75, 74, 73, 72, 71, 70},
  {80, 81, 82, 83, 84, 85, 86, 87, 88, 89},
  {99, 98, 97, 96, 95, 94, 93, 92, 91, 90},
};
unsigned char character[][10] =  //Set the word to be sent
{
  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
  {0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, // 0
  {0, 1, 1, 1, 1, 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}, // 1
  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},


  {0, 1, 0, 1, 1, 1, 0, 0, 0, 0},
  {0, 1, 0, 1, 0, 1, 0, 0, 0, 0}, // 2
  {0, 1, 1, 1, 0, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},


  {0, 1, 0, 1, 0, 1, 0, 0, 0, 0},
  {0, 1, 0, 1, 0, 1, 0, 0, 0, 0}, // 3
  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},


  {0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, // 4
  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},


  {0, 1, 1, 1, 0, 1, 0, 0, 0, 0},
  {0, 1, 0, 1, 0, 1, 0, 0, 0, 0}, // 5
  {0, 1, 0, 1, 1, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},


  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
  {0, 1, 0, 1, 0, 1, 0, 0, 0, 0}, // 6
  {0, 1, 0, 1, 1, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},


  {0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, // 7
  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},


  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
  {0, 1, 0, 1, 0, 1, 0, 0, 0, 0}, // 8
  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},


  {0, 1, 1, 1, 0, 1, 0, 0, 0, 0},
  {0, 1, 0, 1, 0, 1, 0, 0, 0, 0}, // 9
  {0, 1, 1, 1, 1, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
};


unsigned char displayscore [10][10];


int speedS = 400;                                                         // Initial speed of snake
int score;                                                              // Game score
int xValue;                                                             // JoyStick-X
int yValue;                                                             // JoyStick-Y
int zValue;                                                             // JoyStick-Z
int FX, FY;                                                             // Coordinate of food
int SX, SY;                                                             // Coordinate of snake head
int KEY, K;
int Enabled;                                                            // Enable to restart game


char sx[100] ;                                                     //Coordinate of snake body 
char sy[100];
Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 );






void RANDOM() {
A:
  FX = random(0, 9);
  FY = random(0, 9);


  for (int i = 0; i < 3 + score; i++)          //Prevent food display on snake body
  {
    if ( FX == sx[i] && FY == sy[i])
      goto A;
  }
}
void myDelay( unsigned int Time) {                             // During the delay period of snake movement, we have to do something like food glitter and read the direction of Joystick


  for (int t = 1; t <= Time; t++)
  {
    joyStick();
    delay(1);                                     //Read the direction of Joystick 
  }
}
void joyStick() {


  xValue = analogRead(A0);                             // JoyStick-X   The leftmost value is 0, the rightmost value is 1023, and the middle value is 515.
  yValue = analogRead(A1);                             // JoyStick-Y   The bottom value is 0, the top value is 1023, the middle value is 510.


  if (yValue > 950 && KEY != 5) {
    K = 8;
  }
  else if (yValue < 50 && KEY != 8) {
    K = 5;
  }
  else if (xValue < 50  && KEY != 6 && K != 0) {       // Before operate Joystic for the first time, you can't move snake to the left direction. 
    K = 4;
  }
  else if (xValue > 950 && KEY != 4) {
    K = 6;
  }
}
// Here you can compare whether the direction of keypad is opposite to the snake move direction. If it is opposite, then give up the keypad. 
/***************************************************************************************************************************************************************************************************************/
void gameover() {                                      // Once Gameover program stopped, press the central button to restart the game.
  unsigned char value, y;


  Colour[0] = random(3 , 18); // Set color.Parameter is R G B, range 0-255.
  Colour[1] = random(3, 18);
  Colour[2] = random(3, 18);
  c = strip.Color(Colour[1], Colour[0], Colour[2]);
  value = score / 10;
  value = value * 4;
  y = 0;


  for (number = value; number < value + 4; number++)
  {
    for (unsigned char vertical = 0; vertical < 10; vertical++)
    {
      displayscore[y][vertical] = character[number][vertical];




    }
    y++;
  }


  value = score % 10;
  value = value * 4;


  for (number = value; number < value + 4; number++)
  {
    for (unsigned char vertical = 0; vertical < 10; vertical++)
    {
      displayscore[y][vertical] = character[number][vertical];


    }
    y++;
  }


  for (unsigned char horizontal = 0; horizontal < 10; horizontal++)
  {
    for (unsigned char vertical = 0; vertical < 10; vertical++)
    {


      if (displayscore[horizontal][vertical] == 1) //Judge whether the light is on.
      {
        strip.setPixelColor(light[horizontal][vertical],  c);
      }
      else
        strip.setPixelColor(light[horizontal][vertical],  0);


    }
  }


  strip.show();//Send data
  delay(5000);
  K = 0;                  // Reset Joystick direction
  sx[0] = 2;
  sx[1] = 1;
  sx[2] = 0;
  sy[0] = 1;
  sy[1] = 1;
  sy[2] = 1;               // Reset snake coordinate
  score = 0;              // Reset game score
  speedS = 400;                                                         // The initial speed of snake

Tra 5 minuti posto l'altro pezzo di codice, in quanto avevo superato i 9000 caratteri

AGGIORNAMENTO FINALE:
Sono riuscito a farlo, ora funziona tutto.
Confermo quindi che ciò che ha detto @Patrick_M non mi risulta vero

aleelettronica:

byte incomingByte=0;

void serialEvent() {
while (Serial.available())
{
incomingByte = Serial.read();
Serial.write(incomingByte);
}
switch(incomingByte)
{
case 'a':
snakeGame.goLeft(); //snake will go left on the next move
break;
case 'd':
snakeGame.goRight(); //snake will go right on the next move
break;
case 's':
snakeGame.goDown(); //snake will go down on the next move
break;
case 'w':
snakeGame.goUp(); //snake will go up on the next move
break;
case '1': //cheat!
snakeGame.increaseSize();
break;
case '2': //whaaaaaa
snakeGame.setDelay(4);//set speed (actually you set the delay time)
break;
}
}






questo codice usa strip led ma... NON dice dove viene collegato il controller, nè come si fa.
Potete aiutarmi?

come non te lo dice....
ti ho quotato il pezzo di codice che fa proprio questo, come puoi notare viene usata la comunicazione seriale per leggere il controller

Codice del video

#define MATRIXPIN      8

Adafruit_NeoPixel Matrix = Adafruit_NeoPixel(MATRIX_SIZE, MATRIXPIN, NEO_GRB + NEO_KHZ800);

Il pin è l'8

Codice del messaggio #6

#define DATA_PIN 6

Il pin è il 6

Codice nel messaggio #11

#define PIN 2           //Output Pin

Il pin è il 2

Tutti gli sketch riguardano i neopixel e non le matrici 8x8, basta vedere le librerie che usano.

aleelettronica:
AGGIORNAMENTO FINALE:
Sono riuscito a farlo, ora funziona tutto.
Confermo quindi che ciò che ha detto @Patrick_M non mi risulta vero

ciao scusa io ho creato un quadrato 11 x 11 con la stessa striscia che hai usato tu, mi piacerebbe replicare il tuo progetto, potresti postare tutto il codice ? per i collegamenti faccio riferimento al tuo primo post (https://youtu.be/hYM-LaYNgQA)?
grazie in anticipo

>Lucapivello: buonasera, essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, fino a quando non sarà fatta la presentazione, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink: