Go Down

Topic: Flip/mirror a TFT LCD screen (Read 3157 times) previous topic - next topic

2jamesr2

Hi, long-time reader, first-time poster :)

I've bought the Arduino 1.8" TFT LCD screen (http://arduino.cc/en/Main/GTFT) and am looking to develop a small HUD device for use in a car, to be reflected onto the windscreen by placing my unit on the dashboard beneath it. It's somewhat inspired by the Garmin HUD:


My current stumbling point is that the libraries do not have a built-in function that would flip/mirror the display in the same way that Processing offers the mirror function. I need to be able to flip the y-axis over so it can be read properly by the user.

I've had a good search across the internet and on the forum, and have found several people making HUDs or having problems where they initially have a flipped screen. The closest I've come to fixing it myself is this topic: http://forum.arduino.cc/index.php?topic=215574.0, where the OP has started with a flipped screen, but then called a map to invert the axis to solve it for him. I have tried to do this myself byt haven't had much luck. I've looked into the adafruit gfx and st7735 libraries that the tft library is based on and can't find any functions to call on.

Here is the code I'm working with to try to flip the screen. It's just a counter at the moment as a timely reminder of how long I've been searching for a solution  :P The map part is in the setup area.

Code: [Select]
#include <TFT.h> // Hardware-specific library
#include <SPI.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library

#define CS   10
#define DC   9
#define RESET  8 

// pin definition for the Leonardo
// #define CS   7
// #define DC   0
// #define RESET  1

TFT myScreen = TFT(CS, DC, RESET);

// variable to keep track of the elapsed time
unsigned long seconds = 0;
unsigned long newseconds = 0;
unsigned long minutes = 0;
unsigned long width = 160;
unsigned long height = 128;
// char array to print time
char printout[4];
char printout2[4];

void setup() {
    myScreen.begin(); 


//This is my test bed for trying to map a flip but failing miserably

   myScreen.width()= map(myScreen.width(),0,159,159,0);
   myScreen.height()= map(myScreen.height(),0,127,127,0);

//I'm aware this doesn't compile, I've tried a few things that don't work


  myScreen.background(0,0,0); // clear the screen
  myScreen.stroke(255,0,255);
  // static text
    myScreen.setTextSize(2);
  myScreen.text("Running for",0,0);
  myScreen.text("minutes",0,50);
myScreen.text("seconds",0,100);
  // increase font size for text in loop()
  myScreen.setTextSize(4);
}




void loop() {
     // get elapsed time
    seconds = millis();
    newseconds = (seconds - (minutes*60000));
    if (newseconds > 59999) {
      minutes++;
     
    }
    // convert to a string
    String elapsedMins = String(minutes);
    String elapsedSecs = String(newseconds/1000);
    // add to an array
    elapsedMins.toCharArray(printout2,4);
    elapsedSecs.toCharArray(printout,4);
    // print out and erase
    myScreen.stroke(255,255,255);
    myScreen.text(printout2,0,20);
    myScreen.text(printout,0,70);
    delay(1000);
    myScreen.stroke(0,0,0);
    myScreen.text(printout2,0,20);
    myScreen.text(printout,0,70);

}


Does anyone have any pointers as to where to go with this? Is mapping a good way about it?

Or is it something that could be written into the library?

Thanks for reading!

GJH105775

Have you found a solution yet?   I'm looking to do something very similar with CAN bus data.   

david_prentice

Please post a link to the actual display that you are using.   I suspect that it is a 128x160 ST7735S display.

On most controllers you just need to change a single bit in the Manufacturer Panel Register.
With the ST7735S you have to flip MY in the MADCTL User register.

David.

brownjd

Please post a link to the actual display that you are using.   I suspect that it is a 128x160 ST7735S display.

On most controllers you just need to change a single bit in the Manufacturer Panel Register.
With the ST7735S you have to flip MY in the MADCTL User register.

David.
I tried playing with various values to correct a 1.8 TFT SPI 128*160 display that was printing in mirror mode by default. What's weird is that I have a bunch of these, and for some reason, this one prints backwards. Unfortunately, I can't figure out what hex value to use for MY. I've been using the Adafruit_ST7735 library. It has the following default values:

#define MADCTL_MY  0x80
#define MADCTL_MX  0x40
#define MADCTL_MV  0x20
#define MADCTL_ML  0x10
#define MADCTL_RGB 0x00
#define MADCTL_BGR 0x08
#define MADCTL_MH  0x04

I looked at the data sheet, but I can't figure out how these hex values map to the reference material. Any clue?

david_prentice

Quote
Please post a link to the actual display that you are using.   I suspect that it is a 128x160 ST7735S display.
Is it really so difficult to post a link? e.g. the Ebay sale.

People just assume that a 128x160 is a ST7735.     Most manufacturers produce controllers of this style e.g. Sitronix, Himax, Ilitek, Raydium, ...

David.

brownjd

Is it really so difficult to post a link? e.g. the Ebay sale.

People just assume that a 128x160 is a ST7735.     Most manufacturers produce controllers of this style e.g. Sitronix, Himax, Ilitek, Raydium, ...

David.
https://www.ebay.com/itm/1-8-inch-ST7735R-SPI-TFT-LCD-Display-Module-128-160-with-PCB-for-Arduino-51/162145126130

david_prentice

I think that Bodmer has this display.
No,   I do not have that particular display.

I doubt that it contains a ST7735R.    It might have ST7735S.   It might have a completely different make.

I suggest that you try Bodmer's library and configure appropriately.

Flipping directions is pretty simple to do.   But it is simpler to just let Bodmer look after it for you.

David.

brownjd

I think that Bodmer has this display.
No,   I do not have that particular display.

I doubt that it contains a ST7735R.    It might have ST7735S.   It might have a completely different make.

I suggest that you try Bodmer's library and configure appropriately.

Flipping directions is pretty simple to do.   But it is simpler to just let Bodmer look after it for you.

David.
Since flipping is so easy, what's the hex value for MV? Or what are the possible values and I'll test them out?

I've had 3 other identical looking screens (different seller) work great with my current code, so I really don't want to switch out libraries for a single goofy screen. It works just fine except for being backwards. For now, I'd rather work around a simple setting.

david_prentice

Just read the datasheet.   The MADCTL register has MY, MX bits.    I have no idea what mirroring you are talking about e.g. left-right or up-down.

You flip MY for up-down and MX for left-right.

But as I said earlier,    install Bodmer's library and select the correct config in User_Setup.h file.

David.

brownjd

#9
May 19, 2018, 12:12 am Last Edit: May 19, 2018, 12:13 am by brownjd
Just read the datasheet.   The MADCTL register has MY, MX bits.    I have no idea what mirroring you are talking about e.g. left-right or up-down.

You flip MY for up-down and MX for left-right.

But as I said earlier,    install Bodmer's library and select the correct config in User_Setup.h file.

David.
I did read the data sheet (see my original post). I just can't figure out how the hex values used by Adafruit map to the values in the data sheet.

The problem is the text is going right to left. As in a mirror.

I tried bodmer's library, but it depends on <avr/io.h> which does not seem to be included for ESP8266 boards by the Arduino IDE.

david_prentice

#10
May 19, 2018, 12:41 am Last Edit: May 19, 2018, 12:42 am by david_prentice
Go on.   Bodmer has libraries specifically for Expressif targets.   ESP32 and ESP8266.

He also has libraries for AVR.    Just try them.

David.

brownjd

By golly, you're right.

I had tried his ST7735 library. I didn't realize he has other variations.

For those reading along, I think you'll want the TFT_eSPI. It appears to be the kitchen sink.

Now to refactor code and hope it works. Or I could have just plugged in a hex code and gone on down the road. Such is the internet.

brownjd

#12
May 19, 2018, 07:58 pm Last Edit: May 20, 2018, 03:35 pm by brownjd
Well, Bodmer's library didn't work either despite several hours of trying every combination possible. However, using his example, the data sheet, and several hours of tweaking, I'm pretty sure I have an ST7735B. I noticed the library did not handle INITB explicitly, despite having constants for it, so I opted to make my changes for the INITB variant.

Thanks David for pointing me to Bodmer's library. It didn't work, however playing with it did enable me to figure out what settings I need. I can now go back to my regularly scheduled program with the right values.

I had to change ST7735_Rotation.h and add the following to each case. Hopefully this will help someone else suffering from mirrored text. Remember to select ST7735 as your driver and INITB in User_Setup.h

case 0:
} else if(tabcolor == INITB) {
writedata(TFT_MAD_MX | TFT_MAD_RGB);
}

case 1:
} else if(tabcolor == INITB) {
writedata(TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB);
}

case 2:
} else if(tabcolor == INITB) {
writedata(TFT_MAD_MY | TFT_MAD_RGB);
}

case 3:
} else if(tabcolor == INITB) {
writedata(TFT_MAD_MV | TFT_MAD_RGB);
}

david_prentice

Run the diagnostic.    This should give a few clues about the Make and Model of controller.

I am surprised that none of Bodmer's INITx macros matched perfectly.
And yes,   if there is a "new" controller,   it needs an INIT macro of its own.

Copy-paste the result of the readreg diagnostic.    It will help Bodmer (and me) to identify / adapt libraries.

David.

brownjd

#14
May 19, 2018, 11:49 pm Last Edit: May 20, 2018, 12:11 am by brownjd
Okay, how do I run that diagnostic?

Go Up