Arduino lento al representar variables en tft

Hola gente linda… quisiera algunos consejos, para poder optimizar mi codigo ,todo funciona bien pero es muy lento, arduino tarda en responder por ejemplo al encoder y la variable aumenta o decrementa lentamente, les dejo a continuacion el codigo, ya probe poner las funciones dentro y fuera del loop y es lo mismo , cree varias funciones separadas que son siendo llamadas y tampoco, uso una tft 3,5 inch ili 9486 y arduino mega, encoder ky-040 conectados al pin 2 y 3 (con interrupciones en el mega)

#include <Encoder.h>
#include <UTFT.h>
#include <EEPROM.h>
#include <DMXSerial2.h>
#define newStartAddress
#define DMX_USE_PORT1 // USO EL PUERTO 1 SERIAL DEL MEGA EL PUERTO 0 NO SE USA POR COMPARTIRLO CON EL USB
#define  BREAKSPEED      45500
#define  BREAKFORMAT     SERIAL_8E1
#define  DMXSPEED        250000
#define  DMXFORMAT       SERIAL_8N2
#define MINCOLORTEMP     2600
#define MAXCOLORTEMP     10000


//fuentes que se van a usar
extern uint8_t  GroteskBold16x32[];
extern uint8_t  GroteskBold24x48[];
extern uint8_t  GroteskBold32x64[];
extern uint8_t  franklingothic_normal[];
extern uint8_t SevenSegNumFont[];
//fin fuentes

//defino variables
long  estado = 0;
long anterior = 0;
uint16_t _startAddress;
const int RedPin =    10;  // Salida PWM PIN 10 ROJO
const int GreenPin =  9;  // Salida PWM PIN 9 VERDE
const int BluePin =   8;  // Salida PWM PIN 8  AZUL.
const int WarmPin =   7;  // Salida PWM PIN 7 cct
const int CoolPin=    6; //Salida PWM PIN 6 cct
const int Pote=       1;// entrada analogica


//defino el nombre de las variables que voy a usar

char var[20];
unsigned int dimmer;
u
//fin de variables
const uint16_t my_pids[] = {E120_DEVICE_HOURS, E120_LAMP_HOURS};//comandos especificos que va a aceptar x rdm mas abajo se define cada uno
struct RDMINIT rdmInit = {
  "LIGHT-led",//Etiqueta del fabricante
  000001, // ID del modelo del dispositivo
  "PANEL-LED500", // Etiqueta del modelo del dispositivo
  6, // footprint huella 
  (sizeof(my_pids)/sizeof(uint16_t)), my_pids,
  0, NULL
};

//creo los objetos
UTFT LCD(CTE40,38,39,40,41);
Encoder myEnc(2,3);


void setup() {

Serial.begin(9600);
//inicializo tft y limpio la pantalla, defino fondo blanco
LCD.InitLCD();
LCD.clrScr();
LCD.fillScr(255,255,255);
LCD.setColor(0,0,0);
LCD.setBackColor (255,255,255);   
TCCR2B = TCCR2B & 0b11111000 | 0x01;   //temporizador 2 (controla los pines 10, 9)
TCCR4B = TCCR4B & 0b11111000 | 0x01; //temporizador 4 (controla los pin 8, 7, 6)
uint16_t start = DMXSerial2.getStartAddress();

// habilitar  las salidas pwn 
  pinMode(RedPin,    OUTPUT);
  pinMode(BluePin,   OUTPUT);
  pinMode(GreenPin,  OUTPUT);
  pinMode(WarmPin,   OUTPUT);
  pinMode(CoolPin,   OUTPUT);
  DEVICEID thisDevice;
  DMXSerial2.getDeviceID(thisDevice);

}

  void encoder()
  

  { 
    long newPosition = myEnc.read();
 
if((anterior != newPosition)&&(anterior < newPosition)){
  anterior = newPosition;
  estado ++;
  if (estado > 100){estado = 100;}
 
 Serial.println(estado);
 
 }
 
 if((anterior != newPosition)&&(anterior > newPosition)){
  anterior = newPosition;
  estado --;
  if (estado < 0){estado = 0 ;}
 
 Serial.println(estado);}}



void loop() {
  


encoder();
Dimmmer();
ModoBlanco();


 } 
 
 

void Dimmmer()

{sprintf(var,"%3d",estado);
LCD.print(var,342,10);}

void ModoBlanco(){

  ////MODE WHITE                                                                                                                                                                                                                                                    *
//VARIABLES 

LCD.setFont(franklingothic_normal);
LCD.print("DIM",250,32);
                             
                                                                                                                                                                                                                                                  
LCD.setFont(GroteskBold32x64);
LCD.print("WHITE",15,10);

LCD.setFont(GroteskBold24x48);
LCD.print("CCT ",95,105);

LCD.setColor(255,255,255);
LCD.setBackColor (0,0,0);
LCD.print("10.000 K",195,105);


LCD.setColor(0,0,0);
LCD.setBackColor (255,255,255);
LCD.setFont(GroteskBold24x48);
LCD.print("PG",CENTER,202);
LCD.print("0",CENTER,258);
LCD.print("127",45,202);



LCD.setColor(255,255,255);
LCD.setBackColor (0,0,0);
LCD.print("127",365,202);


LCD.setBackColor (255,255,255);
//RGB-W CUADRADOS DE COLOR
LCD.setColor(255,0,250);
LCD.fillRect(130,201,180,251);
LCD.setColor(0,0,0);
LCD.drawRect(130,201,180,251);//cuadrado magenta

LCD.setColor(0,255,0);
LCD.fillRect(300,201,350,251);
LCD.setColor(0,0,0);
LCD.drawRect(300,201,350,251);//cuadrado verde


//LINEAS

LCD.fillRect(15,165,455,163);

LCD.fillRect(239,0,242,80);
LCD.fillRect(120,80,360,83);//linea  titulos
LCD.fillRect(0,80,10,83);
LCD.fillRect(150,300,153,315);
LCD.fillRect(322,300,325,315);
LCD.fillRect(150,312,325,315);
LCD.fillRect(470,80,480,83);

//SELECCIONES

LCD.setColor(0,0,0);
LCD.drawRect(90,101,392,156);//seleccion CCT
//LCD.drawRect(88,99,394,157);// seleccion CCT
//LCD.setColor(230,230,230);
//LCD.drawRect(89,100,393,156);




LCD.setColor(0,0,0);
LCD.drawRect(38,196,186,256);//seleccion minus green
//LCD.drawRect(44,194,188,258);//seleccion minus green
//LCD.setColor(230,230,230); //color de recuadro gris
//LCD.drawRect(45,195,187,257); //




LCD.setColor(0,0,0);
LCD.drawRect(294,196,443,256);//seleccion plus green
//LCD.drawRect(292,194,445,258);//seleccion plus green
//LCD.setColor(230,230,230);
//LCD.drawRect(293,195,444,257);



LCD.setColor(0,0,0); //seleccion  pg color letra
LCD.drawRect(204,196,275,306);//seleccion pg
//LCD.drawRect(202,194,277,308);//seleccion pg
//LCD.setColor(230,230,230);// color de recuadro interno gris
//LCD.drawRect(203,195,276,307);

}


void ModoFiltros(){
  //MODE FILTERS                                                                                                                                                                                                                                                    

//VARIABLES                                                                                                                                                                                                                                                   

LCD.setFont(GroteskBold32x64);
LCD.print("FILTERS",6,10);
LCD.print("100%",342,10);//VARIABLE DIMMER
LCD.setFont(GroteskBold24x48);
LCD.print("CCT ",95,105);

LCD.setColor(255,255,255);
LCD.setBackColor (0,0,0);
LCD.print("10.000 K",195,105);

LCD.setColor(255,255,255);
LCD.setBackColor (0,0,0);
LCD.setFont(GroteskBold16x32);
LCD.print("ROSCO  ",15,180);
LCD.setColor(0,0,0);
LCD.setBackColor (255,255,255);
LCD.print("ZARAZAROSCO123",150,180);


LCD.setColor(0,0,0);
LCD.setBackColor (255,255,255);
LCD.setFont(GroteskBold16x32);
LCD.print("LEE",15,230);
LCD.setColor(0,0,0);
LCD.setBackColor (255,255,255);
LCD.print("ZARAZALEE12345",150,230);


LCD.setColor(0,0,0);
LCD.setBackColor (255,255,255);
LCD.setFont(GroteskBold16x32);
LCD.print("EFFECTS",15,279);
LCD.setColor(0,0,0);
LCD.setBackColor (255,255,255);
LCD.print("POLICE CAR",150,280);



LCD.setFont(GroteskBold16x32);
LCD.setColor(0,0,0);

//LINEAS
LCD.fillRect(15,165,455,163);
LCD.fillRect(239,0,242,80);
LCD.fillRect(120,80,360,83);
LCD.fillRect(0,80,10,83);
//LCD.fillRect(239,295,242,310);
//LCD.fillRect(200,312,280,315);
LCD.fillRect(470,80,480,83);

//SELECCIONES

LCD.drawRect(10,175,132,217);//recuadro Rosco

LCD.drawRect(10,225,132,267);//recuadro lee


LCD.drawRect(10,275,132,317);//recuadro Rosco
  
  
  }

franklingothic_normal.c (16.1 KB)

GroteskBold16x32.c (30.9 KB)

GroteskBold24x48.c (68 KB)

GroteskBold32x64.c (120 KB)

Ubuntubold.c (45.7 KB)

Nunca he utilizado un encoder con arduino, pero he leído el readme de la librería y hay un punto que igual te interesa.

// // This optional setting causes Encoder to use more optimized code,
// It must be defined before Encoder.h is included.
#define ENCODER_OPTIMIZE_INTERRUPTS
#include <Encoder.h>

gracias, pero para mi el tema es que el no se por que tarda tanto en leer el encoder si tiene interrupciones , si pruebo , solo el encoder con un codigo simple funciona bien, el tema es cuando agrego funciones se relentiza totalmente. hay alguna manera de optimizarlo?

Has calculado cuanto tarda void ModoBlanco(), me da a mi que rápido rápido no es.

por eso consulto si existe alguna forma de optimizar las funciones para que vaya mas rápido.

les dejo video para que vean de manera grafica,,giro el encoder rapidamente responde lento

Agrega mediciones usando millis()

si encoder es tu rutina de interrupción para que pones Serial.print dentro de ella. Ya comenta eso!!

void encoder() {
 
  long newPosition = myEnc.read();
 
  if ((anterior != newPosition)&&(anterior < newPosition)) {
      anterior = newPosition;
      estado ++;
      if (estado > 100)
          estado = 100;
      //Serial.println(estado);
  }

  if ((anterior != newPosition) && (anterior > newPosition)) {
      anterior = newPosition;
      estado --;
      if (estado < 0) 
          estado = 0 ;
      //Serial.println(estado);
  }
}

Rutinas de interrupción deben ser veloces, sin nada como un Serial print que tarda muchos mseg.

hola surbyte, el video que subi esta comentado la impresión a consola pero sigue siendo lento , la unica forma que conseguí un poco mas de velocidad , fue solo impriendo la variable estado en el display, comentado la mayoria del codigo,

//incluyo las liberias y defino variables globales, 
#include <Encoder.h>
#include <UTFT.h>
#include <EEPROM.h>
#include <DMXSerial2.h>
#define newStartAddress
#define DMX_USE_PORT1 // USO EL PUERTO 1 SERIAL DEL MEGA EL PUERTO 0 NO SE USA POR COMPARTIRLO CON EL USB
#define  BREAKSPEED      45500
#define  BREAKFORMAT     SERIAL_8E1
#define  DMXSPEED        250000
#define  DMXFORMAT       SERIAL_8N2



//fuentes que se van a usar
extern uint8_t  GroteskBold16x32[];
extern uint8_t  GroteskBold24x48[];
extern uint8_t  GroteskBold32x64[];
extern uint8_t  franklingothic_normal[];

//fin fuentes

//defino variables
long  estado = 0;
long anterior = 0;
uint16_t _startAddress;
const int RedPin =    10;  // Salida PWM PIN 10 ROJO
const int GreenPin =  9;  // Salida PWM PIN 9 VERDE
const int BluePin =   8;  // Salida PWM PIN 8  AZUL.
const int WarmPin =   7;  // Salida PWM PIN 7 cct
const int CoolPin=    6; //Salida PWM PIN 6 cct


//defino el nombre de las variables que voy a usar

char var[20];
unsigned int dimmer;/*

//fin de variables*/
const uint16_t my_pids[] = {E120_DEVICE_HOURS, E120_LAMP_HOURS};//comandos especificos que va a aceptar x rdm mas abajo se define cada uno
struct RDMINIT rdmInit = {
  "LIGHT-led",//Etiqueta del fabricante
  000001, // ID del modelo del dispositivo
  "PANEL-LED500", // Etiqueta del modelo del dispositivo
  6, // footprint huella 
  (sizeof(my_pids)/sizeof(uint16_t)), my_pids,
  0, NULL
};

//creo los objetos
UTFT LCD(CTE40,38,39,40,41);
Encoder myEnc(2,3);



void setup() {

Serial.begin(115200);
//inicializo tft y limpio la pantalla, defino fondo blanco
LCD.InitLCD();
LCD.clrScr();
LCD.fillScr(255,255,255);
LCD.setColor(0,0,0);
LCD.setBackColor (255,255,255);   
//TCCR2B = TCCR2B & 0b11111000 | 0x01;   //temporizador 2 (controla los pines 10, 9)
//TCCR4B = TCCR4B & 0b11111000 | 0x01; //temporizador 4 (controla los pin 8, 7, 6)
uint16_t start = DMXSerial2.getStartAddress();

// habilitar  las salidas pwn 
  pinMode(RedPin,    OUTPUT);
  pinMode(BluePin,   OUTPUT);
  pinMode(GreenPin,  OUTPUT);
  pinMode(WarmPin,   OUTPUT);
  pinMode(CoolPin,   OUTPUT);
  DEVICEID thisDevice;
  DMXSerial2.getDeviceID(thisDevice);


}
 




  void encoder()
  

  { 
    long newPosition = myEnc.read();
 
if((anterior != newPosition)&&(anterior < newPosition)){
  anterior = newPosition;
  estado ++;
  if (estado > 100){estado = 100;}
 
 //Serial.println(estado);
 
 }else if((anterior != newPosition)&&(anterior > newPosition)){
  anterior = newPosition;
  estado --;
  if (estado < 0){estado = 0 ;}
 
// Serial.println(estado);
}}


void loop() {
  encoder();


LCD.setFont(GroteskBold32x64);
sprintf(var,"%3d",estado);
LCD.print(var,342,10); 

 }

tambien trate de usar las entradas analogicas aumentado la frecuencia de muestreo con

 bitWrite(ADCSRA,ADPS2,1);
 bitWrite(ADCSRA,ADPS1,0);
 bitWrite(ADCSRA,ADPS0,1);

Busca el responsable usando millis() con lo que establecerás quien es el que demora mas.. y luego a analizar como optimizar la rutina.
En una consulta parecida el problema estaba en el cambio de fuentes. Esa tarea es lenta.

Gracias Surbyte.. Voy a buscar los tiempos con millis().. No crei q usar una fuente externa llevara tanto tiempo.. Voy a probar tambien usando las fuentes default de la librería utft y agregar las q tengo directamente la libreria a ver que pasa..

Hola gente Linda,, buenas tardes.. les cuento que implemente las fuentes dentro de la libreria UTFT, borre las default que venían , y mejoro solo 50 Ms , estuve haciendo pruebas con la función millis(), y no consigo bajar de los 510 Ms entre que acciono o giro el encoder y lo que muestra en pantalla osea tengo un paso cada mas de medio segundo..Algún consejo?

Nos olvidamos del DMX o me parece?

En el código del post#7 te pasa lo mismo?

Probe implementando el Dmx y sin DMX y el tiempo de retraso es el mismo

descubri que si pongo todo lo que dibuja la tft en setup exepto las variables ,la velocidad aumenta , el tema es que tengo varias pantallas que dibujan diferentes cosas, como hago para cambiar de pantalla desde el setup. no se si se entendio lo que quise explicar.

Usa funciones diferentes para cada pantalla. En general es mejor que prescindas de void loop(). "A los TFT´s les agrada esa forma de programación"

Este ejemplo es el esquema general para "dos pantallas"
Pantalla1: menu principal
Pantalla2: lectura del encoder

void setup()
{
  Pantalla1();
}
void loop(){}


void Pantalla1()
{
  //Aquí va el código que se ejecuta una vez al cargar cada "menu-pantalla"
  while(1)
 {
   //Aquí va el código en ciclo infinito

  //Para salir de esta rutina usa el panel táctil para llamar a Pantalla2
 }
}

void Pantalla2()
{
  //Aquí va el código que se ejecuta una vez al cargar cada "menu-pantalla"
  while(1)
 {
   //Aquí va el código en ciclo infinito

  //Para salir de esta rutina usa el panel táctil para llamar a Pantalla1
 }
}

De esta forma puedes agregar tantos menus o pantallas como quieras y te permita la memoria de tu MCU.

Acá un ejemplo

Hola, gracias TFTLCDCyg , el problema que tengo , primero mi tft no es táctil ,cambio de menu (pantalla), con un pulsador N/A. como puedo hacer para que me sense el boton dentro del bucle while, ya tengo ocupadas las entradas con interrupciones por el dmx , y encoder.
mi segunda consulta es dentro de uno de los menús (ej: pantalla 1)tengo efectos , que tendrían que ir cambiando con un pulsador N/A(normalmente abierto), pero me queda en bucle infinito una vez que entro al efecto. te lo escribo en pseudocodigo desde el q me pasaste

//necesito que sense un boton para cambiar de efecto

efectos  = efecto 1{bucle},efecto 2 {bucle}//como hago para entrar y salir de cada bucle ?

if(boton=high){//algo asi pense pero no me lee el boton hasta q termine el bucle

c++;


while(c=1){bucle

if(boton=high)c++;
}



}




void setup()
{
  Pantalla1();
}
void loop(){}


void Pantalla1()
{
  //aca dibujo las lineas ,defino fondo todo lo estatico.

  while(boton sin interrupcion //como senso para cambiar de pantalla)
 {

 dimmer=(map(analogRead(A0),0,1023,0,100)
lcd.print (dimmer, x,y,x,y)
lcd.print (efectos, x,y,x,y)


}

void Pantalla2()
{
  //Aquí va el código que se ejecuta una vez al cargar cada "menu-pantalla"
  while(1)
 {
   //Aquí va el código en ciclo infinito

  //Para salir de esta rutina usa el panel táctil para llamar a Pantalla1
 }
}

algun consejo?

Vuelve al comienzo sin abandonar lo hecho hasta acá.
Debes determinar quien introduce el retardo y luego ver como resolver.
Dijiste que el encoder funcionaba bien pero en que contexto?

Sera el DMX, si lo comentas sigue todo igual?

Busca el responsable.

No generes mas bucles dentro de un bucle. Como resultado el bucle final será infinito.

El pulsador solo tiene dos estados: 0 y 1. Tomando como base esto, cuando pulses el botón su estado será 1 en ese momento, el comparador que monitorea el valor resultante del pulsador podrá saltar al siguiente menú.

Lo que comenta surbyte no lo dejes pasar, tendrás que reescribir alguna parte de tu código o en un caso extremo (dicho esto por un servidor), replantea tu código desde cero, alguna función te está jugando en contra, ya que no tienes tantos elementos en tu programa, no hay razón para que veas mermada la velocidad de trabajo final.

Mira este ejemplo:

#include <GD23ZU.h>

const int inputPin = PC13;
int value = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(inputPin, INPUT);
  
  GD.begin(GD_STORAGE);

   MP();
}
void loop(){}

void MP()
{
 GD.cmd_loadimage(0, 0);
 GD.load("Ab1.jpg");

 while(1)
 {
   value = digitalRead(inputPin);
   GD.Clear();
   
   GD.SaveContext();
    GD.Begin(BITMAPS);
    GD.Vertex2f(0*16, 0*16);
   GD.RestoreContext();

   GD.SaveContext();
    GD.ColorRGB(0xff,0x00,0x00);
    GD.cmd_text(GD.w/2, (GD.h)-20, 29, OPT_CENTER, "MP");
   GD.RestoreContext();
    
   Serial.println(value);
   if (value == 1) {
    Serial.println(value);
    delay(45);

      M2();
   }
   GD.swap();
 }
}

void M2()
{
 GD.cmd_loadimage(0, 0);
 GD.load("Ab2.jpg");
 while(1)
 {
   value = digitalRead(inputPin);
   GD.Clear();
   
   GD.SaveContext();
    GD.Begin(BITMAPS);
    GD.Vertex2f(0*16, 0*16);
   GD.RestoreContext();

   GD.SaveContext();
    GD.ColorRGB(0xff,0x00,0x00);
    GD.cmd_text(GD.w/2, (GD.h)-20, 29, OPT_CENTER, "M2");
   GD.RestoreContext(); 
   
   Serial.println(value);
   if (value == 1) {
    Serial.println(value);
    delay(45);

      MP();
   }
   GD.swap();
 }
}

Está implementado en una placa nucleoF767ZI con una pantalla NHD de 7"@FT813, usando el botón de abordo de la placa STM32. Solo son dos menús o pantallas. El core STM que estoy usando es el genérico de danieleff.

los micros arm como el stm tienen en todos sus gpio interrupciones , por eso por ahi te funciona , a mi para que me sense el cambio de estado del sensor tengo que terminar de esperar que termine el loop, uso millis() en ves de delays. por otro lado lo que noto que lo hace lento todo mi programa es la pantalla demora mucho tiempo el graficar . no se si es por la libreria uso la UTFT (la ultima) y mientras mas grande es el tamaño de la fuente se va notando mas los delays. he realizado todo un codigo de menus sin DMX , para probar lo que les comento.