Pages: [1] 2   Go Down
Author Topic: Arduino Uno + Raspberry Pi + PHP + LED (update 02/06/2013)  (Read 10968 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola.
Inicio este post por si a alguno le sirve de ayuda para conectar la Arduino a una RaspeberryPi y un interface web para controlar un LED.

Estábamos tratando algo a través de otro post, pero inicio este para que este a la vista y pasar todo el código.

El caso es que se trata de encender, apagar y leer el estado de un LED a través de un entorno web con una Arduino como actuador y la Raspberry como servidor.
De momento hasta que funcione todo bien usamos el ejemplo del LED, lo que quiero al final es controlar varios temas de mi casa, como luces, calefacción, toldos ..etc..

Esquema:


Os dejo los pasos que he realizado hasta ahora:

1- Meter a Arduino el siguiente código (yo lo hago desde un PC con windows8 y uso un clon de ARDUINO UNO comprado en dx.com)

Code:
const int ledPin = 13; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into
int estado;

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("LED_ON_OFF");  
  Serial.println("0 - APAGAR");  
  Serial.println("1 - ENCENDER");    
  Serial.println("9 - ESTADO");      
  Serial.println();  
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // see if there's incoming serial data:
  if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    incomingByte = Serial.read();
    switch (incomingByte){
      case '0':
        digitalWrite(ledPin, LOW);
        estado=0;
        break;
      case '1':
        digitalWrite(ledPin, HIGH);
        estado=1;
        break;
      case '9':
          if(estado==1){
             Serial.println("ENCENDIDO");
          } else {
            Serial.println("APAGADO");
          }//if estado
        break;        
    }//switch
  } else {
    delay(100);
  }//IF Serial
} //loop

2- Conectar la Arduino a la RaspberryPi al puerto USB de debajo

3- Conectar RaspberryPi a la red, en mi caso vía cable al router, y obviamente conectar a la alimentación, en mi caso con un cargador de Samsung

4- Hacer propietario del puerto USB en la RaspberryPi al usuario y grupo que ejecuta el servidor web .. en mi caso en la Raspberry tengo instalada una versión con asterisk por lo que uso el siguiente comando.
Code:
chown asterisk:asterisk /dev/ttyACM0

