Snake – die verfressene Schlange

For another games project of our customer H.U. Küster  I first had to order another MAX7219 8x32 4 in 1 Dot Matrix LED display module (A total of four is needed) to obtain a play area of ​​32x32 luminous points. But the memories were awakened immediately when he described the game: Snake, with each swallowed point longer snake, which was not allowed to touch the edge or her own body. I had this game on my old Nokia phone, and it was the best pastime after a long working week during the waiting time at the Elbe ferry.

As for the Big Clock display I have connected the four matrix LED display modules with Tesa tape and for the first attempt I took four buttons on the breadboard against ground plugged into the pins used in the sketch. Thus, the crimping head of the snake is controlled, and the game starts only when one of the buttons is pressed for the first time.

Power supply for the displays are 5V and GND, the 5V socket of the Micro Controller with ATMega 328P is enough at the beginning. However, the more LEDs light up, the higher the power consumption, and one should consider an external power supply, which can also supply the MCU.


Hardware used:


Micro Controller with Atmega 328P


MAX7219 8x32 4 in 1 Dot Matrix LED display module


Optional: PS2 Joystick Shield Game Pad Keypad V2.0


Optional: KY-023 Joystick module


Optional: KY-006 Passive Piezo Buzzer Alarm Module

Breadboard (Breadboard), Button and Cable (Jumper Wire)

For the data lines for the displays, it must be noted that the program library LEDCONTROL.H " by Eberhard Fahle can only control 8 consecutive displays. Since each matrix module already consists of four individual displays, only two modules can be connected via "Daisy Chain". Then both blocks of 8 modules are instantiated separately.

 #include "ledcontrol.h" // by Eberhard Fahle can be found in the library administrator; But can only drive 8 displays.
 byte Number_displays = 8;
 Ledcontrol Block_1 = Ledcontrol(12, 11, 10, Number_displays); // DIN; CLK; CS; 12-11-10
 Ledcontrol block_2 = Ledcontrol(9, 8, 7, Number_displays); // DIN; CLK; CS; 9-8-7

The pin assignment for the two data lines (DIN, CLK and CS each) results from the sketch or the following circuit diagram:

circuit diagram

The optional speaker is a Piezo speaker. Since this has a very high-impedance, you can connect it directly. Other speakers may need to be connected with series resistor.

Once again the simple game rules: Sense of the game is that a snake must be controlled through the field and has points as a target to eat. With every point the snake gets longer. But it must not go over the edge or meet itself. What is quite simple in the beginning, but becomes more difficult when the snake gets longer and longer.

In the beginning, only the starting point can be seen. If one of the direction buttons is pressed, the first destination appears and the snake starts to move.

If the snake hits the edge or itself, the game is broken off. The snake dissolves limb for limb. After that, the length of the snake is displayed for a few seconds and the game is restarted.

When the game is too fast or too slow, the speed can be change in line 137.

 // speed of the program
In this setting, the game is a bit slow at the beginning, but if you manage to have more than 50 points, you have to fight very well.

Here the original sketch of Mr. Küster Download.

My problem while playing was occasionally that the cheap buttons for the breadboard did not always accept the directional command and I lost. Of course, this can also be done at the line of delay (200); Here the program stops for 200ms and accepts no further entries. So, firstly, better buttons had to be used, e.g. The Joystick Shield, which I already used with other projects (currently only in the Az-delivery shop at Amazon). And second, a program change, so that the waiting time does not lead to the blockade (non-blocking code). There is the example Sketch BlinkWithoutDelay.


The pins for the upper part of the display (DIN = D12, CLK = D11, CS = D10) can be read on the shield, as well as DIN = D9 of the lower part of the display. Then a pin remains free (3V3). CLK then comes to Key (behind it hides D8) and CS comes to the next, unlabelled socket (= D7). The buttons A to D are internally wired, but are slightly different than in the construction of Mr. Küster. So shortly a few changes to the sketch in line 60 make:

 byte Left = 5; byte below = 4; byte above = 2;  byte right = 3; // port for key query

Luckily almost the same pins, only in different order; So no conflicts with the display. However, the optional piezo speaker must then be connected to pin 6.

Since the luminous points were slightly too bright, I have set the intensity to 1 in the lines 73 and 76:

 Block_1.SETIntensity(zw1, 1);   
 block_2.SETIntensity(zw1, 1);

Further changes were necessary for the replacement of the delay (200); by an if query, whether since the last input 200ms have passed. For this we need in the beginning:

 long int Previousmillis = 0;
 long int interval = 200;

Before the decisive DO While Loop:

 Previousmillis = millis();

and then

  if (millis() - Previousmillis >= interval) {
       Previousmillis = millis();
About the variable interval You can vary the speed of the game as described above.

Here the sketch for Download.

Thus, my considerations were not over, because the game could also be played well with the joystick module.

Joystick module

For this, however, further changes must be made at the sketch, because the built-in potentiometers supply values ​​between 0 and 1023 to the analog inputs A0 and A1, in each case approx. 511 in the middle position.

At the beginning of the void loop () function, there are two do while loops for the query of the buttons (buttons), once to start the game and once for the duration of the game. Both must be changed as follows:

 // Do While Grinding
   do {
     // Query of the joystick buttons and set the direction
    if (analogead(A0) > 850) {
       direction = 1;
    else if (analogead(A1) > 850) {
       direction = 2;
     else if (analogead(A0) < 150) {
       direction = 3;
     else if (analogead(A1) < 150) {
       direction = 4;

In fact, I personally could win the most points with the Joystick module. The Joystick at the a.m. Joystick-Shield also uses the analog inputs A0 and A1. However, then the assignments of the direction must be adjusted.

Here is the download of the sketches for the analog joystick and for the Joystick-shield with joystick and buttons.

Have fun reading and playing.

Do you have an interesting project about which we can tell at this point? Write to me: Albrecht [at]
DisplaysFor arduinoProjects for beginners

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN