Go Down

Topic: Diseño Controlador Acuario  (Read 4379 times) previous topic - next topic

car127

Aug 24, 2018, 10:55 pm Last Edit: Oct 26, 2018, 02:30 pm by car127
Hola
Con la guia de Daniel_Arg se realizara un controlador de acuario, donde se iran agregando partes del código hasta completarlo,  constara menú para modificar parametros luz,Hora,fecha,etc, lcd para visualizar información, sensor de temperatura y relés. La idea es tener una base y que cualquiera pueda realizar su controlador y porque no ampliarlo

Materiales:
      Arduino                  Puede ser Nano, Uno o Mega
      Reloj                      DS3231
      Lcd                        20x4 con I2C
      Sensor temperatura DS18B20
      Encoder rotatorio con pulsador
      Resistencia              4,7k - 1/4w =1
      Resistencia              1k - 1/4w    =4
      Led                         Blanco, Rojo, Azul
      Fuente de poder       9v
      Reles arduino           5v 2 canales
      transistor                 2N2222
      Protoboard
      Cables coneccion
     
Esquema  fácil de leer
Nota: La entrada de alimentación varia según su arduino

Adjunte la imagen






Librería
Code: [Select]

        encoder      :  https://github.com/mathertel/RotaryEncoder

        RTC            :  https://github.com/adafruit/RTClib
        (post 36 libreria RTC)

        OneButton  :https://github.com/mathertel/OneButton

        LiquidCristal:https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/
         (Newliquidcrystal_1.3.5)

 

Archivos adjunto con Sketch base

En ultima pagina  se adjunta Sketch final




Swift

#1
Aug 25, 2018, 06:37 am Last Edit: Aug 25, 2018, 06:42 am by Swift
Hola voy a hacer mi aporte:
En esta parte del código:
Code: [Select]
void loop() {
 unsigned long currentMillis = millis();
 button.tick();
 LeeEncoder(0, 7, 1, 1);  // Lee el enconder de 0 a 7, de a 1 paso y con tope final.

 if (currentMillis % 6000 < 5) {  //  Si el resto de dividir currentMillis por 6000 da menos que 5...
 ImprimeFecha();
 ImprimeHora();
 ImprimeTemp();
 }
}

se va a cumplir cuando sea por ejemplo 6000,6001,6002,6003,6004 y  en el "mejor de los casos" pero en el transcurso se cumple y se va a actualizar como 20 veces aquí un ejemplo de lo que digo:

Ahora asi como muestra por serial va actualizar en la pantalla para lo cual presentó algo que puede ser mejor  tendrías que añadir las siguientes líneas y borra en el que tu tienes, espero se entienda
Code: [Select]
#define tiempoPresentarDatos 6000UL // Tiempo al que se quiera realizar las acciones ejemplo 6s (1000ms = 1s)
unsigned long tiempoActualDatos = 0;

void loop() {
 if (millis() - tiempoActualDatos >= tiempoPresentarDatos) { // Si el tiempo actual menos el tiempo anterior  es mayor o igual a 6 segundos
 tiempoActualDatos = millis(); // Actualiza el tiempo Actual
 //Resto del codigo que quieras que se cumpla cada 6 segundos
 }
}


Ahora también por ejemplo en esta parte utilizas una función y en el cual en una condición la utilizas para para comprobar si tiene tope o no
Code: [Select]
void LeeEncoder(int ROTARYMIN, int ROTARYMAX, int ROTARYSTEPS, int ROTARYTOPE )
{
  encoder.tick();  // Lee el encoder y actualiza el puntero. La librería lleva la cuenta desde 0.
  newPos = encoder.getPosition() * ROTARYSTEPS; // Asigna a newPos el puntero del encoder multiplicado por los pasos.

  if (ROTARYTOPE == 1) {  // Si el rotor tiene tope entonces no se pasa de valor
    if (newPos < ROTARYMIN) {    // Solo si el puntero es menor a Valor Mínimo ->
      encoder.setPosition(ROTARYMIN / ROTARYSTEPS);  // Se fija el puntero al valor mínimo por los pasos
      newPos = ROTARYMIN;  
    }
    if (newPos > ROTARYMAX) {   // Solo si el puntero es mayor a Valor Máximo ->
      encoder.setPosition(ROTARYMAX / ROTARYSTEPS);  // Se fija el puntero al valor mínimo por los pasos
      newPos = ROTARYMAX;

    }
  }

  if (ROTARYTOPE == 0) {  // Si el rotor SI tiene tope entonces se pasa del valor máximo al mínimo y viceversa.
    if (newPos < ROTARYMIN) {  // Solo si el puntero es menor a Valor Mínimo ->
      encoder.setPosition(ROTARYMAX / ROTARYSTEPS);
      newPos = ROTARYMAX;  // Entonces el puntero saltará del mínimo al máximo

    }
    if (newPos > ROTARYMAX) { // Solo si el puntero es mayor al Valor Máximo ->
      encoder.setPosition(ROTARYMIN / ROTARYSTEPS);
      newPos = ROTARYMIN;  // Entonces el puntero saltará del máximo al  mínimo.
    }
  }
}

lo que veo un poco innecesario ya que ese no va a cambiar en el transcurso del funcionamiento si no solo cuando se configura por lo que creo que se podría utilizar de esta forma como ejemplo
Code: [Select]
#define encoderTope 1
void loop() {

#if encoderTope == 1
 if (newPos < ROTARYMIN) {    // Solo si el puntero es menor a Valor Mínimo ->
 encoder.setPosition(ROTARYMIN / ROTARYSTEPS);  // Se fija el puntero al valor mínimo por los pasos
 newPos = ROTARYMIN;
 }
 if (newPos > ROTARYMAX) {   // Solo si el puntero es mayor a Valor Máximo ->
 encoder.setPosition(ROTARYMAX / ROTARYSTEPS);  // Se fija el puntero al valor mínimo por los pasos
 newPos = ROTARYMAX;
 }
#else
 if (newPos < ROTARYMIN) {  // Solo si el puntero es menor a Valor Mínimo ->
 encoder.setPosition(ROTARYMAX / ROTARYSTEPS);
 newPos = ROTARYMAX;  // Entonces el puntero saltará del mínimo al máximo
}
 if (newPos > ROTARYMAX) { // Solo si el puntero es mayor al Valor Máximo ->
 encoder.setPosition(ROTARYMIN / ROTARYSTEPS);
 newPos = ROTARYMIN;  // Entonces el puntero saltará del máximo al  mínimo.
 }
#endif
}

Qué te parece @surbyte sería una mejor forma o no haría gran diferencia

car127

#2
Aug 25, 2018, 06:19 pm Last Edit: Aug 25, 2018, 06:20 pm by car127
Hola
    meda estos errores



Code: [Select]
C:\Users\Car127\Downloads\ProyectoControlAcuarioDM\CADUSA1\CADUSA1.ino: In function 'void ImprimeFecha()':

CADUSA1:354: error: too many arguments to function 'void printDigits(int)'

 printDigits(now.day(), DEC);  // Imprime el día

                           ^

C:\Users\Car127\Downloads\ProyectoControlAcuarioDM\CADUSA1\CADUSA1.ino:330:6: note: declared here

