ArduDisplay, when the display becomes interactive!

By on May 27, 2015
Pin It

featured_ardu

 

We are going to build an internet-connected, Arduino-based display, on which we could write directly from a smartphone, by sending the messages over WiFi.

 

In the late 90s of last century LED displays have begun to replace or complement the classic Signs on cinemas and business activities in general. Those displays could be programmed to allow owners to change messages every desired time, adding a sliding effect to the text (text-scrolling), in order to attract potential customers on the street, reporting their opening hours, promotions, news and any other useful information.

Today, in the IoT era (Internet of Things), we can integrate new technologies to LED display, increasing the interaction between it and users thus creating a kind of entertainment form that increases the permanence of the person in front of the display itself and, consequently, in the area where it is placed.

 

Figura1

Time Square (New York)  after the LED display era.

 

The project we will make allows people connecting to a WiFi network with their mobile devices, type a message through a web page and see it displayed on an LED display that we can place at our booth, at a fair or at a party, concert or club.

Our application will have a control panel (also accessible from the network) that will allow us to:

  • approve the messages received before sending them to the display,
  • set the displaying time of each message, the text scroll speed and a default message to display in the absence of messages received;

You can also decide not to filter messages: in this way all messages will automatically be placed in the queue to be displayed. Received messages will be deleted once displayed, but we can also choose to view them cyclically.

 

Components

To make ArduDisplay we will need:

  • Arduino Yun;
  • one to four LED display Sure 3208 (depending on how long we want our display);
  • a connection shield between Arduino and displays or male-male jumpers;
  • a microSD (bigger than 512 MB).

 

We have chosen to implement this project using Arduino Yun because this integrates: a microSD slot, a WiFi card and a Linux distribution called OpenWrt-Yun (from the most popular OpenWrt  ) that will allow us, with its 400 MHz processor and 64 MB dedicated RAM, to transform our Arduino into a web server equipped with PHP5 and MySQL database.

The Arduino source code will fetch messages through PHP (via the Bridge library) and display them on the screen, creating the text-scrolling effect, while the web server will allow users to send messages and allows us to manage them (approve or discard).

Messages and settings (for example, the text persistence) will be saved to a MySQL database.

PHP files and web pages will be stored on the microSD card, while the WiFi network that will connect users will be set up directly from Arduino.

 

Figura2

ArduDisplay functional scheme

 

The Sure Electronics LED display, and in particular the model 3208 we selected, has four 8×8 arrays each formed by 64 red, 3 mm adjustable intensity LEDs and is based on the Holtek HT1632C controller.

We can connect up to four displays in series thanks to IDC 16-pin cable; there are also two terminals with 5 V output voltage, if the current supplied by Arduino is not enough to feed all displays.

Our project will use, for simplicity’s sake, two of these displays.

Every display needs 0.36 Ah with all LEDs on at full intensity. Since we will use the default intensity (approximately half of the maximum available) and will not keep all LEDs on to display text, we will power the whole set through the Arduino pins 5V and GND (Arduino is powered through its Micro-USB connector).

As we said earlier, the microSD will store PHP files and web pages that will be visited by users to post messages, by us to manage the queue and by Arduino to pick them up and display them.

The wiring between the first display in series and our Arduino Yun will be made through a shield that will allow IDC cable direct connection to it.

 

Arduino Yún Configuration

In this section we will discuss the platform setup \in order to obtain as final result an Arduino web server capable of running PHP pages, store data to a MySQL database and create a local WiFi network called “ArduDisplay” that will not require a password to access it.

Also, when we will connect to “ArduDisplay” network we’ll type “http: //scrivi.mi” in the browser, and we will be redirected to the display sending messages page.

 

As a first step we download from our GitHub repositories the ZIP file containing the Arduino sketch, the necessary libraries to manage the display and the files to be put on microSD.

Once downloaded and unzipped, we’ll find, in addition to Arduino sketch and HT1632 folder, a folder named “Arduino” which must be put on the microSD root. This folder contains the ArduDisplay database installation and all PHP files that will be analyzed later; when done, insert the microSD into Arduino.

 

Figura3

MicroSD folder and files structure.

 

Unless your Arduino Yun is new, we should completely reset the default OpenWrt distribution: so we will delete any installations or configurations that could interfere with our project.

To reset the OpenWrt-yun, press the WiFi reset button (located next to the USB-A) for at least 30 seconds: Arduino will restore the factory settings, as if it had just been purchased; This will remove, among other things, all the files installed and also the network settings.

Remember that if following this guide something goes wrong you can always use this method to reset Arduino.

After the reset (or after you turn your new Arduino Yun on), you’ll notice a WiFi network named “Arduino Yun-XXXXXXXXXXXX” (where X represents the alphanumeric characters that vary for each Arduino). Let’s connect and type “http: / /arduino.local “or” http://192.168.240.1 ” to access the control panel, type the password (the default is” Arduino “), click on” Configure “, choose an existing WiFi network to connect to as we will need internet access; Let’s type the password if required and then click on the “Configure & Restart”.

Our Arduino will restart, connecting to the WiFi network that we set; at this point we need to find the IP address assigned by the router (eg 192.168.0.6) as it will be used to launch commands via SSH in the next step.

The IP address can be found in the router configuration page (usually reachable on 192.168.0.1 or 192.168.1.1) among the “Connected devices.”

The next step will be done through the command line, so we will connect to Arduino SSH shell using PuTTY.

Launch it and then insert in the “Host Name” field the Arduino IP address, click on the “Open” button, access as “root” with same password we used to connect to Arduino control panel. To install PHP5, launch the following two commands:

 

opkg update

opkg install php5 php5-cgi

 

Edit uHTTPd config file (OpenWrt-Yún integrated web server) to include PHP:

 

nano /etc/config/uhttpd

 

uncomment the line:

 

list interpreter “.php=/usr/bin/php-cgi”

 

Add the following line to have the uHTTPd to recognize “.php” files:

 

option index_page “index.php”

 

Close and save file (CTRL+X, Y and return).

Finally, restart uHTTPd server to enable the new settings:

 

/etc/init.d/uhttpd restart

 

Then we can install MySQL with the command:

 

opkg install libpthread libncurses libreadline mysql-server

 

Open MySQL config file:

 

nano /etc/my.cnf

 

Assign to “datadir” and “tmpdir” variables the following values:

datadir         = /srv/mysql

tmpdir          = /tmp

 

Close and save, then execute the following commands:

 

mkdir -p /srv/mysql

mysql_install_db –force

/etc/init.d/mysqld start

/etc/init.d/mysqld enable

mysqladmin -u root password ‘admin’

 

In this way we have created a MySQL server, associating it the user “root” and the password “admin”; Now we will have to install the MySQL module for PHP; to do this we run this command:

 

opkg install php5-mod-mysql

 

Open PHP config file:

 

nano /etc/php.ini

 

Uncomment the line:

 

extension=mysql.so

 

Also verify that you have the following block of code with parameters compiled in this way:

 

[MySQL]

mysql.allow_local_infile = On

mysql.allow_persistent = On

mysql.cache_size = 2000

mysql.max_persistent = -1

mysql.max_links = -1

mysql.default_port = 3306

mysql.default_socket = /tmp/run/mysqld.sock

mysql.default_host = 127.0.0.1

mysql.default_user = root

mysql.default_password = admin

mysql.connect_timeout = 60

mysql.trace_mode = Off

 

Save and close (CTRL + X, Y and Enter).

 

After creating the MySQL server we must populate it with our database and our tables. So let’s move to the folder where is the database:

 

cd /www/sd/

 

Open MySQL shell:

 

mysql -u root -p

 

And insert the database password, then run the following SQL command to create the database:

 

source ardudisplay.sql;

 

To verify that everything went well run these two commands:

 

use ardudisplay;

show tables;

 

We should see the table “frasi” (sentences) and the table “impostazioni” (settings).

Then exit from the MySQL shell:

 

exit

 

Figura4

Ardudisplay DB tables

 

Open the configuration file that will be used by our PHP files to connect to the database:

 

nano Common/db_class.php

 

Let’s make sure that this contains the parameters:

 

$this -> mysql_server = “localhost”;

$this -> mysql_username = “root”;

$this -> mysql_pass = “admin”;

$this -> database_name = “ardudisplay”;

 

Save and close (CTRL + X, Y and Enter).

 

