Primer proyecto con Arduino: Invernadero automatizado

Bueno pues como he puesto en el titulo es mi primer proyecto mas o menos serio, he jugado un poco con el arduino y he pensado en hacer algo no muy dificil para darle uso...
Habia pensado en hacer un invernadero automatico y que requiera de la minima ayuda humana. Para empezar queria conectarlo por puerto serie y que me pase los valores de temperatura y nivel de intensidad luminica. Mas adelante habia pensado en incorporarle sensores de humedad, luces, algun tipo de calefaccion, un riego por goteo controlado por un higrometro y alguna chorradica mas que se me vaya ocurriendo sobre la marcha... Tengo ya un LDR y un NTC para ir empezando, y cuando vea que va cogiendo forma el proyecto se lo incorporare al invernadero, por ahora me basta con que vaya funcionando en mi cuarto (que no es poco).

El primer problema que me surge es que intento que me muestre en el monitor serie de arduino la frase "Hola mundo" y me salta el error: 'Serial' was not declared in this scope
He buscado por el foro y la solucion que proponen es volver a instalar, pero me da miedo porque en su momento tuve bastantes problemas con los drivers... Uso Arduino ERW 1.0.4, cualquier ayuda sera bien recibida. :sweat_smile:
Gracias a todos.

Hola :slight_smile:
Si pones el código empleado seguro que alguien te puede ayudar, si no es imposible :wink:
Yo hice algo parecido hace unos 6 años para un proyecto de empresa, es muy buena idea :slight_smile:

No puse el codigo porque me daba vergüenza poner lo poco que pude hacer... estan declaradas unas constantes y poco mas:

#define temperaturaInterior 25 //Temperatura a la que estara el invernadero
#define iluminacionMinima 30 //Iluminacion a la que se encenderan/apagaran las luces
 
void setup(){
Serial.begin(9600);
}

void loop(){
Serial.println("Hola mundo");
}

Tienes que incluir la librería SPI al principio del código para que funcione:

#include <SPI.h>

davidvg:
Tienes que incluir la librería SPI al principio del código para que funcione:

#include <SPI.h>

Acabo de hacer lo que me dices y me sigue saltando el mismo error... No se si es que soy idiota o tengo mala suerte xD
Alguna otra idea?
Gracias

EDITO: He encontrado el problema... Y tenia razon, soy idiota, tenia seleccionada otra placa en herramientas, board... Ahora parece que funciona

Mazis:

davidvg:
Tienes que incluir la librería SPI al principio del código para que funcione:

#include <SPI.h>

Acabo de hacer lo que me dices y me sigue saltando el mismo error... No se si es que soy idiota o tengo mala suerte xD
Alguna otra idea?
Gracias

EDITO: He encontrado el problema... Y tenia razon, soy idiota, tenia seleccionada otra placa en herramientas, board... Ahora parece que funciona

De todos modos no sé qué estaba pensando porque no te hace falta incluir la librería SPI. Se me fue la pinza :sweat_smile:
Me alegro de que te funcione :slight_smile:

Bueno... posteo los avances de hoy, lo poco que he hecho es tomar la temperatura y pasarla por puerto serie...

#include <SPI.h>
#include <math.h>
#define temperaturaInterior 25 //Temperatura a la que estara el invernadero
#define iluminacionMinima 30 //Iluminacion a la que se encenderan/apagaran las luces

int pinNTC = 0;
float Vout = 0.0;    
float rNTC = 0.0;    //Resistencia del NTC
float rFija = 1000;  //Resistencia del divisor
float beta = 3950;   //Valor beta del NTC
float r25 = 2800;    //Valor de la resistencia del NTC a 25ºC
float t0 = 293.15;   //Temperatura minima que lee el NTC
float tempC1 = 0.0;
float tempC2 = 0.1;
float tempK = 0.0;
void setup(){
  Serial.begin(9600);
  pinMode(pinNTC, INPUT);
}

void loop(){
  //Calcular temperatura:
  Vout=(5/1024)*(analogRead(pinNTC));
  rNTC=(Vout*rFija)/(5-Vout);
  tempK = (beta/(log(rNTC/r25)+(beta/t0)));
  tempC1 = tempK - 273.15;
  if(tempC1 != tempC2){
    Serial.println("Temperatura: ");
    Serial.print(tempC1);
    Serial.println(" grados Celsius");
    tempC2 = tempC1;
  }
  delay(5000);
}

Estaria bien que alguien me dijera si funciona porque se me ha estropeado la protoboard y no lo he podido comprobar

