This port of following Arduboy dev libraries (check "libs" folder):
- Arduboy2
- Arduboy Tones
- Arduboy FX
- Arduboy Tones FX
- Arduboy Grayscale lib (Arduboy G)
- Arduboy SynthU
- FixedPointsArduino
and separate Arduboy libs
- Arduboy playtune -> ESPboy_Playtune
- Arduboy ATMlib -> ATMlib
from Arduboy project intended to run on ESPboy project.
It supports ESPboy buttons, LED, sound and TFT display with y-axis scaling.
This port compiles for ESP8266 ESPboy, existing Arduboy2-compatible games and apps. Some of them can use it as a drop-in replacement for the original "Arduboy2" library, other games will run after the slight source code modifications.
- Clone/download this repo somewhere on your computer.
- Now, we are going to replace the existing Arduboy2 libraries on your computer (if you have them installed).
- Navigate to Arduino\libraries folder on your computer and delete "Arudboy2" and "ArduboyTones" folders; take backup of both of them, if required.
- Copy "ESPboy_Arduboy2_lib" folder into Arduino\libraries folder and rename it to "Arudboy2".
- If you had downloaded the code as zip file instead of git clone, then you will have ESPboy_Arduboy2_lib_master folder instead of ESPboy_Arduboy2_lib.
- From within this new Arudboy2 folder, goto libs folder and remove "_master" from both directories.
- ArduboyTones-master --> ArduboyTones
- FixedPointsArduino-master --> FixedPointsArduino
- ArduboyFX-main --> ArduboyFX
- ArduboyTonesFX-master --> ArduboyTonesFX
- Copy the newly renamed libs into the main Arduino\libraries folder.
- Clone/download the ESPboy_Playtune and ATMlibrepo somewhere on your computer.
- Copy "ESPboy_Playtune" and "ATMlib" folders into Arduino\libraries folder.
- If you had downloaded the code as zip file instead of git clone, then you will have ESPboy_Playtune_master folder instead of ESPboy_Playtune.
- If game uses ArduboyG.h or SynthU.hpp, rewrite them with the same files from this repo "libs..." folder
- Goto Arduino\libraries\Arudboy2\GAMES folder and try to compile any main .ino file to check if everything is working fine; example Karateka\Karateka.ino.
- Note: the name of the game folder directory should be exactly same as the main .ino file; please rename the game folder directory as required, example "PPOT RoadTrip" --> "RoadTrip"
- FX-lib using is more complicated and i have to write it later :) ask me to force me to do this :)
- replace the "Arduboy2" library and "Arduboy tones" library in your Arduino Studio libraries folder with these versions.
- do ingame modifications according to the following notes:
- change "#include arduboy.h" to "#include arduboy2.h"
- some games use a function pointer array to pass control to a different parts of the code as the game state changes. In ATMEGA32U4 the memory address is 2 bytes (single word) long, in ESP8266, the memory addresses is 4 bytes (double word) long, So you need to change all "pgm_read_word" to "pgm_read_dword" or "pgm_read_ptr" at the pointers
- if EEPROM is used by the game to keep configs/high scores:
-
- change EEPROM.update() to EEPROM.write()
-
- add EEPROM.commit() after the last EEPROM.put(), EEPORM.write() of each blocks of code.
- For "ArduboyPlaytune" use ESPboy ported verstion and be sure you don't use "tone();" function anywhere (standard "tone();" function catches an interrupt which is ArduboyPlaytune also uses causing a reset)
- For "ATMlib" use ESPboy ported version and be sure to rename the folder from "ESPboy_ATMlib" to "ATMlib"
- you have to put ESP.wdtFeed(); in all loops like while(1) {...}. EPS8266 needs time to process WiFi stack and other internal SDK interrupts and can do it during the pauses like delay(0). Otherwise it watchdog resets.
- games that directly control the SPI or I2C bus to write to OLED display need much more work to port instead of the simple steps above.
- font() array is used in TFT_eSPI display library so you have to change all "font" to "font_"
- there is a problem with a "char" data (signed/unsigned problem). By default Arduino AVR "char" is signed and ESP "char" is unsigned. So you have to change all (where the variable is used not as char, but as int8_t) "char" to "signed char".
- it's also better to change all "short" to "int16_t", "unsigned shot" to "uint16_t", "byte" to "uint8_t", "int" to "int16_t", "unsigned int" to "uint16_t", "long" to "int32_t", "unsigned long" to "uint32_t"
- in AVR compiler "bool function();" returns FALSE in case of function out without "return(value);", but in ESP8266 compiler it returns TRUE
- abs(); function does not work properly with type "float" and "double". It rounds number to integer, so you have to implement your own "abs_();" function as "#define abs(x) ((x)<0 ? -(x) : (x))"
- "%" operator. "a%b" with "b==0" will lead to different results on AVR and ESP architecture. AVR returns "a" and ESP will reset with Error code "Illegal instruction" because a%b uses devision and devision by 0 forbidden.
- 8 keys
- TFT color LCD 128x128
- Faster MCU 80Mh/160Mhz
- RGB neopixel LED
- More memory for program and data. http://0x04.net/~mwk/doc/xtensa.pdf
- Internal flash memory mounted as SPIFFS disk 4-16mb for additional data
- WiFi onboard opens up the possibility for online games, top scores posting online
- OTA (on the air firmware update) update the firmware through WiFi from a web site, the same way as Android playmarket/ Apple istore.
- Cheaper overall cost
99% of the work on the library was done by the contributors to the following repositories:
Arduboy2 library:
- https://github.com/Arduboy/Arduboy
- https://github.com/MLXXXp/Arduboy2
- https://github.com/harbaum/Arduboy2
- https://github.com/hartmann1301/Arduboy2 hartmann1301 migrated the library to the ESP8266 platform
- https://github.com/cheungbx/esp8266_arduboy2
- https://github.com/edgarborja/Arduboy2ESP
Arduboy tones library:
And all the ARDUBOY COMMUNITY!
Please do read through the extensive documentation included there.
Check the LICENCE files in every folder!
If authors against posting the code in this repository for the purpose of learning programming and fun, please let me know, I'll remove it.
- Paintball FX G (BSD-3-Clause) by PPOT
- Oh Hell! FX G (BSD-3-Clause) by PPOT
- Magnets FX G (BSD-3-Clause) by PPOT
- Shroom Knight (GPL-3.0) by Onebit Matt
- Bone Shakers (GPLv3) by James Howard
- Defender FX G (BSD-3-Clause) by PPOT
- Sensitive G (???) spinal
- KUBE G (GPL-3.0) Onebit Matt
- Greenhorn Syndicate FX (???) Atom_Y
- Wolfenduino 3D FX James Howard
- Octopus (???) Roby
- Arduban (MIT) Rob Prouse
- Prince of Arabia FX (BSD-3-Clause) by PPOT
- Piracy - Avast Ye Landlubbers! (MIT license) by Prototype (Bert Veer)
- Choplifter (BSD-3-Clause) by PPOT
- 1943: The Battle of Midway (BSD-3-Clause) by PPOT
- ArduGolf - 18-Hole Mini Golf (MPL-2.0 license) by brow1067
- OBS - OneButtonShoter (BSD-3-Clause) by PPOT
- ArduRogue (MPL-2.0) by tiberiusbrown
- Ardulem (Open source)Alban Nanty
- RickArdurous (Open source) Alban Nanty
- 1944 Return to Midway (MIT) PPOT
- Evasion (MIT) by OBONO
- MiniRogue (BSD-3) by PPOT
- Arduchess (MPL-2.0) by tiberiusbrown
- A-maze (MIT) by Alojz Jakob
- Long Cat (MIT) by jaguile6, Dreamer2345
- Trials of Astarok (Unknonw) by press play on tape
- Number Puzzle (???) by t-iwasaki
- Horde and LATE (???) by justcallmekoko
- Onychophora (MIT) by renato-grottesi
- Cooties attack! (???) by Diego Tarragona
- Crates 3D (MIT) by Brian
- Space Quarth (MIT) by Schuemi
- ECOMD (MIT) by Team ARG
- Ardubrain (Proprietary) by renato-grottesi
- Arduminer (Proprietary) by Bergasms
- Asteroid Belt (???) by Xhaku Hans
- Diamonds (MIT) by redbug - Miguel Vanhove
- Crates (MIT) by jessemillar
- CascadePath (???) by Chris
- AsteroidBelt (???) by Xhaku
- Arduminer (???) by Bergasms
- Ardubrain (???) by renato-grottesi
- MayQ (Proprietary) by cobinee
- SFZ (Proprietary) by cobinee
- Lagunita (MIT) by renato-grottesi
- TeenyTank (MIT) by Jezzamon
- Humanity revenge (???) by Giangregorio
- 1nvader (BSD 3-Clause) by Press Play on Tape
- Bomberman (???) by LHW-HWT
- Juno First (BSD 3-Clause) by Press Play on Tape
- Domino (BSD 3-Clause) by Press Play on Tape
- Road Trip (BSD 3-Clause) by Press Play on Tape
- Blade Runner (Apache-2.0) by NoobGeek Ilya
- Leon Tamer (BSD 3-Clause) by Press Play on Tape
- Turtle bridge (BSD 3-Clause) by Press Play on Tape
- Ninja Fuzzgrauth (???) by Hundstrasse
- Puzzle pack (???) by Atomic
- Trolly Fish (MIT) by Team ARG
- Kong (BSD 3-Clause) by Press Play on Tape
- OilPanic (BSD 3-Clause) by Press Play on Tape
- FirePanic (BSD 3-Clause) by Press Play on Tape
- Bomberboy (???) by evgenykzz2
- CyberHack (BSD 3-Clause) by Press Play on Tape
- DarkStar (CC0 1.0) by Mr.Blinky
- Artillery (???) by Bergasms
- SanSan (???) by Chamekan
- MicroTank (Apache-2.0) by Thomas Hartmann
- LeannaTheLionAB (MIT) by SHDWWZRD of Neo Retro Games
- Shattered Lands - Towers Of Perdition (MIT) by tuxinator2009
- NewBlocksOnTheKid (GNU) by bateske Kevin
- unicorn_dash (MIT) by Yossa Von K
- Square Nose (by-nc-sa 4.0) by JuiceLizard
- Festive fight (Proprietary) by Jonathan Holmes (crait) & Mario Vespa (greycove)
- Kung-Fu escape (MIT) by Anthony Clarke (Sazazel)
- Midnight Wild (Proprietary) by Jonathan Holmes (crait) & Mario Vespa (greycove)
- Helii (MIT)BHSPitMonkey
- Pocket Fighter (unknown) WangRenxin
- Ardu Indy (unknown) by Jacoste
- Chrome Dyno (unknown) by flaki
- Space rocks (LGPL-2.1) by nootropicdesign
- Reversi (MIT) by OBONO
- Hopper (MIT) by OBONO
- Evasion (MIT) by OBONO
- Hollow Seeker (MIT) by OBONO
- Ardubullet (MIT) by OBONO
- ArduBloxx (Apache-2.0) by NoobGeek Ilya
- Catacombs of the damned (MIT) by James Howard
- Mystic Balloon (MIT) by TEAM ARG
- Sun Fire (MIT) by TEAM ARG
- Sirene (MIT) by TEAM ARG
- Arduventure (MIT) by TEAM ARG
- CastleBoy (MIT) by jlauener
- Dark And Under (BSD-3-Clause) by Garage Collective (Cyril Guichard (Luxregina), Simon Holmes (Filmote), Pharap)
- HelloCommander (MIT) by Felipe Manga (FManga)
- Blob Attack (MIT) by TEAM ARG
- Virus-LQP-79 (MIT) by TEAM ARG
- Kong-II (MIT) by Vampirics and Filmote
- LodeRunner (all 154 levels in a single game!) (BSD-3) by Simon Holmes (filmote)
- MicroCity (GPL-3.0) by James Howard
- SpaceCab (GPL-3.0) by Stephane C (vampirics) and Simon Holmes (filmote)
- The Curse Of Astarok (MIT) by Simon Holmes (filmote)
- Rayne the rogue (MIT) by shdwwzrd
- Space Battle - Trench Run (MIT) by Lucas Cardinali (lscardinali)
- MicroTD (CC0-1.0) by drummyfish
- Shadow-Runner-1.6.1 (MIT) by TEAM ARG
- Evade (MIT) by Modus Create
- Rooftop Rescue (MIT) by Bert van't Veer
- Crates 3D (MIT) by Badja (original) & Brian (port)
- JetPac (Proprietary) by Mike McRoberts
- Squario (Proprietary) Squario by arduboychris
- Circuit Dude (Proprietary) by Jonathan Holmes, upgrade to full color game!
- Omega Horizon (Proprietary) by shdwwzrd
- Ard-Drivin (MIT) by Rem and LP
- Tamaguino (GNU GPL v3.0) by Alojz Jakob, ported to Arduboy by Scott R
- Glove (MIT) by fuopy
- Blocks (GPL-3.0) by w3woody
- Galaxion (MIT) by tako2
- Karateka (BSD-3-Clause) by Simon Holmes (filmote)
- Tackle Box (MIT) by Matt
- Not Just a Hat Rack (Proprietary) by Hundstrasse
- Super-Crate-Buino-branched (LGPL-3.0-or-later) by Aurélien Rodot (ported by uXe)
- JumpBoy (Proprietary) by t-iwasaki
- ESP8266_ArduBOYNG - UNKNOWN
- ESP8266_breakout-v - UNKNOWN
- ESP8266_picovaders - UNKNOWN
Contributions to the documentation, code or electronics are welcome.
Use this library at your own risk.
The Arduboy2 library is maintained in a git repository hosted on GitHub at:
https://github.com/MLXXXp/Arduboy2
The Arduboy2 library is a fork of the Arduboy library, which provides a standard application programming interface (API) to the display, buttons and other hardware of the Arduino based Arduboy miniature game system.
The name Arduboy2 doesn't indicate that it's for a new "next generation" of the Arduboy hardware. The name was changed so it can coexist in the Arduino IDE with the current Arduboy library, without conflict. This way, existing sketches can continue to use the Arduboy library and class, without changes, while new sketches can be written (or old ones modified) to use and take advantage of the capabilities of the Arduboy2 class and library.
For notes on the differences between the Arduboy2 library and the original Arduboy library, and for information on migrating a sketch currently using the Arduboy library, see the sections at the end of this document.
Comments in the library header files are formatted for the Doxygen document generation system. The HTML files generated using the configuration file extras/Doxyfile can be found at:
https://MLXXXp.github.io/documents/Arduino/libraries/Arduboy2/Doxygen/html/index.html
A generated PDF file can be found at:
https://MLXXXp.github.io/documents/Arduino/libraries/Arduboy2/Doxygen/pdf/Arduboy2.pdf
The Arduboy2 library can be installed using the Arduino IDE Library Manager:
- In the Arduino IDE select from the menus:
Sketch > Include Library > Manage Libraries...
- In the Library Manager Filter your search... field enter arduboy2.
- Click somewhere within the Arduboy2 entry.
- Click on the Install button.
For more library installation information see
Installing Additional Arduino Libraries - Using the Library Manager
The begin() function, used to initialize the library, includes features that are intended to be available to all sketches using the library (unless the sketch developer has chosen to disable one or more of them to free up some code space):
At the start of the sketch, the ARDUBOY logo scrolls down from the top of the screen to the center.
The RGB LED lights red then green then blue while the logo is scrolling. (If your Arduboy is one of those that has the RGB LED installed incorrectly, then it will light blue then off then red). For users who do not wish to have the RGB LED flash during the boot logo sequence, a flag can be set in system EEPROM to have it remain off. The included SetSystemEEPROM example sketch can be used to set this flag.
A user settable unit name of up to 6 characters can be saved in system EEPROM memory. If set, this name will be briefly displayed at the bottom of the boot logo screen, after the logo stops scrolling down. This feature is only available if the Arduboy2 class is used, not the Arduboy2Base class. This is because it requires the text display functions, which are only available in the Arduboy2 class. A flag in system EEPROM controls whether or not the unit name is displayed on the boot logo screen, regardless of whether the unit name itself has been set. The included SetSystemEEPROM example sketch can be used to set both the unit name and this flag.
Once the logo display sequence completes, the sketch continues.
For developers who wish to quickly begin testing, or impatient users who want to go strait to playing their game, the boot logo sequence can be bypassed by holding the RIGHT button while powering up, and then releasing it. Alternatively, the RIGHT button can be pressed while the logo is scrolling down.
For users who wish to always disable the displaying of the boot logo sequence on boot up, a flag in system EEPROM is available for this. The included SetSystemEEPROM example sketch can be used to set this flag.
If the UP button is pressed and held when the Arduboy is powered on, it enters flashlight mode. This turns the RGB LED fully on, and all the pixels of the screen are lit, resulting in a bright white light suitable as a small flashlight. (For an incorrect RGB LED, only the screen will light). To exit flashlight mode the Arduboy must be restarted.
Flashlight mode is also sometimes useful to allow uploading of new sketches, in case the sketch currently loaded uses a large amount of RAM which creates a bootloader problem.
Pressing and holding the B button when powering on will enter System Control mode. The RGB LED will light blue (red for an incorrect LED) to indicate that you are in system control mode. You must continue to hold the B button to remain in this mode. The only system control function currently implemented is audio mute control.
Pressing the UP button (while still holding B) will set a flag in system EEPROM indicating audio enabled. The RGB LED will flash green once (off for an incorrect LED) to indicate this action.
Pressing the DOWN button (while still holding B) will set the flag to audio disabled (muted). The RGB LED will flash red once (blue for an incorrect LED) to indicate this action.
Releasing the B button will exit system control mode and the sketch will continue.
Note that the audio control feature only sets a flag in EEPROM. Whatever code actually produces the sound must use the audio.enabled() function to check and honor the mute state. Audio libraries written with the Arduboy system in mind, such as the available ArduboyPlaytune and ArduboyTones, should do this. However, be aware that for some sketches, which don't use the Arduboy2 or other compliant library and generate sounds in their own way, this method of muting sound may not work.
As with most libraries, to use Arduboy2 in your sketch you must include its header file at the start:
#include <Arduboy2.h>
You must then create an Arduboy2 class object:
Arduboy2 arduboy;
Naming the object arduboy has become somewhat of a standard, but you can use a different name if you wish.
To initialize the library, you must call its begin() function. This is usually done at the start of the sketch's setup() function:
void setup()
{
arduboy.begin();
// more setup code follows, if required
}
The rest of the Arduboy2 functions will now be available for use.
If you wish to use the Sprites class functions you must create a Sprites object:
Sprites sprites;
Sample sketches have been included with the library as examples of how to use it. To load an example, for examination and uploading to the Arduboy, using the Arduino IDE menus select:
File > Examples > Arduboy2
More information on writing sketches for the Arduboy can be found in the Arduboy Community Forum.
The Arduboy2 library reserves an area at the start of EEPROM for storing system information, such as the current audio mute state and the Unit Name and Unit ID. A sketch must not use this reserved area for its own purposes. A sketch may use any EEPROM past this reserved area. The first EEPROM address available for sketch use is given as the defined value EEPROM_STORAGE_SPACE_START
The library includes an Arduboy2Audio class. This class provides functions to enable and disable (mute) sound and also save the current mute state so that it remains in effect over power cycles and after loading a different sketch. It doesn't contain anything to actually produce sound.
The Arduboy2Base class, and thus the Arduboy2 class, creates an Arduboy2Audio class object named audio, so a sketch doesn't need to create its own Arduboy2Audio object.
Example:
#include <Arduboy2.h>
Arduboy2 arduboy;
// Arduboy2Audio functions can be called as follows:
arduboy.audio.on();
arduboy.audio.off();
The BeepPin1 and BeepPin2 classes are available to generate simple square wave tones using speaker pin 1 and speaker pin 2 respectively. These classes are documented in file Arduboy2Beep.h. Also, BeepDemo is included as one of the example sketches, which demonstrates basic use.
NOTE: These functions will not work with a DevKit Arduboy because the speaker pins used cannot be directly controlled by a timer/counter. "Dummy" functions are provided so a sketch will compile and work properly but no sound will be produced.
If all you want is to play single tones, using the built in BeepPin1 or BeepPin2 classes will be very efficient.
If you want to be able to play sequences of tones or background music, using the ArduboyTones library will be more code efficient than using ArduboyPlaytune or most other sound libraries compatible with the Arduboy. ArduboyTones even produces less code than the Arduino built in tone() function. You'll have to decide on the appropriate library or functions you use to generate sound, based on the features required and how much memory you want it to use.
If your sketch doesn't use any of the functions for displaying text, such as setCursor() and print(), you can remove them. You could do this if your sketch generates whatever text it requires by some other means. Removing the text functions frees up code by not including the font table and some code that is always pulled in by inheriting the Arduino Print class.
To eliminate text capability in your sketch, when creating the library object simply use the Arduboy2Base class instead of Arduboy2:
For example, if the object will be named arduboy:
Replace
Arduboy2 arduboy;
with
Arduboy2Base arduboy;
As previously described, the begin() function includes features that are intended to be available to all sketches during boot up. However, if you're looking to gain some code space, you can call boot() instead of begin(). This will initialize the system but not include any of the extra boot up features. If desired, you can then add back in any of these features by calling the functions that perform them. You will have to trade off between the desirability of having a feature and how much memory you can recover by not including it.
A good way to use boot() instead of begin() is to copy the code from the body of the begin() function, in file Arduboy2.cpp, into your sketch and then edit it to retain the boot() call and any feature calls desired.
As of this writing, the begin function is:
void Arduboy2Base::begin()
{
boot(); // raw hardware
display(); // blank the display (sBuffer is global, so cleared automatically)
flashlight(); // light the RGB LED and screen if UP button is being held.
// check for and handle buttons held during start up for system control
systemButtons();
audio.begin();
bootLogo();
waitNoButtons(); // wait for all buttons to be released
}
To incorporate it into your sketch just keep boot() and whatever feature calls are desired, if any. Comment out or delete the rest. Remember to add the class object name in front of each function call, since they're now being called from outside the class itself. If your sketch uses sound, it's a good idea to keep the call to audio.begin().
For example: Let's say a sketch has its own code to enable, disable and save the audio on/off setting, and wants to keep the flashlight function. In setup() it could replace begin() with:
arduboy.boot(); // raw hardware
// *** This particular sketch clears the display soon, so it doesn't need this:
// display(); // blank the display (sBuffer is global, so cleared automatically)
arduboy.flashlight(); // light the RGB LED and screen if UP button is being held.
// check for and handle buttons held during start up for system control
// systemButtons();
arduboy.audio.begin();
// bootLogo();
// waitNoButtons(); // wait for all buttons to be released
This saves whatever code display(), systemButtons(), bootLogo() and waitNoButtons() would use.
There are a few functions provided that are roughly equivalent to the standard functions used by begin() but which use less code space.
- bootLogoCompressed(), bootLogoSpritesSelfMasked(), bootLogoSpritesOverwrite(), bootLogoSpritesBSelfMasked() and bootLogoSpritesBOverwrite() will do the same as bootLogo() but will use drawCompressed(), or Sprites / SpritesB class drawSelfMasked() or drawOverwrite() functions respectively, instead of drawBitmask(), to render the logo. If the sketch uses one of these functions, then using the boot logo function that also uses it may reduce code size. It's best to try each of them to see which one produces the smallest size.
- bootLogoText() can be used in place bootLogo() in the case where the sketch uses text functions. It renders the logo as text instead of as a bitmap (so doesn't look as good).
- safeMode() can be used in place of flashlight() for cases where it's needed to allow uploading a new sketch when the bootloader "magic key" problem is an issue. It only lights the red RGB LED, so you don't get the bright light that is the primary purpose of flashlight().
The SpritesB class has functions identical to the Sprites class. The difference is that SpritesB is optimized for small code size rather than execution speed. If you want to use the sprites functions, and the slower speed of SpritesB doesn't affect your sketch, you may be able to use it to gain some code space.
Even if the speed is acceptable when using SpritesB, you should still try using Sprites. In some cases Sprites will produce less code than SpritesB, notably when only one of the functions is used.
You can easily switch between using Sprites or SpritesB by using one or the other to create an object instance:
Sprites sprites; // Use this to optimize for execution speed
SpritesB sprites; // Use this to (likely) optimize for code size
Warning: Although this will free up a fair amount of code and some RAM space, without an active USB interface uploader programs will be unable to automatically force a reset to invoke the bootloader. This means the user will have to manually initiate a reset in order to upload a new sketch. This can be an inconvenience or even frustrating for a user, due to the fact that timing the sequence can sometimes be tricky. Therefore, using this technique should be considered as a last resort. If it is used, the sketch documentation should state clearly what will be involved to upload a new sketch.
The ARDUBOY_NO_USB macro is used to eliminate the USB code. The exitToBootloader() function is available to make it easier for a user to invoke the bootloader. For more details, see the documentation provided for these.
A main goal of Arduboy2 is to provide ways in which more code space can be freed for use by large sketches. Another goal is to allow methods other than the tunes functions to be used to produce sounds. Arduboy2 remains substantially compatible with Arduboy library V1.1, which was the latest stable release at the time of the fork. Arduboy2 is based on the code targeted for Arduboy library V1.2, which was still in development and unreleased at the time it was forked.
Main differences between Arduboy2 and Arduboy V1.1 are:
- The ArduboyTunes subclass, which provided the tunes.xxx() functions, has been removed. It's functionality is available in a separate ArduboyPlaytune library. By removing these functions, more code space may become available because interrupt routines and other support code was being compiled in even if a sketch didn't make use them. Another benefit is that without the automatic installation of timer interrupt service routines, other audio generating functions and libraries, that need access to the same interrupts, can now be used. Removal of the tunes functions is the main API incompatibility with Arduboy V1.1. Sketches written to use tunes functions will need some minor modifications in order to make them work with Arduboy2 plus ArduboyPlaytune, ArduboyTones, or some other audio library.
- Arduboy library V1.1 uses timer 1 for the tunes functions. This causes problems when attempting to control the Arduboy's RGB LED using PWM, such as with setRGBled(), because it also requires timer 1. Since the tunes functionality has been removed from Arduboy2, there are no problems with using the RGB LED (except those caused by the RGB LED being incorrectly installed). Of course, using an external library that uses timer 1, such as ArduboyPlaytune, may reintroduce the problems. However, using a library that doesn't use timer 1, such as ArduboyTones, is now an option.
- The code to generate text output, using setCursor(), print(), etc., can be removed to free up code space, if a sketch doesn't use any text functions. The Arduboy2 class includes the text functions but using the Arduboy2Base class instead will eliminate them. With text functions included, the font table and some support functions are always compiled in even if not used. The API for using text functions is the same as Arduboy V1.1 with some additional functions added:
- setTextColor() and setTextBackground() allow for printing black text on a white background.
- getCursorX() and getCursorY() allow for determining the current text cursor position.
- The clear() function will now reset the text cursor to home position 0, 0.
- A new feature has been added which allows the audio on/off flag in system EEPROM to be configured by the user when the sketch starts. The flag is used by the Arduboy and Arduboy2 audio subclass, along with external sound functions and libraries, to provide a standardized sound mute capability. See the information above, under the heading Audio mute control, for more details.
- The color parameter, which is the last parameter for most of the drawing functions, has been made optional and will default to WHITE if not included in the call. This doesn't save any code but has been added as a convenience, since most drawing functions are called with WHITE specified.
- A new function digitalWriteRGB() has been added to control the RGB LED digitally instead of using PWM. This uses less code if just turning the RGB LEDs fully on or off is all that's required.
- The beginNoLogo() function is not included. This function could be used in Arduboy V1.1 in place of begin() to suppress the displaying of the ARDUBOY logo and thus free up the code that it required. Instead, Arduboy2 allows a sketch to call boot() and then add in any extra features that begin() provides by calling their functions directly after boot(), if desired.
- The ArduboyCore and ArduboyAudio base classes, previously only available to, and used to derive, the Arduboy class, have been made publicly available for the benefit of developers who may wish to use them as the base of an entirely new library. This change doesn't affect the existing API.
As of version 2.1.0 functionality from the Team A.R.G. Arglib library has been added:
- The sprite drawing functions, collision detection functions, and button handling functions that Team A.R.G. incorporated from the ArduboyExtra project. The poll() function was renamed pollButtons() for clarity. The Sprites class doesn't require a parameter for the constructor, whereas in Arglib a pointer to an Arduboy class object is required.
- The drawCompressed() function, which allows compressed bitmaps to be drawn. Saving bitmaps in compressed form may reduce overall sketch size.
Team A.R.G. has now migrated all of their games and demos to use the Arduboy2 library.
Since the Arduboy2 library can coexist in the Arduino IDE alongside the Arduboy library V1.1, a currently working sketch that uses Arduboy V1.1 doesn't have to be migrated to Arduboy2. However, if you want to switch a sketch to Arduboy2 for further development, in order to take advantage of any of the changes and enhancements, it's generally relatively easy.
The Arduboy2 library, for the most part, is compatible with Arduboy library V1.1 but migrating a sketch to Arduboy2 will require some small changes, and more so if it uses the tunes functions, such as tunes.tone() or tunes.playScore().
The first thing to do is change the include
for the library header file:
#include <Arduboy.h>
becomes
#include <Arduboy2.h>
If it was "Arduboy.h" (in quotes), it's still better to change it to <Arduboy2.h> (in angle brackets).
The same thing has to be done with creating the library object. (If the object name isn't arduboy, keep whatever name is used.):
Arduboy arduboy;
becomes
Arduboy2 arduboy;
If the sketch doesn't use any tunes functions, there's a good chance this is all that has to be done to make it compile.
If the sketch has sound but only uses tunes.tone(), solutions are:
An easy change is to use the Arduino built in tone() function. You can add a function to the sketch that wraps tone() so that it works like tunes.tone(), like so:
// Wrap the Arduino tone() function so that the pin doesn't have to be
// specified each time. Also, don't play if audio is set to off.
void playTone(unsigned int frequency, unsigned long duration)
{
if (arduboy.audio.enabled() == true)
{
tone(PIN_SPEAKER_1, frequency, duration);
}
}
You then change all tunes.tone() calls to playTone() calls using the same parameter values. For example:
arduboy.tunes.tone(1000, 250);
becomes
playTone(1000, 250);
Changing to the ArduboyTones library is slightly more complicated. The advantage is that it will generate less code than using tone() and will also allow you to easily enhance the sketch to play tone sequences instead of just single tones. ArduboyTones can also play each tone at either normal or a higher volume.
You have to add an include for the ArduboyTones header file:
#include <ArduboyTones.h>
You then have to create an object for the ArduboyTones class and pass it a pointer to the Arduboy2 audio.enabled() function. This must go after the creation of the Arduboy2 object, like so:
Arduboy2 arduboy;
ArduboyTones sound(arduboy.audio.enabled);
You then change all Arduboy tunes.tone() calls to ArduboyTones tone() calls using the same parameter values. For example:
arduboy.tunes.tone(1000, 250);
becomes
sound.tone(1000, 250);
See the ArduboyTones README file for more information on installing and using it.
See the following for how to do this:
If the sketch uses tunes.playScore(), probably the easiest solution is to use the ArduboyPlaytune library. ArduboyPlaytune is essentially the code that was in the Arduboy V1.1 tunes subclass, which has been removed from Arduboy2. It's been cleaned up and a few enhancements have been added, but all the Arduboy V1.1 tunes functions are available.
You have to add an include for the ArduboyPlaytune header file:
#include <ArduboyPlaytune.h>
You then have to create an object for the ArduboyPlaytune class and pass it a pointer to the Arduboy2 audio.enabled() function. This must go after the creation of the Arduboy2 object, like so:
Arduboy2 arduboy;
ArduboyPlaytune tunes(arduboy.audio.enabled);
The sound channels must then be initialzed and assigned to the speaker pins. This code would go in the setup() function:
// audio setup
tunes.initChannel(PIN_SPEAKER_1);
#ifndef AB_DEVKIT
// if not a DevKit
tunes.initChannel(PIN_SPEAKER_2);
#else
// if it's a DevKit
tunes.initChannel(PIN_SPEAKER_1); // use the same pin for both channels
tunes.toneMutesScore(true); // mute the score when a tone is sounding
#endif
If you name the ArduboyPlaytune object tunes as shown above, then you just have to remove the Arduboy object name from any tunes calls. For example:
arduboy.tunes.playScore(mySong);
becomes
tunes.playScore(mySong);
See the ArduboyPlaytune library documentation for more information.
If you don't need to play scores containing two parts, and don't require tones to be played in parallel with a score that's playing, then as an alternative to using ArduboyPlaytune you may wish to consider switching to ArduboyTones. This may require a bit of work because any ArduboyPlaytune scores would have to be converted to ArduboyTones format. It would involve changing note numbers to frequencies. This could be simplified by using the provided NOTE_ defines. Also, durations would have to be converted, including adding silent "rest" tones as necessary.
The benefit of using ArduboyTones would be reduced code size and possibly easier addition of new sequences without the need of a MIDI to Playtune format converter.
The beginNoLogo() function has been removed. Instead, boot() can be used with additional functions following it to add back in desired boot functionality. See the information above, under the heading Remove boot up features, for more details. Assuming the object is named arduboy, a direct replacement for beginNoLogo() would be:
arduboy.boot();
arduboy.display();
arduboy.flashlight();
arduboy.audio.begin();