Weird problem with Game of Life

For C and ASSEMBLY users to post questions and code snippets for programming in C and ASSEMBLY. And for any other C or ASM course related questions.

Moderators: Benj, Mods

Post Reply
Spanish_dude
Posts: 594
Joined: Thu Sep 17, 2009 7:52 am
Location: Belgium
Has thanked: 63 times
Been thanked: 102 times
Contact:

Weird problem with Game of Life

Post by Spanish_dude »

Hi,

So, I'm making a Game of Life on a 16x16 LED Matrix display.
PIC : 18F2455
XT : 4MHz
E-Blocks: LCD & USB
Jumpers : LCD set to default, USB set to A
Driver : Default driver when using the USB Serial component
Flowcode : v3
I wanted to use as less memory as possible so instead of using 1 byte / LED, I used 16 int variables.
1 int = 2 bytes = 16 bits.

I am using an array of 16 int to use as "drawbuffer" (game_of_life_prev[]) and another one (game_of_life_next[]) to "create" the new cycle.
Because I haven't yet received the four 8x8 LED Matrix, I made a little VB program that receives the array of 16 int and prints each 16 bits of an int into a TextBox.

The Game of Life "algorithm" is programmed into the microcontroller.

I'll explain the VB program a bit more in details :
When the VB program is executed, it'll ask the user on which COM port the PIC is connected (mine is COM port 5).
You'll then see 16 TextBoxes for each int of the array.
There are also 2 buttons: a Start button and Receive button.
The start button sends a command ("<ST>") to the PIC so it'll know that the PC is ready to receive data.
The receive button sends a command ("<RY>") to the PIC so it'll know that it can send the data to the PC.

The VB program will then print each bit of each received int into the TextBoxes.
Note : This has already been debugged and works well.

The PIC program :
The PIC starts by initializing the USB Serial.
Once it's done it will wait for the "<ST>" command.
Next it enters the main loop and starts by writing the value of the next cycle into the previous one (game_of_life_prev[] = game_of_life_next[])
Next it'll wait for the "<RY>" command.

If it receives the "<RY>" command, it will send the 16 int.
This is done by getting the 4 nibbles of the int and sending its ASCII value between a start ('<') and stopbyte('>').
Ex.: if the integer is 0x34FD it will send "<34FD>" to the PC.

Once it has send everything to the PC it will make the "new cycle" into the game_of_life_next[] array.
The new cycle is done by checking every bit of the previous cycle and changing them "with the Game of Life rules" and writing everything into the new cycle array.
Checking, setting and clearing bits from each int is done with 3 defines in the supplementary code.

Code: Select all

#define SETBIT(pos, var) (var | (1 << (pos)))
#define CLEARBIT(pos, var) (var & ~(1 << (pos)))
#define GETBIT(pos, var) ((var & (1 << (pos))) && 1)
Then it'll loop back to the begin of the main loop and write the new cycle into the previous one (the drawbuffer).

Okay so now my problem :
The problem I'm having is that the value of only half of the bits in the int array changes with each cycle.
Only the last 8 bits (the lower byte) changes its value on each loop.
The first 8 bits (the higher byte) stays unchanged !

I have done a PC version of the Game of Life (it works great) and the "algorithm" is copy-pasted from there, so I don't understand why it has such a behaviour.

I thought maybe the boostC compiler doesn't like a for loop into another for loop ? (I haven't tried to change the for loops into while loops yet)

Right know I'm a bit tired of compiling-flashing-testing-failing-debugging-compiling-and so on. (It has been a week of trying and failing ...)

I hope someone can see something I don't and is messing up with the algorithm.