Sin sensor, y sin tener el circuito y sin saber qué es cada cosa poco se puede decir. La medida de tensión parece correcta y el cálculo de la NTC en el divisor también.

  tempK = (beta/(log(rNTC/r25)+(beta/t0)));

Sin tener datos del sensor... El resto parece correcto.
¿Qué has hecho para cargarte la protoboard? :astonished: :stuck_out_tongue:

¿Qué has hecho para cargarte la protoboard? smiley-eek smiley-razz

La verdad es que no lo se... pero debe de hacer mal contacto o algo porque todo el rato me dice que estoy a -273.15 grados celsius en mi habitacion y yo no tengo tanto frio XD
El fallo tiene que estar en la placa porque el circuito creo que esta bien montado (un divisor de tension con una R de 1K, luego el cable que va hasta el pin A0 y debajo el ntc conectado a masa) y la entrada analogica no la lee pòrque al cambiar tempC1 por Vout me daba 0.0

Ahora lo que estaba pensando es si se pueden hacer clases como en java, llamarlas desde otra clase y hacer asi una para cada elemento a controlar. Es decir, crear una clase para la temperatura que me mida su valor, me encienda las resistencias de potencia si es menor que la indicada o encienda un ventilador si ha subido demasiado. Otra para la luz y asi con cada elemento que quiera controlar. He pensado que si no se puede podria hacer librerias pero me parece un poco follon... :roll_eyes:

Mazis:

¿Qué has hecho para cargarte la protoboard? smiley-eek smiley-razz

La verdad es que no lo se... pero debe de hacer mal contacto o algo porque todo el rato me dice que estoy a -273.15 grados celsius en mi habitacion y yo no tengo tanto frio XD

Eso es un cero absoluto, es decir 0K (kelvin); algo tienes mal, echa un ojo a las especificaciones del sensor. O tal vez tempK es 0 por algún motivo y eso te da siempre -273.15

Mazis:
Ahora lo que estaba pensando es si se pueden hacer clases como en java, llamarlas desde otra clase y hacer asi una para cada elemento a controlar. Es decir, crear una clase para la temperatura que me mida su valor, me encienda las resistencias de potencia si es menor que la indicada o encienda un ventilador si ha subido demasiado. Otra para la luz y asi con cada elemento que quiera controlar. He pensado que si no se puede podria hacer librerias pero me parece un poco follon... :roll_eyes:

Más bien se pueden hacer clases como en C++, porque es lo que es :slight_smile: Admite clases, librerías, y todo lo que sea C++. Cuando te dije -equivocadamente- que incluyeras el SPI no es más que la librería del protocolo Serie.

Bueno por partes... he conseguido solucionar el problema del ntc, he encontrado un LM35 y lo he sustituido y funciona a la perfeccion, ademas de ser mucho mas facil de programar porque no hacen falta tantas variables ni tantas operaciones... Estoy a 27ºC en mi habitacion XD XD

Más bien se pueden hacer clases como en C++, porque es lo que es smiley Admite clases, librerías, y todo lo que sea C++. Cuando te dije -equivocadamente- que incluyeras el SPI no es más que la librería del protocolo Serie.

C++ y java son muy parecidos ya que es programacion orientada a objetos, yo te hablo de java porque en la universidad(estudio ingenieria electronica) es el lenguaje que nos enseñaron a programar. Si fueras tan amable de explicarme un poco mas cual es la sintaxis para definir una clase te lo agradeceria... Ahora estoy en proceso de programar el funcionamiento del ventilador, habia pensado en usar un transistor y un par de diodos, ya que el ventilador es de 12 V y 0,4 A y el arduino solo me da 40 mA y 5 V...

Mañana subo el codigo con los cambios y algun avance mas que he hecho...

He avanzado algo estos dias y ya tengo casi terminado el control de la temperatura, esta programado entero y me falta ir a comprar las resistencias de potencia para calentar el invernadero... Como el codigo que tengo ahora esta "feo" voy a organizarlo definitivamente en librerias, he escrito el codigo del .cpp y el .h pero no me deja guardarlo con esa extension y no se porque... :~

Para no tener que depender de una fuente de alimentacion externa de un mayor voltaje que el que da arduino y ya solo para el ventilador necesito 12, he pensado en utilizar dos transistores, uno de ellos un mosfet que puede dar una corriente mas alta para alimentar las resistencias de potencia y hacer que calienten, y otro que me llegue a dar los 12 v que necesito.

Tambien he estado mirando si hacer un invernadero yo o comprar uno ya hecho, he visto uno en ikea bueno, bonito y barato, y encima no muy grande que me podria servir como laboratorio para hacer pruebas. Asi que para empezar a probar y asegurarme de que todo funciona mas o menos bien, me puede servir.

En cuanto consiga guardar la libreria subo el codigo para que lo vean, por si a alguien le puede interesar...

Un saludo.

Hola.
Primeramente, enhorabuena por los avances. Casi todos en este foro podemos imaginarnos la satisfacción que estarás sintiendo (me temo que estás enganchándote a esto ;)).
Te cuento, si quieres, cómo creo yo las librerías. Crea primero un sketch, por ejemplo invernadero.ino. Una vez abierto, verás en la parte superior derecha, a la altura de la pestaña de tu sketch, una flecha triangular de la que saldrá un menú desplegable al pinchar. Selecciona "nueva pestaña". Te pedirá el nombre para la pestaña. Teclea, por ejemplo, termostato.h. Repite el proceso para crear termostato.cpp. Pega en cada pestaña el código correspondiente y guarda el proyecto. Los archivos estarán dentro de la misma carpeta del proyecto. Para incluirlos de momento en el propio proyecto, utiliza comillas (#include "termostato.h" en lugar de #include <termostato.h>). Así puedes retocarla a la vez que modificas tu proyecto. Si sólo la vas a utilizar en ese proyecto te vale así, pero si tienes tu librería ya depurada y quieres tenerla "en la biblioteca", crea en la carpeta libraries de Arduino una subcarpeta con el nombre de tus archivos .cpp y .h y copia estos en ella. Ya puedes incluirlos en cualquier nuevo proyecto utilizando #include <termostato.h> (y no aparecerá la pestaña en tu sketch).
¡Ah! Ten en cuenta que si eliminas una pestaña en tu proyecto, también estás borrando el archivo.

Muchas muchisimas gracias, con tu metodo ha sido un momento crear las librerias... Aqui dejo el codigo:

El archivo Temperatura.h:

//Temperatura.h

#Ifndef Temperatura_h
#Define Temperatura_h
#Include "WConstants.h"
#Include "Temperatura.h"

class Temperatura{
  public:
    Temperatura(int pinLM35, int pinRPotencia, int pinVentilador);
    int calcularTemperatura();
    void mostrarTemperaturaSerial(int temp);
    void controlTemperatura(int temp);
  private:
    int _pinLM35;
    int _pinRPotencia;
    int _pinVentilador;
}

#endif

Y el archivo Temperatura.cpp:

//Temperatura.cpp 

#include "WProgram.h"
#include "Temperatura.h"

Temperatura::Temperatura(int pinLM35, int pinRPotencia, int pinVentilador){
  _pinLM35=pinLM35;
  _pinRPotencia=pinRPotencia;
  _pinVentilador=pinVentilador;
}

int Temperatura::calcularTemperatura(){
  //Calcular temperatura con un LM35:
  return (analogRead(_pinLM35))*500/1024;;
}
void Temperatura::mostrarTemperaturaSerial(int temp){
  Serial.println("Temperatura: ");
  Serial.print(temp);
  Serial.println(" grados C");
}  
  
void Temperatura::controlTemperatura(int temp){
    if(temp>=tempReferencia + 5){        //Histeresis de 5ºC
    digitalWrite(_pinVentilador, HIGH);
    if(digitalRead(_pinRPotencia)==HIGH){
      digitalWrite(_pinRPotencia, LOW);
    }
  }else if(temp<=tempReferencia-5){
     digitalWrite(_pinRPotencia, HIGH);
     if(digitalRead(_pinVentilador)==HIGH){
        digitalWrite(_pinVentilador, LOW);
     }
  }else if(temp==tempReferencia){
    digitalWrite(_pinVentilador, LOW);
    digitalWrite(_pinRPotencia, LOW);
  }

Saltan errores por todos lados pero no entiendo nada, en cuanto tenga algo de tiempo lo miro...

Por si te sirve de ayuda, un par de precisiones.
En el archivo .h incluyes el propio archivo .h.

ifndef, define e include son en minúsculas (supongo que en tu sketch están bien y las has puesto en mayúsculas al transcribir, pero por si acaso).
Las librerías que incluyas que no estén en la carpeta del sketch, sino en la biblioteca de librerías, sí debes incluirlas como # include <WConstants.h>
Tras el cierre de llaves de la definición de la clase, pon un punto y coma.
En las últimas versiones del IDE, tal vez sea más sencillo incluir <Arduino.h> en lugar de WConstants y otras.
Saludos.

ifndef, define e include son en minúsculas (supongo que en tu sketch están bien y las has puesto en mayúsculas al transcribir, pero por si acaso).

Pues no.. XD no estaban en mayusculas, he arreglado un poco lo que me dices, pero ahora me salta este otros error... "expected constructor, destructor, or type conversion before string constant" no lo entiendo, en realidad no entiendo nada... :drooling_face:
Estoy empezando a pensar que tal vez no haya sido muy buena idea eso de las librerias...

EDITO: Supongo que si creo diferentes sketch luego podran comunicarse entre ellos, es correcto? O me olvido de librerias y mierdas y lo hago en el mismo skecth todo?

No desesperes, hombre, que vas por buen camino ;). Ahora tal vez no; pero si tu código se va haciendo más grande, agradecerás el haber comenzado el programa de forma estructurada.
Te paso el código de tu penúltimo post ligeramente modificado, aunque ahora mismo me da error de variable no definida; pero funcionando la inclusión de la librería:

Archivo del proyecto (vacío, sólo he declarado un objeto de tu clase):

include "Temperatura.h"

Temperatura miTemperatura(1,2,3);
void setup() {
// put your setup code here, to run once:

}

void loop() {
// put your main code here, to run repeatedly:

}

Temperatura.h

//Temperatura.h

#ifndef Temperatura_h
#define Temperatura_h

class Temperatura{
public:
Temperatura(int pinLM35, int pinRPotencia, int pinVentilador);
int calcularTemperatura();
void mostrarTemperaturaSerial(int temp);
void controlTemperatura(int temp);
private:
int _pinLM35;
int _pinRPotencia;
int _pinVentilador;
}; // ¡OJO AL PUNTO Y COMA!

#endif

Temperatura.cpp

#include "Arduino.h"
#include <Temperatura.h>

Temperatura::Temperatura(int pinLM35, int pinRPotencia, int pinVentilador){
_pinLM35=pinLM35;
_pinRPotencia=pinRPotencia;
_pinVentilador=pinVentilador;
}

int Temperatura::calcularTemperatura(){
//Calcular temperatura con un LM35:
return (analogRead(_pinLM35))*500/1024;;
}
void Temperatura::mostrarTemperaturaSerial(int temp){
Serial.println("Temperatura: ");
Serial.print(temp);
Serial.println(" grados C");
}

void Temperatura::controlTemperatura(int temp){
if(temp>=tempReferencia + 5){ //Histeresis de 5ºC
digitalWrite(_pinVentilador, HIGH);
if(digitalRead(_pinRPotencia)==HIGH){
digitalWrite(_pinRPotencia, LOW);
}
}else if(temp<=tempReferencia-5){ // ERROR: tempReferencia no está definida.
digitalWrite(_pinRPotencia, HIGH);
if(digitalRead(_pinVentilador)==HIGH){
digitalWrite(_pinVentilador, LOW);
}
}else if(temp==tempReferencia){
digitalWrite(_pinVentilador, LOW);
digitalWrite(_pinRPotencia, LOW);
}

Tenia esperanzas de que funcionara o diera menos fallos pero visto lo visto... voy a volver a mi plan inicial y a poner comentarios para cada linea si hace falta para no liarme.

He ido buscando el material que necesito por internet y la semana que viene comprare todo lo necesario para empezar a probarlo... He decido cambiar la manera de calentar/enfriar, el problema que tenia era que no sabia diseñar a pequeña escala un sistema que me enfriara el invernadero, pero por casualidades de la vida, he dado con las celulas peltier, que calientan y enfrian, cambiando solo la polaridad de la corriente(mejor imposible). He pensado que para controlarlo podria usar dos salidas analogicas y dependiendo de si quiero calentar o enfriar, poner una a low y la otra a high y viceversa, esto supongo que es posible no?
Tambien he dado con la solucion para aumentar la humedad, un transductor de ultrasonidos, que hace evaporar el agua de, por ejemplo, un vaso.

En cuanto haga avances con el codigo lo ire posteando por aqui, hasta entonces... Saludos

Estoy aqui de nuevo, he avanzado un poco y he programado un sistema para darle ordenes por el puerto serie, yo creo que funciona pero no me deja compilar porque me da errores en otra parte y no se como solucionarlo... Ya he pedido las celulas peltier y hoy o mañana me deberian llegar ya, he pensado en comprar una shield para arduino con varios reles(esta: http://www.bricogeek.com/shop/shields-arduino/338-arduino-relay-shield.html) alguno la ha probado? funciona bien o no merece la pena?
Otra cosa que me gustaria incorporarle es mandarle las ordenes por bluetooth, pero no se que hay que conectar al arduino para que reciba las ordenes, supongo que un modulo bluetooth, pero no estoy seguro al 100% y como los que he visto son bastante caros, no quiero jugarmela a gastarme una pasta para tenerlo de adorno en mi cuarto...
Aqui les dejo el codigo que tengo hasta ahora, aunque habria que cambiar lo de las resistencias de potencia y los ventiladores, es una tontada que en un segundo se puede corregir...

const int pinLM35 = 0;
const int pinVentilador = 2;
const int pinRPotencia = 4;

const int tempReferencia = 25;

int tempC1, tempC2 = 0;
const long tiempoActualizaTemperatura = 10000;
unsigned long tiempoTranscurrido;
long anteriorMilis = 0;

boolean finOrden=false;
int numPalabras=1;
int asciiLeido=0;
char letraLeida=0;
String palabra="";
String orden1="";
String orden2="";

void setup(){
  Serial.begin(9600);
  pinMode(pinLM35, INPUT);
  pinMode(pinVentilador, OUTPUT);
  pinMode(pinRPotencia, OUTPUT);
}

void loop(){
  //tiempoTranscurrido = millis();
  //if(tiempoTranscurrido-anteriorMilis>tiempoActualizaTemperatura){
    //tempC1=calcularTemperatura();
    //}
    while(Serial.available()>0){
      orden1=leerPalabra();
      if(numPalabras==2){
        orden2=leerPalabra();
      }
      if(finOrden==true){
        iterpretarOrden(orden1, orden2);
        orden1="";
        orden2="";
      }
    }
}

int calcularTemperatura(){
  //Calcular temperatura con un LM35:
  return (analogRead(pinLM35))*500/1024;;
}
  
void mostrarTemperaturaSerial(int temp){
  Serial.println("Temperatura: ");
  Serial.print(temp);
  Serial.println(" grados C");
}  
  
void controlTemperatura(int temp){
    if(temp>=tempReferencia + 3){        //Histeresis de 3ºC
    digitalWrite(pinVentilador, HIGH);
    if(digitalRead(pinRPotencia)==HIGH){
      digitalWrite(pinRPotencia, LOW);
    }
  }else if(temp<=tempReferencia-3){
     digitalWrite(pinRPotencia, HIGH);
     if(digitalRead(pinVentilador)==HIGH){
        digitalWrite(pinVentilador, LOW);
     }
  }else if(temp==tempReferencia){
    digitalWrite(pinVentilador, LOW);
    digitalWrite(pinRPotencia, LOW);
  }
}

String leerPalabra(){
  palabra="";
  while(Serial.available()>0){
    asciiLeido=Serial.read();
    if(asciiLeido!=10 && asciiLeido!=13 && asciiLeido!=32){    //13=retorno de carro, 10=salto de linea , 32=espacio
      palabra=palabra+asciiLeido;
    }else if(asciiLeido==32){                                  //Si hay un espacio devuelve la plabra en mayusculas y aumenta numPalabras
      numPalabras++;
      return palabra.toUpperCase();
    }else if(asciiLeido==10){                                  //Si presionamos enter ya no hay mas que leer y devuelve la palabra en mayusculas
      finOrden=true;
      Serial.flush();
      return palabra.toUpperCase();
    }
  }
}

void iterpretarOrden(String palabra1, String palabra2){
  if(palabra1=="MOSTRAR"){
    if(orden2=="TEMPERATURA"){
      mostrarTemperaturaSerial(calcularTemperatura());
    }else if(palabra2=="HUMEDAD"){
      mostrarHumedadSerial(calcularHumedad());
  }
}

El error me salta al hacer palabra.toUpperCase(); en el metodo leerPalabra... Creo que puede ser porque no puedo llamar al metodo toUpperCase() en la sentencia return, pero no estoy seguro la verdad...

Sigo adelante con mi proyecto... Y tambien sigo con la misma duda que tenia la ultima vez que actualice el post. Alguien sabe porque me salta error en el palabra.toUpperCase(); ?
Ya me han llegado la shield con los reles y el modulo bluetooth para comunicarme con el arduino usando bt... Tambien he comprado el invernadero y he empezado a plantar, por ahora poca cosa ya que tengo que encontrar un macetero del tamaño que necesito, me gustaria que me echarais una mano con el error que me salta para poder meterle el codigo al arduino y empezar a controlar el invernadero.

Gracias a todos.