Go Down

Topic: TFT display seriously slows down the loop? (Read 790 times) previous topic - next topic

Nick_Pyner

Apr 30, 2014, 03:40 am Last Edit: Apr 30, 2014, 05:07 am by Nick_Pyner Reason: 1
My data logging setup uses three DS18B20 and a flow meter with display to a LCD and serial feed to Bluetooth. Backup to SD and internet feed is only every ten seconds.  I want display and serial  update at one second intervals and have a delay of 850ms to achieve this. Display is a 5110 and six numbers are updated.

I am currently upgrading one Mega to use a 400x240 TFT screen. At the moment, I am just using one DS18B20, so the loop is mostly about the display, but it is taking more than a second to go round and I have been obliged to add 3900ms to get an update at five second intervals. Thus, if I want one second updates, I am about 100ms short, and it's only going to get worse.

This is really disappointing.  The fundamental difference between the two is that, with the TFT, I am updating one more number and two graphs.  To add insult to injury, the slow update obliges me to draw lines on the graph rather than simply add a pixel, which I guess makes a bad situation worse.

Needless to say, all the fixed text etc. is done in the setup.

EDIT
OK I have solved the problem sufficiently to enable one-second updates. There was a degree sign on the screen that was flashing when it shouldn't have been, which revealed a right-royal ballsup in the subroutines -  stuff in the wrong place and  stuff being displayed twice.  The loop is unchanged, but fixing the subroutines has saved me 200ms, which is twice what I need right now, and may suffice for the finished product.  This still means that using this display slows the process considerably.

Code: [Select]
void loop() {
int t = millis();
 sec = sec + 1;
 if (sec>460)
 {
   runscrn ();
   sec = 101;
 }
     GetClock();
 if (hour == 0 && minute == 0 && second <2)
 {
   getFileName();
 }
 
 //get the values from the DS8B20's
sensors.requestTemperatures();
InTemp = (sensorValue(InThermo));
//  OutTemp = (sensorValue(OutThermo));  
// DrainTemp = (sensorValue(DrainThermo));
 Serial.println(InTemp);

 diff = (InTemp - 20)/2;

if (flag =1)
{
running();
}
myGLCD.setColor(0, 0, 0);  
  myGLCD.setBackColor(255,255,255);
   tab = 174;
   if (DrainTemp<10)
   {
     tab = 182;
   }
  myGLCD.printNumF(DrainTemp, 2, tab, 150);

   tab = 174;
 if (InTemp<10)
   {
     tab = 182;
   }
  myGLCD.printNumF(InTemp, 2, tab, 165);

    tab = 174;
 if (OutTemp<10)
   {
     tab = 182;
   }
  myGLCD.printNumF(OutTemp, 2, tab, 180);

     tab = 182;    
    if(int(flow) > 9)
   {
        tab = 174;
   }
   myGLCD.printNumI((int)flow, tab, 210);   // Print the integer part of the variable
   myGLCD.drawCircle((tab+10),219,1);             // Print the decimal point
   frac=(flow - int (flow))*100;
   myGLCD.printNumI(frac,(tab+16),210) ;      // Print the fractional part of the variable

     tab = 174;  
      if (Conv < 10 && Conv >=0)
      {
        tab = 182;
      }
      if (Conv < -10)
      {
         tab=166;
      }

  myGLCD.printNumF(Conv, 2, tab, 225);

     tab = 174;    // diff is two digits or 1 digit plus "-" sign
   if (diff <10 && diff >=0)
      {
        tab = tab + 8;
      }
    if (diff < -10)
      {
         tab=tab -8;
      }
  myGLCD.printNumF(diff, 2, tab, 195);
       
myGLCD.setFont(SevenSegNumFont);
kW=InTemp/3;  
whole = int (kW);
frac = int((kW - whole) * 10);
   tab = 362;
   if (whole <10)
   {
       tab = 394;
   }  
myGLCD.setColor(0,255,255);
myGLCD.setBackColor(0,0,0);
    myGLCD.printNumI(whole, tab, 190);
     myGLCD.printNumI(frac, 436, 190);
       myGLCD.setColor(0,250,200);
   myGLCD.drawLine((sec-1),(125-int(oldiff*10)),sec, (125-int(diff*10)));
    myGLCD.setColor(255,150,0);
   myGLCD.drawLine((sec-1),(125-int(kW1*10)),sec, (125-int(kW*10)));
kW1=kW;  
oldiff=diff;

delay(3906);
int t2 = millis();    
int tim = t2-t;
   Serial.println(tim);
}



robtillaart

what might help is to only update the TFT for the values if they have really been updated.
Means you need to keep the last written value in memory.

I also see some calls like setFOnt and setBackground
are these needed in the loop or can these be set once in setup?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Nick_Pyner


what might help is to only update the TFT for the values if they have really been updated.
Means you need to keep the last written value in memory.


That occurred to me as a last resort but I expect the values will be varying too often to merit the conditions.

Quote

I also see some calls like setFOnt and setBackground
are these needed in the loop or can these be set once in setup?


The only change is one colour/size/background for the numbers - and back again.But I found a redundant font change in a subroutine. Thanks...

Grumpy_Mike

Quote
but I expect the values will be varying too often to merit the conditions.

Even if the numbers change a lot there is no need to keep writing the text descriptors they never change.
By not clearing the whole screen you can update only those ares of the screen you need to.

Nick_Pyner

Yes. As I said, all the fixed text is done once. Only the numbers are updated. The disappointing thing is that the actual quantity of work is not that much greater than the 5110, and the cosmetics come at a high price. I only clear the screen when the graph reaches the end - 30 minutes - and that's OK.

Grumpy_Mike

Quote
and the cosmetics come at a high price

:)
Yes that is always the case.

robtillaart

Can you time the LCD.printNumF() function ?

maybe it is faster to make a string of the float yourself and print the string.   (do you need 2 decimals?)
(did some optimizing in printing here - http://forum.arduino.cc/index.php?topic=179111.0 - not trivial but much faster)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Nick_Pyner

Quote
Can you time the LCD.printNumF() function ?


Yes. I was thinking about that last night. I will make up a programme for the purpose. Print ten lines. This was prompted by getting suss about the fonts.

This job uses the Henning Karlsen library and was derived from one of his examples.

he library has three fonts - small, large, and "SevenSeg". All the stuff in large font is fixed before the loop, but I'm getting very suss about the big 7-seg in  the corner. The lines are 5 px thick and there are probably more pixels updated there than in the rest of the display, even though the dp is fixed. There is no dp in the font and the digits are printed individually, which probably doesn't help.

I experimented with printing strings to serial monitor long ago and found that floats won by a wide margin every time. I concluded that the only time one should ever use strings is when the receiving software demanded it - which is not often. I guess that was a bit hasty, and maybe there are times when the hardware is better suited to strings.

Nick_Pyner

It certainly looks like it does........

I am pretty pleased with my TFT display and I have gotten it to do what I want but I might still find that I cannot do it in the one-second loop that I want, and I have been quite taken aback by the time the TFT takes to do its stuff compared with the Nokia 5110.

I made up a test to display six lines of twelve characters i.e. a suitable comparison for the 5110. I sent millis to the serial monitor.

Code: [Select]
      lcd.setCursor(0,0);
lcd.print("12abcdefghuy");


These are the times

6x12
Nokia 5110                     93
6x12
TFT small font             159    this font is about the same size as that on the 5110
TFT big font                 305

4x12
bigger 7Seg font       1040

Go Up