GPIOson – Raspberry GPIO’s über php, javascript und jQuery steuern

Der Weihnachtsmann brachte diese Jahr einen Raspberry PI mit diversen LED’s, Schaltern und Kabeln. Der Elektroniker in mir wurde wieder wach. Schnell fand ich Anleitungen im Web per console und php dieses tolle Teil unter Kontrolle zu bringen.

Relativ schnell konnte ich die ersten LED’s über die Konsole aufleuchten lassen – auch wenn es meine Tochter nur wenig begeisterte das mir auch mal ein Licht aufging…

In Zeiten von HTML5, jQuery und Mobile First wollte ich nun über das Smartphone auch die Lampen leuchten lassen und den Schalter abfragen, ohne ständig die php Datei neu aufzurufen.

Folgende Lösung ist dabei endstanden:
Es gibt 3 Komponenten, eine Webseite (index.html) welche die Buttons rendert und die Bibliotheken zusammenführt. Eine javascript Datei (GPIOson.js) welche die Logik auswertet und dafür sorgt das die php Datei (gpio.php) aufruft um die GPIO’s zu setzten bzw. abzufragen.

Index.html:

   1: <html>

   2: <head>

   3:     <title>Pi Hunter - GPIOson</title>

   4:     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

   5:     <meta http-equiv="content-type" content="text/html; charset=UTF-8" />

   6:   <script type='text/javascript' src='/jquery-1.11.1.min.js'></script>
   1:

   2:   <script type='text/javascript' src='/jquery.mobile-1.4.5.js'>

   1: </script>

   2:   <link href="/jquery.mobile-1.4.5.css" rel="stylesheet" />

   3:   <script type='text/javascript' src='GPIOson.js'>

</script>

   7:     <style type="text/css">

   8:     </style>

   9: </head>

  10: <body>

  11:     <h1>Pi Hunter - GPIOson</h1>

  12:   <fieldset>

  13:     <div data-role="fieldcontain" onclick="switchValue(17)">

  14:       <label for="checkbox-based-flipswitch">GPIO 17:</label>

  15:       <input type="checkbox" id="GPIO17" data-role="flipswitch"  >

  16:     </div>

  17:   </fieldset>

  18:

  19:   <fieldset>

  20:     <div data-role="fieldcontain" onclick="switchValue(27)">

  21:       <label for="checkbox-based-flipswitch">GPIO 27:</label>

  22:       <input type="checkbox" id="GPIO27" data-role="flipswitch"  >

  23:     </div>

  24:   </fieldset>

  25:

  26:   <fieldset >

  27:   <div data-role="fieldcontain" onclick="autoRefresh()" >

  28:   <label for="AutoRefresh">Auto Refresh:</label>

  29:     <select name="flip-select" id="AutoRefresh" data-role="flipswitch"  >

  30:         <option selected="">Off</option>

  31:         <option >On</option>

  32:     </select>

  33:     </div>

  34:   </fieldset>

  35:

  36:   <div id='UpdateResult' ><div>

  37:     <p>Created by eta-arts - Dirk Huntemann</p>

  38:

  39: </body>

  40: </html>

Wichtig sind hier die  onclick events. Diese rufen die Javascript Funktionen in der GPIOson.js auf

Aufbau GPIOson.js :

   1: var g_GpioPins = [

   2:     {

   3:         gpio: '17', mode: 'out', value: 0

   4:     },

   5:     {

   6:         gpio: '24', mode: 'in', value: 0

   7:     },

   8:     {

   9:         gpio: '27', mode: 'out', value: 0

  10:     }

  11: ];

  12:

  13: var g_RefreshTimer = null;

  14:

  15: function getSetPin(pinData) {

  16:     $.ajax({

  17:         url: 'gpio.php',

  18:         type: 'post',

  19:         datatype: 'json',

  20:         data: pinData,

  21:         success: function(data) {

  22:             // Do something with data that came back.  

  23:             var objData = jQuery.parseJSON(data);

  24:             $('#UpdateResult').html(objData.status);

  25:         }

  26:     });

  27: }

  28:

  29: function switchValue(gpio) {

  30:     for (var i_Pin in g_GpioPins) {

  31:         if (g_GpioPins[i_Pin].gpio == gpio) {

  32:             switch (g_GpioPins[i_Pin].mode) {

  33:                 case 'out':

  34:                     switch (g_GpioPins[i_Pin].value) {

  35:                         case 0:

  36:                             g_GpioPins[i_Pin].value = 1;

  37:                             break;

  38:                         case 1:

  39:                             g_GpioPins[i_Pin].value = 0;

  40:                             break;

  41:                     }

  42:                     break;

  43:                 case 'in':

  44:                     console.log('auslesen' + g_GpioPins[i_Pin].gpio);

  45:                     break;

  46:             }

  47:             getSetPin(g_GpioPins[i_Pin]);

  48:             break;

  49:         }

  50:     }

  51: }

  52:

  53: function autoRefresh() {

  54:     //console.log($('#AutoRefresh').val());

  55:     if ($('#AutoRefresh').val() == 'On') {

  56:         autoRefreshStart();

  57:     }

  58:     else {

  59:         autoRefreshStop();

  60:     }

  61: }

  62:

  63: function autoRefreshStop() {

  64:     //console.log('Auto OFF!');

  65:     clearInterval(g_RefreshTimer);

  66:     g_RefreshTimer = null;

  67: }

  68:

  69: function autoRefreshStart() {

  70:     //console.log('Auto On!');

  71:     g_RefreshTimer = setInterval('getSetPin(g_GpioPins[1])', 100);

  72:     getSetPin(g_GpioPins[1]);

  73: }

In Zeile 1-11 werden die Startzustände der GPIO’d definiert.
function getSetPin(pinData) macht den Json call an die gpio.php

gpio.php

   1: if(count($_POST) > 0){

   2:   $gpiocmd = '/usr/local/bin/gpio -g ';

   3:   //echo $gpiocmd; 

   4:   $result=array();

   5:   switch ($_POST['mode']){

   6:     case 'out':

   7:      exec($gpiocmd . 'mode ' . $_POST['gpio'] . ' out');

   8:      exec($gpiocmd . 'write ' . $_POST['gpio'] . ' ' . $_POST['value'],$gpioValue);

   9:      //$result ='Success: Pin ' . $_POST['gpio'];

  10:      $result['value'] = ($gpioValue[0]);

  11:      break;

  12:     case 'in':

  13:      exec($gpiocmd . 'mode ' . $_POST['gpio'] . ' in');

  14:      exec($gpiocmd . 'read ' . $_POST['gpio'],$gpioValue);

  15:      //$result['value'] = ($gpioValue[0]);

  16:      $result=array('status' => $gpioValue[0],'gpio'=>$_POST['gpio']);

  17:      break;

  18:     default:

  19:       $result='Error:wrong mode';

  20:   }

  21: }

  22: else{

  23:   $result='Error:';

  24:   }

  25: echo json_encode($result);

Auch die gpio.php ist recht übersichtlich. Hier wird das Json ausgewertet und anschließen über php exec der

Konsolenbefehl (“Licht an oder Aus”, “Was macht der Schalter?” ) aufgerufen.

Durch einbinden von jQueryMobile und jQuery Mobile sieht das Ganze dann im Browser so aus:

image      image