PS2 Arduboy based on ESP8266

Hi everyone.

I wanna show you my ESP8266 based Arduboy in a ps2 controller. Actually it is more a controller for my other projects where I can also play a few games.

Here is a link with more pictures and informations: thiniverse link

As already said the main chip is an ESP8266. I found a ESP8266 branch of arduboy but It was a bit different with an additional arduino Nano. So I forked the old arduboy(ONE) library and changed a few lines to make it run.

I am using a few librarys to get all this working:

  • PS2X_lib to read the controller buttons (there is a branch with ESP8266 support available)
  • SSD1306_OLED_ESP8266 to write to the 128x64 I2C oled
  • Brzo_i2c is used by the OLEDDisplay lib for 800MHz I2C speed

I also had to made some little changes in the SSD1306_OLED_ESP8266 lib, so sharing my arduboy fork alone wouldn´t really help anybody else. I know nothing about licences so I am not sure if I could share ported games with anybody else.

After playing Squario, which was the first and only arduboy game I ported, i realised that allmost every other game now uses Arduboy2. And by porting I mean adding about 10 lines of code, the rest happens inside the Arduboy lib. I tried to get the Arduboy2 lib running but had some problems with it and the games, there is a lot avr specific code in them.

Right now I am programming my own game based on the old Arduboy lib. I kind of like it more, because I want to use all those adafruit like draw funktions and stuff.

CPU Speed is not an issue if you have 32bit and 80MHz. I hope it will also run fast enough on those avr chips. Flash is more than enough available, so I compile it now and than for a lenoardo board to keep in mind how much there is left if I had a real arduboy.

I also ported the gamebuino library to this platform. The games are easier to port but I do not like the even smaller display resolution, so I got back to arduboy.

13 Likes

I made some progresss with my project.

Changed my mind about the Arduboy2 lib, now I am using it. Had to replace the assembler parts but now it works very well.

Here is my fork: github

I changed the HelloWorld.ino and the Buttons.ino example to show how it can be used.

For audio support I also forked the ArduboyTones lib: github

I also changed the ArduboyTonesTest.ino example.

Games I ported with those librarys:

  • microtd: easy to port, no problems at all
  • bangi: had some problems but did work after some minor changes

How is your experience with porting from the AVR to the ESP?

I think the ESP32 could be a really incredible dev target and I think the environments are close from the 8266 to the 32? Or?

My experience was really good. After getting rid of all the avr pins, ports, assembler and timer stuff I just had to link the display library in. I learnd a lot and it was fun.

I do not own a ESP32 and I have not read a lot about it. It is way faster, I think with a chip like this you could easily control a color display with a lot more pixels.

I think my fork of arduboy2 should also work on a ESP32. The only little thing is I used everywhere these #ifdef ESP8266 lines. To compile it on a ESP32 you have to change those or #define ESP8266 in your code.

Here are some information about my Wemos d1 Mini ESP8266 build. The available pins are very limited, i used:
4 to SPI communicate with the ps2 controller and get the 6 buttons states.
2 to update the I2C display. (and get gyroscope chip data)
1 for a little speaker
1 ADC to measure the batttery voltage
2 Rx and Tx for debug (and bluetooth)
2 pins are free, I could have used them for ws2812 rgb leds

Some information about timings:
Updating the full display takes about 14ms. The display library is smart and remembers if you changed the whole area, if not it will only update the area where pixels changed and will be faster. But still this is the limiting faktor, everything else is done really fast.

Today I made a litte test I want to share. I built a breadboard arduboy based on my esp8266 code I used for the ps2 controller.

I connected 6 buttons and the I2C oled display, no sound and no leds because there where not many pins left and I was too lazy. Those buttons worked and with some little changes many games should be possilbe to play.

On the second picture the following test code is running:

#include "Arduboy2.h"

#ifdef ESP8266
#define I2C_SDA       D2
#define I2C_SCL       D1
SSD1306Brzo oled(OLED_I2C_ADRESS, I2C_SDA, I2C_SCL);

#define MY_BUTTON_A     D0
#define MY_BUTTON_B     D4
#define MY_BUTTON_UP    D6
#define MY_BUTTON_DOWN  D7
#define MY_BUTTON_LEFT  D5
#define MY_BUTTON_RIGHT D8
#endif

// Make an instance of arduboy used for many functions
Arduboy2 arduboy;

// some variables to count the frames pro seconde
uint8_t framesNow = 0;
uint8_t framesCurrent = 0;
uint8_t secondsNow = 0;
uint8_t secondsCurrent = -1;

// returns the frames displayed in the last second
uint8_t getFramesPerSecond() {

  // get the current second
  secondsNow = millis() / 1000;

  if (secondsNow != secondsCurrent) {

    // to reset only with every new second
    secondsCurrent = secondsNow;

    // save the last frames per second
    framesCurrent = framesNow;

    // reset the counter
    framesNow = 0;

  } else {
    // count
    framesNow++;
  }

  return framesCurrent;
}

#ifdef ESP8266
void getButtons() {

  uint8_t buttons = 0;

  if (digitalRead(MY_BUTTON_A))
    buttons |= A_BUTTON;

  if (digitalRead(MY_BUTTON_B))
    buttons |= B_BUTTON;

  if (digitalRead(MY_BUTTON_UP))
    buttons |= UP_BUTTON;

  if (digitalRead(MY_BUTTON_DOWN))
    buttons |= DOWN_BUTTON;

  if (digitalRead(MY_BUTTON_LEFT))
    buttons |= LEFT_BUTTON;

  if (digitalRead(MY_BUTTON_RIGHT))
    buttons |= RIGHT_BUTTON;

  arduboy.setExternalButtons(buttons);
}
#endif

void setup() {

#ifdef ESP8266
  arduboy.setExternalButtonsHandler(getButtons);

  // not sure if this is necessary
  pinMode(MY_BUTTON_A, INPUT);
  pinMode(MY_BUTTON_B, INPUT);
  pinMode(MY_BUTTON_UP, INPUT);
  pinMode(MY_BUTTON_DOWN, INPUT);
  pinMode(MY_BUTTON_LEFT, INPUT);
  pinMode(MY_BUTTON_RIGHT, INPUT);
#endif

  arduboy.begin();

  // set impossilbe high frame rate for max frames
  arduboy.setFrameRate(1000);
}

void printPressedButtonAt(uint8_t yPos, String buttonName) {

  arduboy.setCursor(20, yPos);
  arduboy.print(buttonName + " Pressed");
}

void loop() {

  if (!(arduboy.nextFrame()))
    return;

  // we clear our screen to black
  arduboy.clear();

  // need to change the screen because oled library updates only changed areas
  if (arduboy.everyXFrames(2))
    arduboy.fillScreen(WHITE);

  arduboy.setCursor(0, 0);
  arduboy.print(F("ESP8266 Test "));

  arduboy.print(getFramesPerSecond());

  // print buttons
  if (arduboy.pressed(A_BUTTON))
    printPressedButtonAt(9 * 1, "A");

  if (arduboy.pressed(B_BUTTON))
    printPressedButtonAt(9 * 2, "B");

  if (arduboy.pressed(UP_BUTTON))
    printPressedButtonAt(9 * 3, "UP");

  if (arduboy.pressed(DOWN_BUTTON))
    printPressedButtonAt(9 * 4, "DOWN");

  if (arduboy.pressed(LEFT_BUTTON))
    printPressedButtonAt(9 * 3, "LEFT");

  if (arduboy.pressed(RIGHT_BUTTON))
    printPressedButtonAt(9 * 4, "RIGHT");

  arduboy.display();
}

The display says 64 frames, this is the maximum of frames pro second this built can do. Mostly because of the slow I2C bus, a arduboy.display() takes about 13ms. So games with 60 FPS could be a bit slow, because there is not much cpu time left for other things.

If this is compiled for the leonardo and put it in the emulator than round about 140 frames will be displayed.

That´s it.

working on ESP8266 arduboy like project

could i use your fork of arduboy2 lib to port futher?

Yes of course, I hope it helps you a bit. I am curious about your changes. If you have some questions feel free to ask, maybe I can help.

(I updated the readme of my repo with some eeprom infos)

1 Like

Thank you so much. I’am on the way )

It’s much work to do and one of the ideas is to implement web browser. It’s a first step to OTA (over the air) software update using WiFi without any wires, IDEs, compilers…

OLED is too small but i remember old times of mobile phones with small bw displays and WAP worked fine there. It’s also possible to attach 128х128 color TFT with much more space and colours…
Anyway looking around i found “Arduino PIP web browser” https://hackaday.io/project/3116-pip-arduino-web-browser
It’s seemed to me that it’s possible to port it to the ESP8266.

Totally agree

But having a display with 128x128 pixels wouldn´t help a lot if all the games only use half of the screen in black and white.

I was thinking about scaling the arduboy pixels, and with scaling factor two I mean to just use four pixels to display one arduboy pixel. Sadly the common and cheap
spi display resolutions are not ideal for scaling the arduboy screen.

DisplayScales

I think it is absolutly crazy to use a color display with a high resolution to show arduboy stuff in two colors and a low resolution. But I already have one of those 240x320 pixels displays at home. Also I think the ESP would be powerfull enough and the spi fast enough to do this madness. So maybe I will try this soon.

I can´t help you with the wifi stuff, my knowledge about that is really small.

1 Like

I have checked lot of colour displays IPS and TFT with esp8266.
The best to my mind is 1.44’’ TFT 128х128 and it ideally fits the form factor of the ESPboy device
and there is a special slot for OLED and this TFT on the final version of my psb…
i think the same way, meaning to software emulation the bw 128х64 OLED on the color TFT 128х128 in the ARDUBOY2 lib )

the idea is to keep compatibility of the new device with all previous bw games and apps and at the same time to bring new possibilities of 128х128 color tft

i think it’s real )

I updated my controller a bit.


This is maybe the first homemade arduboy with an ili9341 touchscreen and an ESP32 chip.

You can see in the picture above, using only 128x64 pixels of those 320x240 pixels makes playing really ridiculous. So I scaled every arduboy pixel to a block of four display pixels. Doing this i am using 256128=32.768 of the 320240=76.800 pixels in total. Still far away from being optimal but okay for me.

The ili9341 SPI interface is really fast, but updating the screen with 60 FPS and more was challenging. The problem is there are now 4 times the pixels and every pixel has 16bit color instead of 1 bit of the oled screen. I had to use two big pixel buffers and some other tricks to be that fast.

It is hard to see in the shaky video, I scaled the pixels and played around with some color filters. And with color filter I mean replacing some black pixels that are next to many white pixels with a dark color and replacing some white pixels with a light color. Sometimes the picture gets a bit blurry but often I like the look with the new colors.
Here is a example Picture, first one is original, second with 2 greyscales and the third with yellow and magenta.

Here is a picture of the of Catacombs of the damned. I think it looks really good with some extra colors.

If someone is interessed how I did this check the github links at the top or just ask. The code is messy but it works somehow :laughing:

5 Likes

Lol this is kind of insanely great