Read and change GPIO pin status of Raspberry Pi 3

Asked

Viewed 481 times

1

I am doing a small project with a rRspBerry Pi 3 that consists, among other things, to control some outputs through a web page. I needed to be able to know and print on the page what the status of those exits was at a given moment. I have, for example, a button to turn on an LED and another button to turn off, but I need to print on a text box if the LED is on or off and leave or not on or off the LED depending on its status.

To read the status I can use the function exec("gpio read ".$i, $status); in which $i is the pin I want to read and $status is where you keep the pin status, but I don’t know how to include it on my web page, someone knows how to do it or knows where to look for an example?

Code:

<!DOCTYPE html>
<html>
    <head>




    </head>
    <body>




        <article>  
            <div id="Janelas">
            <h1>Sistemas de Climatização</h1>

            <p>Soalho radiante</p>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

<script type="text/javascript">// <![CDATA[

$(document).ready(function() {

$('#ligar').click(function(){

var a= new XMLHttpRequest();

a.open("GET", "soalholigar.php"); a.onreadystatechange=function(){

if(a.readyState==4){ if(a.status ==200){

 } else alert ("http error"); } }

a.send();

});

});

$(document).ready(function() {

$('#desligar').click(function(){

var a= new XMLHttpRequest();

a.open("GET", "soalhodesligar.php"); a.onreadystatechange=function(){

if(a.readyState==4){ if(a.status ==200){

 } else alert ("http error"); } }

a.send();

});

});



</script>

                <input type="button" id="ligar" value="Ligar">
                <input type="button" id="desligar" value="Desligar">
                <center>


                <input type="text" size="5" name="textgol" value="0">
                </center>


            <p>ZONA 2.</p>

                <input type="button" name="botao-ligar" value="Ligar">
                <input type="button" name="botao-desligar" value="Desligar">

            <p>ZONA 3.</p>

                <input type="button" name="botao-ligar" value="Ligar">
                <input type="button" name="botao-desligar" value="Desligar">

            <p>ZONA 4.</p>

<input type="button" name="botao-ligar" value="Ligar">
                <input type="button" name="botao-desligar" value="Desligar">

            <br/>
            <br/>
            <a href="javascript:window.history.go(-1)">Voltar</a>





    </body>
</html>
  • 1) If you are using jQuery, why not make asynchronous calls via $.ajax? 2) The state of the LED can be changed through other sources or the interface will be the only one to control it? 3) What is the return, in the terminal, when you execute the command gpio directly?

    1. I’m using jQuery but for the first time, I have no experience or great knowledge on the subject. 2) the state of the led can be changed by two more interfaces, hence the difficulty, because if only changed in the web interface could create a variable to save the state. 3) When executing gpio write pin state, I get no return on the terminal, but the pin changes the state.
  • About the return of command, I was referring to gpio read, to know how to treat the response.

  • if gpio read directly on terminal returns 0 or 1, depending on pin state.

1 answer

1

We can imagine two PHP files: read.php, which will read the current pin state, returning the value in JSON, and write.php, that will change the status of the pin.

read php.

We can imagine that the JSON response of this file is in the format {pin: 1, status: 0}, indicating which pin is being read and what its current state is. As we want to obtain the state of our server, this file will treat a GET request, receiving as parameter the pin number to be read. Would something like this:

<?php

// read.php

header('Content-Type: application/json');

$pin = filter_input(INPUT_GET, 'pin', FILTER_VALIDATE_INT);

exec("gpio read {$pin}", $status);

$status = (int) $status;

echo json_encode(['pin' => $pin, 'status' => $status]);

So, when making a request to the URL read.php?pin=1, for example, would have the expected return: {pin: 1, status: 0}.

With jQuery, you can make such a request through $.get:

$.get('read.php', {pin: 1}, function (data) {
    console.log("O LED está " + (data.status == 0 ? "desligado" : "ligado"));
}, 'json');

When executing this code, it would appear in console the message:

O LED está ligado

If the return of PHP has been status = 1, for example.

If you want to, for example, lock the turn button if the LED is on, you can set the button as disabled through this code.

function trigger(pin, status) {
    if (status == 0) {
        // LED está desligado
        $("ligar").attr("disabled", false);
        $("desligar").attr("disabled", true);
    } else {
        // LED está ligado
        $("ligar").attr("disabled", true);
        $("desligar").attr("disabled", false);
    }
}

$.get('read.php', {pin: 1}, function (data) {
    trigger(data.pin, data.status);
}, 'json');

So, when the LED is on, only the off button will be enabled; and when the LED is off, only the on button will be enabled. If you want to do this constantly, just use this logic in conjunction with the function setInterval.

write php.

Already the writing file will change the state of the application, then you should treat a POST request, receiving as parameters the number of the pin that should be changed and its new state. Since the write command has no returns, we don’t need to define the body of the HTTP response, just the state code of the response; that is, a 200 response if all goes well and a 500 if something goes wrong. For this example, I will consider that if something went wrong, some error message would be displayed on the terminal and therefore the exec would return something other than a string empty.

<?php

// write.php

$pin = filter_input(INPUT_POST, 'pin', FILTER_VALIDATE_INT);
$status = filter_input(INPUT_POST, 'status', FILTER_VALIDATE_INT);

exec("gpio write {$pin} {$status}", $error);

if ($error == '') {
    http_response_code(200);
} else {
    http_response_code(500);
}

With jQuery, you can make this request with $.post:

$.post('write.php', {pin: 1, status: 1});

Thus, you can use such code in conjunction with the event click button:

$("#ligar").on("click", function (event) {
    $.post('write.php', {pin: 1, status: 1});
});

$("#desligar").on("click", function (event) {
    $.post('write.php', {pin: 1, status: 0});
});

Other implementation details I believe I can do by myself just changing the logic presented here.

  • Using its logic to read the status of the pin, I created the read.php file with its code and inserted the function that turns off one of the buttons inside a javacript script tab in the <head> of my html page but I can’t get any results. On the other hand I already have a php file that I invoke when the page loads that responds with the status of the pin for the variable date, which by doing Alert(data) I can see its value, there is the possibility of using this variable in your code and thus solve the problem. Thanks for the help and excuse the lack of knowledge!

  • The part that reads the php value is working, if you do an Alert(data.status) in this part the page returns the value, I’m not able to run the Rigger function, I copied your code into a javacript script tab.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.