5- En el servidor web hay varios archivos:
index.php -> Fichero principal
arduino_led_on.php -> Fichero que enciende el LED
arduino_led_off.php -> Fichero que apaga el LED
arduino_led_estado.php -> Fichero que lee el estado - Esta en construcción, ya que no lee nada
on.png -> imagen de bombilla encendida
off.png -> imagen de bombilla apagada
jquery-1.10.0.min.js -> libreria jquery (se puede descargar desde http://code.jquery.com/jquery-1.10.0.min.js)

index.php
Code:
<!DOCTYPE html>
<html>
<head>
<script src="jquery-1.10.0.min"> </script>
<style type="text/css">
.bool-slider
{
         border: 1px solid #CCC;
    color: #FFF;
    font-size: 18px;
    font-weight: 800;
    font-family: Helvetica, Verdana, Arial, sans-serif;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
    
    height: 35px;
    width: 100px;
    border-radius: 25px;
}

.bool-slider.true .inset
{
    background-color: #51a351;
        *background-color: #499249;
    background-image: linear-gradient(top, #62c462, #51a351);
    background-repeat: repeat-x;
    border-color: #51a351 #51a351 #387038;
    border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
        background-image: none;
      box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.bool-slider.true .inset .control{float: left;}
.bool-slider.true .inset .control:after
{
    content: 'On';
    position: relative;
    right: -135%;
    top: 20%;
}

.bool-slider.false .inset
{
    background-color: #da4f49;
    *background-color: #bd362f;
    background-image: linear-gradient(top, #ee5f5b, #bd362f);
    background-repeat: repeat-x;
    border-color: #bd362f #bd362f #802420;
        border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
        background-image: none;
      box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.bool-slider.false .inset .control{float: right;}
.bool-slider.false .inset .control:before
{
    content: 'Off';
    position: relative;
    left: -100%;
    top: 20%;
}

.bool-slider .inset
{
    width: 100%;
    height: 100%;
    border-radius: 20px;
    
}

.bool-slider .inset .control
{
    background-color: #000;
    width: 40%;
    height: 100%;
    border-radius: 20px;
    background-color: #f5f5f5;
    *background-color: #e6e6e6;
    background-image: linear-gradient(top, #ffffff, #e6e6e6);
    background-repeat: repeat-x;
}

.bool-slider .inset .control:hover
{
    cursor: pointer;
}

.bool-slider.disabled
{
    color: #CCC;
}

.bool-slider.disabled .inset
{
  background-color: #f5f5f5;
  *background-color: #e6e6e6;
  background-image: linear-gradient(top, #ffffff, #e6e6e6);
  background-repeat: repeat-x;
}

.bool-slider.disabled .control
{
    cursor: default;
}
</style>

<script>
$(document).ready(function() {
    $('.bool-slider .inset .control').click(function() {
        if (!$(this).parent().parent().hasClass('disabled')) {
            if ($(this).parent().parent().hasClass('true')) {
                $(this).parent().parent().addClass('false').removeClass('true');
$("#led").attr("src","on.png");
$.ajax({
url: 'arduino_led_on.php',
success: function(data) {
//alert('LED ON');
}
});
            } else {
                $(this).parent().parent().addClass('true').removeClass('false');
$("#led").attr("src","off.png");
$.ajax({
url: 'arduino_led_off.php',
success: function(data) {
//alert('LED OFF');
}
});
            }
        }
    });
});
</script>
</head>

<body>

<img id="led" src="off.png">
<div class="bool-slider true">
    <div class="inset">
        <div class="control"></div>
    </div>
</div>


</body>
</html>

arduino_led_on.php
Code:
<?php
$fp 
=fopen("/dev/ttyACM0""w+");
if( !
$fp) {
        die(
"error");
}
fwrite($fp"1");
fclose($fp);
?>


arduino_led_off.php
Code:
<?php
$fp 
=fopen("/dev/ttyACM0""w+");
if( !
$fp) {
        die(
"error");
}
fwrite($fp"0");
fclose($fp);
?>


arduino_led_estado.php
Code:
<?php
$fp 
=fopen("/dev/ttyACM0""wr");
if( !
$fp) {
        die(
"error");
}
 
fwrite($fp"9");
echo 
fread($fp10);
fclose($fp);
?>

(no me funciona de momento)

Imágenes on.png y off.png


Imágenes montaje


6- Ponemos en un navegador la dirección web donde esta el fichero arduino.php .. por ejemplo http://192.168.1.102/arduino.php y le dams al texto ON o OFF

Accediendo por consola y tecleando el siguiente comando y cambiando el '1' por el '0', se enciende y apaga el led
Code:
echo -ne '1' > /dev/ttyACM0

También puede conectarse al puerto directamente
Code:
plink -serial /dev/ttyACM0
« Last Edit: June 02, 2013, 06:56:21 am by benjaminrc78 » Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

He leído que el reseteo se puede paliar con un condensador de 10uF electrolitico entre el pin RESET y GND.
(La banda del condensador marcada con un signo negativo (-) debe ir a masa (GRD)

Alguien lo ha probado ?

Yo hasta mañana no puedo acercarme a una tienda de electrónica, para poder probarlo !

Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola.

Ya he podido hacerme con un condensador de 10uF y efectivamente ahora funciona todo correctamente.
(actualizare el primer post con el código de todo e imágenes)

He creado un PHP nuevo para manejar el LED de una forma más visual usando AJAX y JQUERY.
Me funciona encender y apagar el LED desde la web.

Solo me queda el php para leer el estado del LED para saber si esta encendido o apagado.

En principio al enviarle por el puerto serie un "9", arduino devolvería el estado .. pero no se como hacerlo en PHP.

Alguna ayuda ?
Logged

Alicante
Offline Offline
Sr. Member
****
Karma: 2
Posts: 413
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola!

Está genial que hayas compartido esto con la comunidad. Hay poca cosa de RaspberryPi con Arduino.
Voy a necesitar algo así para un proyecto, si puedes compartir otro ejemplo con algo más estaría de lujo.

Muchas gracias @benjaminrc78. +1
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

de nada !!  smiley-cool
Dentro de poco voy a subir el mismo tutorial, pero usando node.js, solo me faltan unas cosillas de pulir.

Actualmente estoy haciendo pruebas con varios sensores, y voy a hacer otro ejemplo con un LCD.
Para que se le pase un texto vía web y salga en el display.

Y después con un relé .. para encender/apagar aparatos a 220v

Y ya me dedicaré a proyectos mas concretos ... ya que una vez dominando la base, lectura de sensores, manejo por internet .. se puede hacer lo que se quiera !


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gracias por el aporte,
Soy nuevo en la comunidad y la verdad me gusta mucho más la idea de usar una Web como Scada antes que el Acimunt monitoriza o Labview
Ya os contaré cuando lo termine de probar.
Saludos.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buenas,

Yo consegui leer el puerto serie de arduino, os adjunto el codigo del arduino_led_estado.php:

Code:
<?php
$fp 
=fopen("/dev/ttyACM0""w+");
if( !
$fp) {
        die(
"error");
}
 
fwrite($fp"9");
echo 
fread($fp7);
fclose($fp);
?>

Lo que corregi del archivo original fue:
- $fp =fopen("/dev/ttyACM0", "w+"); cambie el wr por w+
- echo fread($fp, 7); cambie el ($fp, 10) por ($fp, 7) Aqui es importante tener en cuenta que solo lee el numero de caracteres que pongamos, si ponemos mas los recorta, lo peor es si ponemos menos que directamente bloquea la raspi, por lo tanto es necesario poner el numero exacto de caracteres o el minimo que vayamos a recibir.

Por ej:

             Serial.println("ENCENDIDO"); 10 caracteres
          } else {
            Serial.println("APAGADO"); 7 caracteres

Por eso puse 7.

Me podeis explicar como puedo hacer que el estado se actualice automaticamente al estar encendido o apagado el led ?

Un saludo
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

¡¡Grande el hilo!!

Yo he hecho lo mismo con Weezy y apache2 como servidor. Funciona todo bien, pero ahora que quiero empezar el desarrollo por mi parte estoy bastante liado. Para empezar no tengo ni idea de JavaScript, por esto no entiendo qué utilidad tiene el script del principio del index.php.

Yo me he ahorrado eso y con tres archivos obtengo el mismo resultado, aquí están:

index.php
Code:
<!DOCTYPE html>
<html>
<body>
<a href="arduino_led_on.php">Enciende</a>
<a href="arduino_led_off.php">Apaga</a>
</body>
</html>

arduino_led_on.php
Code:
<?php
$fp 
=fopen("/dev/ttyACM0""w+");
if( !
$fp) {
        die(
"error");
}
fwrite($fp"1");
fclose($fp);
header('Location:index.php');
?>

arduino_led_off.php
Code:
<?php
$fp 
=fopen("/dev/ttyACM0""w+");
if( !
$fp) {
        die(
"error");
}
fwrite($fp"1");
fclose($fp);
header('Location:index.php');
?>

Mi gran duda es a continuación: Yo quiero utilizar más de un puerto, ¿cómo puedo hacerlo? Y otra cosa, ¿para qué utilizáis el arduino_led_estado.php?

¡Gracias y un saludo!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola!!
Pude hacer andar esto sin problemas con un Arduino Mega y conectado a mi PC que oficia de webserver.

Ahora bien, no hay caso para poder leer el estado del led... alguna sugerencia?

El webserver es un apache sobre windows.

Saludos y gracias!
kaiki
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola!!
Pude hacer andar esto sin problemas con un Arduino Mega y conectado a mi PC que oficia de webserver.

Ahora bien, no hay caso para poder leer el estado del led... alguna sugerencia?

El webserver es un apache sobre windows.

Saludos y gracias!
kaiki

Me temo que todos nos estamos quedando atascados en el mismo sitio smiley-sad
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buenas,

Yo consegui recibir el estado pero de una forma diferente, creando una base de datos con phpmyadmin, como tampoco tengo ni idea de java y no me funcionaba pues lo cambie todo.

Un saludo
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Que tal gente, estuve metiendo manos en este proyecto, me resulto muy interesante, pero como vienen diciendo al parecer nos quedamos todos en el mismo lugar, que es en definitiva leer los datos del puerto serie y mostrarlos en php, estuve revisando por todos lados y encontre el siguiente video que les dejo, todavia no lo he probado pero por lo que se ve funciona, seria cuestion de probarlo. Si mañana me hago un ratito de tiempo veo de realizarlo, mientras tanto se los dejo por aca para que lo vean y saquen conclusiones....



Nos estamos leyendo!!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bueno hoy me hice un tiempito y probe el codigo y el armado del circuito que se puede ver en el video anterior, les aviso funciona, con algunas deficiencias en cuanto a la presentacion de los datos en el navegador, pero lo mas importante que es la comunicacion arduino <>raspberry<>Web esta hecha, solo restara mejorar eso. Por si alguien quiere probarlo, les dejo el codigo transcripto asi les resuta mas facil de realizar

El Codigo PHP:

Code:
<?php
$portAddress 
"/dev/ttyACM0";

echo(
"<h1>Temperatura Via Arduino</h1>");

echo(
"<p>Conectando Aguarde...");
$port fopen($portAddress'w+');
if (!
$port)
{
echo "<br /> No se pudo conectar con el puerto $portAddress";
}
else
{
echo "<br />Conectado con exito al puerto $portAddress";
}
echo (
"</p>");

sleep(3);
fwrite($port,  't');

sleep(1);
echo 
fgets($port);
fcolse($port);

?>

El Codigo en Arduino:
Code:
void setup()
{
  Serial.begin(9600);
  delay(1000);
}

void loop()
{
  if (Serial.available())
  {
  char recibido = Serial.read();
  if (recibido = 't');
  {
  int valorleido = analogRead(0);
  float temperatura = (valorleido * 0.00488) * 100;
  Serial.print("Temperatura: ");
  Serial.println(temperatura);
  }
  }
}

Sera cuestion uniccamente de armar el circuito electronico que solamente constas de un LM35 , facil facil....y funciona

De ahora en mas a seguir metiendo codigo para ver que es lo que no esta funcionando en el anterior..

Saludos!!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Un estupendo Hilo, me ha ayudado bastante. Muchas gracias.

Bueno voy al grano es una pregunta muy corta, el codigo php que muestra nuestro amigo pablorosario, funciona pero (siempre hay un pero) ¿A vosotros os tarda mucho en ejecutarse el codigo? Porque a mi me tarda bastante y estoy pensando que el puerto serial se vuelve un poco loco.

Ahora mismo no dispogo del codigo que tengo escrito para que lo mireis, solo quiero saber eso, ¿si a vosotros os tarda muchos en cargar la web php?

Saludos y gracias
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola buenas estuve revisando el codigo y estoy haciendo un sistema parecido probe el código pero no me funciona en el sentido de que cuando doy encender el led este solo parpadea y no queda encendido si doy apagar realiza lo mismo solo parpadea. al conectar el condensador no realiza nada que problema puede ser si tengo el código funcional lo he revisado y todo y no detecto problemas esta copiado y pegado
Logged

Pages: [1] 2   Go Up
Jump to: