Code isn't uploading properly to my Arduboy

Hello, all! I need help with my code or the IDE possibly. Whenever I verify or compile the code, the Arduino IDE doesn’t present me with any errors, yet when I upload it to my Arduboy, it would either display nothing or it would display the last image the Arduboy was on before compiling, when it should illustrate the 2-D Array. Any help would be much appreciated!

Edit: It also gave me a usb malfunction message, so proceed with caution if you’re considering compiling this code to your Arduboy, as it might be tricky to reflash it afterwards.

#include <Arduboy2.h>
#include <EEPROM.h>
Arduboy2 arduboy;
BeepPin1 beep;

const uint8_t levels[8][12]
{ 
  //Lv1
  {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  
};

uint8_t block[8][12];
uint8_t GameState;

struct Construct
{
  void levelCreate()
  {
    
    uint8_t a;
    
    for(uint8_t e; a<=8; ++e)
    {
      
      block[a][e]=levels[a][e];
      
      if(e == 12 && a != 8)
      {
      
        e=0;
        a+=1;
      
      }
      
    }
    
  }
  
};


struct Illustrate 
{
  
  void levelVisuals()
  {
    
    arduboy.fillRect(0, 0, 96, 64, WHITE);
    uint8_t a;
    for(uint8_t e; a<=8; ++e)
    
    {
      
      switch(block[a][e])
      {
        
        case 1:
        
          arduboy.fillRect((e*8), (a*8), 8, 8, BLACK);
          
        break;
      
      }
      
      if(e == 12 && a != 8)
      {
        
        e=0;
        a+=1;
        
      }
      
    }
    
  }
  
};

Construct construct;
Illustrate illustrate;

void setup()
{
  
  arduboy.boot();
  arduboy.systemButtons();
  arduboy.audio.begin();
  beep.begin();
  arduboy.safeMode();
  arduboy.setFrameRate(32);
  
}

void gameloop()
{
  
  switch(GameState)
  {
    
  case 0:
  
    construct.levelCreate();
    illustrate.levelVisuals();
    
  break;

  }
  
}

void loop()
{
  
  arduboy.clear();
  gameloop();
  arduboy.display();
  
}

Do you ever initialise GameState?

Have you tried putting Serial.println() in at strategic spots to see if your code is doing what you think it is doing.

1 Like

The good news is that it doesn’t appear to be bricking my Arduboy, despite causing USB problems.
I would assume it would cause problems for those rare few Arduboys without the bootloader protection though.


You have several problems, but it seems the thing causing your problem is a mixture of:

  • Using a <= 8 instead of a < 8.
    • Arrays are zero-indexed, so an array of 8 times covers indices 0 to 7, excluding 8.
  • Not initialising a or e.
    • If you don’t initialise a variable then it gets filled with junk data. You should always initialise a variable before you use it.
    • The compiler will warn you about this if you go to File > Preferences and set Compiler warnings to All.

Edit:
In case you want to know the technical reason:
The actual bug is a buffer overrun.
At some point a will be larger than 7 or e will be larger than 11 and thus the code attempts to write beyond the memory allocated to your array.

Think of it as like drawing outside the lines of the picture you’re colouring,
or drawing on the dining room table instead of the paper you’re supposed to be drawing on.


Something that might make your life easier: You’re allowed to do this…

for(uint8_t x = 0; x < 12; ++x)
{
	for(uint8_t y = 0; y < 8; ++y)
	{
		block[y][x] = levels[y][x];      
	}
}

You also need to include:

if(!arduboy.nextFrame())
	return;

At the top of loop, otherwise the frame rate limiting doesn’t work and loop just runs non-stop.


Technically that won’t matter because global variables are all zero-initialised if they aren’t initialised explicitly, but it is indeed good practice to initialise all variables.

1 Like

Also if you want any more help, advice or information, feel free to ask.

It’s working now, thank you, @Pharap and @filmote! I’ve been stubbornly trying to solve this for a couple hours now.

I honestly never knew that was a thing that could be done for the Arduboy, or is it on the IDE itself?

1 Like

That’s good to hear. Tenacity will serve you well. :P

Sorry to cut in, but as I’m here…

You use Serial.println(someVariable) in the Arduboy code while your Arduboy is hooked up via USB to your computer and a serial monitor is open on your computer.
The Arduino IDE has a built-in serial monitor, as does VSCode with the Arduino extension.

To open the serial monitor in the Arduino IDE, press the little magnifying glass icon in the top right.
Alternatively Ctrl+Shift+M will also open it.
You need your Arduboy to be connected and turned on first though.

You can also put while(!Serial); in the setup() function to wait until a serial monitor has connected.

In this case it would have done you little good anyway because what you were doing was messing with the USB code somehow (I’d get a message saying “USB device malfunctioned” from Windows).

1 Like

Have you attempted a running start?

2 Likes

A duck, how topical…

Okay, that makes a lot of sense, thank you.

I got the same message as well. Probably should of mentioned that as well now come to think of it, but I didn’t expect anyone to actually compile it after describing what happened to my Arduboy. That was a fault on my part.


But in all seriousness, let me edit that in.

I am severely lacking in ducks. Does a dachshund work by chance?

1 Like

By the way, if you’re also going to use boot instead of begin,
please remember to include arduboy.flashlight().

With it, sometimes a non-flashing Arduboy will be flashable after entering the so-called ‘flashlight’ mode.
Without it, you don’t have that safety net and can end up having to use the reset button (which is a pain in the arse to time properly).

I’m guessing the main reason you’re using boot is to skip the logo screen for faster development?

I have zero clue how this is in any way relevant, but I’m not complaining. :P

1 Like

Mostly isn’t, just wanted an excuse to show that clip on 7:09-7:11 for both humor and because I have an unresting love for Dragon Ball series.

Will do from now on since that’s the case. So arduboy.safeMode() isn’t as safe as arduboy.flashlight() ironically?

1 Like

Oh right, I ran it outside the thread so the timestamp didn’t carry across. I see now.

Ah, actually, looking at the library, it seems there’s some overlap in functionality.

I’m not quite sure why flashlight isn’t implemented in terms of safeMode.
I might have to pose that question to @MLXXXp at some point.

In which case I think this should be a case of “use one or the other, but not both”.

1 Like

Flashlight mode was intended to be just that: a flashlight/torch used for illumination in the dark. It was added quite early, to the original Arduboy library by @Dreamer3 when it was discovered how bright the RGB LED could be. It was made a part of begin() with the intent that it would always be an available feature, regardless of the sketch loaded.

Reports of the bootloader “magic key” problem started later on. When the cause of the problem was determined, someone (maybe @Dreamer3 again) realised that flashlight mode would run in a tight loop without touching RAM, and thus would get around the problem, so suggested trying it (which worked). Since flashlight mode is available in almost all sketches, it became the standard suggested way of getting around the “magic key” problem.

The fact that flashlight can be seen as a “play on words”, when used to allow “flashing” of a new sketch, is just a coincidence.

Function safeMode() is intended to be a lower memory replacement for flashlight(), to still allow recovery from the “magic key” problem in sketches that are trying to reduce memory size by using boot() instead of begin().

When it was discovered that there was a possibility that flashlight() and safeMode() would not fix the problem, due to RAM being modified in an interrupt service routine, they were changed to address this possibility.

Correct.

2 Likes

The boot logo screen can be skipped by setting a flag in system EEPROM, so that’s not a good reason to use boot(). It should only be used for the various ways of saving memory for very large sketches (of which eliminating the boot logo code is one).

For a “one time” bypass of the logo, you can hold the RIGHT button while powering up or press it while the logo is scrolling down.

The SetSystemEEPROM example sketch, included with the Arduoby2 library can be used to set the flag that disables the logo.

1 Like

This is why I was asking @Revlis’s intent.

Had the answer been “yes” I would have mentioned the logo skipping feature.

Had the answer been “no, it’s to save memory” I would have suggested waiting until the program was much larger before resorting to not using begin.

Unfortunately in the online version of ProjectABE the logo is always drawn due to how the EEPROM is initialised.
I would assume the offline version has a way to specify the contents of EEPROM via an ‘EEPROM file’ of some kind, but I don’t actually know because I’ve never used it, I always test on hardware.

2 Likes

My bad once again, I must have missed the question. I had no clue that it was possible to skip the logo, though I was using it to save memory as well. So it was a bit of both, but I’ll change it to arduboy.begin();.

1 Like

As I say, you can change it back later, but until you genuinely need the space it’s extra effort for little extra gain.

No … I don’t believe some. I know the PokittoEMU has that capability so I wonder if it could be fitted to ProjectABE?

You can still press the RIGHT button before or during the logo if the short time it takes to display is much of a burden.

1 Like