mi codigo necesita ayuda de un experto... XD

1 Mar 2008
266
españa
Provincia
avila
Hola a todos.
Después de mucho cacharrear y leer los códigos de los demás, decidí usarlos en mi propio beneficio copiando y pegando las partes que necesitaba y adaptando lo que no me valía, amos que soy un jeta de cuidao XD

Necesito que alguien que sepa más que yo me revise y me corrija el resultado ya que hay un par de fallos garrafales que no encuentro.

Mi intención fue usar el código de jmcadsl pero simplificarlo:
-sólo hay 3 horas: encendido apagado y apagado de luna
-tres duraciones diferentes de dimeo
-tres potencias de canales de leds: azules blancos y mezcla (aqui ya veremos pero creo que seran 2 blancos, 2 azules, 2 rosas y 2 morados o actínicos) para poner el acuario del color que mas me guste.

Algo que parece sencillo pero no lo es tanto para alguien que nunca ha programado nada y hasta el dia 15 de enero nisiquiera sabía lo que era arduino XD

Lo compila bien y los problemas vienen al ejecutar:

a) cada vez que da una vuelta el loop, el pwm se pone a 0, suma 1, se vuelve a poner a 0, suma 1..........
b) los tiempos de delay entre cada paso estan calculados y he repasado la cuenta un montón de veces, pero el
tiempo de ciclo no se corresponde con el que debería o al menos me da a mi esa impresión, al abrir el serial
monitor el refresco de datos tarda un huevo.

Este es el código:

Código:
///////////////////////////////////////////////////////
//          FRONKONSTIN REEF CONTROLER V1.0          //
///////////////////////////////////////////////////////

// El nombre es en honor a la peli de Mel Brooks "El jovencito Frankestein"
// basicamente porque esta echo a base de cortar, copiar, cacharrear y pegar
// de momento solo hay control de leds y casi todo esta basado en el "L&S Compact Reef"
// gracias a sus creadores.
// Mas adelante (segun lleguen los cacharritos) incorporare control de temperatura de Ph 
// cuatro peristalticas (tres para el balling y otra de reposicion), pantalla SLCD...
/*
Arduino MEGA (Luces Led PWM)

Pines(I/O) 

  D5 - (PWM) Canal Led Azul
  D6 - (PWM) Canal Led Blanco
  D7 - (PWM) Canal Led Mezcla

  D13 - LED Control
 

  D20 - (SDA) Reloj
  D21 - (SCL) Reloj
*/

#include <Wire.h>                // Esta es la libreria de comunicacion I2C
#define DS1307_I2C_ADDRESS 0x68  //reloj

//VARIOS //

byte ledcontrolv = 13;//led control

//RELOJ //

byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte decToBcd(byte val) // Convierte números normales decimales a BCD (binario decimal codificado)
{
  return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val) // Convierte BCD (binario decimal codificado) a números normales decimales 
{
  return ( (val/16*10) + (val%16) );
}
void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.write((uint8_t) 0);
   Wire.write(decToBcd(second));    
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));      
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(decToBcd(year));
   Wire.endTransmission();
}

// Establece la fecha y la hora del ds1307
void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{
  // Resetea el registro puntero
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write((uint8_t) 0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // Alguno de estos necesitan enmascarar porque ciertos bits son bits de control    

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);  
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

// ILUMINACION //

byte ledazul = 5 , ledblanco = 6 , ledmezcla = 7; //Luces

//Potencias
int pmaxazul=       100; // Poténcia máxima luz azul 0-100%
int pmaxblanco=     100; // Poténcia máxima luz blanca 0-100%
int pmaxmezcla=     100; // Poténcia máxima luz mezcla 0-100%
int pluna=	     10; // Potencia de luna (1-10 valores PWM solo leds azules)

//Horas
int hamanecer= 	12; // Hora amanecer
int hatardecer= 22; // Hora atardecer
int hfinluna= 	23; // Hora fin luna 
int duraman=	 5; // Duración del amanecer en minutos
int duratar=	 5; // Duración del atardecer en minutos
int durafinluna= 5; // Duracion del fin de luz de luna en minutos

//Calculos para el programa no modificar 
int pwmazul=0;
int pwmblanco=0;
int pwmmezcla=0;
int pwmmaxazul=(pmaxazul*2.55);
int pwmmaxblanco=(pmaxblanco*2.55);
int pwmmaxmezcla=(pmaxmezcla*2.55);
int pwmluna=pluna;
int delayamanecer=(duraman*60000)/((pwmmaxazul+pwmmaxblanco+pwmmaxmezcla)/3);//Calculamos cada cuanto tiempo da un paso de intensidad
int delayatardecer=(duratar*60000)/((pwmmaxazul+pwmmaxblanco+pwmmaxmezcla)/3);
int delayluna=(durafinluna*60000)/(pwmluna);

void setup()
{
  //VARIOS//
  pinMode (ledcontrolv, OUTPUT);//leds control
  //RELOJ//
  Wire.begin();
  Serial.begin(9600);
  //ILUMINACION//
   pinMode (ledazul, OUTPUT);
   pinMode (ledblanco, OUTPUT);
   pinMode (ledmezcla, OUTPUT);
}

void loop()
{
ledvoff();//Apagamos led control
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);  //Miramos la hora
monitorserie();//Mostramos reloj en monitor serie
luz();// Ejecutamos el programa Luz
ledvon(); //Encendemos led control
delay(100); //Pausa de 0,1 segundo
}

void luz()
{

if (hour >= hamanecer && hour < hatardecer) 
 {
   if (pwmazul <= pwmmaxazul)
    {
      analogWrite(ledazul,pwmazul);
      pwmazul++;
      Serial.println("  Led Azul:");
      Serial.println(pwmazul);
    }
      
   if (pwmblanco <= pwmmaxblanco)
    {
      analogWrite(ledblanco,pwmblanco);
      pwmblanco++;
      Serial.println("  Led Blanco:");
      Serial.println(pwmblanco);
    }
      
   if (pwmmezcla <= pwmmaxmezcla)
    {
      analogWrite(ledmezcla,pwmmezcla);
      pwmmezcla++;
      Serial.println("  Led Mezcla:");
      Serial.println(pwmmezcla);
    } 
   delay(delayamanecer);
 }

if (hour >= hatardecer && hour < hfinluna)
 {
    if (pwmazul > pwmluna)
   {
     analogWrite(ledazul,pwmazul);
     pwmazul--;
     Serial.println("  Led Azul:");
     Serial.println(pwmazul);
   }
  
  if (pwmazul < pwmluna)
   {
     analogWrite(ledazul,pwmazul);
     pwmazul++;
     Serial.println("  Led Azul:");
     Serial.println(pwmazul);
   }
  
  if (pwmblanco > 0)
   {
     analogWrite(ledblanco,pwmblanco);
     pwmblanco--;
     Serial.println("  Led Blanco:");
     Serial.println(pwmblanco);
   }
  if (pwmmezcla > 0)
   {
     analogWrite(ledmezcla,pwmmezcla);
     pwmmezcla--;
     Serial.println("  Led Mezcla:");
     Serial.println(pwmmezcla);
   }
  delay(delayatardecer);
 }

if (hour = hfinluna)
 {
  if (pwmazul > 0)
   {
     analogWrite(ledazul,pwmazul);
     pwmazul--;
   }
   
  if (pwmblanco > 0)
   {
     analogWrite(ledblanco,pwmblanco);
     pwmblanco--;
   } 
  if (pwmmezcla > 0)
   {
     analogWrite(ledmezcla,pwmmezcla);
     pwmmezcla--;
   }
  delay(delayluna);
 }
}

void ledvon()                                 
  {                                          
    digitalWrite (ledcontrolv, HIGH);         
  }                                          
                                              
void ledvoff()                                
  {                                           
    digitalWrite (ledcontrolv, LOW);          
  }                                          
  
void monitorserie()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);  

  Serial.print("20");
    if (year < 10) Serial.print("0");
  Serial.print(year, DEC);
  Serial.print("/");
    if (month < 10) Serial.print("0");
  Serial.print(month, DEC);  
  Serial.print("/");   
    if (dayOfMonth < 10) Serial.print("0");
  Serial.print(dayOfMonth, DEC); 
  Serial.print("  ");
    if (hour < 10) Serial.print("0");
  Serial.print(hour, DEC);
  Serial.print(":");  
    if (minute < 10) Serial.print("0");
  Serial.print(minute, DEC);
  Serial.print(":");
    if (second < 10) Serial.print("0");
  Serial.print(second, DEC);  
  Serial.print("  Dia de la semana:");  
 // Serial.println(dayOfWeek, DEC);   Lo elimino para que no ponga el numero en el serial monitor "cosas mias"
    switch (dayOfWeek) 
    {
    case 1:
      Serial.println("  Lunes"); 
      break;
    case 2:
      Serial.println("  Martes"); 
      break;
    case 3:
      Serial.println("  Miercoles"); 
      break;
    case 4:
      Serial.println("  Jueves"); 
      break;
    case 5:
      Serial.println("  Viernes"); 
      break;
    case 6:
      Serial.println("  Sabado"); 
      break;
    case 7:
      Serial.println("  Domingo"); 
      break;
   }

  Serial.println("  Led Azul:");
  Serial.println(pwmazul);
  Serial.println("  Led Blanco:");
  Serial.println(pwmblanco);
  Serial.println("  Led Mezcla:");
  Serial.println(pwmmezcla);
  delay(1000); //Pausa durante 1 segundo

}
 

jmcadsl

Miembro Honorífico
17 Ene 2010
1.030
España
Provincia
Madrid
Hola.

Pues la verdad es que yo no veo nada raro.....
Lo único es que tienes puesto un delay de 5 minutos en el dimeado, por lo que cada vez que pasa el programa por ahí (para amanecer o atardecer) se queda 5 minutos parado....piensa que si tienes que pasar de valor 0 (0% pwm) a 255 (100% pwm), son 5 x 255 = 1275 minutos. :yb637[1]:

Se me ocurre que podría arduino interpretarlo como un "cuelge" y reiniciar el programa y por eso se te pone otra vez en 0. ?¿?¿?¿

Salu2
 
14 Oct 2009
66
España
Provincia
Granada
Hola,

yo en principio tampoco he visto nada raro.

jmcadsl, creo que los 5 minutos lo tiene puesto para que el amanecer completo dure eso. Creo que no es una pausa de 5 minutos.

Blademan, el refresco puede tardar si estás en las horas del dimeado....aunque si ves que hace cosas raras puedes revisar la alimentación. A mi misteriosamente, el arduino (con el Ds1307) enchufado al usb me funciona diferente a si uso una fuente de alimentación....

Saludos
 

jmcadsl

Miembro Honorífico
17 Ene 2010
1.030
España
Provincia
Madrid
J.pedro, según tiene el compañero declarada la variable delayamanacer, el amanecer no va a durar 5 minutos, sino que cada vez que cambia el valor pwm hace pausa,delay o llámalo x de 5 minutos, por lo que si pasa del 0% al 50% por ejemplo del valor pwm va a pasar por el delay de 5 minutos 127 veces.

Lo cual me parece una pasada, es mi humilde opinión.

Enviado desde mi GT-I9000 usando Tapatalk
 
14 Oct 2009
66
España
Provincia
Granada
Creo que no es así, tiene declarado:



int duraman= 5; // Duración del amanecer en minutos

int pwmmaxazul=(pmaxazul*2.55);
int pwmmaxblanco=(pmaxblanco*2.55);
int pwmmaxmezcla=(pmaxmezcla*2.55);

int delayamanecer=(duraman*60000)/((pwmmaxazul+pwmmaxblanco+pwmmaxmezcla)/3);//Calculamos cada cuanto tiempo da un paso de intensidad

Por lo tanto, delayamanecer debe de ser el tiempo de un paso, para durar 5 minutos.

Por cierto Blademan, ten en cuenta que estás usando tipos "int" que son enteros, así que ten en cuenta los redondeos, que te pueden llevar a error en los tiempos...

Saludos!
 
1 Mar 2008
266
españa
Provincia
avila
Gracias a los dos por responder ahora estoy conel movil, en cuanto llegue a casa pruebo a poner un número entero fijo como delay, a enchufado la fuente de alimentación...
Además el ds1307 tb me funciona raro, funciona bien sí le quito el cable gnd. Tengo una suerte con los relojes... :)
 
1 Mar 2008
266
españa
Provincia
avila
Gracias a los dos por responder ahora estoy conel movil, en cuanto llegue a casa pruebo a poner un número entero fijo como delay, a enchufado la fuente de alimentación...
Además el ds1307 tb me funciona raro, funciona bien sí le quito el cable gnd. Tengo una suerte con los relojes... :)
 

jmcadsl

Miembro Honorífico
17 Ene 2010
1.030
España
Provincia
Madrid
Cierto!!!! No me habia fijado en que multiplicaba el valor pwm x 2.55 .....

Pues entonces no se.....es posible que cuando pwm es 0 y trate de hacer la formula de :

int delayamanecer=(duraman*60000)/((pwmmaxazul+pwmmaxblanco+pwmmaxmezcla)/3);

de error al estar dividiendo entre 0 ?¿?¿??

Pon un valor fijo al delay y prueba como bien has dicho....

Salu2
 
26 Dic 2009
343
España - EU - Tierra - Sistema Solar - Via Láctea
Provincia
Vallekas - Madrid
Buenas,

El problema del código lo tienes en esta línea:
if (hour = hfinluna)

Debería poner if (hour == hfinluna) ;) Parece una tontería, pero resulta que en esa sentencia en vez de hacer una comparación que es lo que quieres (comparar si "hour" vale lo mismo que "hfinluna"), estas haciendo una asignación, estás diciendo que hour sea igual a hfinluna. Es una de las cosas que más tiempo me ha hecho perder cuando programo en C (que es básicamente lo mismo que el lenguaje de arduino).

Un saludito :D
 
1 Mar 2008
266
españa
Provincia
avila
pues no se si has dado tantos cabezazos como he dao yo, pero yo estos ultimas dias he dao muuuuchos y ese "=" de m**rda era el problema...
muchas gracias a todos, sabiendo que hay gente que responde asi de bien y rapido da gusto liarte la manta a la cabeza con cosas mucho mas grandes que tu.
 
10 Jun 2012
1
BARCELONA
Provincia
BARCELONA
Hola a todos.

Estoy buscando alguien que viva en Barcelona y que domine el uso del Arduino, para un proyecto remunerado.
Me urge.
¿Algún interesado en trabajar ?
 
Arriba