
7-inch TFT LCD backlight control
Introduction
I am currently working on a project on an Arduino using a TFT display. Recently, I wanted to add a seemingly simple function to it - the brightness adjustment function. I found the necessary method in the documentation for the library for working with the TFT display (UTFT Library): I
setBrightness(br);
wrote all the code, did everything as it should. I decided to check, but, to my surprise, nothing happened. I started to understand. Two days later, I noticed a small note on the method:
"This function is currently only supported on CPLD-based displays."
That is, this library does not support my display. But I found out that the display itself supports brightness adjustment. For a very long time I searched the Internet for configuration methods, but did not find it, so I decided to achieve my goal myself, no matter what, and I succeeded. And so I decided to share with those who may find this useful.
What do we need?
- As a basis, I used the Frearduino ADK v.2.2 based on the ATmega2560 processor
- TFT LCD Mega Shield v.2.2
- The display itself is a 7 "TFT LCD SSD1963 (here you will find its description, as well as the necessary documentation )
- UTFT Library - a universal library for working with TFT displays (You can find the library itself, as well as the documentation here )
- Soldering iron
We will deal with iron
Opening the display circuit, you can see that the mp3032 converter has three inputs: LED-A, PWM, 5V. Initially, PWM is inactive. This input is not used at all. The backlight is controlled by LED-A.

If you look at the back of the display, you can find the area labeled as
"Backlight control"
. Here we will find these very inputs. To control the backlight by the PWM method, it is necessary to ensure that everything is the other way around: LED-A is inactive, PWM is active. To do this, you will have to re-solder the jumper. Here is a photo of what should happen:
Software part
Since our library cannot give what we need, we will write the desired function ourselves. To do this, open the documentation for the controller that controls the display (SSD1963). SSD1963 is controlled using special commands that are transmitted from Arduino through special outputs, which are described in the documentation:

The control is carried out as follows: Arduino outputs via RS (D / C in the table) 0 if we are going to transmit a command, 1 if data. After transmitting the command, RS switches to 1, and then the necessary parameters are transmitted. All commands and parameters are transmitted through the outputs D0-D7. If you have an ATmega2560, then all these eight outputs are combined in port C.
So, for a start, we will write a function for transmitting data on the bus. For ease of use, I will write directly in UTFT.h:
void Lcd_Writ_Bus(uint8_t bla)
{
digitalWrite(WR,LOW); //Настраиваем SSD1963 на чтение
digitalWrite(CS, LOW);
PORTC = bla; //Передаем на шину данные в виде одного байта
digitalWrite(CS,HIGH);
digitalWrite(WR,HIGH);
}
It is also worth paying attention to the names of methods, since functions with the same names can already be found in the library.
Add two functions to output commands and data:
void Lcd_Write_Com(uint8_t data)
{
digitalWrite(RS,LOW); //Переключаем RS в режим чтения команды, то есть 0
Lcd_Writ_Bus(data);
}
void Lcd_Write_Data(uint8_t data)
{
digitalWrite(RS,HIGH); //Переключаем RS в режим чтения данных, то есть 1
Lcd_Writ_Bus(data);
}
Now the backlight setting itself. To learn how to do all this, open the documentation and look for a command to configure PWM.
Note:
PWM can be controlled using DBC - a dynamic brightness control system, but for simplicity I did not use it. If you want, you can find the necessary information in the same documentation.So, here is what we need:

That is, first we must transmit the “0xBE” command, and then, as 3 parameters, pass the signal frequency, the duration of the duty cycle, and also the third parameter, which determines whether DBC is on or not (0x01 - off, 0x09 - on) .
To adjust the brightness itself, you only need to change the frequency of the duty cycle. Since we transmit data as a single byte, the values of the cycle can be from 0 to 255. I decided to determine 9 levels of brightness (from 0 to 8). Therefore, all 256 values must be divided into 9 steps. But it is also worth paying attention to the fact that if the steps are equal, then the brightness will not change as smoothly as we would like. That is, already, for example, at the 4th stage, the brightness will be almost maximum, and from the 4th to the 8th stage it will change almost imperceptibly. Given this, I decided to use a geometric progression with denominator 2. That is, the brightness will be calculated by the following formula:
(2 ^ lvl) - 1
, where lvl is the brightness level from 0 to 8. Note that since the values start from zero, you must subtract one. Of course, you can choose the steps and their values yourself, but I gave here such a fairly simple example. Now the code itself:void setBright(byte lvl)
{
byte brightness(1);
for (byte i(1); i <= lvl; i++) //Возведение в степень
brightness *= 2;
Lcd_Write_Com(0xBE); //Вывод команды
Lcd_Write_Data(0x01); //Ставим частоту 760Гц
Lcd_Write_Data(brightness-1); //Выводим длину рабочего цикла
Lcd_Write_Data(0x01); //Отключаем DBC
}
Now you can use
UTFT.setBright(byte lvl);