What Students Can Learn from a PLC Snake Game in Siemens SCL
This project is more than a small PLC game. It is a practical teaching case that shows how students can move beyond basic input-output control and start thinking in terms of states, data, timing, hardware mapping, and verification.
The goal is to use Siemens SCL to control a 16x16 LED matrix and build a working Snake Game. During this process, students learn several problem-solving ideas that are not easy to discover in traditional PLC lessons.
1. Separate Logic from Hardware Mapping
A key lesson is that the game logic should not be directly tied to physical output addresses.
Inside the program, the snake uses a simple coordinate system:
X = 0 to 15
Y = 0 to 15
X = 0 means left
X = 15 means right
Y = 0 means top
Y = 15 means bottom
However, the real LED matrix is controlled by Siemens output words, bytes, and bits. For example, the first row is mapped from:
Q0.0, Q0.1, Q0.2, Q0.3, Q0.4, Q0.5, Q0.6, Q0.7,
Q1.0, Q1.1, Q1.2, Q1.3, Q1.4, Q1.5, Q1.6, Q1.7
Therefore, the program needs a mapping layer:
IF #SnakeX[#i] <= 7 THEN
#BitIndex := #SnakeX[#i] + 8;
ELSE
#BitIndex := #SnakeX[#i] - 8;
END_IF;
The important engineering idea is:
The logical model and the physical I/O mapping should be separated.
This is useful not only for LED matrices, but also for Modbus registers, PROFINET I/O mapping, HMI tags, SCADA tags, and byte-order problems.
2. Use a Layered Program Structure
The Snake Game can be divided into three layers:
1. Game logic
Direction, snake body, food, collision, score
2. Timing control
GameTimer, GameTick, MoveTime
3. Display output
LedBuffer, BitIndex, LedRow_00 to LedRow_15
This teaches students not to mix all conditions and outputs together.
A good design flow is:
Read input
-> update direction
-> wait for GameTick
-> calculate next position
-> check collision
-> update snake body
-> generate LED buffer
-> write LED output
This is a major step beyond simple PLC logic such as:
Condition is true -> Output ON
Condition is false -> Output OFF
3. Use a State Machine Instead of Only Boolean Logic
The game has several operating states:
Idle
Running
Game Over
Win
Restart
Therefore, the program uses a CASE-based state machine:
CASE #State OF
10:
// Idle
20:
// Running
30:
// Game Over
40:
// Win
END_CASE;
This teaches students that Boolean logic is not always enough. When a machine has steps, memory, events, and transitions, a state machine is usually a better solution.
This concept applies directly to conveyors, sorting systems, pick-and-place machines, automatic warehouses, packaging machines, and batch processes.
4. Understand Scan Cycle vs. Application Event
A PLC runs cyclically, but the snake should not move every scan. If it did, it would move too fast to observe.
The program uses a timer to generate a movement event:
#GameTimer(IN := (#State = 20), PT := #MoveTime);
#GameTick := #GameTimer.Q;
The snake only moves when GameTick becomes TRUE:
IF #GameTick THEN
// Move snake
END_IF;
The key point is:
The PLC scan cycle is not the same as the application control cycle.
This idea is useful for communication polling, periodic sampling, HMI refresh, machine cycle timing, and step-by-step process control.
5. Use Arrays to Represent Moving Objects
The snake body is not written as hundreds of individual Boolean tags. It is stored as arrays:
SnakeX : Array[0..255] of Int;
SnakeY : Array[0..255] of Int;
The structure is:
SnakeX[0], SnakeY[0] = snake head
SnakeX[1], SnakeY[1] = first body segment
SnakeX[2], SnakeY[2] = second body segment
This teaches students how to use data structures in PLC programming.
The lesson is:
When many similar data items exist, use arrays and indexes.
This idea is very useful for product tracking, conveyor station data, recipe tables, alarm lists, warehouse locations, and production history.
6. Learn Shift Register Thinking
The snake body movement is based on a simple but powerful algorithm:
FOR #i := #BodyLimit TO 1 BY -1 DO
#SnakeX[#i] := #SnakeX[#i - 1];
#SnakeY[#i] := #SnakeY[#i - 1];
END_FOR;
Each body segment copies the previous segment position. Only the snake head actually moves according to the direction.
This is similar to shift-register logic in industrial automation.
It can be applied to:
Object tracking on conveyors
Station-to-station data transfer
Product status shifting
Inspection result tracking
Packaging line data movement
FIFO-style material tracking
7. Calculate the Next State Before Updating the Real State
The program does not immediately overwrite the snake position. It first calculates the next possible position:
#NewX := #SnakeX[0];
#NewY := #SnakeY[0];
Then it checks whether the new position is valid. Only after validation does the program update the real snake position.
The engineering principle is:
Calculate first, validate second, commit last.
This is useful for motion command validation, robot position checking, safety interlocks, recipe validation, and automatic sequence transitions.
8. Learn Bit Operations with SHL and OR
The LED matrix is generated using bit operations:
SHL(IN := WORD#16#0001, N := #BitIndex)
Then the bit is added into the row buffer:
#LedBuffer[#SnakeY[#i]] :=
#LedBuffer[#SnakeY[#i]] OR SHL(IN := WORD#16#0001, N := #BitIndex);
This teaches students that a WORD can represent 16 LED points.
Instead of writing 16 separate Boolean outputs, the program uses:
WORD as a 16-bit row
SHL to generate a bit mask
OR to combine display points
LedBuffer to prepare output before writing to hardware
This is a strong example of why SCL is suitable for data-oriented PLC problems.
9. Use MOD for Position Generation
The food position is generated with a simple pseudo-random method:
#FoodX := #Seed MOD 16;
#FoodY := (#Seed / 16) MOD 16;
MOD 16 keeps the value inside the range 0 to 15.
This teaches students how to convert a changing number into a valid matrix position.
The same idea can be used for station indexing, recipe selection, device polling, buffer addressing, and circular queue logic.
10. Treat Collision Detection as Illegal State Checking
The program checks wall collision:
IF (#NewX < 0) OR (#NewX > 15) OR (#NewY < 0) OR (#NewY > 15) THEN
#GameOver := TRUE;
END_IF;
It also checks self-collision by comparing the new head position with the snake body:
FOR #i := 0 TO #BodyLimit DO
IF (#NewX = #SnakeX[#i]) AND (#NewY = #SnakeY[#i]) THEN
#SelfCollision := TRUE;
END_IF;
END_FOR;
This teaches students how to detect illegal states before updating the machine state.
In real automation, this maps to position limits, duplicate station occupancy, invalid routing, robot conflict checking, and conveyor zone conflict detection.
11. Reset Must Prevent Later Logic from Rewriting Outputs
During development, one issue appeared: Reset cleared the LED buffer, but later logic drew the snake again in the same scan.
The solution was:
IF NOT #Reset THEN
// Draw food and snake
END_IF;
The key lesson is:
Reset logic must not only clear values. It must also prevent later logic from writing them again.
This is a common real-world PLC issue in emergency stop logic, alarm reset logic, manual-auto switching, output arbitration, and machine initialization.
12. Use Watch Table to Verify the Causal Chain
The Watch Table should not only check whether the LED turns on. It should verify the full causal chain:
DI button
-> NextDirection
-> GameTick
-> Direction
-> HeadX / HeadY
-> SnakeX / SnakeY
-> LedBuffer
-> LedRow output
-> physical LED display
Recommended Watch Table variables:
State
Direction
NextDirection
HeadX
HeadY
FoodX
FoodY
SnakeLength
Score
GameTimer.ET
GameTick
GameOver
Win
LedRow_00 to LedRow_15
This teaches students how to debug by tracing cause and effect, not just by looking at the final output.
13. SCL Solves a Different Type of Problem Than Ladder
Ladder is excellent for:
Start/stop circuits
Interlocks
Simple output logic
Safety contact logic
Basic machine conditions
But this project requires:
Arrays
Indexes
Loops
State machines
Bit shifting
Data movement
Collision checking
Coordinate mapping
These are easier to express in SCL.
The important message is:
SCL is not better because it is newer. It is better when the problem is data-oriented and algorithmic.
14. The Development Process Is More Valuable Than the Final Code
The most important learning point is the process:
Start with a simple idea
-> build a minimal version
-> test with Watch Table
-> find mapping errors
-> fix Reset behavior
-> verify movement
-> add snake body
-> add food and score
-> fix syntax errors
-> complete the final version
This teaches students that engineering is not about writing perfect code in one attempt.
Engineering is about:
Defining assumptions
Testing assumptions
Using evidence
Separating logic layers
Fixing one problem at a time
Protecting verified functions
Upgrading gradually
Summary
This Snake Game SCL project teaches much more than a game.
It helps students learn:
State machine thinking
Coordinate modeling
Array-based data structures
Timer-driven events
Bit-level output mapping
Collision detection
Data buffering
Watch Table diagnostics
Step-by-step engineering validation
These skills are not always visible in traditional PLC examples such as motor start-stop circuits, self-holding circuits, or traffic lights.
The core message is:
PLC programming is not only about turning outputs ON and OFF. It is about modeling states, data, timing, hardware mapping, and verification.
That is why this Snake Game is a strong teaching case for modern PLC education, especially when combined with Siemens SCL, Factory I/O, and AI-assisted development.