Manage a connection between PHP and an Arduino board

published: 3 June 2019 / updated 4 June 2019

Lire cette page en français

 


Prerequisites

To communicate a Web application with an ARDUINO card, you must first:

To make communication tests between your web server and the ARDUINO card, create a subdirectory arduino in your development space on the server PC and assign an arduino alias to the Apache server link with this directory arduino. You can open the web page by typing as URL: http://localhost/arduino/.

ATTENTION

To work, the ARDUINO board must always be connected to the PC on which the Apache server is installed.

The Apache server runs in the background and does not prevent the PC for other uses.

Pausing or stopping the PC on which the Apache server is installed interrupts communication between the scripts in PHP language and the ARDUINO card.

The PHP script will not work if it is installed on a remote server.

The HTML code and PHP rough formwork

We connected our ARDUINO board containing the FORTH language on the COM7 serial port USB cable.

From this moment, we will replace the communication terminal <-> card with a communication web server <-> card. To do this, it is imperative to close the terminal that communicates with the card if this terminal is open.

In the arduino directory corresponding to the arduino alias, we create the index.php file that contains the following content:

<!DOCTYPE html>
<html>
<head>
<title>gestion carte ARDUINO sur COM7</title>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
</head>
<body>
<article>
<h1>Gérer une liaison entre PHP et une carte Arduino</h1>
<?php
$device = "COM7";
exec("mode $device BAUD=38400 PARITY=n DATA=8 STOP=1 xon=off octs=off rts=on");
$comport = @fopen($device, "wb+");
var_dump($comport);
if ($comport) {
    sleep(1);
    fputs($comport,"\n");
    sleep(1);
    $result = fgets($comport);
    var_dump($result);
    fputs($comport,"words\n");
    sleep(1);
    $result = fgets($comport);
    var_dump($result);
    sleep(1);
    $result = fgets($comport);
    var_dump($result);
    fclose($comport);
}
?>
</body>
</html>

ATTENTION

The PHP code given as an example is raw formwork. It is Windows compatible and must be adapted if you are running Linux.

There are no error tests or code optimizations.

If your Apache server is active, open the browser of your choice (Firefox, Chrome, etc ...), and in the URL bar, type:
  http://localhost/arduino/

PHP code execution result in index.php:

Gérer une liaison entre PHP et une carte Arduino
 
C:\HTMLEDIT\arduino\index.php:15:resource(4, stream)
 
C:\HTMLEDIT\arduino\index.php:21:string '?E FlashForth 5 ATmega2560 22.05.2019
 
' (length=39)
 
C:\HTMLEDIT\arduino\index.php:25:string 'words
 
' (length=8)
 
