Introduction: Remotely Controlled Multifunction Scoreboard Based on Arduino, ESP8266 and UPanel Firmware: Interface Development
The solution used here to remotely control Arduino by means of either smartphone
or tablet in place of push buttons, displays, etc. is applicable to many projects in which the microcontroller needs to be remotely controlled, so the application to the Multifunction Scoreboard (MFS) may be seen as a good guide for this simple and smart solution.
The project for realization of this MFS was born during the maintenance works of the 5 players soccer team’s field in which my son plays. The coach, imaging the field at the end of the works, said: “It would be great to have an electronic scoreboard out there”, indicating the area between the two coaching and team areas “but it is too expensive for an oratory team”. So I began to think a way to build one free of charge for the team and very cheap for me! I combined my current profession of electronic engineer and my family tradition of wooden boat builder.
In this Instructables I will show you the concept and the realization of the MFS’s interface mainly focusing on the state of art smartphone/tablet wireless remote control while in a future Instructables I will show you its physical realization.
Step 1: CONCEPT
Thinking of the information to be displayed, mainly score, timer, period, timeout and time, I observed only that numbers could change so I envisaged that I would have need of at least 4 digits, 7-segments display digit.
First problem: how to build the big 7-segments display digits?
After several hours searching internet I found few cases of custom big 7-segments display digits not having good look and, at the end, I decided to use the one I supposed performing enough based on styrofoam mask as described in https://www.sparkfun.com/tutorials/47 (Fig. 1a). I would have preferred to use a 3D printer as described in http://www.thingiverse.com/thing:1028309 (Fig.1b) but I haven’t got a 3D printer! Another solution it would have been to buy digits used in petrol totems but they are very expensive. I recommend 3D printer solution if you can. Anyway, in the solution with styrofoam mask, I decided to replace the LED stripes with 14 cm length COB LED bars (Fig. 1c) in order to achieve a total digit height of about 30 cm.
Second problem: how to remotely control the scoreboard?
The first idea was to use push buttons and leds preferably wireless or, at least, an infrared remote control but I was not convinced of the solutions because what I liked was to use a simplest state of art device like either smartphone or tablet avoiding solders and strange boxes.
Also in this case after searching internet I found an extremely simple and smart solution at http://www.miupanel.com/. A suite called µPanel consisting of an App, available for IOS and Android, downloadable for free and a cheap module able to bridge the App and a microcontroller using Wi Fi connection (Fig. 2) was found. The module is the famous ESP‑01 (based on ESP‑8266) equipped with µPanel firmware. In Fig. 2 also the voltage adapter ADP-01 is shown to adapt 3.3 V of the ESP-01 to 5.0 V. The App receives from the microcontroller, via the ESP module, a string of characters representing a screen panel and visualizes it in a similar way as an internet browser. Each screen panel consists of pictures, switches, buttons, leds and also more complex graphic elements as you can see at http://www.miupanel.com/. From each screen panel is possible to exchange commands and information with the microcontroller. A screen panel used in the MFS is shown in Fig. 2b and it is very simple compared with those realizable with the µPanel suite.
Third problem: what microcontroller do I use?
I decided to use Arduino Mega 2560 (Fig. 3) which could provide the required number of pins to drive the four 7-segments display digits (at least 28 digital pins).
I highlight that the choice of the µPanel suite was a win one because it allows for:
- wireless command and control of Arduino by means of screen panels with exceptional graphic displayed on either smartphone or tablet
- saving electronic components, wiring, solders, etc.
- high flexibility while designing the screen panels layout due to a large amount of virtual components allowing for an incremental development of both interface and Arduino sketch focusing the design on the functional aspects first and look aspects after
- high reliability due to hardware minimization
- no remote control cost
- upgrade of the functionality and interface of the MFS during its lifecycle.
At the end the trade off was: four 7-segments display digits built using COB LED bars sequentially displaying the required information, remotely controlled by either smartphone or tablet using µPanel suite and locally controlled by Arduino Mega 2560.
I decided to drive the four 7-segments displays through four Sainsmart 8 relay modules (Fig. 4) to mitigate the risk of the custom 7-segments display not working (I never built them before!) having as backup solution digits consisting of high brightness LED array.
Step 2: LAYOUT
To put on the paper all the ideas I started with the 7-segments display digit designed taking into account 14 cm length COB LED bars and the layout of the MFS (Fig. 5).
Since the same oratory has basket teams too I extended the project of MFS to count up to 199 simply adding a 2-segments display digit for Home and Guest driven by 2 additional relay. Anyway I finally built the multifunction scoreboard to count up to 99 even if HW and SW can support 199.
Sorry if some of the words shown on the multifunction scoreboard are in Italian but I live in Italy and I had to design the MFS to be understood by Italian people. Anyway adaptation to other languages is very simple.
After designing the layout I discover that the MFS would have been about 90 cm height and 140 cm wide so I decided to subdivide it into two parts to be folded during storage and transportation.
Step 3: INTERFACE
The interface consists of 6 screen panels as shown in Figg. 6 to 11.
Some of them are static panels, i.e. they do not change their look at runtime while others are dynamic and change their look at runtime on the basis of the Arduino sketch variable values. A good example of dynamic panel is shown in Fig.8; this panel simulates what is displayed on the real MFS reproducing the static layout designed at step 2.
The use of panels which simulate the real object status (in this case the MFS status) is recommended during design, development and test of the µPanel interface in order to complete both the interface and the Arduino sketch (or any other microcontroller software) avoiding the use of the real hardware.
In Fig.12 the possible transitions between the panels are shown.
In order to make easy the panels development an on line panel simulator is available at http://www.miupanel.com/Panel-Design/ONLINE-PANEL...
At the moment of publication of this Instructables the on line panel simulator is available only for visualization of a string defining the panel layout. The structure of the string describing a panel and all the graphical options provided are very well explained at http://www.miupanel.com/. Here it is sufficient to indicate that a panel has a layout structured as an array and each element of the array, called container, can be structured as an array as well and so on. Visualization options may be indicated either for each array element or for groups of array elements. Macro may also be used for repetitive operations.
In developing a panel it is necessary to pay attention to the great number of brakets that can easily lead to a mistake so, in order to store the string describing a panel, it is recommended to use a text file and a top-down design approach.
The following process has been used to define panel shown in Fig.7.
Panel has been subdivided in main containers with some options for dimensions, styles, background and foreground colors.
D!F90{^{-r30!228,114%90{T:SEZIONE1;}}_{-r30!228,114%90{T:SEZIONE2;}}_{-r30!228,114%90{T:SEZIONE3;}}_{-r30!228,114%90{T:SEZIONE4;}}_{T:SEZIONE5;}}
Copying and pasting the string in the online panel simulator the panel shown in Fig. 13a is obtained. The available orange (!F90) area is subdivided into 2 main containers. The former contains further 4 containers with blu diffused background (!228,114), white rounded (r30) contour (-) and dimension of 90 percent (%90) of the whole horizontal dimension of the container which contains them; the 4 containers are aligned (_). The latter container contains, at the moment, only text.
The final panel is then achieved detailing the content and the style of each container as detailed in the following and shown in Fig from 13a to 13h.
Section 1 ({T:SEZIONE1;}) has been subdivided into 2 sections on different rows and the same thing for section 2 ({T:SEZIONE2;}):
{T:SEZIONE1;}: --> {{T:SEZIONE1.1;}_{T:SEZIONE1.2;}}
{T:SEZIONE2;}: --> {{T:SEZIONE2.1;}_{T:SEZIONE2.2;}}
Replacing each substring the panel shown in Fig.13b is obtained.
Section 1.1 ({T:SEZIONE1.1;}) has been detailed to include 4 containers in 2 rows (_) and 2 columns (|) to contain push buttons to increment and decrement the match score:
{T:SEZIONE1.1}: --> {fb*10{^B5%40,10r80!FFF:LOCALI +;_B6%40,10r80!FFF:LOCALI-;{^B7%40,10r80!FFF:OSPITI+;_B8%40,10r80!FFF:OSPITI -;}}
Section 1.2 ({T:SEZIONE1.2;}) has been detailed to include 2 couple of 3 green digits in 2 columns:
{T:SEZIONE1.2}: --> {*10{-r30!228,114{LI5:0;&L15:0;&L25:0;}}|{&&}|{-r30!228,114{LJ5:0;&L35:0;&L45:0;}}}
Fig.13c shows the result.
Continuing to detail all the containers ….
{T:SEZIONE2.1}: --> {fb*10{^B9%30,10r80!FFF:CRONO;|L9G:0;}|{LAG:0;|^BA%30,10r80!FFF:TIMEOUT;}}
{T:SEZIONE2.2}: --> {^*10{-r30!228,114{L55:0;&L65:0;}}|{&&}|{-r30!228,114{L75:0;&L85:0;}}}
{T:SEZIONE3;}: --> {fb*10{^BB%26,10r80!FFF:SUPPL.;|LBG:0;}|{LCG:0;|^BC%26,10r80!FFF:RIGORI;}}
{T:SEZIONE4;}: --> {fb*10{^B3%40,10r80!FFF:TEMPO;}|{^B3%40,10r80!FFF:DISPLAY;}}
{T:SEZIONE5;}: --> {fb{*15{^BI%40,10r80!FFF:SIMULA;}}|{*15{^BH%40,10r80!FFF:ESCI;}}}
… we obtain the result shown in Fig.13f.
In this case it is possible to avoid the horizontal and vertical scroll bars try to adapt the panel to the device dimensions using the w style (Dw!F90; in place of D!F90;).
The result is shown in Fig.13g (Fig. 13h adjusts only the contour radius).
The Arduino sketch implements the dynamic version of the panel shown in Fig. 13h through a call to a function which subdivide the panel string in substrings and includes the runtime variables values.
void sendMatchPrimaryScreen () {
Serial.print(P("$P:D!F90;{^{-r30!228,114%90{{fb*10^{B5%40,10r80!FFF:LOCALI +;_B6%40,10r80!FFF:LOCALI -;}"));
Serial.print(P("|{^B7%40,10r80!FFF:OSPITI +;_B8%40,10r80!FFF:OSPITI -;}}_{*10{-r10!228,114{LI5:0;&L15:0;"));
Serial.print(P("&L25:0;}}|{&&}|{-r10!228,114{LJ5:0;&L35:0;&L45:0;}}}}}"));
Serial.print(P("_{-r30!228,114%90{{fb*10{^B9%30,10r80!FFF:CRONO;|L9G:0;}|{LAG:0;|^BA%30,10r80!FFF:TIMEOUT;}}"));
Serial.print(P("_{^*10{-r10!228,114{L55:0;&L65:0;}}|{&&}|{-r10!228,114{L75:0;&L85:0;}}}}}_"));
Serial.print(P("{-r30!228,114%90{fb*10{^BB%26,10r80!FFF:SUPPL.;|LBG:0;}"));
Serial.print(P("|{LCG:0;|BC%26,10r80!FFF:"));
if (defGame == 0) {Serial.print(P("RIGORI"));}
if (defGame == 1) {Serial.print(P("RIGORI"));}
if (defGame == 2) {Serial.print(P("TIRI"));}
if (defGame == 3) {Serial.print(P("****"));}
if (defGame == 4) {Serial.print(P("RIGORI"));}
if (defGame == 5) {Serial.print(P("RIGORI"));}
Serial.print(P(";}}}_{-r30!228,114%90{fb*10{^B3%40,10r80!FFF:TEMPO;}"));
Serial.print(P("|{B3%40,10r80!FFF:DISPLAY;}}}_{fb*15{{^BI%40,15r80!FFF:SIMULA;}}|{{^BH%40,15r80!FFF:ESCI;}}}}"));
Serial.println("");
if (screenId == startScreenId) { // current screen is Start Screen
handleStart();
};
screenId = matchPrimaryScreenId;
};
The final panel is shown in Fig.13h.
The complete string of Fig.13h is as follows.
Dw!F90;{^{-r30!228,114%90{{fb*10{^B5%40,10r80!FFF:LOCALI +;_B6%40,10r80!FFF:LOCALI -;}|{^B7%40,10r80!FFF:OSPITI +;_B8%40,10r80!FFF:OSPITI -;}}_{*10{-r10!228,114{LI5:0;&L15:0;&L25:0;}}|{&&}|{-r10!228,114{LJ5:0;&L35:0;&L45:0;}}}}}_{-r30!228,114%90{{fb*10{^B9%30,10r80!FFF:CRONO;|L9G:0;}|{LAG:0;|^BA%30,10r80!FFF:TIMEOUT;}}_{^*10{-r10!228,114{L55:0;&L65:0;}}|{&&}|{-r10!228,114{L75:0;&L85:0;}}}}}_{-r30!228,114%90{fb*10{^BB%26,10r80!FFF:SUPPL.;|LBG:0;}|{LCG:0;|^BC%26,10r80!FFF:TIRI;}}}_{-r30!228,114%90{fb*10{^B3%40,10r80!FFF:TEMPO;}|{^B3%40,10r80!FFF:DISPLAY;}}}_{fb{*15{^BI%40,10r80!FFF:SIMULA;}}|{*15{^BH%40,10r80!FFF:ESCI;}}}}
For the definition of the other panels the same technique has been used. In particular the scoreboard screen of Fig. 9 is statically defined as follows (see Fig. 14):
Dw!F90;{^{!000%98{{-r10%95,10*15{Tfbi#FF0:ATLETICO S. ANNA;}}_{-r10%95,50{{%95,10{{%20*10M1fbi#F00:RETI;}|{%20*10M2fbi#F00:CRONO;}|{%20*10M3fbi#F00:TEMPO;}|{%20*10M4fbi#F00:TIMEOUT;}}}_{%95*12{^%45{LI5:0;L15:0;L25:0;}}|{^%45{LJ5:0;L35:0;L45:0;}}}_{%95,10{{>%30*15M5fbi#0F0:LOCALI;}|{&&&&&&&&&&&&&}|{<%30*15M6fbi#0F0:OSPITI;}}}}}}}_{!228,114%98{{-r10%95{fb*10{^B5%40,10r80!FFF:LOCALI +;_B6%40,10r80!FFF:LOCALI -;}|{&&&}|{^B7%40,10r80!FFF:OSPITI +;_B8%40,10r80!FFF:OSPITI -;}}}_{-r10%95{fb*10{^B9%30,10r80!FFF:CRONO;|L9G:0;}|{LAG:0;|^BA%30,10r80!FFF:TIMEOUT;}}}_{fb*15{^B2%40,10r80!FFF:EXIT;}}}}}
At runtime the panel is dynamically managed by a call to a function to take into account the values of variables:
void sendScoreboardScreen () {
Serial.print(P("$P:D!F90;{^{!000%98{{-r10%95,10*15{Tfbi#FF0:"));
Serial.print(logo2);
Serial.print(P(";}}_{-r10%95,50{{%95,10{{%20*10M1fbi#"));
if ((mode == 0 && task == 1) || (mode == 1)) {Serial.print(P("F00"));} else {Serial.print(P("000"));};
Serial.print(P(":RISULTATO;}|{%20*10M2fbi#"));
if ((mode == 0 && task == 2) || (mode == 2)) {Serial.print(P("F00"));} else {Serial.print(P("000"));};
Serial.print(P(":CRONO;}|{%20*10M3fbi#"));
if ((mode == 0 && task == 3) || (mode == 3)) {Serial.print(P("F00"));} else {Serial.print(P("000"));};
Serial.print(P(":TEMPO;}|{%20*10M4fbi#"));
if ((mode == 0 && task == 4) || (mode == 4)) {Serial.print(P("F00"));} else {Serial.print(P("000"));};
Serial.print(P(":TIMEOUT;}}}"));
Serial.print(P("_{%95*12{^%45{"));
if (Ab2 != OFF_EXTRA) {
Serial.print(P("LI5:"));
if (Ab2 == UNO_EXTRA) {Serial.print("1");} else {Serial.print(Ab2);};
Serial.print(P(";"));
};
if (Ab1 != OFF) {
Serial.print(P("L15:"));
Serial.print(Ab1);
Serial.print(P(";"));
};
if (Ab0 != OFF) {
Serial.print(P("L25:"));
Serial.print(Ab0);
Serial.print(P(";"));
};
Serial.print(P("}}|{^%45{"));
if (Bb2 != OFF_EXTRA) {
Serial.print(P("LJ5:"));
if (Bb2 == UNO_EXTRA) {Serial.print("1");} else {Serial.print(Bb2);};
Serial.print(P(";"));
};
if (Bb1 != OFF) {
Serial.print(P("L35:"));
Serial.print(Bb1);
Serial.print(P(";"));
};
if (Bb0 != OFF) {
Serial.print(P("L45:"));
Serial.print(Bb0);
Serial.print(P(";"));
};
Serial.print(P("}}}_{%95,10{{%20*15M5fbi#"));
if ((mode == 0 && task == 1) || (mode == 1)) {Serial.print(P("0F0"));} else {Serial.print(P("000"));};
Serial.print(P(":LOCALI;}|{&&&&&&&&&&}|{%20*15M6fbi#"));
if ((mode == 0 && task == 1) || (mode == 1)) {Serial.print(P("0F0"));} else {Serial.print(P("000"));};
Serial.print(P(":OSPITI;}}}}}}}"));
Serial.print(P("_{!228,114%98{{-r10%95{fb*10{^B5%40,10r80!FFF:LOCALI +;_B6%40,10r80!FFF:LOCALI -;}"));
Serial.print(P("|{&&&}|{^B7%40,10r80!FFF:OSPITI +;_B8%40,10r80!FFF:OSPITI -;}}}_{-r10%95{fb*10{^B9%30,10r80!FFF:CRONO;|L9G:"));
Serial.print(timer);
Serial.print(P(";}|{LAG:"));
Serial.print(timeout);
Serial.print(P(";|^BA%30,10r80!FFF:TIMEOUT;}}}_{fb*15{^B2%40,10r80!FFF:ESCI;}}}}}"));
Serial.println("");
screenId = scoreboardScreenId;
};
Step 4: SKETCH
The complete Arduino sketch which, together with the µPanel suite, allows to test the MFS functionalities, including smartphone/tablet Wi Fi remote control, is available in this Instructables step for downloading. The electric circuit which shows how to connect Arduino and the µPanel suite is shown in Fig. 15. It has to be noted that to try the interface, only Arduino, ESP-01 with µPanel firmware and µPanel App are necessary.
Attachments
Step 5: TEST
Fig.16 shows some tests of the MFS, in particular Arduino sketch and µPanel panels tests.