Attached are the PC Game of Life source code, the Flowcode Game of Life and the Excel file with the VB program.
I tried my best to add comments in the Flowcode Game of Life (I'm not the type of guy that writes comments everywhere in his code :P)
Attachments
Game of Life.zip
VB program + PC Game of Life src & bin + Flowcode Game of Life
(32.24 KiB) Downloaded 466 times

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: Weird problem with Game of Life

Post by JonnyW »

Hi Spanish_dude.

Without seeing the program this is only a guess. Is this on an 8-bit pic?

Chances are the bit-shifts are 8-bit. This means the instruction codes most likely only support (1 << 7) as the maximum shift available. I would guess that the ints are 'faked' using two byte values and accumulators.

Try for your defines:

Code: Select all

#define GETBYTE(pos, var) (*((char *)&var + (pos >> 3)))
#define SETBIT(pos, var) (GETBYTE(pos, var) | (1 << (pos & 7)))
#define CLEARBIT(pos, var) (GETBYTE(pos, var) & ~(1 << (pos & 7)))
#define GETBIT(pos, var) ((GETBYTE(pos, var) & (1 << (pos & 7))) && 1)
And see how these are (or something like that). This only requires 8-bit shifts.

If this doesnt work we can have a greater look at the Flowcode and see if there is any issues.

Lemme know how things go, cheers,

Jonny

Spanish_dude
Posts: 594
Joined: Thu Sep 17, 2009 7:52 am
Location: Belgium
Has thanked: 63 times
Been thanked: 102 times
Contact:

Re: Weird problem with Game of Life

Post by Spanish_dude »

Hi Jonny,
Yes, it's an 8-bit PIC.

I'm going to try with those defines right now.
I'll let you know if it works or not ;).

Thx anyway for your help !

Regards,

Nicolas L. F.

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: Weird problem with Game of Life

Post by JonnyW »

OK, good luck. If you'd like to see the problem at work on a PC, you can use the C code in Visual Studio (assuming you have it as you're using VB) to exhibit a similar problem:

Code: Select all

int x, y;
y = 33;
x = 1 << y;
printf("%d\r\n", x);

Spanish_dude
Posts: 594
Joined: Thu Sep 17, 2009 7:52 am
Location: Belgium
Has thanked: 63 times
Been thanked: 102 times
Contact:

Re: Weird problem with Game of Life

Post by Spanish_dude »

Hi again,

So I just tried the defines, it was kind of tricky to understand :P, but it didn't work :s.
Almost everything is cleared after one loop.

Could there be another way to fix this problem I'm having :/ ?

Thx for your help Jonny

Regards,

Nicolas L. F.

PS: I'm using VB in Excel. I use code::blocks as IDE.

EDIT: Never mind, I got it to work. :mrgreen:
Your defines works great.
The problem I got after testing with your defines was that instead of writing an integer into the integer array I wrote a byte (SETBIT and CLEARBIT returns a byte) so half of the integer was set to 0.

Thanks for your help Jonny !
Last edited by Spanish_dude on Fri Mar 18, 2011 6:29 pm, edited 1 time in total.

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: Weird problem with Game of Life

Post by JonnyW »

Hmm. Im unsure what could be the issue then.

Unfortunately I havent got a Pic8 to hand at the moment. The only thing I can suggest is that, having looked at the Flowcode maybe try bracketing the variables in the defines, though it doesnt look like this is a problem. Either that or big-endianness could be an issue though I doubt this too.

If you can debug the code then try it with a simpler program? Given the symptoms and the 8-bit platform Id be surprised if...

Oh, goddamit. Sorry. The defines I gave you take a single byte and set a bit of this! They wont work, my fault, sorry.

Those defines get a single byte and apply the bit-shift to this. This then needs to be added to the other byte to work. Its a little messy in pre-processor so heres a function and hopefully that will help.

Code: Select all

short set16(short var, char pos)
{
  char lo, hi;
  // Separate bytes
  lo = *((char *)&var + 0);
  hi = *((char *)&var + 1);
  // Apply shift
  if (pos < 8)
    lo = lo | (1 << pos);
  else
    hi = hi | (1 << (pos & 7));
  // Write back result
  *((char *)&var + 0) = lo;
  *((char *)&var + 1) = hi;
  return var;
}
Im afraid I havent tested this and it is a bit long winded, but it should work better than that other stuff I posted! You should be able to do similar functions for clear() and get().

Having spoken with Ben and Sean, apparently the pic8 should be able to do the bitshifts, but only if the shift is a constant, otherwise it might wrap.

Good luck and hope this helps,

Jonny

Spanish_dude
Posts: 594
Joined: Thu Sep 17, 2009 7:52 am
Location: Belgium
Has thanked: 63 times
Been thanked: 102 times
Contact:

Re: Weird problem with Game of Life

Post by Spanish_dude »

I edited my previous post, it seems to be working :mrgreen:

Thanks for your help !

User avatar
JonnyW
Posts: 1230
Joined: Fri Oct 29, 2010 9:13 am
Location: Matrix Multimedia Ltd
Has thanked: 63 times
Been thanked: 290 times
Contact:

Re: Weird problem with Game of Life

Post by JonnyW »

That's good news. Hope it all goes well!

Post Reply