void printDigits(int digits) {  // Esta función agrega un cero a dígitos menores a 10

    ^

CADUSA1:356: error: too many arguments to function 'void printDigits(int)'

 printDigits(now.month(), DEC);  // Imprime el mes

                             ^

C:\Users\Car127\Downloads\ProyectoControlAcuarioDM\CADUSA1\CADUSA1.ino:330:6: note: declared here

void printDigits(int digits) {  // Esta función agrega un cero a dígitos menores a 10

    ^

exit status 1
too many arguments to function 'void printDigits(int)'


car127

#3
Aug 25, 2018, 08:23 pm Last Edit: Aug 25, 2018, 09:22 pm by car127
Ok, funcionando


 

surbyte

Muy complicado aunque funciona, porque no usan sprintf

Code: [Select]

void ImprimeFecha() {
  DateTime now = rtc.now();  // Consulta al RTC
  lcd.setCursor(0,0); // Fija el cursor en la primera línea
  lcd.print(DiaDeSemana[now.dayOfTheWeek()]); // Imprime el día de la semana
  lcd.setCursor(10,0);
  printDigits(now.day(), DEC);  // Imprime el día
  lcd.print('/');   // Separador
  printDigits(now.month(), DEC);  // Imprime el mes
  lcd.print('/');  //  Separador
  lcd.print(now.year(), DEC);  // Imprime el año
}

void ImprimeHora() {
   DateTime now = rtc.now();   // Consulta el RTC
   lcd.setCursor(13,1);  // Fija cursor en 13,1
   lcd.write(1);  // Imprime el gráfico
   lcd.print(':');
   printDigits(now.hour());  // Imprime hora
   lcd.print(':');
   printDigits(now.minute());  // Imprime minuto
   MinActual = now.hour()*60+now.minute();   // Se actualiza la variable MinActual que será usada para encender y apagar las luces del acuario. Su valor va de 0 a 1439.
}


Otra forma que evita el problmea de los dias/meses/horas/minutos de 1 digitos es esta
Code: [Select]
void ImprimeFecha() {
  char buffer[20];
  DateTime now = rtc.now();  // Consulta al RTC
  lcd.setCursor(0,0); // Fija el cursor en la primera línea
  lcd.print(DiaDeSemana[now.dayOfTheWeek()]); // Imprime el día de la semana
  lcd.setCursor(10,0);
  sprintf(buffer,"%02d/%02d/%04d", now.day(),  now.month(), now.year());
  lcd.print(buffer);
}

void ImprimeHora() {
   char buffer[20];
   DateTime now = rtc.now();   // Consulta el RTC
   lcd.setCursor(13,1);  // Fija cursor en 13,1
   lcd.write(1);  // Imprime el gráfico
   sprintf(buffer,"%02d:%02d:%02d", now.hout(), now.minute(), now.second());
   lcd.print(buffer);

   MinActual = now.hour()*60+now.minute();   // Se actualiza la variable MinActual que será usada para encender y apagar las luces del acuario. Su valor va de 0 a 1439.
}

car127

#5
Aug 26, 2018, 06:35 pm Last Edit: Aug 26, 2018, 07:28 pm by car127
En el void ImprimeTemp la parte del else faltaba los //

La parte del termometro con RTC tengo que probar con otro sketch para ver si funciona, ley por hay que en algunas versiones no funciona.


verificando eso sigo.



Code: [Select]

C:\Users\Car127\Downloads\ProyectoControlAcuarioDM\CADUSA1\CADUSA1.ino: In function 'void ImprimeTemp()':

CADUSA1:366: error: 'class RTC_DS3231' has no member named 'getTemperature'

     Tlamp = rtc.getTemperature(); // Asigna a Tlamp la temperatura del RTC

                 ^

C:\Users\Car127\Downloads\ProyectoControlAcuarioDM\CADUSA1\CADUSA1.ino: In function 'void MideTemperatura()':

CADUSA1:380: error: 'class RTC_DS3231' has no member named 'getTemperature'

      Tlamp = rtc.getTemperature();  // Se asigna a la variable Tlamp la temperatura del RTC

                  ^

C:\Users\Car127\Downloads\ProyectoControlAcuarioDM\CADUSA1\CADUSA1.ino: In function 'void overheating()':

CADUSA1:445: error: 'Termostato' was not declared in this scope

      Termostato();     // Corrobora el termostato para el calefactor

                 ^

CADUSA1:446: error: 'ControlCo2' was not declared in this scope

      ControlCo2();    // Comprueba si el Co2 debe estar activo

                 ^

exit status 1
'class RTC_DS3231' has no member named 'getTemperature'


car127

Es la biblioteca que uso no hace referencia a temperatura, me puedes adjuntar tu biblioteca del rtc


class RTC_DS3231' has no member named 'getTemperature'

Daniel_Arg

Es la biblioteca que uso no hace referencia a temperatura, me puedes adjuntar tu biblioteca del rtc

RTClib

car127

#8
Aug 26, 2018, 10:12 pm Last Edit: Sep 19, 2018, 03:45 am by car127
Es la misma que tenía, reclama lo mismo.
Adjunto lo que llevó

Daniel_Arg

A mi me compila bien..

¿Porque el sketch ahora se llama CADUSA1.ino? ¿No tendrás en una misma carpeta CADUSA.ino y CADUSA1.ino?

car127

#10
Aug 27, 2018, 12:30 am Last Edit: Aug 27, 2018, 12:52 am by car127
no vario nada solo que no me funcionaba bien y lo baje denuevo despues me percate que era un mal contacto del encoder

la libreria del rtc de tu compu tiene el comando que falta al parecer revice los archivos .cpp y h y no aparece

car127

Esta vivoooooo después de varios intentos lo logre, aprendi algo nuevo respecto a las librerías me voy a celebrar, mañana sigo

car127

Pruebas con sensor temperatura DS18B20



La actualización de la información de corte de  un cable demora aproximadamente 20seg
al desconectar cable rojo muestra información diferente no el de falla

La actualización de la información de temperatura demora aprox. 50 seg

 ver forma de bajar tiempo

Adjunto imajen


car127

Prueba de temperatura de RTC3231

Se toma temperatura ambiente y luego se acerca un cautin



La actualización de températura con demora

car127


Go Up