Cellular automation using an Arduino Uno and a Heltec I2C OLED display.

This project took a couple of iterations to create.  My original design for the program revolved around using the LolShield, and I wanted to recreate Conway's Game of Life on it, however I would be able to do little more than a simple glider on that display due to its size.

I then took some of the concepts from that and applied it to the OLED display that I recently played around with.  This design revolved around using a two-dimensional array of structs to represent each pixel.  Each struct would have an x and y value to dictate its position on the board, then it would have variables to indicate its on/off state, whether or not the cell was "Alive" or "Dead", and another two-dimensional array of structs that functioned as an adjacency list.

Two cell-state variables were used so that I could make the program pass through the array and change alive/dead states of the cells without the changes affecting each other on the same pass through. After one pass through, I would have it loop through again to change the on/off states, and draw each respective pixel, then it would display the whole picture.

After programming all of this, and the other logic to dictate the changing of cells according to the rules for Conway's Game of Life, I ran into some issues.  Mainly, that the array was entirely too big.  Since the main array had 8192 elements - one for each pixel of the 128x64 display - the problems rose mainly from that taking up too much memory, but the bigger issue was with the way I had the adjacency list set up.  It was set up in a way where it essentially seemed to store nearly infinite copies of each element, since I didn't have it use pointers.  This resulted in an infinite memory requirement.

This is the code that I had originally come up with that was full of problems.

After talking with my dad about the issue, it was clear that I had to scrap most of what I had done, and go about the project in a much different manner.

The design that was necessary, was that I had to create changing bitmaps to update and display.  This bitmap, would be similar in nature to the one used for the Adafruit logo in one of the stock code examples that came with the libraries, where it's a single dimensional array of 8 bit binary numbers, where each bit represents the state of a pixel.  There would be 2 bitmaps, one that is parsed, and one that is updates as the first is parsed, then the second is copied to the first and the bitmap is displayed, then the process repeats.

As the bitmap is parsed, the rules for the game would be used to change the map, using some math and bit shifting and logical operations to check and set certain bits.

So I now went and recreated the previous code I had made, but implementing it in a way to work with the bitmap.  One of the hard parts here would be setting and checking individual bits, though my dad sent me some functions to deal with the setting and checking of bits, and suggested the use of simple byte arrays in RAM, rather than trying to throw them into flash memory.

After some trial and error, and further learning on how to use the library, I was able to display the initial bitmap for the little glider.  The glider, however, would not move and I couldn't figure out why.  After quite a bit of troubleshooting, we decided that the built in function for drawing raw bitmaps wasn't going to work and would be too much hassle, so I opted for having it parse the byte map bit by bit, drawing each "alive cell" along the way.

After implementing the individual drawing of each pixel,  I found that the logic I implemented had mostly worked.  As the original goal was to recreate Conway's Game of Life, I had written the logic for that, however some patterns for oscillators didn't really work how they should, and there was no apparent reason why it wouldn't work.  However, some standstill patterns seemed to work, so that was nice.

As a result, the code still worked as simple cellular automation, but not strictly with the premise of Conway's game.  Regardless, getting this to (mostly) work was nice and took quite a while, so I'm pretty happy with the end result.

Here's a horribly blurry gif of what I put together:


via GIPHY

Also here is the code:

Comments

  1. Great work! Try moving your test pattern to the middle of the field. Maybe the border handling is messing up the rules somehow.

    ReplyDelete

Post a Comment