Go Down

Topic: Arduino y php consulta (SOLUCIONADO) (Read 10073 times) previous topic - next topic

Pipper

Jan 28, 2012, 06:54 pm Last Edit: Feb 03, 2012, 05:54 pm by Pipper Reason: 1
Bueno mi problema es q necesito comunicar el arduino con un servidor web estoy en un proyecto de domotica, si bien me compre el ethernet shield el servidor web dentro de arduino lo noto demasiado lento... ahora mis consultas son:

1) Se puede hacer q arduino trabaje como cliente web y pida variables a un servidor web que este alojado en mi maquina y de acuerdo a eso realize las acciones necesarias?, sera mas rapido q el servidor web estando en arduino?

2)Coneccion de Arduino con php, he leido mucho al respecto pero no logro q funcione, alguien tiene algun ejemplo funcional? yo voy a poner mi codigo basico de como me parece q tendria q estar funcionando pero nada :(.

Codigo en arduino:
Code: [Select]
void setup()
{
 Serial.begin(9600);
}
void loop()
{
 while (Serial.available() == 0);
  int val = Serial.read() - '0';
   Serial.println(val);
}


Codigo Php:

Code: [Select]
<?
$datos= 1;
       exec ("echo ".$datos." > /dev/ttyACM0");
delay(5000);
       
?>


bueno cualquier ayuda que me den gracias :), saludos a la comunidad

Sergegsx

es totalmente posible, de hecho yo lo tengo montado en mi casa con una gran cantidad de sensores, funciones, base de datos, interface web, ....
vamos que es realizable.

Yo me baso en la idea de que el arduino no tiene que ser el servidor que para eso ya estan los servidores online con mas capacidad, velocidad, y accesibilidad. Entonces lo que mi arduino (master) hace es recoger datos y enviarlos al servidor online. Como? pues llamando a un archivo php y pasandole los valores en la llamada.
get http://miservidor.com/upload.php?A=1234&B=32435&C=25456
luego dentro del archivo php hago un GET de los parametros y los trabajo, guardandolos en la base de datos mysql, hace calculos, envia emails, etc etc.

lo mismo se podria hacer si por ejemplo llamas a un php preguntando si hay el arduino tiene que hacer alguna accion
get http://miservidor.com/actions.php

y que el php haga las consultas en bases de datos o lo que sea e imprima por pantalla con un simple ECHO los comando que debe hacer el arduino.
luego el arduino lee la respuesta de la web que sera una linea de texto tipo
luces1=1;motor1=0 etc
o codificado de alguna forma
L1M0....

suerte y ves poniendo tus progresos e intentaremos ayudarte.

Pipper

Bueno la verdad que despues de probar y probar intentando utilizar el comando exec en php no he logrado resultados...asi q me pondre a ver como tu lo dices...mas o menos me hago la idea de lo que me explicaste, pero mucho no capte como hacerlo...pero bue me pondre e ire postiando mis avances o estancadas :D ja ja gracias por la ayuda saludos.

Pipper

Sergegsx he estado platicando toda la tarde, ya me arden hasta los ojos jeje no logro captar tu idea, he echo los ejemplos del libro arduino cookbook pero no los puedo adaptar a lo q quiero, y si bien tu idea en mi mente la entiendo no logro transcribirla a la practica :D je, si podes o alguien puede hacerme un mini ejemplo funcional de como seria, asi puedo continuar gracias, igual voy a seguir viendo si entiendo como es la movida y tratar de seguir avanzando....

Pipper

#if ARDUINO > 18
#include <SPI.h>         // needed for Arduino versions later than 0018
#endif

##include <Ethernet.h>
#include <TextFinder.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,177 };

Server server(80);

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.println("ready");
}

void loop()
{
  Client client = server.available();
  if (client) {
    TextFinder  finder(client );
    while (client.connected()) {
      if (client.available()) {
        // counters to show the number of pin change requests
        int digitalRequests = 0; 
        int analogRequests = 0;
        if( finder.find("GET /") ) {
          // find tokens starting with "pin" and stop on the first blank line
          while(finder.findUntil("pin", "\n\r")){
            char type = client.read(); // D or A
            int pin = finder.getValue();
            int val = finder.getValue();
            if( type == 'D') {
              Serial.print("Digital pin ");
              pinMode(pin, OUTPUT);
              digitalWrite(pin, val);
              digitalRequests++;
            }
            else if( type == 'A'){
              Serial.print("Analog pin ");
              analogWrite(pin, val);
              analogRequests++;
            }
            else {
              Serial.print("Unexpected type ");
              Serial.print(type);
            }
            Serial.print(pin);
            Serial.print("=");
            Serial.println(val);
          }
        }

Este es el ejemplo del libro que creo viene por ahi la onda, pero no lo logro adaptar, si hacemos con este ejemplo pasamos por url localhost?pinD13=1 prende el led lo mas bien, por eso pense q por ahi venia la idea, entonces hice la siguiente pagina intentando captar pero no lo logre:

<form action='/prueba2.php' method="GET"><p><input type="hidden" name="pinD13" value="0">
<input type="submit" value="Off"/></form>

<form action='/prueba2.php' method="GET"><p><input type="hidden" name="pinD13" value="1">
<input type="submit" value="On"/></form>

Pero no logro hacerlo funcionar se que algo esta fallando pero necesito saber que pliss je je.

Sergegsx

Pipper no te preocupes, y tranquilo que ya veras que facil que es.
Esta tarde te escribo todo en detalle.
enviame un privado a sobre las 18:00 si aun no te he escrito

Pipper

Te escribi y al rato te desconectaste je...bueno cualquier cosa mandame un privado o acordate de poner escribir :), yo mientras voy a seguir probando esa y alguna otra alternativa a ver si sale algo :D, saludos

Pipper

Bueno he logrado comunicarme con php via Serial ahora voy a poner por si ha alguien le sirve... el tema de esto q no me convence es que tendria q tener el arduino conectado a una maquina todo el tiempo o no? mmmmm no me convence.

Bueno para los que les interese ahi les paso la data:

Es una clase echa por Remy Sanchez Clase

Nuestro codigo php quedaria:

Code: [Select]
<?php

// Include the PHP serial class
include "php_serial.class.php";

// Start a new serial class
$serial = new phpSerial;

// Specify the device being used
$serial->deviceSet("/dev/ttyACM0");

// Set baud rate
$serial->confBaudRate(9600);
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl("none");

// Open the device
$serial->deviceOpen();

// Write to the device
$serial->sendMessage("1");

// Close the port
$serial->deviceClose();

?>


El codigo de arduino para leer:

Code: [Select]
void setup()
{
Serial.begin(9600);
}

void loop()
{
if (Serial.available() > 0) {
byte variable = Serial.read();
Serial.println(variable);
}
}


Lo que si no logro es por ejemplo si quiero hacer dos botones que prendan y apagen un led probe poniendo en el action el $serial->sendMessage("1"); pero cada ves q se actualiza la pagina se me ejecuta todo :S....

Bueno el que me quiera ir ayudando gracias desde ya seguire postiando a medida que vaya avanzando :D, saludos.


Pipper

Bueno avances al dia de la fecha: hoy pude entender como mandar a traves de ethernet shield a un servidor web una el valor de una variable:

Codigo Arduino:
Code: [Select]
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x11, 0xAC };
byte ip[] = { 192, 168, 1, 19 };
byte server[] = { 192,168,1,33 };

Client client(server, 80);

void setup()
{
 Ethernet.begin(mac, ip);
 Serial.begin(9600);
 Serial.println("Coneccion Cliente");
 Serial.println();

 delay(1000);

 Serial.println("connecting...");

 if (client.connect()) {
   Serial.println("connected");
   //client.println("GET /arduino.txt HTTP/1.0");
   client.println("GET /prueba1.php?led=18 HTTP/1.0"); // aca mando la variable led con el valor 18
   client.println();
 } else {
   Serial.println("connection failed");
 }
}

void loop()
{
 if (client.available()) {
   char c = client.read();
   Serial.print(c);
 }

 if (!client.connected()) {
   
   
   Serial.println();
   Serial.println("disconnecting.");
   Serial.println("");
   client.stop();
   for(;;);
 }
}
 


El codigo php para recibir la variable seria
Code: [Select]

<?php
$variable 
$_GET['led'];
?>



Bien ahora mi consulta es la siguiente como hago lo mismo de modo inverso, osea como mando el valor de una variable desde php a arduino... espero alguien me ayude que la verdad nadie postea raro en una comunidad de este tipo, bueno saludos

Sergegsx

ya te puse como hacerlo

Code: [Select]


lo mismo se podria hacer si por ejemplo llamas a un php preguntando si hay el arduino tiene que hacer alguna accion
get http://miservidor.com/actions.php

y que el php haga las consultas en bases de datos o lo que sea e imprima por pantalla con un simple ECHO los comando que debe hacer el arduino.
luego el arduino lee la respuesta de la web que sera una linea de texto tipo
luces1=1;motor1=0 etc
o codificado de alguna forma
L1M0....


es decir el arduino llama a un php como has echo antes, el php hace la consulta mysql, luego el php imprime con un ECHO los resultados. finalmente el arduino despues de hacer la llamada al php lee la respuesta de la llamada al php, por lo que leera el ECHO que ha enviado el php.

luego el arduino separa la linea que ha recibido en los parametros que se le han pasado. por ejemplo separados por un ";".
mirate el ejemplo de WebClient que viene con arduino, en el se llama a un web, y se lee por serial el texto que contesta la web.

Pipper

#10
Jan 30, 2012, 11:51 pm Last Edit: Jan 31, 2012, 03:59 am by Pipper Reason: 1
Se que me habias puesto como hacerlo, pero te pedi un ejemplo funcional para poder entenderlo jeje, asi todo teorico si me lo imagino pero no lo veo todo tan claro, pensa q vos lo entendes por q sabes hacerlo pero yo no :(, por eso necesito ir guiandome de algunos ejemplos para ver como funciona la comunicacion entre ambos... esta noche vere como lo hago de la otra forma saludos.

luego el arduino separa la linea que ha recibido en los parametros que se le han pasado. por ejemplo separados por un ";".
mirate el ejemplo de WebClient que viene con arduino, en el se llama a un web, y se lee por serial el texto que contesta la web.


No logro hacer esa parte como separo las lineas??, intente usar Textfinder pero no me funciona...

Sergegsx

a veces se aprende mas intentando hacer las cosas uno mismo que recibiendo la solución y haciendo un copia/pega.
ademas te he dado un ejemplo de como hacerlo, se llama WebClient y viene con arduino.
en el tienes la parte de:
1. llamar a una web
2. recibir los datos que contesta la web
3. mostrarlos por serial

ahora solo te faltaria a la vez que los muestras por seria, guardarlos en unas variables.

este ultimo punto a mi me costo infinidad de horas, y cuando lo resolvi habia aprendido un monton. de hecho tienes un post mio de no hace mucho tratando el tema, buscalo

yOPERO

#12
Jan 31, 2012, 05:33 pm Last Edit: Jan 31, 2012, 05:36 pm by yOPERO Reason: 1

es totalmente posible, de hecho yo lo tengo montado en mi casa con una gran cantidad de sensores, funciones, base de datos, interface web, ....
vamos que es realizable.


@Segegsx

Que tal anda el tema de delay en el sistema que tienes montado?
Cuando haces clic en el comando en tu página web, cuanto tarda?
Lo tienes montado en local o con IP publica.

Estoy pensando en hacer data  plotting a una pagina web por lo que la velocidad es importante:

Arduino>>>serial port>>>web server>>>> internet

un saludo.
Engineering is the art of
making what you want from
things you can get.

     

[SOLUCIONADO]

Pipper

#13
Feb 01, 2012, 12:10 am Last Edit: Feb 01, 2012, 12:15 am by Pipper Reason: 1
Otra ves yo con espero algunos adelantos je, bueno primero voy a poner los codigos despues mis preguntas...

Codigo Arduino:
Code: [Select]
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x11, 0xAC };
byte ip[] = { 192, 168, 1, 19 };
byte server[] = { 192,168,1,33 };
int posicion=0;
int prend;
int foco;
Client client(server, 80);

void setup()
{
 Ethernet.begin(mac, ip);
 Serial.begin(9600);
 Serial.println("Coneccion cliente");
 Serial.println();

 delay(1000);

 Serial.println("connecting...");

 if (client.connect()) {
   Serial.println("connected");
   //client.println("GET /arduino.txt HTTP/1.0");
   client.println("GET /prueba2.php?led=1");
   //client.println("GET /prueba2.php?led=2");
   client.println();
 } else {
   Serial.println("connection failed");
 }
}

void loop()
{
   
   if (client.available()) {
   char dato_recibido = client.read();
  if (dato_recibido=='B' && posicion==0){
     posicion=1;
     //Serial.println("POSICION 1");
     //Serial.println(dato_recibido);
   }
   if (((dato_recibido=='H')) && posicion==1){
     posicion=2;
     //Serial.println("POSICION 2");
     //Serial.println(dato_recibido);
   }
   if (((dato_recibido=='1')||(dato_recibido=='2')||(dato_recibido=='3')||(dato_recibido=='4')||(dato_recibido=='5')) && posicion==2){
     posicion=3;
     if (dato_recibido=='1')  foco=13;
     //Serial.println("POSICION 3");
     //Serial.println(dato_recibido);
   }
   if (((dato_recibido=='A')||(dato_recibido=='Y')) && posicion==3){
     posicion=4;
     if (dato_recibido=='A')  prend=1;     //A led encendido
     if (dato_recibido=='Y')  prend=0;    //Y  led apagado
     //Serial.println("POSICION 4");
     //Serial.println(dato_recibido);
     //Serial.println(prend);
   }
   if (dato_recibido=='F' && posicion==4){
     posicion=0;
     pinMode(foco, OUTPUT);
     digitalWrite(foco,prend);
     //Serial.println("POSICION 5");
     //Serial.println(dato_recibido);
     //Serial.println(prend);
     //Serial.println(foco);
   }
}
if (!client.connected()) {
   
   Serial.println();
   Serial.println("disconnecting.");
   Serial.println("==================================");
   Serial.println("");
   client.stop();
   for(;;);
 }
}


Bueno mas o menos la idea es recibir tramas por ejemplo BH1AF (donde B el inicio de mi trama, H para decir q se trata de habitacion, 1 numero de la habitacion, A o Y led encendido o apagado, F final de la trama).

Codigo Php:

Code: [Select]
<b>Apretar Boton para prender o Apagar led</b>
<form action='/prueba2.php' method='GET'><p><input type='hidden' name='pin' value='0'>
<input type='submit' value='Off'/></form>
<form action='/prueba2.php' method='GET'><p><input type='hidden' name='pin' value='1'>
<input type='submit' value='On'/></form>
<?php
$estado
=$_GET["pin"]; //esta es la variable que modifico con los botones
$val =$_GET["led"];    //esta es la variable que consulta el arduino.
$con mysql_connect("localhost""*****""*****");
if(!
$con)
{
die('Could not connect: ' .mysql_error());
}
mysql_select_db("arduino"$con);

$result mysql_query("SELECT `numero`, `estado` FROM `habitacion` WHERE numero=$val");  //aca consulto la base de datos con elarduino
while($rs mysql_fetch_array($result)) {
echo 
"$rs[1]";
mysql_close($con);
}
echo 
$estado;
if (
$estado==0){
mysql_query("UPDATE habitacion set estado='BH1YF' WHERE numero=1");
mysql_close($con);
}
if (
$estado==1){
mysql_query("UPDATE habitacion set estado='BH1AF' WHERE numero=1");
mysql_close($con);
}
//mysql_query("INSERT INTO `led`(`habitacion`) VALUES ($val)");
?>


Bien lo que hago hasta ahora con mi pagina son dos botones On y Off y se apretas actualiza el valor en la base de datos del estado de nuestro led....Ahora bien mis preguntas que he estado probando no logro entender bien, como hacer varias consultas desde el arduino osea preguntar por varias variables, hice varios client.print(GET /) pero solo ejecuta el primero (se q se debe a como se ejecuta por partes el codigo en arduino pero no logro entender).

Mi otra pregunta es mas o menos similar como hago en ese codigo de arduino para que quede a la escucha de alguna variable, por que siempre se ejecuta y se termina el codigo queda en disconect, intente varias modificaciones sin lograr lo que queria probe con while, probe sacando el disconect, probe sacando el for que hay (sucede algo asi como un lazo infinito :S)...bue, me gustaria saber como le doy ahora mas dinamismo a la cosa...yo voy a seguir probando opciones, pero si alguno me va ayudando con tips se lo agradesco, saludos y seguimos avanzando wiiii.

Pipper

Bueno no logro hacer q el cliente se quede preguntando por las variables al servidor, osea se ejecuta una ves se ejecuta bien y tomo todas las variables que necesito, pero necesito repetir el prosedimiento si no se corta tengo q volver a correr el arduino me explico??.

Lo que hice fue crear una funcion y la llamo desde el loop(), pero no logro q se ejecute como yo quiero, osea se llama bien a la funcion pero no hace lo q esta dentro de ella que seria preguntar por los datos con GET y mostrarlos por serial....

A ver si alguien me da una mano :(...

Go Up