C:\HTMLEDIT\arduino\index.php:28:string 'p2+ pc@ @p hi d. ud. d> d< d= d0< d0= dinvert d2*
d2/ d- d+ dabs ?dnegate dnegate s>d rdrop endit next for in, inline repeat while again
until begin then else if zfl pfl xa> >xa x>r dump .s words >pr .id ms ticks r0 s0 latest
state bl 2- ['] -@ ; :noname : ] [ does> postpone create cr [char] ihere ( char ' lit
abort" ?abort ?abort? abort prompt quit true false .st inlined immediate shb interpret
'source >in tiu tib ti# number? >number ud/mod ud* sign? digit? find immed? (f)
c>n n>c @+ c@+ place cmove word p'... (length=1307)

If you have this result, it's because the PHP script has perfectly communicated with the ARDUINO card!

In our PHP code, we ran fputs($comport,"words\n");. In clear, we passed the word FORTH words followed by a carriage return \n (equivalent to pressing Enter).

We put a one second delay between each order, the time for the stamp receive the information transmitted by the ARDUINO card, here the contents of the FORTH dictionary after execution of words.

Interest of this type of connection

From the WEB server, it is possible to query the parameters of the card, state of the pines, registers, etc ...

Example: your card reads the temperature of a horticultural greenhouse. With the web server you can query the ARDUINO card and save in a real database these temperature readings.

Since the character strings transmitted to the ARDUINO card are generally FORTH words, you can remotely activate any function. In the case of our horticultural greenhouse, Ventilation can be closed if the general temperature is too low.

If your web server is visible from the Internet (provide secure access), you can access your server from anywhere in the world, whether from a PC, tablet, a smartphone ...

We will see this in a detailed and very simple example: how to light and turn off an LED connected to pin 26.

Turn on and off an LED from the Internet

We will analyze in detail how FORTH will help us manage the ports on an ARDUINO board, but especially how FORTH will communicate with a web application.

Manage in FORTH a led on the pine 26

We will first set the registers of PORT B and define the bit mask of pin 26:

37 constant PORTB    \ définition registre PORT du port B 
36 constant DDRB     \ définition registre DDR  du port B 
35 constant PINB     \ définition registre PIN  du port B 
%10000000 constant PIN26 \ masque binaire du PIN26 

We then define init-ddrb which selects all the pins of the PORT B output:

: init-ddrb ( ---) 
    $ff DDRB c! ;       \ initialise PORT B en sortie sur les huit bits 

Caution: do not confuse physical connector numbers and pin numbers

On the ARDUINO cards, the physical connectors are marked, some by numbers, others by their function, example: GND, TX, RX, 5V, etc ...

The mapping for associating pin numbers with physical connectors is in this document:
 Pin out map on ARDUINO DUE
 Pin out map on ARDUINO MEGA 2560
 Pin out map on ARDUINO MICRO
 Pin out map on ARDUINO NANO
 Pin out map on ARDUINO UNO
 Pin out map on ARDUINO YUN

For example, the led '13' which is connected to the ARDUINO MEGA board with the physical terminal 13 is related to the PIN 26. In all our texts, the term "pin" will always refer to PIN code XX as referenced in the technical documents of ARDUINO cards. The mention of a physical connector will be done with the term 'terminal'. Example:

  PIN 19 (terminal 53) (penultimate terminal, all at the bottom, left on an ARDUINO MEGA 2560 board)

To learn more about how to program the connectors of the different ARDUINO boards:
Understanding ARDUINO card connectors

In order to set the PORT B output when starting the ARDUINO card, we will type manually this from the terminal connected to the ARDUINO board:

' init-ddrb is turnkey 

Thus, each time the ARDUINO card is started, the word init-ddrb will be executed. If we did not do this initialization, the ignition and extinguishing actions of the LED on the pin 26 would be inoperative or random ...

We define led26? which stacks the state of the LED. If we execute led26?, we will have as result:

: led26? ( --- )        \ récupère état LED connectée au pin 26 
    PORTB c@ 
    PIN26 and 
    0= if               \ LED sur pin 26 éteinte 
        ." éteinte" 
    else                \ LED sur pin 26 allumée 
        ." allumée" 
    then ; 

And finally, we define two words, led26-on and led26-off, respectively to turn on and off the LED connected to PIN 26.

: led26-on ( ---)       \ allumage LED sur PIN 26 
    PINB c@             \ recupere contenu registre PIN du port B 
    PIN26 or            \ OU logique avec valeur et masque PIN26 
    PORTB c! ;          \ met resultat dans registre PORT du port B 
: led26-off ( ---)      \ extinction LED sur PIN 26 
    PINB c@             \ on recupere le contenu du registre PIB du port B 
    PIN26 $ff xor       \ on recupere le masque de bit et on inverse les bits 
    and PORTB c! ;      \ ET logique et remet valeur dans registre PORT B 

These words are tested after compiling them in FORTH. Turn on the terminal, then we test in interpreter mode these different words. Here is exactly what is displayed on the ARDUINO card:

  ok<#,ram>
init-ddrb  ok<#,ram>
led26? éteinte ok<#,ram>
led26-on  ok<#,ram>
led26? allumée ok<#,ram>
led26-off  ok<#,ram>
led26? éteinte ok<#,ram>
  ok<#,ram>

If everything went well, the LED connected to pin 26 had to turn on and off.

Now let's see how to handle this from a PHP script encapsulated in a Web page....

Manage the led on pin 26 from a PHP script in a web page

Here is the content of our index.php page that will allow us to turn on and off our LED connected to pin 26 on the ARDUINO board:

<!DOCTYPE html>
<html>
<head>
<title>gestion carte ARDUINO sur COM7</title>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
</head>
<body>
<article>
<h1>Allumer éteindre LED sur pin 26</h1>
 
<?php
function initCom($device='COM7') {
    exec("mode $device BAUD=38400 PARITY=1 DATA=8 STOP=n xon=on octs=off rts=on");
//    exec("mode $device BAUD=38400 PARITY=n DATA=8 STOP=1 xon=off octs=off rts=on");
    $comport = @fopen($device, "wb+");
    if ($comport) {
        fputs($comport,"\n\n");
        usleep(300000);
        $result = fgets($comport);
    } else {
        die("erreur port ".$device);
    }
    return $comport;
}
 
function closeCom($handle) {
    if ($handle!=null) {
        fclose($handle);
    }
}
 
function sendArduino($forth) { // transmission un ou plusieurs mots FORTH
    $handle = initCom();
    fputs($handle,$forth."\n");
    usleep(300000);
    $result = utf8_encode(fgets($handle));
    closeCom($handle);
    return $result;
}
 
function getEtatLed() {
    return sendArduino("led26?");
}
 
function led26on() {
    return sendArduino("led26-on");
}
 
function led26off() {
    return sendArduino("led26-off");
}
?>
<p><b>LED: </b><?php echo getEtatLed(); ?></p>
 
<form action='index.php' method='POST'>
    <input type='submit' name='action' value='allumer'/>
    <input type='submit' name='action' value='éteindre'/>
</form>
<?php
if (isset($_POST) && !empty($_POST)) {
    if ($_POST['action']=='éteindre') {
        led26off();
    } elseif ($_POST['action']=='allumer') {
        led26on();
    }
}
?>
</body>
</html>

Some explanations:

Access to the PHP script from a touch pad

If Apache has been correctly configured, you can test the script from the PC hosting Apache, just by opening your browser and typing http://localhost/arduino.

Here's how to make this script accessible on your local network: Rendre WAMP accessible en réseau local.

You then have to find the local address of the PC hosting the script of ignition and extinction of our LED, for our case: 192.168.1.9.

We take the digital tablet (a smartphone is also the case), it connects to the local network WiFi, we open the browser, then we type: http://192.168.1.9/arduino/. If all goes well, you should see this on the screen of the tablet or smartphone:

our application visible on smartphone

Screen copy of what we see on the PC:

partial screen copy

On this screen, we have the status of the LED as tested before an action "turn on" or "turn off". These actions are initiated by simply clicking on one of the two buttons (in gray on the screen photo).

As a conclusion

We did not focus on the design of the application. The primary goal is to do as as simple as possible, but above all efficient and functional.

It lacks, for example, a whole lot of additional routines managing the reliability of serial communication between the server and the ARDUINO card. We leave you to set up these routines.

But if you have followed everything and eventually experimented, you will find that build a web interface to control an ARDUINO card is at your fingertips.

In our example of LED switching on and off, we have limited the scope of our server to a restricted access to the local network, ie to the devices connected to your box or Internet router. In principle, the application localhost/arduino is not accessible from Internet.

It is possible to make this application visible from the Internet. But this is not the subject of our article.

If the application is visible from the Internet, you can order your application programmed in FORTH and connected to your private web server from your smartphone, wherever you are, connected in WiFi or 3G/4G/5G.

Finally, you will have noticed that we can control actions on the ARDUINO board programmed in FORTH language simply by indicating the words to execute (led26? led26-on led26-off) without having to nest these words in a loop or any other general function. Because, in FORTH language, every word remains accessible from the moment it is defined in the dictionary ...