AZ-Touch Mod als analoge Uhr mit Anzeige für Sonnenauf und -untergang

Before I raised larger projects, in my case a fully automatic aquarium control with some features, I try to make subprojects from making them and later programming the big whole. This has many advantages as you can test and optimize code before, before you start with the big one. This project was created because I first wanted to query the data for sunrise and destruction, as well as the time zone. With these little data, the idea came to realize an analog clock on the AZ-Touch wall mod, which is also used in parts then in the aquarium control. Especially the AZ-Touch wall mod is perfect for such tasks with some modifications.

Some lines of code I have already used in other projects and can go through an optimization loop here. So that the clock is not the only one, the daily updated time of sunrise and disc is visualized on the display. So that we not only display simple texts, monochrome images should be used on the display. How to do and how to convert e.g. Bitmaps converts to the ESP32 NODEMCU readable data, today the topic will be from the blog post.

The hardware and software for this blog

So that you can rebuild this blog, you need the components from Table 1:

number Component
1 ESP32 NODEMCU Module WLAN WIFI Development Board with CP2102 (Successor Model for ESP8266)
1 AZ-Touch Mod wall housing set with 2.4 inch Touch screen for ESP8266 and ESP 32
1 AZ-Touch Mod wall housing set with 2.8 inch touchscreen for ESP8266 and ESP32
1 12V power supply for power supply

Table 1: Components for the analog clock

You need software:

In addition, you need access to, with the free basic version for this project completely sufficient.

The program LCD Image Converter

When programs are developed, you always have to make sure that the outputs on the display everyone understands. In the case of diagnostic expenditure English or the mother tongue ranges, but in graphical user interfaces for the end user, short GUI, either everything must be translated into any language, or you use unique pictograms.

For my analog clock I did not want to write everything, especially by the limited space, but pictograms for the sunrise and destruction used, see Figure 1.


Figure 1: Bitmaps for analog clock

The problem is, the pictures I have created with Paint quickly as a bitmap, extension BMP, but this can not read the AZ-Touch or the ESP32 NODEMCU. Since these are simple pictograms, a function could now be written in the source code, which draws with character functions, circles, lines, etc., this on the display, but that is far too much mathematics and a picture can be quickly in readable machine code being transformed.

Image converter

Figure 2: The program LCD Image Converter

My choice fell to the program LCD Image Converter, see Figure 2, which is both a very simple character and font editor, but also the ability to convert images into machine code. The latter I will show you for monochrome pictures, but can also be used for colored images.

First, the image to be converted must be selected via File -> Open, see Figure 3.

Open bitmap

Figure 3: Loading a picture file

After loading the picture, you have two interesting changes in the surface. First, see the selected image in the middle and bottom right the image size, here 64 x 64 pixels.

Next, we open via Options -> Conversion ... the conversion interface, see Figure 4.

Conversion interface

Figure 4: Open conversion interface

So that the image is displayed correctly on the display, in our case a monochrome picture, the settings still need to be adjusted. First, the profile will Monochrome provided and in the tab "Scanning" TOP TO BUTTOM, See Figure 5.

Update Scanning Settings

Figure 5: Customize Scanning Settings

This causes the machine code to have the correct orientation from top to bottom. Next, the Preprocessing tab is changed, see Figure 6.

Update Processing Settings

Figure 6: Customize Preprocessing Settings

Here is the option Inverse Activated, otherwise the picture will not be colored in the selected color, but the background from the image on the display. Now the button Show Preview Press and the result is displayed in the next window, see Figure 7.


Figure 7: Preview of the picture and machine code

Interesting here is the right part in the new window Previewwhere the many hex data are displayed. This is now the image data in machine code, which is to be displayed later on the AZ-Touch. Copy the entire content and create a new header file, e.g. bitmap.h.

First, insert the following lines at the beginning of the file, see code 1.


 #Ifndef _bitmap_h
 #define _bitmap_h
 #Ifdef arduino_arch_AVR
Code 1: Defines for the bitmap.h

The first 3 lines cause the header file to be properly stored in the code. The other lines cause the PGMSpace.h to be charged correctly for ESP microcontrollers or Arduino-microcontrollers.

So later in the source code the monochrome picture sunrise If the corresponding variable must be applied, see code 2.

 contam unsigned Char sunrise[] Progmem = {
Code 2: Create array for monochrome image

Now add the copied content from the LCD Image Converter to the array, see code 3, which reproduces the shortened content of the newly created header file.

 #Ifndef _bitmap_h
 #define _bitmap_h
 #Ifdef arduino_arch_AVR
 // icon for Sunset 64 * 64 pixels
 contam unsigned Char sunrise[] Progmem = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Code 3: Machine Code for the Array Sunrise, greatly shortened

The same procedure with the array, will now be performed for all other graphics. At the end, depending on the number of graphics, you have a header file with many lines. For the two graphics in this project, almost 150 lines of code fall.

This completes the preparations for the analog clock.

The analog clock on the AZ touch

Overall, this smaller project comprises just under 500 lines of code. The code is ready for you as usual on my Github repository and is equipped with many comments, which is also a reason for the many lines. However, some functions and sections should be explained in more detail so you understand how the code works.

In the very beginning in the source code, the definite for the colors of the clock are determined, see code 4.

 / * --- Some Color Definitions, Feel Free to Change --- * /
 #define face tft_orange
 #define numeric_point tft_black
 #define background tft_white
 #define hourcolor tft_red
 #define minutecolor tft_black

Code 4: Defines for the colors of the clock

Here you can swap the color according to your mood and mood, pay attention to the definite in the file Tft_espi.h In the library of the same name. This simplifies the exchange of colors immensely.

According to the includes of the required libraries, one of the most important parts for the project, setting the WLAN parameters and the required API data for, see code 5.

 contam Char * SSID       = "";       // Change SSID from Network
 contam Char * password   = "";  // CHANGE PASSWORD FROM NETWORK
 / * --- Needed variables for --- * /
 contam String apical = ""; // Change API-Key from
 contam String location = "";                   // Change Location for

Code 5: WLAN access and API information

At this point please insert the required data to connect later to the ESP32 NODEMCU with the Internet and can also download the weather data from Here you should have registered with

The setup () function activates the TFT, the WLAN with the stored data, synchronizes the time from the ESP32 NODEMCU with the NTP server and records the basic graphics on the display. To see which part of the setup () function is currently being processed, there is a kind of status output on the display, see Figure 8.

AZ-Touch Pre Output

Figure 8: Status from the start of the program

You can see that immediately, where the program may not progress and you can not see the analog clock. This helps immensely if the AZ-Touch is not connected to the PC. If everything is successfully completed, the clock is displayed with all the data after 5 seconds, see Figure 9.

AZ-Touch program

Figure 9: AZ-Touch with all data

As you will quickly see, the loop () function does not happen much in the loop () function, see code 6. Only four required functions are called and data sent to the serial monitor.

 * =================================================================
 * RETURNS: Void
 * Description: Main Loop to Let Program Work
 * =================================================================
 void loop()
   // serial output
   IF(pprevsecond != second() || Bfirstrun)
     Serial.print(DaySofttheweek[weekday()] + "., ");
     Serial.print(GetDigits(hour()) );
     Serial.print(GetDigits(minute()) );
     Serial.Println(GetDigits(second()) );
     pprevsecond = second();
     Bfirstrun = false;

Code 6: The loop () function of the project

But right here lies the advantage! The loop () function is not crowded and you can quickly exchange code. The functions have unique names, which is why they will quickly find out what function is what work step. However, I would like to respond to all functions of the loop () function.

Drawtime () causes the pointer of the clock to be redeveloped at each hour or minute change. When you view the function in the source code, the old hands are first overwritten with the background color from the display and then the new pointer is drawn. Here is the most mathematics for the pointers, since according to the time the pointers must be arranged at the correct angle. Since not each pixel is not drawn by us in the source code, but is defined by a line with a start and end point, we must calculate the endpoint of the pointers via the angle functions Sinus and Cosinus, starting from the clock center, the end point of the pointers. If this happened, the pointer is drawn to the clock using Drawline ().

Do not shy away to look at the Drawtime () function and the functions invoked in it, even if the end result works.

Immediately after DraWTime () follows the function UpdateopenweathermapData (), which, as the name implies, asks the current data from This happens in three main steps:

  1. Prepare and send request for the client
  2. Waiting for answer and required data, here the JSON format, prepared
  3. Prepare data from JSON format and save important data

This part of the code is a bit more complex because an HTTPS telegram is prepared for, here via the function requestData () and the answer must be formatted correctly. For this purpose, unnecessary data should be eliminated at the response telegram. Afterwards, UpdateopenWeathermapData () converts the received JSON string to the correct class and extracts the time zone data, sunrise and destruction. These new data is compared with the existing ones and initiated an update of the GUI or the time zone when changing. Since our required data does not change secondary, the work described above will only be carried out every 30 minutes.

So that our analog clock always displays the correct time, the internal clock is synchronized by the ESP32 NODEMCU with the NTP server every 15 minutes with the ESP32 function every 15 minutes, so our watch should always run seconds.

Most recently, the update debris unset () function occurs, which is probably the simplest in contrast to the previous functions. If the updateopenweathermapData () function has a change of sunrise and destruction, the old time is deleted on the display and the new time is entered.

It's so easy that everything is likely to sound in theory, just the first three functions in the loop () function are quite complex nature. On the one hand, because there is a lot of mathematics used, on the other hand, because the procurement of the data of is not trivial. A great help in procuring the data was the good and detailed API document from And the fact that I have previously created a similar requestData () function for another project. This should be almost universally usable, if you want to request data for another project from another page. Since I'm not a friend of HTTP transmissions, the requestData () function uses the safer HTTPS variant, which can also be used for HTTP.

The complete source code you will find here

Preparation for the project

Before you compile the program and then frustrated that this fails. In the project directory you will find a file with the name User_setup.h. Please replace it in the order C: \ user \Your name\ Documents \ arduino \ libraries \ tft_espi, see Figure 10. It makes sense to rename the file there with the same name, z, b. in User_setup_old.h.

User setup

Figure 10: User_setup.h overwrite

For the new AZ-Touch mods, it does not matter if you used the 2.4 "or 2.8" variant. Since both have the same resolution, the source code can be used directly for both variants without further adjustments.

What still remains to do? Now as described above, you must override the data for WLAN and with your data. Furthermore, you can change colors at will or use your own pictograms for the clock after the instructions. For those of you who have fun mathematics, you can miss the pointers other forms, creativity are not limited. Since there is still a bit of space on the display, would even be conceivable to display the date and day of the week at the clock. This information is already available in the source code, only need to be visualized at the correct position in the display.

I hope you will enjoy a lot of pleasure with the clock and the interest in simple or more complex IoT projects is awakened.

Further projects for AZ-Delivery from me, see

DisplaysProjects for beginners




Habe den Fehler gefunden


============= Function: RequestData Returns: String Description: Request to to get latest data =============
String RequestData()
WiFiClientSecure client;
client.setInsecure(); <—————- diese Zeile fehlt im Programm. Ohne kann er keinen client.connect(clientAdress,443 ) aufbauen und es kommt zu “Failed to connect”
Jörn Weise

Jörn Weise

Hallo flai,
Vielen Dank für die Blumen. Wie bereits im Blog beschrieben, ist das nur ein Teilprojekt die etwas größeres, aber wie immer sollte man größere Projekte immer in kleinere Zwischenschritte unterteilen und manchmal kommt dabei auch etwas neues mit kleinen Änderungen raus.


Willi Wegemann

Willi Wegemann

bekomme Fehler "cannot declare variable ‘ntpUPD’ tobe of abstract type ‘WiFiUPD’ " beim compilieren.
Wer weiss Rat ?
p.s. habe #include Time statt TimLib . Konnte TimeLib nicht finden. Server streikt




Habe das problem das ich keine Daten von rein bekomme.
wenn ich die Adresse direkt aufrufe geht es

Wifi connecting…
Wifi connected, IP address:
Failed to connect
Received data:
Failed to connect
Received data:
Update time: SUCCESS

Kann wer helfen ?

Danke Rudolf

Wolfgang Specht

Wolfgang Specht

ich habe ein Problem bei der Herstellung der WiFi Verbindung.
Es kommt die Meldung Failied to connect.
Die Hardware läuft mit fehlerfrei mit anderen Prorammen.


Andreas Wolter

Andreas Wolter

Der Link zu den vollständigen Quellcodes wurde aktiviert. Wir entschuldigen uns für die Verspätung.



Eine sehr schöne und inspirative Umsetzung. Vielen Dank für die Bereitstellung des Codes und die ausführlichen Erläuterungen.

Wolfgang Specht

Wolfgang Specht

Hallo ,
wo finde ich den kompletten Quellcode. Der Link im Text funktioniert nicht(ist Schwarz hinterlegt).
Bitte um Info




Hallo Forum,

bitte bei “Den kompletten Quellcode finden Sie hier” Link einfügen.

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN