Control de luces de Acuario

Si este código sigue cometiendo el mismo error vamos a tener que medir (usando millis()) los tiempos de las rutinas.

#include <Wire.h>
#include "RTClib.h"
#include <UTFTGLUE.h>             //tft
UTFTGLUE tft(0,A2,A1,A3,A4,A0);   //tft

RTC_DS3231 rtc; // Declaramos un RTC DS3231

const int led[5] = {10,45,13,46,44}; //pines led, Deben ser PWM


volatile unsigned long contador_dimmer = 0; // La definimos como volatile
int i,j; //Variables auxiliares para ciclos repetitivos
unsigned long T ;
unsigned long R ;

//Declaramos variables monitor TFT---------------------------------------

char nombreDia[7][12] = {"Domingo__", "Lunes____", "Martes___", "Miercoles", "Jueves___", "Viernes__", "Sabado___"};
char nombreMes[12][12]= {"Enero_____", "Febrero___", "Marzo_____", "Abril_____", "Mayo______",  "Junio_____", "Julio_____","Agosto____","Septiembre","Octubre___","Noviembre_","Diciembre_"};
int dameSegundo,dameMinuto,hora,dia,mes,diaDeLaSemana;
long anio; 

char dameFecha[10];
char dameHora[20];

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

DateTime HoraFecha;

void setup () {
  Serial.begin(9600);

  for(i=0; i<4; i++){ //salidas pines led
    pinMode(led[i], OUTPUT);
  }
 
   // Comprobamos si tenemos el RTC conectado
  if (! rtc.begin()) {
      Serial.println("No hay un módulo RTC");
      while (1);
  }

  //definimos propiedades monitor tft------------------------------------------------ 
  tft.reset();
  uint16_t identifier = tft.readID();
  if (identifier == 0xEFEF) identifier = 0x9486;
  tft.begin(identifier);
  tft.InitLCD(); 
  tft.fillScreen(BLACK); //Rellenamos la pantalla de color negro*/
  
}

// hay que descomentar la linea de debajo y compilar solo una vez para actualizar hora
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));


//--- Contador creado por cada interrupcion---//
void dimmer_mas(){
  if (contador_dimmer == 255UL)
      contador_dimmer = 0UL;
  else
      contador_dimmer++; // Contador veces interrupcion
  
}

void dimmer_menos(){
  if (contador_dimmer == 0UL)
      contador_dimmer = 255UL;
  else
      contador_dimmer--; // Contador veces interrupcion
}
 
void loop () {
  if (millis() - T> 1000UL) {   //mostrará la hora cada 1 segundo o 1000 mseg
      queHora();                 
      T = millis();
  }

  if (millis() - R> 21176UL) {  //se ejecuta 2.8 veces por cada minuto para hacer 85 pasos en 30m, cada 21,176s
     enciendeLeds();
     R = millis();
  }
  //delay(100);
}

void queHora(){
  DateTime now = rtc.now();
  HoraFecha = rtc.now(); //obtenemos la hora y fecha actual
  
  dameSegundo   = HoraFecha.second();
  dameMinuto    = HoraFecha.minute();
  hora          = HoraFecha.hour();
  dia           = HoraFecha.day();
  mes           = HoraFecha.month();
  anio          = HoraFecha.year();
  diaDeLaSemana = HoraFecha.dayOfTheWeek();

  //tft.clrScr(); //borra texto tft

  tft.setCursor(20,20); //Posicion del cursor
  tft.setTextSize(2); //Tamaño de la fuente
  tft.setTextColor(RED, BLACK); //Color de la fuente en rojo

  /*las posiciones son ancho y alto, por ese orden*/
  tft.print(nombreDia[diaDeLaSemana], 10,5);
  sprintf(dameFecha,"%02d", dia); tft.setCursor(10, 25);  tft.println(dameFecha);
  tft.print("de", 40,25);
  tft.print(nombreMes[mes-1], 70,25);
  tft.print("del", 195,25);
  sprintf(dameFecha,"%4d", anio); tft.setCursor(235,25);  tft.println(dameFecha);

  tft.setCursor(10, 60);
  tft.setTextColor(WHITE, BLACK);  tft.setTextSize(4);
  sprintf(dameHora,"%02d:%02d:%02d", hora, dameMinuto, dameSegundo);
  tft.println(dameHora);

  sprintf(dameHora,"%02d:%02d:%02d %02d/%02d/%02d", hora, dameMinuto, dameSegundo, dia, mes, anio);
  Serial.println(dameHora);
}


void enciendeLeds(){
  analogWrite(led[1],0);
  analogWrite(led[2],0);  
  analogWrite(led[3],0); 
  analogWrite(led[4],0); 


  if (dameMinuto == 8) {
      if (dameSegundo >= 0  && dameSegundo <= 3) {
          contador_dimmer=0;
      }
  }
  if (dameMinuto >= 8 && dameMinuto <38){
      dimmer_mas();
      ledAzul();
      monitor_dimmer();
  }
}

void ledRojo(){
  analogWrite(led[0],contador_dimmer);
}

void ledVerde(){ 
  analogWrite(led[1],contador_dimmer);   
}

void ledAmarillo(){ 
  analogWrite(led[2],contador_dimmer);   
}

void ledBlanco(){ 
  analogWrite(led[3],contador_dimmer);    
}

void ledAzul(){ 
  analogWrite(led[4],contador_dimmer);
}

void monitor_dimmer(){
  Serial.print("contador_dimmer = ");
  Serial.println(contador_dimmer);
  delay(100);
  Serial.println();
}

mmm no se muy bien a que te refieres con lo de medir los tiempos... a añadir otra función de millis cuando carga los datos en el tft?

Pies que según creo ya estoy midiendo en millies cada segundo en el reloj y el contador del dimmer cada 21, 17seg

Quiero que midas con millis() las partes que generar duda.
Ejemplo cuando presentas la hora y lo muestras x serial.

Solo quehora por el momento.

Me dice que tarda en completar esa función 1766.... osea 1.766seg con lo que es imposible que cuente de 1 en 1....

tiene alguna solución?

Como lo sospeché.. y era algo que no podía probar nadie salvo tu mismo!!.
Buen trabajo por lo que te toca, me refiero a la medición de tiempos.

Veamos como mejorar eso.
Tiene que ser mas dinámica la rutina queHora() la forma de presentar la información.
O bien no presentar tanto en el peor de los casos y solo lo que cambie para hacerlo rápido.

Prueba esta rutina a ver si mejora algo o no es suficiente

void queHora(){
  DateTime now = rtc.now(); //obtenemos la hora y fecha actual
  
  dameSegundo   = now.second();
  dameMinuto    = now.minute();
  hora          = now.hour();
  dia           = now.day();
  mes           = now.month();
  anio          = now.year();
  diaDeLaSemana = now.dayOfTheWeek();

  //tft.clrScr(); //borra texto tft
  tft.setCursor(20,20); //Posicion del cursor
  tft.setTextSize(2); //Tamaño de la fuente
  tft.setTextColor(RED, BLACK); //Color de la fuente en rojo


  /*las posiciones son ancho y alto, por ese orden*/
  sprintf(dameFecha,"%s %02d de %s del %4d", nombreDia[diaDeLaSemana], dia, nombreMes[mes-1], anio); 
  tft.println(dameFecha);

  tft.setCursor(10, 60);
  tft.setTextColor(WHITE, BLACK);  
  tft.setTextSize(4);
  sprintf(dameHora,"%02d:%02d:%02d", hora, dameMinuto, dameSegundo);
  tft.println(dameHora);

  sprintf(dameHora,"%02d:%02d:%02d %02d/%02d/%02d", hora, dameMinuto, dameSegundo, dia, mes, anio);
  Serial.println(dameHora);
}

Si esto no es suficiente, entonces el TFT es lento y haremos algo mas simple. Actualizar la hora, y cuando cambie el dia, actualizamos dia y asi. Nada que provoque un dolor de cabeza.

Pues asi va mas lento... me da ahora 1,861seg...

He separado la hora por fecha, hora, minutos y segundos... y se ha reducido a 1,048sg se ve que la pantalla es mas lenta que el caballo del malo, por que solo muestra los segundos y da retardo igualmente!
Solo baja a 1,001sg si se queda en blanco... alguna idea mas? o ves si hay algo que se pueda reducir?