Now that we have transformed our Arduino into a web server with PHP and MySQL database, we must ensure that when you type Arduino address on the browser, you are not redirected to the control panel, but to the page where to send posts; to do this we move to the folder where the web server files are, with this command:

 

cd /www/

 

Rename the file that redirects to control panel with these two commands:

 

cp index.html OLDindex.html

rm index.html

 

Create the PHP files that make the correct redirects:

 

nano index.php

 

Write the code inside:

 

<?php

header(“Location: sd/index.php “);

?>

 

Save and close (CTRL + X, Y and Enter).

 

After you clear your browser cache, when you enter the Arduino IP address you’ll be redirected to the message posting page.
At this point, we have to ensure that Arduino creates its dedicated Wi-Fi network. By holding down the Wi-Fi reset button for 5 seconds (but less than 30, otherwise we will lose all the work done so far) the initial network “Arduino Yun-XXXXXXXXXXXX” will be setup. Let’s connect to this network and go to control panel (http://192.168.240.1/cgi-bin/luci/webpanel/homepage), then click on “advanced configuration panel (luci) “, move to main menu’s “Network” section and then to subsection “Hostnames”.
In this section we will add a rule that will translate the IP address to “http: //scrivi.mi”: click on the Add button, insert “scrivi.mi” in Hostname field and select “–custom -” in the IP address field, then write “192.168.240.1”;

Finally click on “Save & Apply”.
At this point we will have the following addresses:

 

  • http://scrivi.mi to send messages to the displays;
  • http://scrivi.mi/sd/admin to manage the received messages and other settings (this section will be analyzed later in the article);
  • http://scrivi.mi/cgi-bin/luci/webpanel/homepage to connect to Arduino control panel.

 

The last operation we have left to do is changing the Arduino WiFi network SSID: we connect to advanced control panel (luci) using the new address, scroll down the page to the section “Wireless” and we click on our network name.
Then we type “ArduDisplay” in ESSID and we click on “Save & Apply”, wait until Arduino restarts and then connect to the network “ArduDisplay”.

 

PHP files analysis

Let’s look at the functions of each PHP file that we put on the microSD card.
In the “www” folder, which will be the root of our site, we find the file index.php: this file will be loaded immediately after typing “http: //scrivi.mi” and contains the text box to send a message to device.
The message will be received by the file invia_frasi.php who will write it in the database with a 0 status (to be approved) if we had set “Approve messages” to “Yes” in the control panel, otherwise 1 (approved), that means that our message will be directly queued to display without approval.
We then find the file ritorna_frasi.php, who will feed a new phrase every time Arduino will ask it through the “Process” object\; if the “Cycle phrases” mode is turned off it will extract the first sentence from the queue (with condition 1), otherwise the default sentence will be returned (it can be changed at any time from the control panel).

Each time you extract a sentence to show, this will be immediately deleted from the database.
If “Cycle sentences” mode is on the sentence extracted will not be deleted: in this way all the received sentences will be displayed cyclically.
The file ritorna_impostazioni.php is called by Arduino together with ritorna_frasi.php: they are responsible to set the screen duration (in seconds) of a phrase and the scroll speed (also selectable from the control panel that we will see below) to Arduino.

 

Moving to the “admin” folder, we find the index.php file that contains a simple text box to log in to control panel (via the file login.php); the default password to access the control panel is “admin”, you can change once logged.
Admin.php page allows us to do many different tasks: if “Approve phrases” option is active we will see the messages to be approved in the left box, the queued messages in the central box while in the right box we can change some ArduDisplay settings:

 

  • Password admin: It is the password to access the control panel;
  • Durata frase display: is the permanence time (in seconds) of a sentence on the LED display;
  • Velocità scroll: It is the text-scrolling speed;
  • Approva frasi: if set to “Yes”, the sentences must be approved before going to the display queue;
  • Ciclo frasi: phrases, once sent to the display, are not deleted since Arduino will cyclically show them;
  • Frase default: it is shown by default when no messages are present in the queue

 

Clicking the “Logout” button will invoke the file logout.php that will allow us to exit the ArduDisplay control panel.
The folder “Common” however, contains the javascript library that allows calls to be made to PHP files (jQuery), the CSS style sheet, the buttons images to approve or delete a received message and the db_class.php file that we analyzed in the previous paragraph and contains the PHP class and data to connect to the MySQL database.

 

Arduino sketch

In the ZIP archive you downloaded you will find a file named “ArduDisplay_v1.ino” and a folder called “HT1632”.
The display we used requires a library to work, represented by the above-mentioned folder.
To use it you must copy the entire folder to Arduino libraries directory (usually located in “Documents \ Arduino \ libraries”).
Now we can connect Arduino to the computer with the USB cable and open the file with the extension “.ino” in Arduino IDE.
Check that the COM port and Arduino model indicated by the IDE are correct, if so then you can proceed to compile and upload the code.
Let’s look at the code in the file by referring to Listing 1.

 

#include <Process.h>
#include <HT1632.h> 
#include <font_8x4.h>
byte numero_display=2;
byte wr =3;
byte data = 5;
byte cs1 = 6;
byte cs2 = 9;
byte cs3 = 0;
byte cs4 = 0;
int larghezzaTesto;
unsigned char* fraseCorrente =(unsigned char*) “”;
unsigned char* fraseVecchia =(unsigned char*) “”;
int translazione=0;
byte tempoDisplay;
int tempoDelay;
String id_frase=”-1”;
int iterazioni;
int cont=0;
void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  Bridge.begin();
  digitalWrite(13, LOW);
  switch(numero_display){
    case 1:
      HT1632.begin(cs1,wr,data);
      break;
    case 2:
      HT1632.begin(cs1,cs2,wr,data);
      break;
    case 3:
      HT1632.begin(cs1,cs2,cs3,wr,data);
      break;
    case 4:
      HT1632.begin(cs1,cs2,cs3,cs4,wr,data);
      break;
    default:
      break;
  }
  for(int i=0;i<numero_display;i++){
    HT1632.renderTarget(i);
    HT1632.clear();
    HT1632.render();
  }
  delay(40000);
}

void loop() {
  if(cont==0){
    for(int i=0;i<numero_display;i++){
      HT1632.renderTarget(i);
      HT1632.clear();
      HT1632.render();
    }
    caricaImpostazioni();
    cambiaFrase();
  }
  controlliDisplay();
  cont=(cont+1)%iterazioni;
}

void controlliDisplay(){
  for(int i=0;i<numero_display;i++){
    HT1632.renderTarget(i);
    HT1632.clear();
    HT1632.drawText(fraseCorrente, OUT_SIZE * (numero_display-i)-translazione , 0, FONT_8X4, FONT_8X4_END, FONT_8X4_HEIGHT);
    HT1632.render();
  }
  translazione = (translazione+1)%(larghezzaTesto + OUT_SIZE * numero_display);
  delay(tempoDelay);
}

void caricaImpostazioni(){
  Process p;
  String temp;
  p.begin(“/usr/bin/php-cgi”);
  p.addParameter(“-q”);
  p.addParameter(“/mnt/sda1/arduino/www/ritorna_impostazioni.php”);
  p.run();
  while (p.available()>0) {
    char c = p.read();
      if(c!=’|’){
        temp += c;
      } else {
        tempoDisplay=temp.toInt();
        temp=””;
      }
  }
  tempoDelay=temp.toInt();
  iterazioni=tempoDisplay*1000/tempoDelay;
}
void cambiaFrase(){
    Process p;
    String temp=””;
    p.begin(“/usr/bin/php-cgi”);
    p.addParameter(“-q”);
    p.addParameter(“/mnt/sda1/arduino/www/ritorna_frasi.php”);
    p.addParameter(id_frase);
    p.run();
    while (p.available()>0) { 
      char c = p.read();
      if(c!=’|’){
        temp += c;
      } else {
        id_frase=temp;
        temp=””;
      }
    }
    fraseVecchia=fraseCorrente;
    unsigned char b[temp.length()+1];
    temp.getBytes(b,temp.length()+1);
    fraseCorrente = b;
    if(fraseCorrente!=fraseVecchia){
      translazione=0;
      larghezzaTesto = HT1632.getTextWidth(fraseCorrente, FONT_8X4_END, FONT_8X4_HEIGHT);
    }
}

 


First, the libraries are included: the first one handles the communication between the two processors on the card, while the other two are necessary to manage the display, the third in particular associates to each character its graphical representation.

Then there is the number of displays, the declaration of pins needed for their control, followed by the variables declaration:

 

  • larghezzaTesto is the pixel width of the phrase to show;
  • fraseCorrente and fraseVecchia respectively indicate the sentence just received and the previous one, this is used to decide whether to reset the text position at the changing of the phrase (if the phrase does not change, it is not moved back to the origin, thus giving a sense of continuity);
  • translazione is the current phrase pixels shift respect to the origin;
  • tempoDisplay is the phrase displaying time, in seconds;
  • tempoDelay indicates the time in milliseconds to wait between two loop executions, a shorter time implies a greater sliding speed;
  • id_frase It is the database id of the sentence shown, and is required to implement the functionality “ciclo frasi”;
  • iterazioni indicates the number of times that the loop cycle must be executed before changing a sentence, this depends on tempoDisplay and tempoDelay, in fact if for example a sentence must be shown for 10 seconds with a time between one cycle and the other of 100 milliseconds, you will find that this will last for 100 cycles;
  • cont tracks how many iterations have been executed.

 

In “setup” instead we turn on a led that will be switched off as soon as the bridge between the two processors onboard has been established, then initialize the screen in different ways depending on the number of connected displays and clean it/them, waiting 40 second to start the WiFi network and Arduino web server.
In the cycle loop we check if the “cont” variable is equal to 0, this event occurs only when the program starts or when a sentence has been displayed for the set cycles number. If the occurrence is true, we turn off the display for the necessary time to change sentence. Then the functions caricaImpostazioni and cambiaFrase are invoked.
We then move on to the actual display management: the phrase is rendered on each screen with a proper shift (specific for each display) and then the shift is increased step-by-step (putting it to zero when the sentence has “passed” all the screens) waiting a period of time that depends on sliding speed (delay).
The last instruction of the loop increments the variable “cont”, setting it to zero when all the iterations have been executed.

The functions caricaImpostazioni and cambiaFrase invoke, using a Process type object, a PHP file present on OpenWrt-yun to manage the output they receive (a serial stream of characters).
The function caricaImpostazioni receives a text like “tempoDisplay | tempoDelay” then will extract from the string received the two parameters and assign them, after a conversion, to the relevant variables; cambiaFrase instead receives a stream of type “id_frase | message”.
While it is possible to directly assign the sentence id to its variable, to make the message just received understandable by the display libraries it is necessary to convert the String to Byte with the getBytes function. Finally we check if the new sentence is the same as the previous one: if not we cancel the translation vector and we conclude by calculating the width in pixels of the new sentence.
If you wanted to implement a different number of displays, simply change the variable numero_display and assign the correct pin number to variables cs1, cs2, cs3 and cs4.

 

Display Connection

 

After you have configured and loaded the Arduino sketch, we move to the connection between the display and the board; we can connect in two ways: the fastest way is certainly to use the dedicated shield, otherwise we will connect the first display to Arduino using the idc cable together with jumpers.
Following the figure we will connect jumpers to pins in the following way:

 

PIN Arduino PIN Display
3 WR
5 DATA
6 CS1
9 CS2
10 CS3
11 CS4
5V +5v
GND GND

 

After connecting the first display to Arduino, we can connect all the others in series using new IDC cables.
Regardless of the connection mode chosen, do not forget to set the address of each display (1 to 4) by using the dip switches on the rear.

 

Figura5

Connection between Arduino and the first display through jumpers.

 

Project end

At this point, we can position our ArduDisplay, power it (for example via Micro-USB) and wait about a minute for the software initialization and the setting of WiFi network.
If all went well, Arduino, finding no sentence to show, will display the default phrase.
We can connect with any device to the “ArduDisplay” network, type in the browser “http: //scrivi.mi” and send a test message.
Now let’s move to “http: //scrivi.mi/sd/admin”, accessing with the default password “admin” and confirm the message just received: after just a few seconds we will see it on display.

 

Figura6
Testing ArduDisplay.

 

From Store

ARDUINOYUN

About LucaBellan

Leave a Reply

Your email address will not be published. Required fields are marked *