MCUFRIEND_kbv Library for Uno 2.4, 2.8, 3.5, 3.6, 3.95 inch mcufriend Shields

We did not understand each other a little. In which file (name) I need to make the edits sent to you. Do I need to change anything in the sketch in order for my wiring to be applied?

Sorry you all wrote in the message, forgive my carelessness))))

You don't need to do anything. Just wire up your shield correctly i.e. official "Bobuino".

If you want to connect wires to random pins you must VERIFY the wiring first with LCD_ID_readreg.ino.
This means defining your custom wired pins as proper Arduino pins.

There is no point in going any further until you post a "good" output from LCD_ID_readreg.ino together with the your defines.

David.

Hallo David,

I have a 4inch TFT Touch Shield (https://www.waveshare.com/wiki/4inch_TFT_Touch_Shield) with an ILI9486 driver. I put the shield on an Red Board from SparkFun (SparkFun RedBoard - Programmed with Arduino - DEV-13975 - SparkFun Electronics). Then I installed the librarys MCUFRIEND_kbv and Adafruit_GFX like it was said in "mcufriend_how_to.txt". I started the example graphictest_kbv.ino, but the touchscreen stayed white or it flashed.

Like you suggested in some other topics I run diagnose_TFT_support.ino. There i got this response.

Diagnose whether this controller is supported
There are FAQs in extras/mcufriend_how_to.txt

tft.readID() finds: ID = 0x2828

MCUFRIEND_kbv version: 2.9.8


This ID is not supported
look up ID in extras/mcufriend_how_to.txt
you may need to edit MCUFRIEND_kbv.cpp
to enable support for this ID
e.g. #define SUPPORT_8347D

New controllers appear on Ebay often
If your ID is not supported
run LCD_ID_readreg.ino from examples/
Copy-Paste the output from the Serial Terminal
to a message in Displays topic on Arduino Forum
or to Issues on GitHub

Note that OPEN-SMART boards have diff pinout
Edit the pin defines in LCD_ID_readreg to match
Edit mcufiend_shield.h for USE_SPECIAL
Edit mcufiend_special.h for USE_OPENSMART_SHIELD_PINOUT

If I get it right my ID should not be ID = 0x2828, it should be:
ILI9486 320x480 ID=0x9486

So my question is, if and how I can work around this problem.

Go on. You can see from the schematic that it is a shift-register abortion from Waveshare.
They take a cheap 8080-16 Parallel display and connect it to shift registers.

This sounds like a good wheeze i.e. drive a parallel display with SPI.

In practice the shift registers slow it down. Especially when you compare it to the same ILI9486 controller using its native SPI interface.

Look at Bodmer's libraries. He supports some of the RPi shift-register abortions.

Oh. It is not possible to read from the shift-register abortion. So you can't even use a SPI read_ID program.

David.

So if I understand you right, I can not get a decent library working on this display?

There is a library available from waveshave (https://www.waveshare.com/wiki/File:4inch_TFT_Touch_Shield_Code.7z), but it has not so many tools and I find it complicated to work with.

Bodmer has excellent libraries for Expressif chips e.g. ESP8266, ESP32

Bodmer has written libraries for AVR and ARM boards. You will have to check for yourself.

I have only ever looked at Waveshare code for an SPI HX8347. It was crap.

I am sure that someone has written a driver for Adafruit_GFX style library. It would be trivial. I have no interest in these shift register displays.

David.

Good day, David! Thank you for your work. I managed to connect my display with your help. Everything is working. Thanks again!

Did you use the default BOBUINO pins and wiring ?
Or did you use the custom SPECIAL wiring that I wrote for you ?

It is a very BAD idea for MightyCore to produce three different wiring schemes.
If they emphasized board names like BOBUINO or MIXUINO punters could distinguish them.

David.

No, I did not use the standard Bobuino contacts.
Yes, I used a special wiring that you wrote for me.
The device is of my own design, it is a board for studying the work of the microcontroller, as well as for my particular tasks.

The structure includes a DS18B20 temperature sensor, a DS3231 real-time clock, a radio receiver on the RDA5807, an MPU6500 accelerometer, the display was specialized based on SED1520, and now ILI9341V is installed with your help. The MCU immediately stood at ATMEGA32L but had to switch to ATMEGA1284, there was an acute problem and lack of memory.
Now everything is OK.

Unfortunately, the speed of work for large-scale tasks with the display is extremely low, but enough for my device.
I can send you a scheme if you are interested to see))))

