Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Invernadero domótico

Componentes y suministros

Arduino MKR1000
× 1
Arduino UNO
× 1
Sensor de temperatura DHT22
× 1
Arduino Wifi Shield 101
× 1
dispositivo Android
× 1
Escudo de control de motor de CC con BTN8982 para Arduino Infineon
× 1

Aplicaciones y servicios en línea

Arduino IDE
Eclipse

Acerca de este proyecto

Descripción general

Las condiciones ambientales del invernadero cambian continuamente, por eso necesitamos un monitoreo eficiente.

Hay muchos beneficios de usar un sistema automático, por ejemplo, menos trabajo o, lo más importante, los usuarios pueden verificar sus propias inversiones desde su casa mediante una PC o un teléfono inteligente.

Otra ventaja importante es la posibilidad de almacenar datos en una base de datos. Esto puede marcar la diferencia entre ganar o perder dinero.

Además, gracias a un sistema de control en tiempo real podemos intervenir de forma inmediata, evitando problemas para el cultivo.

El sistema de monitoreo automático en invernaderos está compuesto por sensores que leen datos ambientales y actuadores, llamados “Esclavos”. Se comunican vía Wireless con el dispositivo central, llamado “Master”. Este último envía posibles cambios a los esclavos (como cambio de umbrales) y datos a través de WiFi al servidor web también.

1. ¿Cómo funciona?

Podemos dividir este proyecto en tres partes diferentes:

  • Maestro
  • Esclavo
  • Servidor web

Hemos utilizado un Arduino / Genuino MKR1000 para el maestro, un Arduino / Genuino Uno para el esclavo.

El maestro se comunica con un servidor web a través de WiFi (WINC1500 integrado), el esclavo adquiere temperatura y humedad con el sensor DHT22, y luego envía estos datos al maestro a través de WiFi (escudo WiFi WINC1500).

2. Maestro

El Master se encuentra en “modo Access Point” y espera que la conexión Slave reciba la temperatura y humedad que se elaboran y envían al Web Server.

El Maestro comprueba si hay datos disponibles, en este caso crea un paquete UDP formado por nuevos umbrales y CRC. De hecho, calcula el CRC que será utilizado por el esclavo para validar la configuración recibida.

Una vez que el Maestro sale del "modo de punto de acceso", se conecta al WiFi para enviar datos al servidor web donde se colocarán en un gráfico.

3. Esclavo

El esclavo adquiere temperatura y humedad mediante el sensor DHT22 y después de 5 minutos envía datos al maestro. También crea un paquete UDP, se conecta al Maestro y luego envía los datos.

Luego espera si hay algunos datos disponibles, como nuevos umbrales. En este caso, el esclavo recibe nuevas configuraciones y calcula el CRC usando las fórmulas Dallas-Maxim.

Posteriormente se compara el CRC calculado con el CRC recibido del Maestro. Si los dos CRC son iguales, el esclavo guarda la nueva configuración en la EEPROM.

4. Servidor web

El servidor web guarda todos los datos que luego se pueden almacenar en un historial.

Para hacer eso, hemos utilizado un script PHP que se conecta a la base de datos y muestra los datos de dos formas diferentes

  • en un gráfico, usando otro script PHP
  • en una aplicación de Android, en formato JSON usando otro script PHP

5. APLICACIÓN

La aplicación nos permite consultar los datos en una base de datos.

En la primera pantalla, podemos seleccionar el rango de tiempo a mostrar y con el botón "GRÁFICO", contacta con el servicio web y obtiene los datos.

La aplicación muestra datos en gráficos.


Código

  • Crear gráfico
  • Secuencia de comandos de conexión con el sitio web
  • Crear tabla
  • Maestro domótico de invernadero
  • Esclavo domótico de invernadero
  • getdati
Crear gráfico PHP
Hemos utilizado esto para crear un gráfico
  SetScale ("textlin"); $ theme_class =new UniversalTheme; $ graph-> SetTheme ($ theme_class); $ graph-> img-> SetAntiAliasing ( falso); $ gráfico-> título-> Set ('Título'); $ gráfico-> SetBox (falso); $ gráfico-> img-> SetAntiAliasing (); $ gráfico-> yaxis-> HideZeroLabel (); $ gráfico -> yaxis-> HideLine (falso); $ gráfico-> yaxis-> HideTicks (falso, falso); $ gráfico-> xgrid-> Show (); $ gráfico-> xgrid-> SetLineStyle ("sólido"); $ gráfico-> xaxis-> SetTickLabels ($ time_axis); $ gráfico-> xgrid-> SetColor ('# E3E3E3'); $ gráfico-> xaxis-> SetLabelAngle (90); $ gráfico-> leyenda-> SetPos (0.5, 0.08, 'center', 'top'); // Crea la primera línea $ p1 =new LinePlot ($ parameter1); $ graph-> Add ($ p1); $ p1-> SetColor ("# 6495ED"); $ p1-> SetLegend ('your_parameter1'); $ graph-> yscale-> SetGrace (0); // Crea la segunda línea $ p2 =new LinePlot ($ parameter2); $ graph-> Add ($ p2); $ p2 -> SetColor ("# B22222"); $ p2-> SetLegend ('your_parameter2'); $ graph-> yscale-> SetGrace (0); $ graph-> legend-> SetFrameWeight (1); // Línea de salida $ gráfico-> Trazo ();?> 
Sitio web de secuencia de comandos de conexión PHP
Hemos usado esto para guardar datos en DB
 "; echo "parámetro1". $ _GET ['parámetro1']. "
"; echo "parámetro2". $ _GET ['parámetro2']. "
"; // Crear conexión $ conn =mysqli_connect ($ servername, $ username, $ password, $ dbname); // Comprobar conexión si (! $ conn) {die ("Conexión fallida:". mysqli_connect_error () );} $ sql ="INSERT INTO invernadero (nombre, parámetro1, parámetro2) VALUES ('". $ nombre. "', '". $ parámetro1. "', '". $ parámetro2. "')"; if ( mysqli_query ($ conn, $ sql)) {echo "Nuevo registro creado con éxito";} else {echo "Error:". $ sql. "
". mysqli_error ($ conn);} mysqli_close ($ conn);?>
Crear tabla SQL
Hemos usado este script para crear la tabla
 CREATE TABLE IF NOT EXISTS `invernadero` (` id` int (11) NOT NULL, `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,` temp` float NOT NULL, `umid` float NOT NULL) ENGINE =MyISAM DEFAULT CHARSET =utf8; 
Maestro domótico de invernadero C / C ++
Este es el código del Máster
 / * Proyecto invernadero de automatización * // * Autores:Antonio La Mura, Umberto Festa * // * Fecha:03/03/2016 * // * Nuestra idea es permitir a los usuarios, que compran frutas y hortalizas cultivadas en invernaderos, para conocer con exactitud todos los pasos de plantación que han tenido los productos, como el uso de fertilizantes químicos y otros productos similares. Se colocará un código QR en los productos vendidos que será leído por una aplicación de teléfono inteligente específica. Proporciona información sobre las condiciones ambientales en las que se han cultivado los productos y los productos químicos utilizados. El sistema de monitoreo automático en invernaderos está compuesto por sensores que leen datos ambientales y actuadores, llamados esclavos. Se comunican vía Wireless con el dispositivo central, llamado Master. Este último envía posibles cambios a los esclavos (como cambio de umbrales) y datos a través de WiFi también al servidor web. Cuando el producto está listo para venderse, se solicita la generación del código QR al servicio web y se coloca en el paquete. La última parte del sistema es la aplicación móvil que se encarga de escanear los códigos QR y muestra la información relativa al usuario. * // * Master * // * DEVO AGGIUNGERE SOLO LA PARTE CHE MI SERVE PER RICEVERE LE NUOVE SOGLIE CHE VENGONO INVIATE DALL'APP * // * Bibliotecas utilizadas * / # incluyen  #include  #include  #include  #include  / * Variables de conexión * / char ssid [] ="SSID"; / * Su red SSID (nombre) * / char pass [] ="pass"; / * Su contraseña de red (usar para WPA, o usar como clave para WEP) * / int keyIndex =0; / * Su clave de red Número de índice (necesario solo para WEP) * / char ssid_ap [] ="Arduino"; / * Nombre de AP creado * / char pass_ap [] =""; / * (Aún no soportado) * / int status =WL_IDLE_STATUS; unsigned int localPort =2390; / * Puerto local para escuchar en * / char server [] ="www.cormaz.altervista.org"; / * Dirección de nombre para Google (usando DNS) * / WiFiServer server_ap (80); WiFiClient client_ap; WiFiUDP Udp; RTCZero rtc; WiFiClient client; char packetBuffer [255]; / * Búfer para contener paquetes entrantes * / char ReplyBuffer [255]; / * Una cadena para devolver * // * Variables para nuevos umbrales * / float humax =0; float humin =0; float tumax =0; float tumin =0; / * Funciona como Access Point (flag =false), conecta to WebServer (flag =true) * / boolean flag =false; boolean threeshold_available =false; void setup () {/ * Inicializar serie y esperar a que se abra el puerto:* / Serial.begin (9600); while (! Serial) {; / * Espere a que se conecte el puerto serie. Necesario solo para puerto USB nativo * /} Serial.println ();} void loop () {int packetSize; temperatura doble doble zumbido int id; byte crc; String strURL; // Verifique la presencia del escudo:/ ************************************* ***********************************************/ Si ( WiFi.status () ==WL_NO_SHIELD) {Serial.println ("escudo WiFi no presente"); / * No continúe:* / while (verdadero); } / ********************************************** ************************************* / // Intento de conectarse a la red WiFi:/ * *********************************************** *********************************** / while (status! =WL_CONNECTED) {Serial.print ("Creando Red denominada:"); Serial.println (ssid_ap); / * Conectarse a la red WPA / WPA2. Cambie esta línea si usa una red abierta o WEP:* / status =WiFi.beginAP (ssid_ap); / * Espere 10 segundos para la conexión:* / delay (10000); server_ap.begin (); } Serial.println ("Conectado a wifi"); / ********************************************** ************************************ / // Iniciar comunicación UDP / ****** *********************************************** ****************************** / Udp.begin (puerto local); printWifiStatus (); cliente_ap =servidor_ap.available (); if (client_ap) {/ * Si obtiene un cliente * / / * Estoy esperando información * / Serial.println ("nuevo cliente"); / * Imprime un mensaje desde el puerto serie * / / * Si hay datos disponibles, lee un paquete * / packetSize =Udp.parsePacket (); if (packetSize) {Serial.print ("Paquete recibido de tamaño"); Serial.println (tamaño del paquete); Serial.print ("Desde"); IPAddress remoteIp =Udp.remoteIP (); Serial.print (remoteIp); Serial.print (", puerto"); Serial.println (Udp.remotePort ()); / * Leer el paquete en packetBuffer * / int len ​​=Udp.read (packetBuffer, 255); if (len> 0) packetBuffer [len] =0; Serial.println ("Contenido:"); Serial.println (packetBuffer); char * comando =strtok ((char *) packetBuffer, ";"); int count =0; while (command! =0) {/ * Divide la información * / switch (count) {case 0:id =atoi (command); descanso; caso 1:temp =atof (comando) / 10; descanso; caso 2:hum =atof (comando) / 10; descanso; } comando =strtok (0, ";"); contar ++; } Serial.print ("Paquete recibido de"); Serial.print (id); Serial.print ("T:"); Serial.print (temp, 1); Serial.print ("H:"); Serial.println (zumbido, 1); / ********************************************** ************************************ / retraso (20); / * Calcula el CRC-8, así que crea una matriz de bytes * / / ********************************* ******************************************* / byte bhmax =( byte) humax; byte bhmin =(byte) humin; byte btmax =(byte) tumax; byte btmin =(byte) tumin; byte crc32_str [4] ={bhmax, bhmin, btmax, btmin}; crc =CRC8 (crc32_str); Serial.println ("CRC:"); Serial.println (crc); / ********************************************** ******************************* / if (threeshold_available ==true) {snprintf (ReplyBuffer, sizeof (ReplyBuffer), " % d;% d;% d;% d;% d;% d ", id, (int) humax, (int) humin, (int) tumax, (int) tumin, (int) crc); / * Enviar una respuesta, a la dirección IP y al puerto que nos envió el paquete que recibimos * / Udp.beginPacket (Udp.remoteIP (), Udp.remotePort ()); Udp.write (ReplyBuffer); Udp.endPacket (); }} / * Imprime el monitor serial * / / * Cierra la conexión:* / client_ap.stop (); Serial.println ("cliente desconectado"); bandera =verdadero; } / * Buen AP * / / **************************************** ************************************* / / * Conéctese al servidor y envíe datos a DataBase * / / ********************************************* ********************************* / if (flag ==true) {/ * Intento de conectarse a la red Wifi :* / while (status! =WL_CONNECTED) {Serial.print ("Intentando conectarse a SSID:"); Serial.println (ssid); / * Conectarse a la red WPA / WPA2. Cambie esta línea si usa una red abierta o WEP:* / status =WiFi.begin (ssid, pass); / * Espere 10 segundos para la conexión:* / delay (10000); } Serial.println ("Conectado a wifi"); printWifiStatus (); strURL ="GET /YourAddress.php?id="; strURL + =id; strURL + ="&parámetro1 ="; strURL + =temp; strURL + ="&parámetro2 ="; strURL + =zumbido; strURL + ="HTTP / 1.1"; Serial.println ("\ nIniciando la conexión al servidor ..."); // si obtiene una conexión, informe a través de serie:if (client.connect (servidor, 80)) {Serial.println ("conectado al servidor"); // Realizar una solicitud HTTP:client.println (strURL); client.println ("Anfitrión:www.cormaz.altervista.org"); client.println ("Conexión:cerrar"); cliente.println (); client.stop (); Serial.println ("¡Ok!"); } / * Si el servidor está desconectado, detenga el cliente:* / if (! Client.connected ()) {Serial.println (); Serial.println ("Desconectando del servidor"); client.stop (); / * No hacer nada para siempre:* / while (verdadero); } bandera =falso; } / ********************************************** ******************************** /} / * Calcular algoritmo CRC-8 - basado en fórmulas Dallas / Maxim * / byte CRC8 (byte constante * datos) {byte crc =0x00; while (* datos) {byte extract =* data ++; para (byte tempI =8; tempI; tempI--) {byte sum =(crc ^ extract) &0x01; crc>> =1; if (suma) {crc ^ =0x8C; } extraer>> =1; }} return crc;} void printWifiStatus () {/ * Imprime el SSID de la red a la que estás conectado:* / Serial.print ("SSID:"); Serial.println (WiFi.SSID ()); / * Imprima la dirección IP de su escudo WiFi:* / IPAddress ip =WiFi.localIP (); Serial.print ("Dirección IP:"); Serial.println (ip); / * Imprime la fuerza de la señal recibida:* / long rssi =WiFi.RSSI (); Serial.print ("intensidad de la señal (RSSI):"); Serial.print (rssi); Serial.println ("dBm");} 
Esclavo domótico de invernadero C / C ++
Este es el código del Esclavo
 / * Proyecto invernadero de automatización * // * Autores:Antonio La Mura, Umberto Festa * // * Fecha:21/03/2016 * // * Nuestra idea es permitir a los usuarios, que compran frutas y hortalizas cultivadas en invernaderos, para conocer con exactitud todos los pasos de plantación que han tenido los productos, como el uso de fertilizantes químicos y otros productos similares. Se colocará un código QR en los productos vendidos que será leído por una aplicación de teléfono inteligente específica. Proporciona información sobre las condiciones ambientales en las que se han cultivado los productos y los productos químicos utilizados. El sistema de monitoreo automático en invernaderos está compuesto por sensores que leen datos ambientales y actuadores, llamados esclavos. Se comunican vía Wireless con el dispositivo central, llamado Master. Este último envía posibles cambios a los esclavos (como cambio de umbrales) y datos a través de WiFi también al servidor web. Cuando el producto está listo para venderse, se solicita la generación del código QR al servicio web y se coloca en el paquete. La última parte del sistema es la aplicación móvil que se encarga del escaneo de códigos QR y muestra la información relativa al usuario. * // * Esclavo * // * Bibliotecas utilizadas * / # incluyen  #include  #include  #include  #include  // Definir todos los PIN # definir HUMIDIFICADOR A4 # definir CALENTADOR A5 # definir DHT22_PIN 4 // Definir motor # definir IS_1 0 #define IS_2 1 # define IN_1 3 # define IN_2 11 # define INH_1 12 # define INH_2 13 # define TCONST 100 // Tiempo de retardo entre pasos // Variable para restablecer millis () extern unsigned long timer0_millis; int status =WL_IDLE_STATUS; char ssid [] ="Arduino"; // su red SSID (nombre) char pass [] =""; // su contraseña de red (úsela para WPA o úsela como clave para WEP) int keyIndex =0; // su clave de red Número de índice (necesario solo para WEP) unsigned int localPort =2390; // puerto local para escuchar onchar packetBuffer [255]; // búfer para contener el paquete entranteWiFiUDP Udp; // Definir DHT22DHT22 myDHT22 (DHT22_PIN); // Variable para enviar flotador hmin =0; flotar hmax =0; flotar tmin =0; flotar tmax =0; int duty_motor =0; flotar humedad; temperatura de flotación; // Variable para enviar cada 10 segundos intervalo largo sin firmar =600000; void setup () {Serial.begin (9600); while (! Serial) {; // espera a que se conecte el puerto serie. Necesario solo para puerto USB nativo} // Inicializar PIN (ENTRADA - SALIDA) pinMode (CALENTADOR, SALIDA); digitalWrite (CALENTADOR, BAJO); pinMode (HUMIDIFICADOR, SALIDA); digitalWrite (HUMIDIFICADOR, BAJO); // Establecer el PIN para el pinMode del ventilador (IN_1, OUTPUT); pinMode (IN_2, SALIDA); pinMode (INH_1, SALIDA); pinMode (INH_2, SALIDA); // Restablecer reset_ports (); escritura digital (INH_1, 1); escritura digital (INH_2, 1); Serial.println ("Comenzando ..."); delay (2000);} void loop () {// si hay datos disponibles, lee un paquete int packetSize =Udp.parsePacket (); tiempo largo sin firmar =millis (); currentMillis largo sin firmar =millis (); DHT22_ERROR_t errorCode; int i =0; char name [] ="clie1"; humedad =myDHT22.getHumidity () * 10; temperatura =myDHT22.getTemperatureC () * 10; char toSend [32]; errorCode =myDHT22.readData (); byte crc; int crc_ric; // Compruebe los errores de DHT22 de humedad y temperatura del sensor / ************************************* *************************************** / switch (código de error) {case DHT_ERROR_NONE:char buf [128]; sprintf (buf, "Lectura de solo enteros:Temperatura% hi.% 01hi C, Humedad% i.% 01i %% RH", myDHT22.getTemperatureCInt () / 10, abs (myDHT22.getTemperatureCInt ()% 10), myDHT22. getHumidityInt () / 10, myDHT22.getHumidityInt ()% 10); descanso; caso DHT_ERROR_CHECKSUM:romper; caso DHT_BUS_HUNG:romper; caso DHT_ERROR_NOT_PRESENT:romper; caso DHT_ERROR_ACK_TOO_LONG:romper; case DHT_ERROR_SYNC_TIMEOUT:break; case DHT_ERROR_DATA_TIMEOUT:break; caso DHT_ERROR_TOOQUICK:romper; } / ********************************************** ******************************** / // Imprime los valores, cuando cambia / ******* *********************************************** *********************** / if (humedad! =myDHT22.getHumidity () * 10 || temperatura! =myDHT22.getTemperatureC () * 10) { Serial.print ("T:"); Serial.print (myDHT22.getTemperatureC (), 1); Serial.print ("C"); Serial.print ("H:"); Serial.print (myDHT22.getHumidity (), 1); Serial.println ("%"); } / ********************************************** ******************************** / // Enviar los parámetros cada 10 minutos / ******** *********************************************** ********************** / if (millis ()> intervalo) {// Conexión a AP / ************ *********************************************** ****************** / // comprobar la presencia del escudo:if (WiFi.status () ==WL_NO_SHIELD) {Serial.println ("escudo WiFi no presente "); // no continúe:while (verdadero); } // intenta conectarse a la red Wifi:while (status! =WL_CONNECTED) {Serial.print ("Intentando conectarse a SSID:"); Serial.println (ssid); // Conéctese a la red WPA / WPA2. Cambie esta línea si usa una red abierta o WEP:status =WiFi.begin (ssid); // esperar 10 segundos para la conexión:delay (10000); } Serial.println ("Conectado a wifi"); / ********************************************** ******************************* / Serial.println ("\ nIniciando la conexión al servidor ..."); // si obtiene una conexión, informe a través de serial:Udp.begin (localPort); snprintf (toEnviar, tamaño de (toEnviar), "% s;% d;% d", nombre, (int) humedad, (int) temperatura); // enviamos una respuesta, a la dirección IP y al puerto que nos envió el paquete que recibimos Udp.beginPacket (Udp.remoteIP (), Udp.remotePort ()); Udp.write (para enviar); Udp.endPacket (); Serial.println ("Envío finalizado"); resetMillis (); while (millis () <10000) {packetSize =Udp.parsePacket (); if (packetSize) {/ * Leer el paquete en packetBuffer * / int len ​​=Udp.read (packetBuffer, 255); if (len> 0) packetBuffer [len] =0; Serial.println ("Contenido:"); Serial.println (packetBuffer); char * comando =strtok ((char *) packetBuffer, ";"); int count =0; while (command! =0) {/ * Divide la información * / switch (count) {case 0:snprintf (name, sizeof (name), "% s", command); descanso; caso 1:hmax =atof (comando) / 10; // atof (char *) mi converte un tipo char * in double break; caso 2:hmin =atof (comando) / 10; descanso; caso 3:tmax =atof (comando) / 10; descanso; caso 4:tmin =atof (comando) / 10; descanso; caso 5:crc_ric =atoi (comando); descanso; } comando =strtok (0, ";"); contar ++; } Serial.print ("Respuesta:"); Serial.print (nombre); Serial.print (";"); Serial.print (hmax, 1); Serial.print (";"); Serial.print (hmin, 1); Serial.print (";"); Serial.print (tmax, 1); Serial.print (";"); Serial.println (tmin, 1); Serial.print ("CRC recibido:"); Serial.println (crc_ric); // calculamos CRC-8 y obtengo la matriz de bytes / ********************************** ******************************************* / byte bhmax =(byte ) hmax; byte bhmin =(byte) hmin; byte btmax =(byte) tmax; byte btmin =(byte) tmin; byte crc32_str [4] ={bhmax, bhmin, btmax, btmin}; crc =CRC8 (crc32_str); Serial.println ("CRC:"); Serial.println (crc); / ********************************************** ******************************* / if (crc_ric ==(int) crc) {// Guardar en EEPROM EEPROM_writeDouble (0, tmax); EEPROM_writeDouble (4, tmin); EEPROM_writeInt (8, hmax); EEPROM_writeInt (10, hmin); }}} retraso (10); } / ********************************************** ******************************** / WiFi.disconnect (); // Gestione el HUMIDIFICADOR, CALEFACTOR y ventilador según el valor del sensor / ********************************* *********************************************** * / // CALENTADOR if (myDHT22.getTemperatureC ()> =tmax) {digitalWrite (CALENTADOR, ALTO); } if (myDHT22.getTemperatureC () <=tmin + 1) {digitalWrite (CALENTADOR, BAJO); } // HUMIDIFICADOR if ((int) myDHT22.getHumidity ()> =hmax) {digitalWrite (HUMIDIFICADOR, ALTO); } if ((int) myDHT22.getHumidity () <=hmin + 1) {digitalWrite (HUMIDIFIER, LOW); } // Ventilador, motor sin escobillas if (myDHT22.getTemperatureC ()> =tmax + 4) {// Rotación del motor de acuerdo con temperatura, servicio -> 0 por t =tmax + 4 y servicio -> 100 por t> tmax + 10 // Rotazione del motore al variare della temperatura, duty -> 0 per t =tmax + 4 e duty -> 100 per t> tmax + 10 duty_motor =map (i, tmax + 4, tmax + 10, 0, 100); si (tmáx> tmáx + 10) {motor_de_uso =100; } analogWrite (IN_2, duty_motor); retraso (TCONST); } if (myDHT22.getTemperatureC () <=(tmax + tmin) / 2) {reset_ports (); // Rotación del motor según temperatura, duty -> 0 per t =tmax + 4 y duty -> 255 per t> tmax + 10 duty_motor =0; analogWrite (IN_2, duty_motor); retraso (TCONST); } / ********************************************** ************************************* / delay (1000);} // Guardar doble en EEPROMvoid EEPROM_writeDouble (int ee, valor doble) {byte * p =(byte *) (void *) &value; for (int i =0; i > =1; if (suma) {crc ^ =0x8C; } extraer>> =1; }} return crc;} // Se usa para reiniciar millis () void resetMillis () {cli (); timer0_millis =0; sei ();} 
getdati PHP
Hemos utilizado esto para conectar nuestra aplicación con la base de datos
 "; // seleccionar una base de datos para trabajar con $ selected =mysql_select_db ("serra", $ dbhandle) o morir ("No se pudieron seleccionar ejemplos"); $ datada =$ _GET ["datada"]; $ dataa =$ _GET ["dataa"]; // ejecuta la consulta SQL y devuelve los registros $ result =mysql_query ("SELECT hum, temp, date FROM record WHERE date> =' ". $ datada." 'y fecha <=' ". $ dataa." '"); $ registros =matriz (); // recupera los datos de la base de datos mientras ($ fila =mysql_fetch_array ($ resultado)) {$ tmp =matriz ("hum" => $ fila {'hum'}, "temp" => $ fila {'temp'}, "fecha" => $ fila {'fecha'}); array_push ($ registros, $ tmp); // echo "HUM:". $ fila {'hum'}. "TEMP:". $ fila {'temp'}. "Fecha:". // mostrar los resultados $ fila {'fecha'}. "
";} echo json_encode ($ registros); // cerrar la conexión mysql_close ($ dbhandle);?>
Aplicación GrenHouse
En la primera página tienes que configurar la fecha usando dos DatePicker. Cuando presionas el botón "GRAPHIC", realiza una llamada HTTP GET al script PHP "getdati" enviando los parámetros y la fecha que hayas elegido. Luego recibe el JSON y lo decodifica, luego de que crea el gráfico usando la biblioteca GraphViewhttps://github.com/cormaz/app_greenhouse.git

Esquemas

Conexión:Arduino UNO - DHT22 - Relé

Proceso de manufactura

  1. Animación de mapa de bits en ILI9341 TFT Touchscreen Display Shield
  2. Controlador DMX operado por la web
  3. Arduino Spybot
  4. FlickMote
  5. Televisión casera B-Gone
  6. Reloj maestro
  7. Reloj HSV
  8. Juguete controlado por Android con Raspberry Motor Shield
  9. Encuéntrame
  10. Arduino Power
  11. BLUE_P:Escudo de programación inalámbrico Arduino