Are TFT commands executed asynchronously?

Greetings community.

I have a project which is already finished and used on a daily / weekly basis. It had a problem though, where random code gets executed, or so I thought. Johnwasser helped me with fixing my array which got readen out of boundaries. But there are still some issues... Let us list some of them:

  • Display Rotation changes on the runtime, even
TFTscreen.setRotation(3);

called only once in setup phase.

  • Display Background color changes to red, even the color Red is not defined anywhere. So I think, a byte responsible for RGB gets shifted or something.

  • And then there is this:


    This straight up looks like, he started doing something, but halfways he got interrupted to do something else. The top part (black part with 65%) indicates the normal procedure. The bottom part only occurs when I am near a certain Landmark and disappears, when Landmark is behind me.

Since this occurs pretty much randomly, or at least not deterministically, I am wondering if setting up some delays after writing on screen would fix the problem?

My last resort is pinning RESET and some digital pin together and executing a reset every minute or so. Super annoying... But this is last resort.

Previous Thread about the same issue: <Solved> Buffer Overflow, how to debug, how to fix - Programming Questions - Arduino Forum
Full Code: totally-legal-blitzermelder/MotorbikeEnhancher3000/FullProject/main at master · Stefan-Kosker/totally-legal-blitzermelder · GitHub

Appreciate the help

What does 0x0F do to the display? You appear to be in this portion of the code when the error occurs:

   void warnUserFromRadar(int speedLimit, int distanceToRadar) {
      distanceToRadar = makeDistanceValueFasterToComprehend(distanceToRadar);
      removeText("\x0F:" + String(oldSpeedLimit), ALERTTEXTMARGINLEFT, ALERTTEXTMARGINTOP);
      addText("\x0F:" + String(speedLimit), ALERTTEXTMARGINLEFT, ALERTTEXTMARGINTOP);
      removeText(String(oldDistanceToRadar) + "m", ALERTTEXTMARGINLEFT, ALERTTEXTMARGINTOP + ALERTTEXTMARGINBETWEEN);
      addText(String(distanceToRadar) + "m", ALERTTEXTMARGINLEFT, ALERTTEXTMARGINTOP + ALERTTEXTMARGINBETWEEN);
      oldSpeedLimit = speedLimit;
      oldDistanceToRadar = distanceToRadar;
    }

Looks a bit like you are executing the above code, then overwriting it with the normal display. Is there anything that clears the display between this part of the code and the return to the normal display?

Hello David,

appreciate the answer. 0x0F is the sun icon. See here:

Basically, the end result is something like this: "☼ 50"

Yes. The disarmAlert function in main.ino is responsible for getting back to the regular screen.

void disarmAlert() {  
  tftDisplay.alertMode = false;
  tftDisplay.clearDisplay();
  fuelSensor.lastTimeSensorRead = 0;
  oilTemperatureSensor.lastTimeSensorRead = 0;
}

Important Part being clearDisplay() function:

    void clearDisplay() {
      if (alertMode) {
        TFTscreen.background(AlertBackgroundColor_R, AlertBackgroundColor_G, AlertBackgroundColor_B);
        TFTscreen.setTextSize(5);
      } else {
        TFTscreen.background(NormalBackgroundColor_R, NormalBackgroundColor_G, NormalBackgroundColor_B);
        TFTscreen.setTextSize(2);
        drawImagesInitially(InitialIconColor);
      }

dr-o:
Important Part being clearDisplay() function:

    void clearDisplay() {

if (alertMode) {
        TFTscreen.background(AlertBackgroundColor_R, AlertBackgroundColor_G, AlertBackgroundColor_B);
        TFTscreen.setTextSize(5);
      } else {
        TFTscreen.background(NormalBackgroundColor_R, NormalBackgroundColor_G, NormalBackgroundColor_B);
        TFTscreen.setTextSize(2);
        drawImagesInitially(InitialIconColor);
      }

You are setting the background color and text size, but I don't see anywhere that you are actually clearing the display itself.

david_2018:
You are setting the background color and text size, but I don't see anywhere that you are actually clearing the display itself.

Hello David, thank you for your answer. .background IS the clearer. Check this out mate:

Basicly what TFTBackground does is, set every pixel on given color.

So it is basically:

screen.fill(255,255,255);
screen.rect(0,0,screen.width(), screen.height())

I hate to say it, but i think you are suffering from memory fragmentation. The TFT library sucks up quite a lot for starters, but when you use the String class like this

void applyWriteCommand(String text, int x, int y, int8_t color_r, int8_t color_g, int8_t color_b) {
      char _text[text.length() + 1];
      text.toCharArray(_text, text.length()+1);
      _text[text.length()] = '\0'; // In case 'toCharArray' doesn't add the null terminator.

      TFTscreen.stroke(color_r, color_g, color_b);
      TFTscreen.text(_text, x, y);
    }

you are doubling up on memory usage, half which does not get released until the parent function terminates, that combined with the concatenations. Hmm unless you are not using an UNO, this is asking for trouble.

How bad is it doc?
Fun aside. What are my Options? I once created a Test where I saved Up the free memory causing memory Fragmentation. It looked good. I can create a small logging and save it to eeprom though. Then I can read it after Problems haplened

dr-o:
Hello David, thank you for your answer. .background IS the clearer. Check this out mate:
TFT - Arduino Reference

Basicly what TFTBackground does is, set every pixel on given color.

So it is basically:

screen.fill(255,255,255);

screen.rect(0,0,screen.width(), screen.height())

Unfortunately I am not very familiar with that particular TFT library.

As for the possibility of memory problems, the only place I saw you using String was in the DisplayOnTFT.h file, and those instances can easily be replaced with char arrays.

The symptoms suggest a buffer overflow somewhere. Especially the screen orientation changing...

aarg:
The symptoms suggest a buffer overflow somewhere. Especially the screen orientation changing...

Yeah Buffer overflow, heap Fragmentation. Something memory related, i can Imagine. Ideas for Debugging?

Ideas for Debugging?

The obvious regarding the 'String' class would be to get rid of it in favor of char *. That would also mean getting rid of the concatenation of the creation of the String before it is passed as an Argument and replacing it with a known length buffer. Buffer overflow is hard to detect, so i guess you'd have to just check all possible overflow places. That the problem arises after a while is more an indicator of fragmentation though.

Uhm, okay, so. Changing all Strings to char[]. And then test again? Allrighty. Thanks.

This is kinda a brute force debugging method, fixing all potential problem points. But fine by me.

If you believe the problem is specific to the display, then post in the display forum, and specify exactly what hardware you are using, how it is interconnected, etc. Without that, we are making suggestions based only on the code, and familiarity with what has caused similar problems with other code - String is known to cause memory problems if not used carefully.

This is kinda a brute force debugging method

With memory related issues i can not think of any other way.

david_2018:
If you believe the problem is specific to the display, then post in the display forum, and specify exactly what hardware you are using, how it is interconnected, etc. Without that, we are making suggestions based only on the code, and familiarity with what has caused similar problems with other code - String is known to cause memory problems if not used carefully.

Allrighty, can switch to usage of char arrays, no problems there. Can ask it there as well. I was just wondering, if display connection is asynchronous or not. That is all actually. If it is asynchronous, then it would be also another possible problem source.

dr-o:
I was just wondering, if display connection is asynchronous or not. That is all actually. If it is asynchronous, then it would be also another possible problem source.

Arduino's have a single processor running a single thread, so pretty much everything is asynchronous. though I highly doubt it is causing your problem. You got some heavy hitters helping you, I would listen to them.

I was just wondering, if display connection is asynchronous or not

To be honest, i don't know. I never had a SPI - TFT screen, so i googled and found In this thread that at least the SPI transmission isn't. (or so he says) And i doubt that the TFT library itself would do something Async. Of course the object itself is created on the heap, and it is very possible that also the send buffer is created on the heap (check within the TFT.h to verify) If so then memory fragmentation is your most likely cause (as it was anyway)

Hutkikz:
Arduino's have a single processor running a single thread, so pretty much everything is asynchronous. though I highly doubt it is causing your problem. You got some heavy hitters helping you, I would listen to them.

That makes it rather synchronous I would say?
@Deva_Rishi: so, Change Strings to Char Arrays and Test it again. Will do thanks

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.