ESP32 + 7in LCD + Fast RGB Interface

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi and welcome to bites and bits elro recently released a new LCD panel with a built-in esp32 microprocessor on the back of it now the difference with this panel to normal sort of U micro processor ones is that it actually uses a very fast 16bit parallel RGB interface to interface the esp32 and the actual screen itself so the upshot of that is that we should get a very fast data rate between the microprocessor and the LCD panel which should give us some very good performance on this large 800x 480 pixel display so in this video I want to have a look at the actual device itself and see what it um involves we'll then have a look at how well it performs and how we can optimize that performance then to make sure that the drivers we use allow us to create some really good projects using this as a display either as a control panel or perhaps as some other sort of and game display or so on so let's start by having a look at the actual device itself and see what it can do so the display unit comes as a single item with the ESP 32 circuit board mounted on the back of the actual LCD panel so power is via a single USB type-c connector which also serves as the main USB port to connect to our development system or you can use it of course as a separate USB port whilst your system is running now the processor on this board is an asp32 S3 with a dual core 32bit L6 microprocessor that can run at up to 240 MHz it also has has integrated Wi-Fi and Bluetooth wireless functions like most other esp32 units now this particular processor is tamed with 512k of fast static Ram backed up with 8 megabytes of of almost as fast pseudo static Ram or this PS Ram that's running over this fast SPI Channel now the esp32 also has 4 mbytes of built-in flash storage but it also has an SPI connected SD card reader that we can use them for some Mass data storage now around this board there are a number of IO connections so we have two Ur ports for serial Communications along with a single gpio output now now this single GPI output is probably the weakest area of the board so you won't be able to connect lots of different buttons and devices to the screen without resorting to using one of the UR channels for that connection now we also have a battery connector with battery management circuitry and that will allow you then to plug in any of these LiPO batteries and it will actually then power that and recharge that uh from the main um USB power input now there also is an i s s driven speaker output and that allows us to get some sound out of the board and that's taken down to this little two pin connector uh down here now the touch panel on the device is a capacitive touch screen now it doesn't support multi-touch but it is actually quite accurate and responsive and that will actually make this unit ideal as some sort of control panel for one of your projects and with the price of this unit coming in at around about £40 or $40 this does represent incredibly good value for money so when you first power on display out of the box it will start to run a demo application that shows its compatibility with the lvgl control full panel software now this software is a very powerful user interface building tool that allows you to create very professional level displays with all the modern features you'd expect such as scrolling panels touch controls graphical instruments and so on and all of these interfaces can be created and hooked up to your code using a freefor personal use version of their development software now I'm not going to be going into the use of this tool in this video but it is well worth a look if you want to put a great user interface onto your project and I probably will cover this in a video later as it is a very powerful tool but for this video I'm actually going to look at the performance of the LCD panel as a standard display for our projects so the big difference between this unit and other asp32 LCD panel combos is the way that it actually interfaces with this LCD panel so there are a range of ways to interface an LCD panel with your microcontroller and an SPI is a very common method where your esp32 talks to the LCD controller chip using a Serial Communications protocol and commands and pixel data are sent over a simple three wire interface and you're able to create a very acceptable video output on smaller resolution LCD panels but the downside of this serial channel is that it is is slow and it does transfer single bits of data at each clock cycle on that bus so this method of course can restrict the resolution of the panel that you can sensibly control with a microcontroller now the RGB interface used in this panel has a 16bit parallel datab bus Which is the main reason why we don't have so many IO connections left over from our esp32 uh especially when you also consider that you're going to need a few clock lines and control lines to control the um LCD so with the driver chip using the standard 16bit pixel color data we therefore send two bytes or one complete pixel of information per clock cycle on the bus now the driver chip allows us to display graphics on the screen using the standard range of primitive drawing commands such as pixels lines boxes and and so on or of course we can send the display data over as a screen air data dump which will allows us to fill in an area on the LCD panel in one block now to do this we can use frame buffers in our code and then use dma channels to perform the actual sending of the data over the interface and all of this then adds up to give us a very streamlined system for getting the display data from the esp32 onto the LCD panel so if we run the interface add its maximum stable frequency of 50 15 MHz this actually gives us around about a frame rate of 35 frames per second at least this is the theoretical frame rate that our 15 MHz bus should give us and of course um that that doesn't allow for various sort of timing and Control Data being sent one of the problems sort of with this interface though is that this RGB interface isn't supported by all of the LCD driver libraries that we would normally use in our our doino and and um esp32 based projects so in this video I'm actually going to be using a library called the Lan Library which is actually the one that's suggested by the elro sample software so the sample software that you get with the screen be downloaded from the elro website and it includes a number of examples for how to drive the screen the speaker the SD card the touchcreen and various other bits of the hardware now now to get the driver um to work we do need to set up a few class objects that Implement parts of the RGB interface so again this is all detailed in both the elro samples and the driver Library code uh and I do admit I did have to do a bit of um work between those two um as um both seem to contain some bits that we needed to do um but not the full picture for this particular screen but again all of my code code I will make available to you so if you do um decide to get hold of one of these um you should get um my full driver um code that will let you get up and running very quickly but I am going to briefly go through the setup here um but as I say um go go through to that um Library uh and also then um do make sure you look visit the bytes and bits. co.uk website and look at the project page for this particular project um for more information out there so the the actal driver setup then is a bit more involved for this RGB interface but once you've got it going it's actually identical then to use the driver for our various projects so first of course we have to import the actual library and again you can see on this particular example code here we're importing our library and then a couple of extra objects that we're going to be using we then need to create our own class that's going to inherit from the generic lgf X device class and this lets us build up our LCD panel model um that's specific then to um this particular device so you can see here that our code we are creating a new class which inherits from the lgf X device class and inside that we're going to embed then a a bus instance a panel instance and a light instance so in our class Constructor function there then we actually have to initialize these objects so you can see here that the panel object then models the actual LCD panel itself along with some of its parameters such as the width and height we then need to set up a bus class and this sets up the hardware interface between the esp32 and the panel itself and you can see here that we are defining a range of pins to drive the various lines on our RGB data bus and you can see here the data lines and the control lines coming through and we also then of course do need to specify what speed we want to run this bus up uh so again I'm I'm running it here at the full 15 mahz finally then we have a light class and this allows us to control the brightness of the backlight on the LCD panel so as you can see the the bus and the light objects are actually embedded inside the panel object and that's then set as the main panel in the library code so that we can now just simply use the main class methods and the um class itself then will use our definition of our LCD panel model to actually send the correct signals out to drive our display so after the setup code then um we should now be able to draw on our LCD panel so in this very first uh test SC all we're doing here is we're getting the code to fill the screen with a solid color color and then pause before changing color and this is just to show that our actual screen is well basically that we're able to talk to it and get it displaying some information so in this next um piece of code we're again using this LCD fill screen method to fill the screen with a random color but now um we're going to start looking at the performance of the screen so we're going to time how long it takes for that particular full screen function to complete so so this method will send a full screen of pixel data to the panel as a single block right command so it should actually give us our maximum full screen frame update rate um at this particular bus speed so as you can see from the code uh running this task we've got it to display how long it takes there and and this value of course is in microsc so it's taking us about 33,000 micros seconds or or or 33 milliseconds to complete that fill screen uh function uh which pretty much gives us our 30 frames per second at this maximum data rate so this means that we should be able to animate our display by completely blanking our screen and then redrawing all of our screen objects rather than having to draw a screen object rub it out redraw the new place and and so on so let's try and add some animation and see if we can actually make that work so in this sketch we're going to be bouncing a number of boxes around the screen so we're going to be clearing the display between each frame update so the basic algorithm then is to update the position of the boxes then once we've got everything ready to um render we're going to clear the screen render the boxes and then loop back around again so if we if you show this working then as you can see this does actually work and we do maintain a great frame rate so we're getting pretty much our our standard 30 uh frames per second but with all of these screen objects being drawn in real time we are getting some strange timing effects happening here where areas off our screen are starting to disappear um and so on um now I the the screen is obviously being updated as the code suggests but I think this um strange um effect is probably down to our eyes um and our persistance of vision um where we are catching areas of the LCD panel while they are in various states of update so sometimes we're catching it when it's our eyes catching when it's partway through clearing the screen so part of the screen is shown as blank and so on uh and so this display with it being continuously being changed with complete screen wipes um and again these screen wipes then are taking up most of the display time this is why we are seeing the image disappearing at that certain intervals so to get around this then um we actually need to keep the full frame so once we generate the full frame we actually need to keep that in view for a short time to let our eyes actually register that as a complete image so we can add a short delay after the actual frame update is complet complete and as you can see once we run this particular um version of the software we now do get a nice um correctly viewed and and not perfect but a reasonably stable display um but of course the downside here is that we are now adding in a delay in our frame R drawing cycle so we are artificially slowing down our frame rate and as you can see from the display we do still get the frame being built in our sort of 36 37 milliseconds but of course we're we're now delaying for about a tenth of a second afterwards um to stop the flicker effect so if you are creating a display that doesn't need to update quickly and you want just a very quick and easy way of actually getting your screen up and running then this uh screen blanking and then redrawing dials um can actually work quite well again if if you're happy with your data being updated at this sort of 10 frames per second or less and of course you are always going to get that slight flicker as we clear the screen and then start redrawing again but of course it is a usable technique so we do need to have a look at how we can improve this then and and the obvious um answer is to use something called a frame buffer so in this next step we're going to use a memory based frame buffer and this is where we keep a represent ation of the screen in our system memory we then do all of our rendering onto this uh memory representation and then we send all of that pixel data as a single update to the LCD panel so this should remove the flicker effect and this strange persistence Vision error that we're getting so the Lan Library actually has um all of this ready made for us so we have an lgf X Sprite class and that will do all of the hard work for us so so the class defines a block of screen memory that you can actually size to whatever screen dimensions you want and then that can be rendered anywhere on the screen using a single block right command so we can create a Sprite here that is actually a full screen size draw our next frame onto it and then display that so that it actually refreshes the whole panel and in this in this demo here that's exactly what we're doing so as you can see we now get a correctly animated display with a nice steady output without any of that flickering effect but if you look at the um speed at Texs or the time at Texs to generate a frame you can see that we've lost a bit of speed in handling the Sprite memory so the extra overhead then of translating the Sprite memory version uh putting that out then to the screen has taken our frame rate down to about 15 frames per second so so in fact we we've all we've practically doubled then the time it takes to actually generate a single frame but this methods method does allow us then to have complicated drawing routines and we won't have that building up in front of the user as each individual element is drawn we can actually do all of our rendering offscreen in our memory buffer and then just simply show the finished frame as one single screen update now this does give us a very usable technique for controlling our screen and I think this is pretty much what the lvgl uh control panel software is doing in in in sort of creating a frame buffer and then being able to render full screen updates um in that and you and as we saw with the demo there that does actually work very well and and probably if you looked at it it was giving us around about this 15 frames per second update time but we can try and optimize this a little bit further so if if we actually zoom in and take a closer look at a a small region of our screen uh if we actually look at these pixels that are changing we can actually see that the majority of the pixels on our screen are actually not changing between frames uh mostly they are are sort of Fairly static and only changing them with when sort of in this particular demo when one of the boxes passes across it there uh so this does mean that a lot of the screen data that we're sending across our RG GB interface for each of the frame updates is actually just wasted time so what we should be doing is looking for these pixel changes between frames and only sending those over to the screen and this way we actually may only have to send say 10% of the screen pixels over the RG inter RGB interface so that will greatly increase our frame rate now to do this um we actually need to do something called double buffering for our display and this will let us have one buffer that represents what's currently on the screen so in other words the last frame that was rendered and then one buffer which is where we're going to generate our new frame and then when it comes time to send the new frame out to the screen we can simply scan the differences between the old frame and the new frame doing that row by row and then sending over only the change pixels so in this code that I'm showing you here we have a new function called diff draw so in this code uh we're actually using two of the these lgf X Sprite objects and then we're alternating them so that they for one Cycle One becomes the current frame one becomes the new frame and then we swap them around for the next cycle so when it's time to update the display what we do here is we actually look at the pixel data for each Sprite going along each row of pixels from top to bottom if we find a a series of pixels which are the same we simply skip over them and do nothing but then as soon as we find that one of the pixels has changed between the old frame and the new frame we actually Mark the start position of that on the row we then continue along our row and until we find pixel data that then starts to match back up again and this then gives us a strip along the row of pixels which have all been altered between the frames and that's what we actually then send across to our LCD panel and then the process repeats itself so we we're now at a pixel which matches so we carry along until we find a pixel that doesn't match and then Mark that block and so on and we go across every row and across every column so if we run this bit of code and have a look at what we're getting you can see that we actually get a really nice looking display um same as before but the actual frame rate then um gets us back up to around about our 30 frames per second that we had initially um so um you can see there that we've made quite a big difference so um this particular difference routine here um to be honest it's it's very basic um it is part of the Len um examples code uh again I I have modified it slightly to make could work with our display um but I I have to be honest and I didn't actually write it all myself but as you can see it it it's a fairly basic idea of of what it's doing just simply finding change pixels and sending them across so this particular method as I said it's basic it does rely on there being uh not a lot of change between frames so it is just simply working on individual changed pixels so if we have lots of change ched pixels um and unchanged pixels on a particular line it will end up sending lots of very small strips of data and and if that starts to get a very complex display um it it can actually end up increasing our frame drawing time as it sort of sends little tiny blocks of data across rather than one big block um but as I say um for for most of the displays that you will you'll probably be working with especially if you're using control panels and even some lot of game code um you will find that most of the screen doesn't change between frames either it's just simply sort of background um images or it's blank screen or or whatever so so this um basic routine actually will give us a in in general a very good Improvement in performance so this then leads us on to the final demo so this is actually the um a demo taken from the Lan example page which actually sort of brings together all of these techniques so it's the bouncing circles demo so this code does use the double buffer display driver but it also starts then to make use of the Dual processors inside the esp32 to share the processing load off of modeling the balls and updating the screen so in this particular one each of the balls um is is being modeled correctly so the physics is being modeled correctly here with proper Collision detect ction and collision reactions between the various balls uh there's also of course you can see here a background B grid being drawn per fra per frame uh and that just adds some interest into the display so as you can see uh we do it does have a frame rate counter up in the top corner here and so as our first balls come onto the screen we're running at about 20 frames per second uh and this then starts to drop off as the load um the processing load to calculate the ball physics and models increases uh so the actual uh time to draw the screen doesn't particularly change but we are now loading up the processor in actually modeling our code uh but again I I'm really showing this here as an example of what actually can be achieved with our trusty little esp32 and then using this 16bit RGB interface on this elro display to actually give us um what I consider to be a pretty impressive piece of Hardware where we are getting a a good frame rate okay so it's not it's not your sort of Xbox type 60 frames per second but uh a good frame rate then for a full screen at our 800 by 480 pixels just from our esp32 so um again if you were just running this as a control panel or even using some games codes I think this display would cope fantastically well so um well that pretty much wraps it up for this video so I have been really impressed at the speed and quality of this 7-in display um and and how it actually opens up then our esp32 projects to being able to use this larger LCD unit again I haven't really looked at the touchs screen um but that is is fairly standard and just works as you would expect um and it gives us a display driver which allows us to run that full screen then at a very usable frame rate using some simple add driver software which has an interface which will most of us will be used to if we've used any of these LCD panels before so with it also being compatible then with this lvgl library that does open up a lot of other use cases uh where we can build some very very impressive uh professionall looking touch enabled user interfaces uh and I will be looking at that in more detail later on so uh keep an eye out for that video coming up so if if you have enjoyed this video do please click that like button and subscribe to channel for lots of other making coding and gaming projects I look forward to seeing you again in another video very soon and bye for now for more games programming Electronics projects and retro games please make sure you like this video subscribe to my YouTube channel and visit my [Music] website
Info
Channel: Bytes N Bits
Views: 7,666
Rating: undefined out of 5
Keywords: esp32, lcd driver, touchscreen
Id: HhNNu7Av7M4
Channel Id: undefined
Length: 27min 41sec (1661 seconds)
Published: Fri Feb 02 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.