Do you know the Pixel-Table project? I had the idea to realize such a pixel thing, but not as a table, instead to put it on the wall.
So that I can lying on the couch and play some games on it while relaxing. :)
Implemented games are:
- Space Invaders
- Pixel Draw
additional functions are:
- Show current time
- Show color animations
The PixelWall has an ESP8266 so it can connect to my home-WLAN. But it is also possible to use the PixelWall as an access point and connect directly to it.
To make it easy to use my PixelWall, the wall delivers a Website for control after connecting. All Apps are controllable/playable via the webpage. So it is not neccessary to install any software for usage.
Additionally there is a NES controller which makes it easier to play the games.
All software and mechanical drawings I putted on github: https://github.com/C3MA/PixelWall
Feel free to use it for your own project.
Step 1: Starting With the Electronic
From another project there is an existing PCB with WS2812 LEDs. The PCB has 3 rows with 12 LEDs each row.
I decided to use this PCB 6 times. So I get a 12x18 LED matrix.
First step was it to solder all the 216 LEDs, around 100 capacitors and an ESP8266.
The manually soldering needed about 10 hours.
After a first quick test it figured out: everything is working.
So we can go to the mechanic part.
Step 2: Creating the Mechanic
First of all we need a seperater for each pixel. The idea is to put the horizontal and vertical band via a V-cut together.
Each band has a thickness of 3mm and a height of 17mm. They are cutted from a HDF plate by a lasercutter.
All the scetches for the lasercutter are drawn in FreeCad (named "Leiste" in the mechanic folder of the github project)
The grid is given by the Layout of the PCB. It has a 28mm column width and 31mm row height.
Next question is: How to fix the bands on the PCB? Gluing isn't such a good idea, because it should be possible to disassemble if something is defect. So I decided to screw it. But a screw will split the 3mm thin band. So I printed with 3D printer a pocket for the band (this is the part named "Halter" in the github project). This worked pretty good to fix them on the PCB.
Next step is to get a frame for it. There are some online shops who offer to cut individual picture frames. So I ordered a frame with the size 343mm x 565mm.
The frame gets an additionally hole on the bottom side for the power supply.
The plexiglas front plate I also ordered online. It is a WN770 opal Milchglasoptik LD45% size: 567x344x2mm
It has a translucence of 45%.
Putting all parts together into the frame.
At the end there will be screwed some strips to the back, so that everything is fixed and cant fall out.
To have an option for operability of the pixelWall without any WLAN communication, I created an plugable control panel which can be inserted optionally on the right side of the frame (called "Bedieneinheit" in the github project).
Step 3: Software - Basics
One of the usecases is to play games on the PixelWall.
But writing a pixel game will always need a useful debugging environment. I dont know any way to debug ESP8266 controller in a suitable way. So I decided to simulate the whole code on my PC. The ESP code is written in Arduino C++, so I used Visual Studio C++/CLI language for the simulation on PC. There are some differences between standard C++ and the C++/CLI language. For example in C++/CLI you cant create an object of String type, due to garbage collection it is not allowed to create an object or reference/pointer to such an object. In C++/CLI you have to use handles: String^. But such handles didnt exists in C++ standard. So I had to be creative to bring both worlds together. I solved this by creating an own Arduino.h file for the simulation. This file just overrides in the simulation all strings through a define "#define String String^". This is not a common way, but it works :)
Except to some small compiler switches all the ESP code is than compilable in Visual Studio C++/CLI.
The first class I wrote is the LED-Matrix class. This class handles the control and mapping of the WS2812 LEDs.
This class was written two times: once for the ESP8266 controller (LEDMatrixArduino.cpp) and another one which will control shapes on the Form GUI in the simulation (LEDMatrixGUI.cpp).
This class provides some basic methods for setting and clearing an individual LED by its column and row.
Additionally it provides a setBrightness function. This value will be considered if an LED will be set. So all LED-set commands can be done with full brightness. For example: If the brightness is set to 50% and the setLed() function is called with RGBColor(255,255,255) it will set the LED to 127,127,127.
On top of the LED Matrix class I putted a LED Panel class. This class provides some useful functionallities for any application. It provides two indipendent layers. This can be helpful for the application. For example on tetris game: layer0 is for the fixed stones on the bottom and the layer1 is to display the falling stone. So each cycle the stone falls one pixel to the bottom, the application just can clear layer1 and draw the stone on its new position. Its not neccessary to redraw all fixed stones at the bottom.
Additionally the panel provides
printImage - to print some icons like smileys or WLAN symbol
printDigit - to print one digit at a specific position
printFormatedNumber - to print a number with prefixes zeros
printNumber - to print an integer number
printLineH - horizontal line with specific length
printLineV - horizontal line with specific length
Step 4: Software - Application Concept
The general concept for the pixel Wall is:
- Each application has its own name
- An application is started by calling the pixelWall URL including the application name (for example: 192.168.4.1/tetris)
- The URL can also have GET parameters which will be forwarded to the application
- Each application has to deliver a website which is displayed in the browser.
- This website can optionally open a websocket connection to the application for fast interactions
- The application can use this websocket connection to communicate back to the web frontend.
- Beside the web interface the application gets additionally push button events from the control panel and NES controller.
To make it easy to develop new applications for the PixelWall, I created an interface for applications named "IPixelApp.h". This interface containes 8 definitions:
- virtual void start() = 0;
- virtual void end() = 0;
- virtual void loop() = 0;
- virtual void newWebsocketData(uint8_t * payload, size_t lenght) = 0;
- virtual WebsiteResponse_t getWebsiteResponse(String parameter) = 0;
- virtual void buttonEvent() = 0;
- virtual void timerTick() = 0;
- virtual String getName() = 0;
start/end - this function is called if the application gets started / ended because another application starts
loop - this function is called from the main loop of the main programm. This call is irregular and outside of an interrupt.
newWebsocketData - this function is called if the web frontend sent data.
getWebsiteResponse - this is used by the main programm to get the webpage which should be respont to the request.
buttonEvent - this is called if any button on the control panel was pressed or released.
timerTick - this function is called each 10ms, triggered by a timer interrupt. It can be used for time base but must not contain any time intensive things, because its an interrupt context.
getName - this should return the name of the application for the URL
Step 5: Software - Applications
The following 7 applications are implemented in the current version:
This is a spezial App which displays the current WLAN state of the PixelWall. If the wall could connect to a present WLAN, it will display the IP Address which it got from the Network.
If it was not possible (has no ssid setuped or the WLAN is not present or the password is wrong) it will open an Accesspoint. In this case you can connect to the PixelWall via the default Accesspoint IP from ESP8266: 192.168.4.1
On the Webinterface this App presents 6 Buttons. By pressing the button you can start the appropriate Application.
This App for setup the WLAN SSID and password. Just insert the credentials of your WLAN and on the next start of the PixelWill it will try to connect to this WLAN.
There are three classic games programmed in the PixelWall:
- Space Invaders
All games can be played via the webinterface or with the NES controller.
This is a App which displays colors on the PixelWall. You can choose if it should be a moving rainbow, fading different colors, showing static color or just display random colored pixels.
With this App you can set each pixel seperately by tapping with your finger on the Webinterface. So you can draw some cracy pictures :)
Step 6: Control Via Twitch Extension
There is an Extension on Twitch named GetInTouch. This Extension allows to integrate Arduino projects into your livestream, so that viewers can control your arduino during streaming.
The Arduino library for this is written for Arduinos. But it turned out that it runs also on ESP8266 propably.
To use it in the Stream following steps are neccessary:
Step 7: Control by Nintendo NES Controller
After using it a while, it turns out, that playing on touch mobile phone is not so easy. From time to time you miss the buttons because you have no feedback on your finger whether you are over the button or not.
Additionally sometimes Websocket communication can leak for a short time.
Therefor I decided to buy an old Nintendo NES controller. This controller has a very simple interface. Its just a 4021 shift register which runs with 3,3V. So it can be connected directly to the ESP8266.
All button events on the controller where forwarded to the running application through the buttonEvent() function.