Need help with C++

I am stuck with C++. The code should eventually draw a tilemap but I have strange effects I cannot explain. Maybe somebody can help me out. The code is quite simple actually.

http://pastebin.com/BLh16fT6

If you test this you will see three tiles that are correct. I wrote two comments where you can try the issues by yourself. Am I already scratching the memory limit? Am I reading rubbish data for some apparent reason?

Any help is appreciated.

This is obviously a problem with PROGMEM > http://playground.arduino.cc/Main/PROGMEM

I could fix it for reading from the ‘PlayFieldMap’ array using https://github.com/Chris--A/PGMWrap but there is no overloading function for ‘drawBitmap’ to pass the pointer.

PlayFieldMap is in program memory, so you can’t just access it directly as if it were in RAM.

unsigned char idx = PlayFieldMap[i];

should be changed to:

unsigned char idx = pgm_read_byte(PlayFieldMap + i);
1 Like

Is there a counterpart to ‘pgm_read_byte’ to write into the array?

void munchFood( const int x, const int y ) {
  const unsigned int tile = y * MAP_COLUMNS + x;
  const unsigned char data = pgm_read_byte(PlayFieldMap + tile) & 0x3F;
  PlayFieldMap[tile] = data; // does not have an effect
}

No, because program memory is read-only. If you need to alter the PlayFieldMap array then put it in RAM.

If I do I get this message from the compiler: Low memory available, stability problems may occur.

unsigned char PlayFieldMap[] = {0x00, 0x01, ....}; // 28*31 entries = 868bytes

Should I ignore this message?


Probably not. Now my Arduboy is bricked after the second compile.
avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
Found programmer: Id = “��”; type = }
Software Version =

It depends. The program will need a certain amount dynamically allocated RAM for local variables, the call stack, etc.

The warning is probably based on the typical amount of dynamic RAM that the program will need when running. If your program needs less than this amount, then it will be fine. If it uses more, then it will likely blow up at some point.

So I am doomed? Because after resetting Arduboy I can upload my game just once. The second time it throws those exceptions and I need to reset again.

It’s probably not truly “bricked”. The high use of RAM likely causes the sketch to modify the “magic” RAM location that the bootloader uses to detect a reset. If the sketch runs OK after it’s loaded but you can’t upload another sketch afterwards, then this may be the problem.

You can recover using the reset button, as you’ve done before, but as I’ve already mentioned in the other topic you created, it’s better to include a call to flashlight() after boot() so you can hold the UP button while powering up to allow another upload.

We are talking less then 1kb for that specific array.

Sketch uses 11906 bytes (41%) of program storage space. Maximum is 28672 bytes.
Global variables use 2136 bytes (83%) of dynamic memory, leaving 424 bytes for local variables. Maximum is 2560 bytes.

I do not know how bricked is defined, but I need to reset it now everytime. It works once and thats it.

I do not get this flashlight() thing though. If I now press UP and power on Arduboy I see a white screen and a bright LED lightning up. What is the point? The problem remains. No second upload.

And 1K is reserved by the library for the screen buffer. If your array uses about 1K then that leaves about 0.5K of the 2.5K total for everything else.

It’s an unfortunate problem with the bootloader. Instead of using the very last RAM location for its magic number, it uses a location farther down. High RAM usage sketches may clobber this location even though there is sufficient RAM to allow proper operation.

Then you must have a large amount of global variables that initialise RAM (and thus one that clobbers the magic number) before flashlight mode is entered. Unless you can reduce the amount of RAM used by global variables, you indeed do have a problem.

Nothing special. You can take a look if you like: http://pastebin.com/VkUxPspU

Sorry for being blunt, but I find that amazing that somebody actually built a device with such low specifications. 1.5kb free memory is just insanely low. For a simple Pacmac I need to optimise the hell out of it? I thought this is supposed to get people into programming not scare them away.

There are currently over 100 perfectly functional and enjoyable sketches written for the Arduboy that are able to make due with the “insanely low” amount of RAM available.

Yours is the first sketch I’ve heard of so far that can’t be recovered using flashlight mode.

Maybe check out Ardu-man for some ideas.

http://community.arduboy.com/t/ardu-man-inspired-by-pac-man/1550

Sorry again. I do not want to argue with you. I find it hard to believe that you cannot put a reasonable amount of RAM into such a device. Nevertheless, I will optimise the memory usage.

It is definitely not much ram to work with, however the limitation I most often come up against is in program space. If you’re looking for a way to handle tile maps check out Mystic Balloons technical page on the TEAM arg website.

http://team-arg.com/mybl-technical.html

The Virus LQP-79 page has a different way of handling tile maps for larger worlds.

http://team-arg.com/vlqp-technical.html

Another C++ beginner question. I need to check if a certain bit is checked in an unsigned integer.

This is my array with the food-pellets in my pacman map. Each integer represents one row. Each bit is than one column.

unsigned int pellets[] = {
  0x00000000, 0x7ff9ffe0, 0x42090420, 0x42090420,
  0x42090420, 0x7fffffe0, 0x42402420, 0x42402420,
  0x7e79e7e0, 0x20004000, 0x20004000, 0x20004000,
  0x20004000, 0x20004000, 0x20004000, 0x20004000,
  0x20004000, 0x20004000, 0x20004000, 0x20004000,
  0x7ff9ffe0, 0x42090420, 0x42090420, 0x73f9fce0,
  0x12402480, 0x12402480, 0x7e79e7e0, 0x40090020,
  0x40090020, 0x7fffffe0, 0x00000000
};

This is the method to check if a pellet is at a certain map position:

boolean evalFood( const unsigned int x, const unsigned int y ) {
  unsigned int row = pellets[y];
  unsigned int mask = 1 << x;
  return 0 != (row & mask);
}

I double-checked the values in the array and they are correct. However I get rubbish when displaying them. The pellets are shifted by 8 columns and truncated after 11 columns. Any help is appreciated.

Part of the fun is trying to see what can be done in low memory space. That said, we are working on a new system with more memory for the future. The cool thing is all of the memory optimization done now will pay off even more with the expanded space.

In some ways Arduboy forces you to make efficient code and is meant to challenge you. It’s meant to be fun!

Also, we just used an Arduino Leonardo as the basis of the system, not much additional system design was considered at the time! Keep us posted on the project!

1 Like