It is fairly easy to create a custom Arduino board. You provide a boards.txt entry and a variant/pins_arduino.h

From my point of view. I created a library for ready made shields to plug into commercially available boards with Arduino headers.

Yes, you can use different hardware with different wiring as a SPECIAL. But I don't encourage it.

Your wiring scheme should give you good graphics performance. If you think it is slow, I suggest you look at your software design e.g. only redraw the smallest areas that have changed.

David.

Hi David,

Thanks for your work in building this library!

I am building a home automation device using an UNO 3.5 inch LCD with AT Mega 2560 board. The LCD controller has ID = 0x6814, has touch and the resolution is 320x480 (it is 8-bit board). Using the special option and USE_MEGA_8BIT_PROTOSHIELD I wired LCD_D0-LCD_D7 to D22-D29 on the AT Mega board.

I am using a SD card that is wired to AT Mega to prins D50-D53 (hardware SPI). Using the example provided in this post,

https://forum.arduino.cc/index.php?topic=366304.1965 at post #1975

I am using routine showRAW to read raw files from SD card and show them on LCD. These are small raw files that are shown as icons on the screen.

Showing the images on the screen is a bit slow (laggy), I am wondering if there are ways to improve the speed and show the icons even faster on LCD.

If you are using USE_MEGA_8BIT_PROTOSHIELD it should work faster than a Uno.
And you can use the hardware SPI on 50-53 for fast SD performance.

Yes, you can display the RAW file faster.

If you have "small" icons they should display much faster because there are less pixels in a smaller image.

What size icons? I can estimate the time.

David.

david_prentice:
What size icons? I can estimate the time.

David.

The raw files that I am using are located here SD Card Images. These files 4-6k each, some are larger.

For example in one screen I am reading and showing on LCD the following raw files:
File name File size
4clock.raw 6k
4feeding.raw 6k
4sched.raw 6k
4sensors.raw 6k
4dosing.raw 6k
4screen.raw 6k
4ato.raw 6k
4lunar.raw 6k
4color.raw 6k
4graph.raw 6k

Also the reading of files from SD card is done using FULL_SPEED.

But I was thinking if further optimization could be done inside showRAW routine. Maybe doing some cleanup of resources.

Thanks,
Chris

The RAW images are 48 x 63. The Screen one is a little shorter.
I draw those 8 RAW images from SD on a Uno. It took 2.33 seconds which was painful.

I suspect that I could speed it up. You should be faster with your SPECIAL.

If you are only changing one image at a time the speed is not critical. 8 images is too SLOW.

I might do a few experiments.
Of course you could fit many of those 48x63 images in Flash memory instead of SD.

David.

Try this function:

const int RAWPIXELS = 128;
uint8_t buf[RAWPIXELS * 2];      // size in bytes

uint8_t showRAW(int x, int y, const char *nm, int w, int h)
{
    uint8_t first = 1;
    int32_t n = w * h;  //size of RAW image in pixels
    File inFile = SD.open(nm);
    if (inFile == NULL) return 1;    //can't open
    tft.setAddrWindow(x, y, x + w - 1, y + h - 1);
    while (n > 0) {
        int cnt = RAWPIXELS;
        if (n < cnt) cnt = n;
        n -= cnt;
        int avail = inFile.available();
        if (avail < cnt * 2) cnt = avail / 2;
        inFile.readBytes(buf, cnt * 2);
        tft.pushColors(buf, cnt, first);
        first = 0;
    }
    tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1);
    inFile.close();
    return 0;
}

On my Uno each image takes 0.293 sec from SD. But only 0.015 sec from PROGMEM.

David.

david_prentice:
On my Uno each image takes 0.293 sec from SD. But only 0.015 sec from PROGMEM.

David.

Thanks for your help. I tested the function and it is faster. I adapted a bit the code, it is just a routine that does not return any integer.

I was looking on the web for similar approaches to show RAW files and I found this one drawRAW. I was trying to adapt it but I was not that successful and then I check the thread and you have uploaded the new code.

Using the link above and comparing the code, I did some small changes in the routine and it works even faster. In the new coding I replaced the following lines as below:

//const int RAWPIXELS = 128;
   const int RAWPIXELS = 256;

//inFile.readBytes(buf, cnt * 2);
   inFile.read(buf, cnt * 2);

Try and implement the changes for UNO and let me know your opinion.

Not sure if from the link above, you would be able to improve more the speed. The logic is similar with your new coding.

Chris

I dug out my ProtoShield and a Mega2560.
0.0291s, 0.010s with RAWPIXELS=128, readBytes()
0.0097s, 0.010s with RAWPIXELS=128, read()
0.0093s, 0.010s with RAWPIXELS=256, read()
0.0093s, 0.010s with RAWPIXELS=512, read()

With a Uno:
0.0294s, 0.015s with RAWPIXELS=64, readBytes()
0.0102s, 0.015s with RAWPIXELS=64, read()
0.0294s, 0.015s with RAWPIXELS=128, readBytes()
0.0101s, 0.015s with RAWPIXELS=128, read()

There is not enough SRAM to try RAWPIXELS=256 on a Uno unless I change my test program.

There is still a massive overhead for the SD instead of PROGMEM. SD.h has to open the file, read sectors into its private buffer via SPI. Then copy from its private buffer to your buffer for pushColors()

read() is obviously more efficient than readBytes()
Increasing the size of buffer does not make much difference.

Yes, you can optimise the SD. e.g. use root directory, unfragmented files etc.

David.

david_prentice:
There is still a massive overhead for the SD instead of PROGMEM. SD.h has to open the file, read sectors into its private buffer via SPI.

David.

I did some tests and checked the difference when using different values for RAWPIXELS. I think I will go with the option 256.

I had some issues, at some point the code execution was freezing. Even a hard reset (power out and reconnecting again) would not show images on LCD. I thought it is the parameter RAWPIXELS but in the end turned to be a cold solder wire (CS pin on the SD card board). I am just testing the device for now and I only built a breadboard with wires going to different modules. After I repair the cold soldering, it looks like is working fine.

About using PROGMEM, I will see how it goes. For the moment the coding is using 52% of the flash memory. I still want to add coding for networking access, I will see if there is any space left alter.

Thanks for your help! Maybe you could include the routine/function in the standard library, just a suggestion.

Chris

I could add several hardware methods e.g. render Fonts or show .BMP format files.

However these Shields are designed for a Uno. The library would get too big.

I could reduce the size of the library by dropping ILI9320 style controllers. Or making a separate class.
The whole idea was to detect and run with multiple controllers.

I seriously advise using proper Shields with good soldered joints. The Arduino headers mate well electrically and mechanically.

Incidentally, you can calculate a theoretical "best" time for a 6kB RAW file on an SD.
Approx 15 Sector Reads. 8ms with SCK=8MHz. 10ms to render the image. Total = 18ms (compared to the 93ms that I reported in #2557)

You can see that there is a lot of scope for improving the SD time.
Yes, I could improve the 10ms "MCUFRIEND_kbv" time.

David.

I try 'button_simple.ino' and the display and buttons work.

I use:
MEGA 2560,
Elegoo 2.8" TFT LCD Shield (https://www.elegoo.com/product/elegoo-uno-r3-2-8-inches-tft-touch-screen/)
and
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <TouchScreen.h>

But there are one command I don't know what to do: on_btn.drawButton(false);
I think it has to inverse the colors, but nothing happens.

By the way: Is there a place to see all the commands and what they has to do?