Close
0%
0%

AI Snake on a on ATtiny1616

Run a python snake AI model. Copy the matrices and basic linear algebra functions to a chip. Watch the chip run the AI model.

Public Chat
Similar projects worth following
The idea is simple: download an open-source Python Snake AI model, customize and run the Python code to tune the model, and wait for it to train. Once trained, copy the model (its matrices) and basic linear algebra functions to a chip, then watch the chip run the AI model. As a bonus, build a human vs. AI game.

Since most AI models boil down to an input, trained matrices (the black box), and an output, I'll take someone else's code, train a small AI model, and put it on a chip. A small chip that costs a dollar and has only ~2 KB of stack/heap memory and ~16 KB of Flash memory.


model_params.txt

plain - 11.44 kB - 05/21/2025 at 23:34

Download

game.py

x-python-script - 4.30 kB - 05/21/2025 at 23:34

Download

cArrays.py

x-python-script - 1.66 kB - 05/21/2025 at 23:34

Download

agent.py

x-python-script - 4.89 kB - 05/21/2025 at 23:34

Download

snake_ai_businessCard.cpp

cpp - 20.40 kB - 05/21/2025 at 23:34

Download

  • 1
    Train the AI
    1. Go to the first GitHub repo, link here
    2. Download the ZIP.
    3. Open the Python repository.

    Step 1: Modify agent.py for a smaller network

    The neural network, one line 11, is defined like:

    self.model = Linear_QNet(11, 256, 3)
    

    This means an 11 size input which holds the snake's position and the food location. 256 is the size of the neural net or "the brain". Output size of 3 holds the directions (e.g., left, straight, right)

    I think a 256-neuron network is too large for our ATtiny1616's memory. So, I made the neural network smaller, from 256 to 64:

    self.model = Linear_QNet(11, 64, 3) # <-- /////////////// My changes are here /////////////// #
    

    I changed a few training parameters:

    Learning rate (line 11):

    # LR = 0.001
    LR = 0.0005 # <-- /////////////// My changes are here /////////////// #
    

    Initial randomness (line 88):

    # self.epsilon = 80 - self.n_games
    self.epsilon = 160 - self.n_games
    

    I figured a lower learning rate and more randomness might help compensate for the smaller neural net. Who knows! I liked the simplicity of this project and didn’t spend any time fine-tuning. Experiment with your own models or try different neural network architectures.

    Step 2: Modify game.py for an 8x8 grid

    We need to train the AI on an 8x8 grid to match our LED hardware. In this repo, each cell is 20 pixels. To get an 8x8 grid, change line 31 in game.py from:

    # def __init__(self, w=640, h=480):
    def __init__(self, w=160, h=160) # <-- /////////////// My changes are here /////////////// #
    

    Step 3: Train Your Model

    Run your model in agent.py. I trained it for about 2000 iterations.

    You now have trained AI matrices ready to deploy on-chip!

    I also wrote a simple Python script that prints your trained matrices as C++ arrays (for Flash memory).

    Step 4: Run my code cArrays.py

    This prints out the c arrays we can paste in our Arduino or C++ code.

  • 2
    C++ Code

    Code is essentially converting the Python Snake game to C++, and implementing a few simple linear algebra functions.

    The function void get_action(bool state[11], uint8_t action[3]) moves the snake according to the trained matrices.

    The only functions used to integrate the trained matrices (for the AI magic) are: a simple matrix-vector multiplication of the form Ax + b, followed by a ReLU activation function.

    The ReLU function is straightforward, set any negative value to zero.

    The trained matrices are saved to flash memory using the PROGMEM keyword and accessed using the function pgm_read_float.

    Game play:

    Gameplay switches between human and AI. Be ready when it's your turn, the snake will start moving and If you're not ready, it will crash into a wall. Letting robots win.

    The score is displayed by lighting up the same number of pixels as the snake's length. This is an attempt to save memory by not loading in a pixel-to-bitmap image font.

  • 3
    Hardware Build

    I'll assume you have an 8x8 LED matrix driven by an HT16K33A. Note Adafruit's BiColor LED Matrix has everything setup. You need four buttons pulled high. Meaning one side of each button is connected to ground, and the other side is connected to a GPIO pin and pulled up to Vin thru a 10k resistor.

    Connections are simple. If you're using the business card version, just leave the expose the male pins for programming. If you have separate parts, the LED matrix's SDA and SCL pins connect to the ATtiny 1616 SDA SCL pins. The buttons connect to pins 0 through 3.

    Simple diagram is in the pictures (note: it shows only one button and the HT16K33A driver should already be connected to the LEDs, leaving just the Vin, GND, SDA, and SCL pins to wire)

    Programming an ATtiny1616

    These are the best directions, but I'll summarize:

    1. In Arduino, add the following URL to your Boards Manager Preferences:
    2. http://drazzy.com/package_drazzy.com_index.json
    3. Install megaTinyCore from the Boards Manager.
    4. Under Tools, select:
      • Board: megaTinyCore → ATtiny1616
      • Chip: ATtiny1616
      • Clock: 10 MHz
      • Programmer: SerialUPDI – SLOW (57600 baud)
    5. Go to Sketch > Upload Using Programmer and upload a blank sketch to confirm everything works.

    You should see your UPDI friend blinking and the code uploading successfully to the board.

    Next upload the snake_ai_businessCard.ino code by Upload Using Programmer and thats it. You're ready to play against your own AI.

View all 3 instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates