Skip to content

Instantly share code, notes, and snippets.

@ticklemynausea
Last active December 26, 2017 10:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ticklemynausea/fef8047274368ca67d6d to your computer and use it in GitHub Desktop.
Save ticklemynausea/fef8047274368ca67d6d to your computer and use it in GitHub Desktop.
Nokia_5110_LCD_GameOfLife
// Nokia 5110 LCD-Display (SIZE_HxSIZE_V Bildpunkte)
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#define LCD_WIDTH 84
#define LCD_HEIGHT 48
#define LCD_HEIGHT8 (LCD_HEIGHT >> 3)
#define map(i, j) (i + LCD_WIDTH*j)
#define map_x(i, j, k) (i)
#define map_y(i, j, k) (j*8+k)
#define map_i(x, y) (x)
#define map_j(x, y) (y/8)
#define map_k(x, y) (y%8)
#define for_i for (int i = 0; i < LCD_WIDTH; i++)
#define for_j for (int j = 0; j < LCD_HEIGHT8; j++)
#define for_k for (int k = 0; k < 8; k++)
#define for_n for (int n = 0; n < 8; n++)
#define for_x for (int x = 0; x < LCD_WIDTH; x++)
#define for_y for (int y = 0; y < LCD_HEIGHT; y++)
#define for_y_a for (int y_a = y - 1; y_a <= y + 1; y_a++)
#define for_x_a for (int x_a = x - 1; x_a <= x + 1; x_a++)
#define bit_read(matrix, i, j, k) bitRead(matrix[map(i, j)], k)
#define bit_set(matrix, i, j, k) bitSet(matrix[map(i, j)], k)
#define bit_clear(matrix, i, j, k) bitClear(matrix[map(i, j)], k)
#define bit_set_xy(matrix, x, y) bit_set(matrix, map_i(x, y), map_j(x, y), map_k(x, y))
#define bit_read_xy(matrix, x, y) bit_read(matrix, map_i(x, y), map_j(x, y), map_k(x, y))
#define bit_clear_xy(matrix, x, y) bit_clear(matrix, map_i(x, y), map_j(x, y), map_k(x, y));
#define pixel_set(i, j, k) display.drawPixel(i, j*8+k, BLACK)
#define pixel_unset(i, j, k) display.drawPixel(i, j*8+k, WHITE)
#define pixel_map(i, j, k) display.drawPixel(i, j*8+k, bit_read(matrix, i, j, k) == 1 ? BLACK : WHITE)
#define between(n, a, b) ((n >= a) && (n <= b))
#define NORTH 0
#define NORTHEAST 1
#define EAST 2
#define SOUTHEAST 3
#define SOUTH 4
#define SOUTHWEST 5
#define WEST 6
#define NORTHWEST 7
#define RAND_RANGE 255
// Initialize LCD Display
// D7 - Serial clock out (CLK oder SCLK)
// D6 - Serial data out (DIN)
// D5 - Data/Command select (DC oder D/C)
// D4 - LCD chip select (CE oder CS)
// D3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);
unsigned char matrix[LCD_WIDTH * LCD_HEIGHT8] = {0};
unsigned char matrix_new[LCD_WIDTH * LCD_HEIGHT8] = {0};
unsigned char toggle = 0;
void initialize_matrix() {
for_x {
for_y {
char rand = random(RAND_RANGE);
if (between(rand, 0, RAND_RANGE / 2)) {
bit_set_xy(matrix, x, y);
}
}
}
}
// implemented using dubaiss' "neighbours XXX" algorithm
void evolve_matrix() {
// new state
unsigned char neighbour[8] = {0};
unsigned char byte_cell;
unsigned char byte_cell_new;
unsigned char byte_cell_count;
// calculate new state
for_i {
for_j {
byte_cell = matrix[map(i, j)];
/* * get each bit's neighbour one byte at a time * */
/* east and west */
neighbour[WEST] = 0b00000000;
if (i > 0) {
neighbour[WEST] = matrix[map((i - 1), j)];
}
neighbour[EAST] = 0b00000000;
if (i < (LCD_WIDTH - 1)) {
neighbour[EAST] = matrix[map((i + 1), j)];
}
/* north */
neighbour[NORTH] = 0b00000000;
neighbour[NORTHEAST] = 0b00000000;
neighbour[NORTHWEST] = 0b00000000;
if (j > 0) {
neighbour[NORTH] = matrix[map(i, j - 1)];
if (i > 0) {
neighbour[NORTHWEST] = matrix[map(i - 1, j - 1)];
}
if (i < (LCD_WIDTH - 1)) {
neighbour[NORTHEAST] = matrix[map(i + 1, j - 1)];
}
}
neighbour[NORTH] = (byte_cell << 1) | ((neighbour[NORTH] & 0b10000000) >> 7);
neighbour[NORTHEAST] = (neighbour[EAST] << 1) | ((neighbour[NORTHEAST] & 0b1000000) >> 7);
neighbour[NORTHWEST] = (neighbour[WEST] << 1) | ((neighbour[NORTHWEST] & 0b1000000) >> 7);
/* south */
neighbour[SOUTH] = 0b00000000;
neighbour[SOUTHEAST] = 0b00000000;
neighbour[SOUTHWEST] = 0b00000000;
if (j < (LCD_HEIGHT8 - 1)) {
neighbour[SOUTH] = matrix[map(i, j + 1)];
if (i > 0) {
neighbour[SOUTHWEST] = matrix[map(i - 1, j + 1)];
}
if (i < (LCD_WIDTH - 1)) {
neighbour[SOUTHEAST] = matrix[map(i + 1, j + 1)];
}
}
neighbour[SOUTH] = ((neighbour[SOUTH] & 0b00000001) << 7) | (byte_cell >> 1);
neighbour[SOUTHEAST] = ((neighbour[SOUTHEAST] & 0b00000001) << 7) | (neighbour[EAST] >> 1);
neighbour[SOUTHWEST] = ((neighbour[SOUTHWEST] & 0b00000001) << 7) | (neighbour[WEST] >> 1);
/* calculate each bit of next gen */
byte_cell_new = 0b00000000;
for_k {
byte_cell_count = 0;
for_n {
byte_cell_count += (neighbour[n] & 0b00000001);
}
byte_cell_new >>= 1;
if ((byte_cell_count == 3) || ((byte_cell_count == 2) && (byte_cell & 0b00000001))) {
byte_cell_new |= 0b10000000;
}
for_n {
neighbour[n] >>= 1;
}
byte_cell >>= 1;
}
matrix_new[map(i, j)] = byte_cell_new;
}
}
// apply new state
for_i {
for_j {
matrix[map(i, j)] = matrix_new[map(i, j)];
}
}
}
void update_display() {
uint8_t color;
for_i {
for_j {
for_k {
pixel_map(i, j, k);
}
}
}
display.display();
}
void toggle_pin() {
if (toggle == 1) {
digitalWrite(13, HIGH);
toggle = 0;
} else {
digitalWrite(13, LOW);
toggle = 1;
}
}
void setup() {
// random seed
randomSeed(analogRead(0));
// initialize display
display.begin();
// set contrast
display.setContrast(60);
// clears the screen and buffer
display.clearDisplay();
// gpio pins
pinMode(13, OUTPUT);
// initialize matrix
initialize_matrix();
}
void loop() {
update_display();
evolve_matrix();
toggle_pin();
delay(50);
}
@Deliaz
Copy link

Deliaz commented Jun 22, 2017

Thx, I adapted it for my project with display SH1106
https://github.com/Deliaz/walletboard-game-of-life

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment