Arduboy Types and their max, min, and unsigned values?

I understand that the Arduboy has a 8-bit processor but I am confused has to what types it can use. I noticed that when I use int I am really using short and that if I want the value of a int I have to use long int. I also noticed that when coding float and double seem to do the give the same precision (two decimal places).

What types does Arduboy support and what are their max and min values? What is the limitations of the Arduboy?

When it comes to coding for the arduboy int and short are used interchangeably (what I mean is int = short) which that means max, min and unsigned values are

//Short MIN is -32768
//Short MAX is 32767
//Unsigned short MAX is 65535

And long int is really int from a normal computer which means my max, min, and unsigned vales are

//Max value for long int (which is really the MAX val for int) is 2147483647
//Min value for lont int is -2147483648
//Unsigned long value for long int is 4294967295

And long long int does not work. Because that’s just too much for the 8-bit processor? When it comes to float and double. Float and double seem interchangeable in the way int and short are when it comes to the arduboy. I don’t get what my bounds are with either? Also how do I use precision if there is any? If I do something like

float test = 12.12345;
arduboy.print(F("FLOAT:"));
arduboy.setCursor(arduboy.getCursorX() + 2, arduboy.getCursorY());
arduboy.print(test);

It will only display “FLOAT:12.12” Does that mean in memory it is only stored as test = 12.12 or does arduboy.print() only print out a precision of two? And does the arduboy2.h library or arduboy.h library offer precision control or concatenation like stdio.h printf() or maybe iostream? Where you could write something like

int foo = 12.12345;
printf("\n %0.5f",foo)
int jeff = 57;
printf("\n Jeff's age is %d", 57+1);

Also what does that mean for arrays max values? And linked list and general memory management. Any help would be great thanks. I am still learning.

https://www.arduino.cc/reference/en/language/variables/data-types/int/

@filmote This is useful thanks. But do you know how to set a precision with a float to send back to the display?

Pretty sure the arduboy print simply extends the standard Serial print. In which case:

Serial.println(1.23456, 4) gives “1.2346”

https://www.arduino.cc/en/Serial/Print

2 Likes

HOLY COW! That makes so much sense now. I now I get how to do it. I did not realize that. Thanks. So is it possible to not use the arduboy or arduboy2 library at all? I can send the sketch

Uses a FOR loop for data and prints a number in various formats.
*/
int x = 0;    // variable

void setup() {
  Serial.begin(9600);      // open the serial port at 9600 bps:    
}

void loop() {  
  // print labels 
  Serial.print("NO FORMAT");       // prints a label
  Serial.print("\t");              // prints a tab

  Serial.print("DEC");  
  Serial.print("\t");      

  Serial.print("HEX"); 
  Serial.print("\t");   

  Serial.print("OCT");
  Serial.print("\t");

  Serial.print("BIN");
  Serial.print("\t"); 

  for(x=0; x< 64; x++){    // only part of the ASCII chart, change to suit

    // print it out in many formats:
    Serial.print(x);       // print as an ASCII-encoded decimal - same as "DEC"
    Serial.print("\t");    // prints a tab

    Serial.print(x, DEC);  // print as an ASCII-encoded decimal
    Serial.print("\t");    // prints a tab

    Serial.print(x, HEX);  // print as an ASCII-encoded hexadecimal
    Serial.print("\t");    // prints a tab

    Serial.print(x, OCT);  // print as an ASCII-encoded octal
    Serial.print("\t");    // prints a tab

    Serial.println(x, BIN);  // print as an ASCII-encoded binary
    //                             then adds the carriage return with "println"
    delay(200);            // delay 200 milliseconds
  }
  Serial.println("");      // prints another carriage return
}

to my arduboy but nothing happens in the display. I am guessing arduboy.h and arduboy2.h handle that? Is there simple command that lets me do it with out the library? Has anyone tried stuff like that?

Unfortunately, there is no simple way to render to the screen without using the Arduboy library or another library that knows the commands to send to the display. As you have discovered, the only other way to capture data is via the serial port and you will end up doing this a lot when you need to debug your code.

1 Like

I am trying to recall which game it was, but someone recently posted a game that didn’t use the Arduboy library at all and instead wrote straight to the screen. The arduboy library has a screen buffer allowing you to read and write to the buffer before pushing it to the screen. Without the buffer, you cannot control elements overwriting each other on screen easily. The downside is that the buffer takes 1Kb of the 2.5Kb available.

1 Like

Very interesting. I like the challenge of working with such little space. Freeing 1Kb if needed would be nice.

It’s possible to use the library and just use Arduboy2Core not Arduboy2… that will boot the hardware and give you low-level functions to write the screen, but not waste 1kb of RAM.

On the Arduboy:

char is 8 bits
short int is 16 bits
int is 16 bits
long int is 32 bits
long long int is 64 bits

If in doubt, you can use the macros declared in limits.h:

https://en.cppreference.com/w/c/types/limits

You can also use limits.h to figure out the size for yourself by doing:

arduboy.println(sizeof(int) * CHAR_BIT);

(CHAR_BIT is a macro that defines how many bits are in a char. It’s rare, for CHAR_BIT to not be 8, but some architectures don’t have 8 bit bytes.)

If you’ve read something telling you that int is supposed to be 32 bits then you’ve been lied to.

The actual definition of int as per the C++ standard is that it is guaranteed to be at least 16 bits, it mustn’t be smaller than 16 bits but it may be larger.

Typically on 32 bit processors it’s 32 bits and on 64 bit processors it’s 64 bits, but that’s not guaranteed.

Legally it only has to be 16 bits.

https://en.cppreference.com/w/cpp/language/types

Be aware that while they’re functionally equivalent on the Arduboy, short and int are not the same type and you shouldn’t use them interchangably.

By definition both short an int are defined as being at least 16 bits in size, but int will be of a size that is more optimal for speed (i.e. on a 32 bit system it will often be 32 bits) whereas short will be of a size that’s more optimal for space (i.e. it will often be 16 bits, even on a 32 bit system).

The fundamental types are defined by minimum ranges of values, not by absolute bit widths.
This is because because C++ is designed to be usable on lots of different processors with different rules and architectures.

It does work.

You just can’t print it because there’s no print(long long int) function.

On AVR chips, float and double have the same precision.
They are still considered different types though.
This behaviour is non-standard - it’s an exception for AVR chips because a proper 64 bit double would be impractical.

The thing to note here is that it’s actually the print function that’s behaving oddly.

The float always has the same amount of precision, but the print function by default only prints up to two digits of precision, to use more you must pass a second argument indicating the relative amount of precision that you want, e.g.:

arduboy.print(F("FLOAT: "));
// 16 indicates the precision
arduboy.print(12.12345f, 16);

If you’re worried about size, you’re best off using the fixed width integer types.

https://en.cppreference.com/w/c/types/integer

Note that the language that compiles for the Arduboy is actually C++, but the Arduino people didn’t implement the C++ standard library so the standard library facilities actually follow the C standard and thus aren’t in the std namespace.


Avoid linked lists because they typically don’t perform very well.
They’re less of an issue on processors that aren’t reliant on cache, but they’re still generally slow because of the amount of pointer indirection involved in their operation.

Avoid new and delete, avoid malloc and free.
Dynamic allocation should be avoided where possible even on modern computers, but on something like the Arduboy where there’s only 2.5KB of RAM (and 1KB of that is used for the frame buffer), it should be avoided almost completely (with a few rare exceptions).
Prefer to statically allocate everything if possible.


@Dreamer3 is correct here, but this means you won’t have access to the print functions and won’t be able to draw anything.

You’d then have to handle the drawing yourself which could get quite complicated.

2 Likes

Thank you this was exactly the information I needed to know.

If you’ve read something telling you that int is supposed to be 32 bits then you’ve been lied to.

Yes lol I have been lied too. I legit up until now always thought int was 32 bits. That why it was so supersizing to me. It makes sense though why its not and why it depends on the hardware. I only ever programmed on 64 bit cpus so I never had to think about it it before. Even in assembly class. Also good to know long long int does work. I don’t know how its physically possible lol. Kind of lame there is no way to print to screen for it. Maybe a update in the future for the libraries?

1 Like

I thought it would be.

Make sure to have a look at some of the links,
and maybe bookmark cppreference - it’s an excellent website.

It’s a common lie people tell students to make their lives easier.

If you’re only ever working with desktop computers, it’s usually not important because you usually don’t use numbers large enough to encounter overflow problems.

int is usually actually 64 bits on 64-bit CPUs, so it’s possible that you’ve been working with 64-bit ints and haven’t noticed because the 32-bit overflow point is very high.

Technically it’s possible to have numbers of arbitrary length as long as the CPU has a carry bit and an instruction that can add with carry.

You just do an add with carry on all bytes, starting with the least significant byte and working up to the most significant byte.
When you hit the most significant byte you either use an add without carry or use an add with carry and then clear the carry bit.

That one’s actually Arduino’s fault rather than the Arduboy’s fault.

All the print functions on Arduboy2 are inherited from the Arduino Print class.
It would be possible to add one, but I think needing to print a long long int is probably very rare.

32 bits can already hold values higher than the total amount of memory available in most AVR chips.


If you have any more questions, feel free to ask.

I’m probably the closest thing we have to a ‘C++ language expert’ here.

1 Like

Getting a 5x7 font on the screen or even full sprites (at even 8px intervals) isn’t very difficult. But yeah if you want to draw circles and lines and such or draw things overlapping other things with transparency you’ll have a tough time with no buffer. All depends what you’re trying to accomplish.

Using a 64-bit int on a 8-bit chip is going to be very slow and waste lots of flash storage (with all the low-level instructions required to fetch/store and then do a chain of 8 ADD operations)… even working with longs burns a significant amount of flash space compared to int16 or int8.

I am looking to be able to read, write, and clear the EEPROM. I am considering using the get() and put() functions. From https://www.arduino.cc/en/Reference/EEPROM

to store and fetch from the EEPROM but I am confused how to know how much EPROM I the arduboy has. And what amount of space I can play with. It says on the kickstarter there is 1KB EEPROM and I think that the arduboy2 library uses some of that memory and some of it is used for the device its self. I don’t want to overwrite something by mistake and brick my arduboy. Can you point me in the write direction?

It’s true that directly copying stuff to the frame buffer isn’t too hard if you can decipher the datasheet enough to understand how the display works, and honestly I found the datasheet to be rather complicated last time I looked.

The list of ‘commands’ wasn’t very comprehensive,
it left me with more unanswered questions than before I read it.

The Arduboy has 1024 bytes (1KB) of EEPROM.

The first 16 bytes are reserved and the Arduboy2 library uses the EEPROM_STORAGE_SPACE_START macro to indicate this:

(Personally I frown upon using defines for constants and prefer to use constexpr variables.)

So you have 1008 bytes free to use for saving,
but I would advice using an address later than 16 if you can.

In other systems, like SD cards, this usually isn’t an issue because they have a chip designed to do wear levelling, but the EEPROM chip in the Arduboy doesn’t do automatic wear levelling.

So if everyone saved to the start of EEPROM we’d end up with everyone having the early parts of EEPROM burned out and the later parts of EEPROM untouched.
To avoid this we (Arduboy programmers) generally pick a semi-random place to save to, to try to wear EEPROM out more evenly.

Also, don’t worry about overwriting other people’s save data, we had discussions about trying to come up with a system to avoid it, but in the end we couldn’t agree on a single system so overwriting other games’ saves is considered to be expected behaviour.

I find it’s best to just use the aliases defined in Arduino.h (or wherever the heck they actually live :slight_smile: ), ie int8_t, uint8_t, int16_t and all the rest. Rather than having to remember “oh yeah, shorts are 16 bits”, it’s just right in the name.

You don’t even have to learn much. Just take a sprite that already works with most of the existing draw routines and call SPI.write to send it to the screen. If it’s only 8 pixels tall it’ll just work (and show up repeatedly or in the top left corner). Now if you want to move the hardware “cursor” yes you’ll need to learn 1 or 2 commands… maybe Ive just been doing this too long, but it’s not that much to parse if you’re motivated.

If you have any specific questions I’d be happy to help.

And if all you wanted was to say display 8 lines of text you can just paint them straight to the screen. That’s actually why the (send8Pixels) or whatever I named it is included in Core… just the very minimum someone needs to start building different graphics drivers on top of the hardware.

But yeah I guess if your new to programming or struggling to build your first game trying to write your own graphics stack might not be the best learner project. :slight_smile: