Open d3mac123 opened 11 months ago
Yes as long as you're using the AXS15231B files from my repo.
Your main full screen sprite needs to be the full size of the Long display so change the main sprite to 640x180. Then when updating the display you always push this sprite using lcd_PushColors_rotated_90() in this case. All other writes to the display are actually writes to the main sprite so instead of
tft.setPivot(SCREEN_X/2,SCREEN_Y/2);
you need to use
sky.setPivot(SCREEN_X/2,SCREEN_Y/2);
or which ever sprite you want to set a pivot for.
Using this display buffer approach you'd only refer to the tft object here and nowhere else:
TFT_eSPI tft = TFT_eSPI(); TFT_eSprite back = TFT_eSprite(&tft); TFT_eSprite sky = TFT_eSprite(&tft);
I think I see what your making. Forgive me if I'm wrong. Try this:
TFT_eSPI tft = TFT_eSPI(); TFT_eSprite back = TFT_eSprite(&tft); TFT_eSprite sky = TFT_eSprite(&tft);
const uint16_t SCREEN_X = 320; // Screen sizes are set here. const uint16_t SCREEN_Y = 170;
int angle=0; int pline;
void setup() { pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, LOW); // turn off backlight asap to minimise power on artifacts Serial.begin(115200); axs15231_init();
back.createSprite(640,180); back.setSwapBytes(1); //only needed for the main top level sprite
sky.createSprite(SCREEN_X2,SCREEN_Y2); sky.setPivot(SCREEN_X/2,SCREEN_Y/2);
lcd_fill(0,0,180,640,0x00); // clear screen digitalWrite(TFT_BL, HIGH); // turn on backlight
}
void loop() { back.fillSprite(TFT_BLACK); pline = 0;
sky.fillRect((SCREEN_X/2) - SCREEN_X, ((SCREEN_Y/2) - SCREEN_Y)+ pline, SCREEN_X2, ((SCREEN_Y/2) + SCREEN_Y) + pline,cBlue); //SKY sky.fillRect((SCREEN_X/2) - SCREEN_X, SCREEN_Y + pline + 1, SCREEN_X 2, SCREEN_Y + (SCREEN_Y/2) + pline + 1,cRed); //GROUND sky.drawLine((SCREEN_X/2) - SCREEN_X, SCREEN_Y + pline, SCREEN_X * 2, SCREEN_Y + pline,TFT_WHITE);
sky.pushRotated(&back,angle,TFT_BLACK);
back.drawNumber(angle,160,100,2); //back.pushSprite(0,0); //not needed lcd_PushColors_rotated_90(0, 0, 640, 180, (uint16_t*)back.getPointer());
angle++; if(angle==360) { angle=0; } }
I recommend that you call your main display buffer sprite 'full_screen' or 'screen_buffer' or something like that. Then you can re-use the code in other projects without possibly confusing references to project specific gui elements.
To place a rotated sprite to an arbitrary location you can use the new TFT_eSPI Viewport function. It's very useful as saves doing a lot of arithmetic.
The reason I need to have a larger than the screen size sprite (it works on the regular T-Display, btw) is for the full rotation - see here
Having it set only to the full screen size gets me the wrong drawing - see below
Yes I understand. I was only guessing the dimensions. But it does work with the sky.pushRotated(&back,angle,TFT_BLACK); ? You're not getting the crash now?
Your project looks great. Is it a flight sim avionix?
I am not getting the crash anymore (although refreshing the full-screen is painful as you can see by the movie).
Regarding the project, this is for a real airplane :) - My main avionics display is a Dynon Skyview, which transmits all the data wireless via UDP. I use the ESP32 to capture the data and serve as a backup system. Also, I am adding more functionality, like the checklist part.
Yes the full screen update is slow due to the low max spi rate of the display plus the fact that we have to do software rotate for landscape mode. But I'm working on partial update for TFT_eSPI. You can see in my LVGL demo that things are very fast as I already implemented partial update (it was much easier to do for LVGL). Partial update is only beneficial if animations are restricted to regions less than full screen.
But for an artificial horizon which requires a full screen sprite rotate there's only so much you can do. At the moment my lib is not using DMA as it was problematic with alpha3. I will add that after successful tests. Then things should be faster all round.
I think the Long will be fine for you to develop your product but at some point you'll probably want to migrate your code to a hardware configuration with a similar display form factor but which allows not only faster MCU->Display comms but a native landscape mode. There are loads of parallel RGB displays out there with similar dimensions. They come with a different set of problems for the current ESP32_Arduino Core implementation but speed is definitely not one of those problems.
A good entry point for using RGB 40-pin displays is Adafruit Qualia: https://www.adafruit.com/product/5800
They have a hopefully growing list of officially supported displays.
BTW, your video IMG_5317.MOV wouldn't play.
Video is working fine for me... Weird...
The artificial horizon is not the main feature (probably neither the second, as I have already a second display in the aircraft as a backup). I just added that because, why not? 😃
The reason I like the Long format is for the checklist part and because panel space is very limited in my case.
It's probably my browser (Brave). If you upload a zip of your video I can download.
There is a 10MB limit on videos you can add directly to comments and 25MB limit on a zipped file upload.
Just out of interest, you say UDP for the data transfer. Is that a wifi peer-to-peer config? Sounds interesting. Does the Dynon Skyview offer other ways to transmit its data? Or is it acting as a wifi hotspot?
I always wondered how 'In-Cockpit' telemetry was done if not hard wired.
You're a pilot? I'm jealous! Love planes. I took a 2 week hang gliding course and a basic helicopter lesson once. I nearly got into auto-gyros but was put off by some overly negative microlight enthusiasts! :) I plan to do sailplanes tho.
Dynon transmits via Wifi/UDP (if you have their Wifi module - a USB dongle that creates a hotspot) or via serial ports. All avionics use serial but I had to opt for the WiFi mode because all my serial ports are already in use by other stuff.
I got my pilot license a few years ago (just as a hobby). Before planes, I flew powered paragliders for a decade. I like gyros and helicopters but, I don't think they are my thing :)
Any updates on the library (refresh rates, rotation, etc)? BTW, do you recommend any good tutorials on the LVGL? Maybe it is the time to move on from TFT_eSPI?
I'm going to be adding some demos for the T4-S3 AMOLED soon so some of that stuff will filter back to the Long. I started using LVGL when I tried Square Line Studio for the first time. It's really a very good way to learn about LVGL. I'm not familiar with any tutorials but the on-line documentation for LVGL is fantastic! There are also great tutorials on YT for getting started with Square Line Studio.
Nik, I am running into a somewhat similar issue, not so much with rotating the screen but with partial screen updates. I was able to get a slider to work with a partial screen sprite but I have not been able to get partial screen updates to work with displaying text. Wasn't sure if you had made any progress on adding the partial screen update to this demo. For this particular project it is probably not worth the time to switch it all over to LVGL as I have 8-10 screens that my project uses. There are only 2 screens where I am wanting to implement a partial update to speed up the display. In time sensitive areas I am using the 2nd core to draw the screen while using the main core for time sensitive processing but it would be nice to speed up the draw time. Below is the code snippet for my brightness slider which is a partial update that is working.
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite sprite = TFT_eSprite(&tft);
TFT_eSprite s1 = TFT_eSprite(&tft);
s1.createSprite(450, 100);
while (touchWait) {
if (!digitalRead(TOUCH_INT)) {
getTouch();
if (tx >= 240 && tx <= 420 && ty >= 110 && ty <= 170) {
touchWait = false;
plotPulse = false;
} else if (tx >= 440 && tx <= 620 && ty >= 110 && ty <= 170) {
touchWait = false;
plotPulse = true;
} else if (tx >= 124 && tx <= 528 && ty >= 60 && ty <= 100) {
bright = map(tx, 124, 528, 30, 255);
EEPROM.put(addrBright, bright);
EEPROM.commit();
s1.fillSprite(tftBg);
s1.drawString("Brightness", 220, 30, GFXFF);
s1.fillRoundRect(22, 67, 406, 16, 8, tftBtn);
s1.fillRoundRect(24, 69, map(bright, 30, 255, 0, 404), 12, 6, dIOrange);
s1.fillCircle(map(bright, 30, 255, 24, 428), 75, 14, tftText);
s1.fillCircle(map(bright, 30, 255, 24, 428), 75, 7, dIOrange);
lcd_PushColors_rotated_90(100, 0, 450, 100, (uint16_t *)s1.getPointer());
ledcWrite(TFT_BL, bright);
} else {
}
}
}
I fiddled with it some more and ended up getting it to work with the exception of the graph. The graph would work sometimes but other times would draw shifted by roughly 10 pixels in x and y and then draw again normally and would produce some weird glitchy behavior. Other than that I was able to draw partial screens at up to 100 FPS depending on the size. The size in the example above got me to about 76 FPS instead of 11.5 for a full screen update.
Is the pushRotate function already implemented? I am trying to run this piece of code but it is crashing when pushRotate is called.