-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
using TFT_eSPI library methods #508
Comments
readRect() reads from the TFT screen RAM built into the display so is not the function to use. However, the explanation for the error is that you are trying to copy an area of the screen image to the FLASH which has a pointer of type "const int" whereas the library function expects a normal "int" type RAM address pointer. drawBitmap() is also not the function to use, it draws a bitmap that is stored in an array of bytes and where a pixel is represented by 1 bit. There are a number of ways of achieving what you want to do. The way I would do what you wish is:
The library will crop the FLASH image as needed to write a portion of the master bitmap to the Sprite. So for example if you have a 20x20 pixel bitmap in FLASH in an array called master[]: This plots the master bitmap at position -10, 10 relative to the top left corner of the sprite "spr". Thus only the bottom right 10x10 area actually plots to the sprite because most of the master image is outside of the sprite area. Try to create a simple example based on the above, if it does not work then post yopur example and I will have a look. Things should get easier when I finish a user manual for the library but I have a long "To Do" list at them moment! |
Thank you for your comment Bodmer.
This drawing loop needs to be modified more as i need to create couple of instances of the sprites, each in different location on the display and each with its own CURRENT_ROW number meaning its own part of the master array displayed. |
You are on the right track. Just use 1 small sprite for all digits. That should be plenty fast enough. With a image 1 digit wide and 11 high you could avoid using sprites and use a pointer with pushImage. However using a sprite would allow row by row shading using the alphaBlend() function. See the alphablend example in the smooth font example menu list. |
So i wrote a piece of code as per previous suggestions and it is really fast - delay(REFRESH_SPEED) isreally needed! :) I used one small sprite only. It's enough for my needs. As for alphaBlending() - i uploaded the example you were talking about. Work really nice. I tried to understand the code and i'm confused. I don't know where should i use
? i can't find the way to read pixel color in sprite:/ Could you point me in good direction? Thank you:) |
uint16_t pixelColor = spr.readPixel(x,y); Where spr is the sprite instance. |
Bodmer - i analysed your alphaBlend example and i wrote a piece of code which is working. I can see shadows overlayed on the sprite content.
Here's the piece of code for shadowing:
alpha_table[] is one dimensional array i use to store alpha levels for each row. Any clue how to speed things us? Rednering the lower 5 digits is even harder as the lower counted has to display the upper counter value divided by the number. This number is different each time i power up the device (i'm using random() function with 'analog read seed' trick). So or the lower counter the offsets needed to pull data from PROGMEM array are calculated using floating point math and converted to integers. I expect all these calculations are very fast as esp8266 is 32 bit processor and 160MHz is not ATmega328... [code] Display driver = 9341 TFT_CS = D2 (GPIO 4) Display SPI frequency = %.1f MHz So i know i successfully set CPU to 160MHz. The goal is make one transition (i.e. from digit showing 3 to 4) on the counter (arranged like this XXX,YY ) the X-digit every, say 2 seconds. This requires 400*400=16000 (!) updated of sprites on the previous digits YY (i hope you get my point:)) As already mentioned each sprite (36x40 pixels) update requires getting from PROGMEM and applying alpha blending... Yes i can speed up things by increasing offset increments when pushing data from PROGMEM array to sprite but by doing it i'm loosing the impression of the fluent motion of the digits on the TFT. |
You are updating the digits a LOT more than I expected so it will be slow. For 10 digits based on a 40MHz SPI clock using screen write time only you could roll all digits 4x a second. But this will slow down due to FLASH access and shading a bit. So to roll digit X would take 40s. If you want to emulate the old style odometer then only the least significant digit needs to scroll, all other digits only "snap" to the new value (worst case being x99,99 rollover) when the least significant digit rolls over. So those digits that snap to the next position could have a much coarser scroll rate as the eye has persistence and it happens fast. An option for the digits that snap to the next position is to show a "blurred" digit" and only animate the fast few steps of a rapid roll-over digit. I am sure that doing it this way will be plenty fast enough. spr.drawPixel(x,y,color) should work (see example) but will not be much faster than fillRect. Without seeing you code and looking for any inefficiency then it is difficult to comment further. |
You my be interested in this, which has bugs but does run. It ran originally on a humble Arduino Mega, so you will see compromises had to be made on how it works. Digit roll delay and ripple delay can be controlled by the #define settings at the start of the sketch. The display was 126 x 160 so the odometer uses an anti aliased bitmap to improve perceived resolution. It may give you some ideas. Bear in mind this is an early attempt to help with someone elses code, |
Thank you for the files - i'll analyse this example. |
When i get home next week i'll check the SPI frequency on my oscilloscope. How can i tell now what is my SPI freq? As you can see, the 'Read_User_Setup.ino' output i saying nothing about SPI speed. Why there is no data? |
This is the normal output from an ESP8266 for the default setup:
Check you have the latest ESP8266 board support package loaded (latest is 2.6.3). It looks like you have a very old version loaded with a bug in the printf function. The sketch uses a perfectly legal printf line that works fine on my ESP8266 and ESP32. You could change this to use the simper Serial.print() e.g:
Incidentally: If you use SPIFFS loader in the IDE tools menu then you need to upgrade it with 2.6.3 as the SPIFFS format has changed and is not compatible with newly compiled sketches. |
Actually i tried SPIFFS and installed SPIFFS loader. However there is something wrong with my setup as i can't use any of your TFT_eFEX library examples. Tons of errors:/ I need to read how to check what esp8266 package i have. Probably i'll have to remove everything and install once again. I'm confused as some of the libraries are installed in user/documents/arduino/lib folder (if i remember right - got no access to my PC at the moment) and some stuff is installed in different location, like appdata/local..... (pretty long path). |
Loading board package via the IDE Board Manager menu option is yhe easiest method. |
⸮ Display driver = 9341 TFT_CS = D2 (GPIO 4) Display SPI frequency = 27.00 I changed the way the frequency was displayed as per your advice. It works:) SPI speed is 27 MHz:/ Found frequency definition in User_Setup.h, changed the right things and it is now 40 MHz:) Loaded the counter sketch @ 40 MHz - working, then changed to 80 MHz - working as well (cheap 320x240 TFT 2.2" from Aliexpress). However the rolling speed is EXACTLY the same - so the esp8266 is the bottle neck. Now i know i have to look at the sketch itself and library in search of optimisation. https://github.com/esp8266/Arduino/releases/download/2.3.0/package_esp8266com_index.json So version 2.3.0:/ |
if you are running the example I provided the the rolling speed is controlled by the sketch setting at line 36 at 10ms per pixel line. this allows the sketch to run at the same speed on different processors. Try setting to 0. The 80MHz clock will almost certainly show display corruption in some screem intensive sketches, 40MHz seems totally reliable on my displays. |
Dear Bodmer,
i'm playing tith your fantastic library. Thank you for it!
I have a 565 bitmap stored in flash as PROGMEM 16 bit array.
When i use "pushImage" method the image stored in array is displayed on the screen with no problems. Then i wanted to use the method i found in TFT_eSPI.h file:
void readRect(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
so i created the buffer 10x10 long and tried to read 10x10 pixels rect from my 565 array:
uint16_t my_buffer[100] = readRect(0,0,10,10,*my_array);
and i got:
I'm desperately trying to learn how to pull part of the 565 BMP array stored in PROGMEM and push it on the display. The reason for that is i need to store one big BMP flie in form of PROGMEM array (not necessarely, it can be just BMP file in SPIFFS or on SD card however i think doing it on PROGMEM array will be the fastest way) and displaying only small part of it by using pointers in my sketch - i can achieve some sort of animation by doing this. To be even faster i need to use sprites approach and define bigger sprite and smeller sprite then read part of an array for fir smaller sprite and place it in the bigger one. By doing this i could put couple of smaller sprites (meaning couple of big array fragments) into the bigger sprite in a very fast manner and the just pushSprite on the display. But how to do it?:(
When reading your library files i can see some usefull tools that i think may help to do it. However i do not understand why i couldn't successfuly use 'readRect'.
Or how to use:
void pushRect(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
What i understand *data should be my array. But again - what if i need to push only a part of *data?
I also went to TFT_eSPI.cpp file and found this:
Maybe this method can be modified do pass more arguments to drawBitmap. Arguments like: X,Y position in bitmap array and another width W and height H this time not the bitmap array size but small rectangle W and H big pulled from the array.
Please help me to sort it out. I've spent so many hours trying. Programming i my hobby however i'm not professional in it:(
The text was updated successfully, but these errors were encountered: