Hi everyone,
I've done up this sketch:
#include <SPI.h>
#include <SD.h>
#include <FTOLED.h>
OLED oled(7, 2, 3);
#define imageWidth 63
#define imageHeight 63
#define MIN 1
boolean values[imageWidth][imageHeight];
boolean nextValues[imageWidth][imageHeight];
void setup() {
oled.begin();
oled.fillScreen(GREEN);
delay(1000);
oled.fillScreen(BLACK);
randomSeed(analogRead(A0) * 10 + analogRead(A6) * 10);
initialise();
}
void loop() {
for(byte x = MIN; x < imageWidth; x++) {
for(byte y = MIN; y < imageHeight; y++) {
byte neighbourCount = 0;
if(values[x - 1][y]) {
neighbourCount++;
}
if(values[x][y - 1]) {
neighbourCount++;
}
if(values[x - 1][y - 1]) {
neighbourCount++;
}
if(values[x + 1][y]) {
neighbourCount++;
}
if(values[x][y + 1]) {
neighbourCount++;
}
if(values[x + 1][y + 1]) {
neighbourCount++;
}
if(values[x - 1][y + 1]) {
neighbourCount++;
}
if(values[x + 1][y - 1]) {
neighbourCount++;
}
if((values[x][y] == HIGH) && (neighbourCount < 2)) {
nextValues[x][y] = LOW;
}
if((values[x][y] == HIGH) && (neighbourCount == 2 || neighbourCount == 3)) {
nextValues[x][y] = HIGH;
}
if((values[x][y] == HIGH) && (neighbourCount > 3)) {
nextValues[x][y] = LOW;
}
if((values[x][y] == LOW) && (neighbourCount == 3)) {
nextValues[x][y] = HIGH;
}
neighbourCount = 0;
}
}
update();
}
void update() {
for(byte x = MIN; x < imageWidth; x++) {
for(byte y = MIN; y < imageHeight; y++) {
if(nextValues[x][y]) {
oled.setPixel(x, y, GREEN);
}
else {
oled.setPixel(x, y, BLACK);
}
}
}
memcpy(values, nextValues, sizeof(values));
}
void initialise() {
for(byte a = MIN; a < imageWidth; a++) {
for(byte b = MIN; b < imageHeight; b++) {
nextValues[a][b] = random(0, 129) % 2;
}
}
update();
}
Which is Conway's Game of Life, a zero player game involving the interactions of cells and those around them.
I then upgraded the code to include a RAM module (because having two 128*128 arrays won't fit in the Arduino's RAM):
#include <SPI.h>
#include <SD.h>
#include <FTOLED.h>
#include <eRAM.h>
#define SS_PIN 5
eRAM ram(SS_PIN, SPI_CLOCK_DIV2);
OLED oled(7, 2, 3);
#define imageWidth 128
#define imageHeight 128
#define MIN 1
void setup() { // initialise all the stuff
Serial.begin(115200);
ramClear();
oled.begin();
oled.fillScreen(GREEN);
delay(1000);
oled.fillScreen(BLACK);
randomSeed(analogRead(A0) * 10 + analogRead(A6) * 10);
initialise();
}
void loop() {
for(int x = MIN; x < imageWidth; x++) {
for(int y = MIN; y < imageHeight; y++) {
int neighbourCount = 0;
// checks if the cell has neighbours
if(ramReadArrayA(x - 1, y)) {
neighbourCount++;
}
if(ramReadArrayA(x, y - 1)) {
neighbourCount++;
}
if(ramReadArrayA(x - 1, y - 1)) {
neighbourCount++;
}
if(ramReadArrayA(x + 1, y)) {
neighbourCount++;
}
if(ramReadArrayA(x, y + 1)) {
neighbourCount++;
}
if(ramReadArrayA(x + 1, y + 1)) {
neighbourCount++;
}
if(ramReadArrayA(x - 1, y + 1)) {
neighbourCount++;
}
if(ramReadArrayA(x + 1, y - 1)) {
neighbourCount++;
}
// decide if the cell will live or not based on its neighbours
if((ramReadArrayA(x, y) == HIGH) && (neighbourCount < 2)) {
ramWriteArrayB(x, y, LOW);
}
if((ramReadArrayA(x, y) == HIGH) && (neighbourCount == 2 || neighbourCount == 3)) {
ramWriteArrayB(x, y, HIGH);
}
if((ramReadArrayA(x, y) == HIGH) && (neighbourCount > 3)) {
ramWriteArrayB(x, y, LOW);
}
if((ramReadArrayA(x, y) == LOW) && (neighbourCount == 3)) {
ramWriteArrayB(x, y, HIGH);
}
neighbourCount = 0;
}
}
update();
}
void update() { // update the display
for(int x = MIN; x < imageWidth; x++) {
for(int y = MIN; y < imageHeight; y++) {
if(ramReadArrayB(x, y) == HIGH) { // if the cell is alive
oled.setPixel(x, y, GREEN);
}
else {
oled.setPixel(x, y, BLACK);
}
}
}
ramCopyArrays();
}
void initialise() {
for(int a = MIN; a < imageWidth; a++) {
for(int b = MIN; b < imageHeight; b++) {
int randomNum = 0;//random(0, 1234) % 2;
if(randomNum == 1) {
ramWriteArrayB(a, b, HIGH);
}
else {
ramWriteArrayB(a, b, LOW);
}
}
}
ramWriteArrayB(16, 16, HIGH);
ramWriteArrayB(16, 17, HIGH);
ramWriteArrayB(17, 16, HIGH);
ramWriteArrayB(17, 17, HIGH);
update();
}
void ramClear() {
for(long zxc = 0; zxc < 32768; zxc++) {
ram.writebyte(zxc, 0);
}
}
byte ramReadArrayA(long first, long second) { // For reading bytes from the first array
return ram.readbyte((second * imageWidth) + first);
}
void ramWriteArrayA(long first, long second, int data_value) { // For writing bytes to the first array
ram.writebyte((second * imageWidth) + first, data_value);
}
byte ramReadArrayB(long first, long second) { // For reading bytes from the second array
return ram.readbyte((second * imageWidth) + first + imageHeight);
}
void ramWriteArrayB(long first, long second, int data_value) { // For writing bytes to the first array
ram.writebyte((second * imageWidth) + first + imageHeight, data_value);
}
void ramCopyArrays() {
for(long arrayIndexA = 0; arrayIndexA < imageWidth; arrayIndexA++) {
for(long arrayIndexB = 0; arrayIndexB < imageHeight; arrayIndexB++) {
ramWriteArrayA(arrayIndexA, arrayIndexB, ramReadArrayB(arrayIndexA, arrayIndexB));
}
}
}
Anyway, I am using a Freetronics EtherMega (just basically Arduino Mega 2560 with inbuilt ethernet), a Freetronics OLED screen (just an SPI screen), and a 23k256 SRAM module.
But none of those are the problem. They all work fine together, no problems with SPI or anything.
The problem is I am getting results I don't expect. I have put in the seed as a 22 square, which should just stay as a square forever. But it seems there is a "leak" and the screen starts displaying pixels "leaking" from the top-right corner of the cube. By leaking I mean pixels that should be "dead" are becoming "alive" when they shouldn't.
Now, I think I have the reading and writing from the arrays correct; my idea was to represent the arrays, despite being 2D, in a linear representation. So to find [a] you would go along bsize_of_a and then add a, and you would be at [a]. And to get to that same point but in array 2 (I have two arrays on the same "line") you would do the same but add size_of_a so you start at the start of the second array.
However if I am missing something here please do say so (it's quite likely I missed something there).
But otherwise I don't know why the code wouldn't be working, could anyone please inform me of what is wrong?
Thank you.
P.S. Oh I forgot to mention: disregard the fact that the imageWidth and imageHeight are different on each code that won't make any difference, just the first code doesn't have the RAM for 128128 so it has 6363.