#include <Wire.h>
#include "RTClib.h"
#include <UTFTGLUE.h>             //tft
UTFTGLUE tft(0,A2,A1,A3,A4,A0);   //tft

RTC_DS3231 rtc; // Declaramos un RTC DS3231

const int led[5] = {10,45,13,46,44}; //pines led, Deben ser PWM


volatile unsigned long contador_dimmer = 0; // La definimos como volatile
int i,j; //Variables auxiliares para ciclos repetitivos
unsigned long F ;
unsigned long H ;
unsigned long M ;
unsigned long S ;
unsigned long D ;

//Declaramos variables monitor TFT---------------------------------------

char nombreDia[7][12] = {"Domingo__", "Lunes____", "Martes___", "Miercoles", "Jueves___", "Viernes__", "Sabado___"};
char nombreMes[12][12]= {"Enero_____", "Febrero___", "Marzo_____", "Abril_____", "Mayo______",  "Junio_____", "Julio_____","Agosto____","Septiembre","Octubre___","Noviembre_","Diciembre_"};
int Segundo,Minuto,hora,dia,mes,diaDeLaSemana;
long anio; 

char dameFecha[50];
char Vhora[2];
char Vminuto[2];
char Vsegundo[2];

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

DateTime HoraFecha;

void setup () {
  Serial.begin(9600);

  for(i=0; i<4; i++){ //salidas pines led
    pinMode(led[i], OUTPUT);
  }
 
   // Comprobamos si tenemos el RTC conectado
  if (! rtc.begin()) {
   Serial.println("No hay un módulo RTC");
   while (1);
  }

  //definimos propiedades monitor tft------------------------------------------------ 
  tft.reset();
  uint16_t identifier = tft.readID();
  if (identifier == 0xEFEF) identifier = 0x9486;
  tft.begin(identifier);
  tft.InitLCD(); 
  tft.fillScreen(BLACK); //Rellenamos la pantalla de color negro*/
  
}

// hay que descomentar la linea de debajo y compilar solo una vez para actualizar hora
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));


//--- Contador creado por cada interrupcion---//
void dimmer_mas(){
  if(contador_dimmer==255UL){
    contador_dimmer=0UL;
  }else{
   contador_dimmer++; // Contador veces interrupcion
  }
}
void dimmer_menos(){
  if(contador_dimmer==0UL){
    contador_dimmer=255UL;
  }else{
   contador_dimmer--; // Contador veces interrupcion
  }
}
 
void loop () {
  DateTime now = rtc.now();
  HoraFecha = rtc.now(); //obtenemos la hora y fecha actual
  
  if (millis() - F> 1440000UL) {   //mostrará cada 24 horas               
      F = millis();
      queFecha();
  }
  if (millis() - H> 3600000UL) {   //mostrará la hora cada 1 hora
      queHora();                 
      H = millis();
  }
  if (millis() - M> 60000UL) {   //mostrará la hora cada 1 minuto
      queMinuto();                 
      M = millis();
  }
  if (millis() - S> 1000UL) {   //mostrará la hora cada 1 segundo o 1000 mseg
      queSegundo();                 
      S = millis();
      Serial.println(S);
  }

  if (millis() - D> 21176UL) {  //se ejecuta 2.8 veces por cada minuto para hacer 85 pasos en 30m, cada 21,176s
     enciendeLeds();
     D = millis();
  }
  //delay(100);
}


void queFecha(){
  dia = HoraFecha.day();
  mes = HoraFecha.month();
  anio = HoraFecha.year();
  diaDeLaSemana = HoraFecha.dayOfTheWeek();

  tft.setCursor(20,20); //Posicion del cursor
  tft.setTextSize(2); //Tamaño de la fuente
  tft.setTextColor(RED, BLACK); //Color de la fuente en rojo
  
  /*las posiciones son ancho y alto, por ese orden*/
  tft.print(nombreDia[diaDeLaSemana], 10,5);
  sprintf(dameFecha,"%02d", dia); tft.setCursor(10, 25);  tft.println(dameFecha);
  tft.print("de", 40,25);
  tft.print(nombreMes[mes-1], 70,25);
  tft.print("del", 195,25);
  sprintf(dameFecha,"%4d", anio); tft.setCursor(235,25);  tft.println(dameFecha);
}

void queHora(){
  hora = HoraFecha.hour();

  sprintf(Vhora,"%02d", hora);
  tft.setCursor(10, 60);
  tft.setTextColor(WHITE, BLACK);  tft.setTextSize(4);
  tft.println(Vhora);
}

void queMinuto(){
  Minuto = HoraFecha.minute();

  sprintf(Vminuto,":%02d:", Minuto);
  tft.setCursor(65, 60);
  tft.setTextColor(WHITE, BLACK);  tft.setTextSize(4);
  tft.println(Vminuto);
}

void queSegundo(){
  Segundo = HoraFecha.second();

  sprintf(Vsegundo,"%02d", Segundo);
  tft.setCursor(160, 60);
  tft.setTextColor(WHITE, BLACK);  tft.setTextSize(4);
  tft.println(Vsegundo);
}


void enciendeLeds(){
  analogWrite(led[1],0);
  analogWrite(led[2],0);  
  analogWrite(led[3],0); 
  analogWrite(led[4],0); 


/*if(dameMinuto == 8){if(dameSegundo >= 0  && dameSegundo <= 3){contador_dimmer=0;}}
if(dameMinuto >= 8 && dameMinuto <38){
    dimmer_mas();
    ledAzul();
    monitor_dimmer();
}*/

}



void ledRojo(){
  analogWrite(led[0],contador_dimmer);
}
void ledVerde(){ 
  analogWrite(led[1],contador_dimmer);   
}
void ledAmarillo(){ 
  analogWrite(led[2],contador_dimmer);   
}
void ledBlanco(){ 
  analogWrite(led[3],contador_dimmer);    
}
void ledAzul(){ 
  analogWrite(led[4],contador_dimmer);
}

void monitor_dimmer(){
  Serial.print("contador_dimmer = ");
  Serial.println(contador_dimmer);
  delay(100);
  Serial.println();
}

Cambia de placa TFT o ve que elemento es el que demora tanto.. cambiar tamaño de la fuente, cambiar color.. etc.

Esta librería nunca la he visto

#include <UTFTGLUE.h>             //tft

Seguro que no funciona con otra librería?

Bueno revisé para atras y encontré que has puesto la librería completa con ejemplos.

Prueba medir lo mismo en los ejemplos disponibles a ver con que te encuentras. Si es un problema de seteo o resulta que tu TFT es lento.

La pantalla que tengo es una mcufriend iD=0x9797 creo que también trabaja con 0x9486, he vuelto a revisar las librerías, con la que mejor trabaja funcionando los ejemplos es UTFTGLUE.h, he probado con la MCUFRIEND_kbv.h que también trae el paquete que os puse y da el mismo resultado, con el resto de librerías parece que no funciona.

He estado haciendo pruebas con poco o nada de resultado.. quitando el tamaño y color el el tiempo se reduce a 0.005sg, con las propiedades activas, tarda en pintar un numero 0.048sg.

También he probado con los ejemplos y en pinar una linea de texto tarda 0.012sg

con los ejemplos para que me ponga hola mundo tarda 0.069sg...

Hay una cosa que no entiendo, en el momento en que pinta algo siempre va a tener un retardo que se va a añadir a al segundo que le estamos dando en el loop para temporizar, con lo que haga lo que haga siempre va añadir x tiempo a ese segundo no?, si es así no es un problema de retardo de la pantalla sino que estamos sumando mas tiempo al calculo y siempre añadirá un retardo, osea el segundero siempre seguiría fallando cada x segundos

ERROR!! Tienes un RTC que no esta influenciado por nada.
Tienes un millis() que tampoco esta influenciado por nada.
Los retardos son nuestra responsabilidad al crear nuestro código y punto.

He estado haciendo pruebas con poco o nada de resultado.. quitando el tamaño y color el el tiempo se reduce a 0.005sg, con las propiedades activas, tarda en pintar un numero 0.048sg.

Bien has visto quien es responsable de los tiempos mas largos asi que empecemos por evitarlos y luego de a poco ver si pueden ser introducidos sin alterar la presentación. Ya veremos cómo o si vale la pena!!

Comenta todos los cambios de tamaño y color y veamos que tenemos.

los tiempos son:

con color y tamaño: 0.048

sin color: 0.017
sin tamaño:0.010

sin color y sin tamaño: entre 0.006 y 0.004

A ver si te comprendo
con color y tamaño gueHora() que antes tardaba 1800 mseg ahora 48 mseg? o hablas de otro ejemplo?

Has esas pruebas con queHora() y queFecha() no nos olvidemos que tienes dos.

Bueno los tiempos de queSegundo() son :

con color y tamaño: 10048

sin color: 10017
sin tamaño:10010

sin color y sin tamaño: entre 10006 y 10004

Lo había puesto abreviado

void queSegundo(){
  Segundo = HoraFecha.second();

  sprintf(Vsegundo,"%02d", Segundo);
  tft.setCursor(155, 60);
  tft.setTextColor(WHITE, BLACK); 
  tft.setTextSize(4);
  tft.println(Vsegundo);
}

Como van a ser 10048 debe ser seran 1048 mseg o no?
Lo primero son 10.048 segundos y lo segundo 1.048 segundos.

Si esto

void queSegundo(){
  Segundo = HoraFecha.second();

  sprintf(Vsegundo,"%02d", Segundo);
  tft.println(Vsegundo);
}

demora 1004 mseg

Mira este hilo reportando en 2015 los problemas de lentitud de este TFT.
Parece ser que el problema es el manejo de pines.

Acá otro hilo interesante Link

Cambia de TFT

Tienes razón 1048 he puesto un 0 de mas...

Pues menuda castaña si no vale el tft... en cuanto se supone que debería cargar?

cual me recomiendas?

He puesto ya por curiosidad las librerías del enlace que me has indicado, y la pantalla se queda en negro o blanco, lo que si he conseguido es que me carga estos valores de lectura en el monitor, aunque la pantalla estaba en negro.

TFT LCD test
LCD driver chip: 0
Benchmark Time (microseconds)
Screen fill 1379324
Text 189572
Lines 1066340
Horiz/Vert Lines 144860
Rectangles (outline) 104680
Rectangles (filled) 3267948
Circles (filled) 1227028
Circles (outline) 446792
Triangles (outline) 338316
Triangles (filled) 1728440
Rounded rects (outline) 212860
Rounded rects (filled) 3798436
Done!

@Perdido, si hablas de un programa menciona cual es el sketch y en que contexto ocurre todo.

Cuando dices Texto insume 189572 useg, cuanto texto? Cual es la rutina, tiene cambio de color, no lo tiene.. son condiciones que no se como comparar con el anterior.

Claro que debe aportar pero no veo la referencia en este momento.

Ayúdanos por favor!!

jeje ese es el problema que no lo se el contexto exactamente :astonished:

he ejecutado la librería\ejemplo: SWTFT-Shield\examples\graphicstest (me he olvidado de ponerlo antes)

El ejemplo funciona parcialmente solo muestra los datos que os he puesto en el monitor de programación, la pantalla tft se queda en blanco. Si la conoces igual podria valer para comparar con respecto a alguna que tengas por ahí... sino supongo que no valdrá para mucho por lo que comentas.

TFT LCD test
LCD driver chip: 0
Benchmark Time (microseconds)
Screen fill 1379324
Text 189572
Lines 1066340
Horiz/Vert Lines 144860
Rectangles (outline) 104680
Rectangles (filled) 3267948
Circles (filled) 1227028
Circles (outline) 446792
Triangles (outline) 338316
Triangles (filled) 1728440
Rounded rects (outline) 212860
Rounded rects (filled) 3798436
Done!

La única librería que he conseguido que funcione mas o menos es la MCUFRIEND_kbv modificada, ni siquiera funciona la ultima versión oficial... solo ha funcionado la que os puse creo que en el #45

No puedo ubicar el ejemplo dentro del .zip

Parece que no me he explicado bien, son dos librerías diferentes!

La del test que funciona a medias, esta sacada del link que has puesto antes y pertenece a la librería SWTFT-Shield que viene en ese paquete. Por desgracia solo funciona parcialmente, en la pantalla no muestra nada.

Por otro lado tengo puesta la que si que funciona, la MCUFRIEND_kbv modificada pero es la que da retardos. Por lo que he visto en comentarios es mas lenta en MEGA que en UNO