🔧 Build Your Smart Home Dreams!
The AZDelivery 3 x AZ-Touch MOD DIY Smart Home Kit features a 2.8 inch TFT LCD touchscreen module with a high-resolution display, a compact wall-mount casing, and a versatile power input range. It includes an E-Book for easy setup and project guidance, making it an ideal choice for tech-savvy DIY enthusiasts looking to enhance their smart home experience.
J**N
It’s a kit, expect to build it, expect to learn from it
Great little touchscreen. Wanted to build a touch screen smart bulb switch panel for all my smart bulbs in my house, interfacing through homeassistant. It took lots of Googling plus a really helpful review on here showing correct pin out configurations. I built this using the esp32 nodemcu module from AZ delivery. Here is my config for esphome, I hope it helps someone:esphome: name: tscontrolesp32: board: esp32dev framework: type: arduino# Enable logginglogger:# Enable Home Assistant APIapi:ota: password: ####wifi: ssid: !secret wifi_ssid password: !secret wifi_password manual_ip: static_ip: ###.###.###.### subnet: 255.255.255.0 dns1: ###.###.###.### #dns2: #.#.#.# gateway: ###.###.###.### # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: ###### password: ########captive_portal:spi: clk_pin: GPIO18 mosi_pin: GPIO23 miso_pin: GPIO19xpt2046: id: touchscreen cs_pin: GPIO14 irq_pin: GPIO27 update_interval: 50ms report_interval: 1s threshold: 400 dimension_x: 240 dimension_y: 320 calibration_x_min: 3860 calibration_x_max: 280 calibration_y_min: 340 calibration_y_max: 3860 swap_x_y: Falseoutput: # backlight - platform: ledc pin: 15 id: gpio_15_backlight_pwm inverted: truelight: # backlight for HA - platform: monochromatic output: gpio_15_backlight_pwm name: "ILI9341 Display Backlight" id: back_light restore_mode: ALWAYS_OFFtext_sensor: - platform: homeassistant id: mblightgroup entity_id: light.bedside_lights - platform: homeassistant id: emmabedside entity_id: light.smart_lighting_tunable_white_and_color_3 - platform: homeassistant id: jonbedside entity_id: light.smart_lighting_tunable_white_and_color_2_2 - platform: homeassistant id: kitchenlights entity_id: light.kitchen_lights - platform: homeassistant id: kitchenlight1 entity_id: light.smart_bulb_2 - platform: homeassistant id: kitchenlight2 entity_id: light.smart_bulb_3 - platform: homeassistant id: kitchenlight3 entity_id: light.smart_bulb_4 - platform: homeassistant id: livingroomlights entity_id: light.living_room_lights - platform: homeassistant id: livingroomlight1 entity_id: light.mk_smart_led_bulb_rgbpro - platform: homeassistant id: livingroomlight2 entity_id: light.mk_smart_led_bulb_rgbpro_2 - platform: homeassistant id: porchlight entity_id: light.smart_bulb - platform: homeassistant id: toiletlight entity_id: light.smart_lighting_tunable_white_and_color - platform: homeassistant id: landinglight entity_id: light.smart_lighting_tunable_white_and_color_3_2 - platform: homeassistant id: hallandlandinglights entity_id: light.hall_and_landing_lights - platform: homeassistant id: halllight entity_id: light.smart_lighting_tunable_white_and_color_4 - platform: homeassistant id: girlslight entity_id: light.smart_lighting_tunable_white_and_color_2display: - platform: ili9341 model: TFT 2.4 id: touch_display cs_pin: GPIO5 dc_pin: GPIO4 reset_pin: GPIO22 rotation: 180 pages: - id: page1 lambda: |- it.fill(Color::WHITE); if (id(mblightgroup).state == "on") // KEY1 { it.image(27, 10, id(bulb_on)); } // Bulb on Icon else { it.image(27, 10, id(bulb_off)); } // Bulb off Icon it.print(5, 70, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Master Bedroom"); if (id(kitchenlights).state == "on") // KEY2 { it.image(147, 10, id(bulb_on)); } // Bulb on Icon else { it.image(147, 10, id(bulb_off)); } // Bulb off Icon it.print(135, 70, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Kitchen Lights"); if (id(livingroomlights).state == "on") // KEY3 { it.image(27, 90, id(bulb_on)); } // Bulb on Icon else { it.image(27, 90, id(bulb_off)); } // Bulb off Icon it.print(15, 150, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Lounge Lights"); if (id(hallandlandinglights).state == "on") // KEY4 { it.image(147, 90, id(bulb_on)); } // Bulb on Icon else { it.image(147, 90, id(bulb_off)); } // Bulb off Icon it.print(145, 150, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Hall Lights"); if (id(toiletlight).state == "on") // KEY5 { it.image(27, 170, id(bulb_on)); } // Bulb on Icon else { it.image(27, 170, id(bulb_off)); } // Bulb off Icon it.print(25, 230, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Toilet Light"); if (id(girlslight).state == "on") // KEY6 { it.image(147, 170, id(bulb_on)); } // Bulb on Icon else { it.image(147, 170, id(bulb_off)); } // Bulb off Icon it.print(145, 230, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Girls Light"); it.image(37, 260, id(prev)); // Previous Icon it.image(157, 260, id(next)); // Next Icon - id: page2 lambda: |- it.fill(Color::WHITE); if (id(emmabedside).state == "on") // KEY1 { it.image(27, 10, id(bulb_on)); } // Bulb on Icon else { it.image(27, 10, id(bulb_off)); } // Bulb off Icon it.print(7, 70, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Emma Bedside"); if (id(jonbedside).state == "on") // KEY2 { it.image(147, 10, id(bulb_on)); } // Bulb on Icon else { it.image(147, 10, id(bulb_off)); } // Bulb off Icon it.print(135, 70, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Jon Bedside"); if (id(porchlight).state == "on") // KEY3 { it.image(27, 90, id(bulb_on)); } // Bulb on Icon else { it.image(27, 90, id(bulb_off)); } // Bulb off Icon it.print(20, 150, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Porch Light"); //if (id(hallandlandinglights).state == "on") // KEY4 //{ it.image(147, 90, id(bulb_on)); } // Bulb on Icon //else //{ it.image(147, 90, id(bulb_off)); } // Bulb off Icon //it.print(145, 150, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Hall Lights"); if (id(landinglight).state == "on") // KEY5 { it.image(27, 170, id(bulb_on)); } // Bulb on Icon else { it.image(27, 170, id(bulb_off)); } // Bulb off Icon it.print(15, 230, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Landing Light"); if (id(halllight).state == "on") // KEY6 { it.image(147, 170, id(bulb_on)); } // Bulb on Icon else { it.image(147, 170, id(bulb_off)); } // Bulb off Icon it.print(145, 230, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Hall Light"); it.image(37, 260, id(prev)); // Previous Icon it.image(157, 260, id(next)); // Next Iconfont: - file: '/config/fonts/Roboto-Medium.ttf' id: RobotoMed size: 14# - file: 'fonts/materialdesignicons-webfont.ttf'# id: font_icon# size: 75# glyphs:# - "\U000F0E4F" # mdi-lightbulb_off# - "\U000F06E8" # mdi_lightbulb_oncolor: - id: COLOR_CSS_PURPLE red: 41% green: 13% blue: 55% white: 100%image: - file: "/config/images/slide-on.png" id: slide_on resize: 100x53 type: RGB24 - file: "/config/images/slide-off.png" id: slide_off resize: 100x53 type: RGB24 - file: "/config/images/bulb-icon-on.png" id: bulb_on resize: 65x65 type: RGB24 - file: "/config/images/bulb-icon-off.png" id: bulb_off resize: 65x65 type: RGB24 - file: "/config/images/next-icon.png" id: next resize: 45x45 type: RGB24 - file: "/config/images/previous-icon.png" id: prev resize: 45x45 type: RGB24binary_sensor: - platform: xpt2046 xpt2046_id: touchscreen id: touch_key1 x_min: 0 x_max: 119 y_min: 0 y_max: 89 on_press: - if: condition: and: - display.is_displaying_page: page1 - light.is_on: back_light then: - logger.log: "Key1 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.bedside_lights - if: condition: and: - display.is_displaying_page: page2 - light.is_on: back_light then: - logger.log: "Key9 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.smart_lighting_tunable_white_and_color_3 - platform: xpt2046 xpt2046_id: touchscreen id: touch_key2 x_min: 120 x_max: 239 y_min: 0 y_max: 89 on_press: - if: condition: and: - display.is_displaying_page: page1 - light.is_on: back_light then: - logger.log: "Key2 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.kitchen_lights - if: condition: and: - display.is_displaying_page: page2 - light.is_on: back_light then: - logger.log: "Key10 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.smart_lighting_tunable_white_and_color_2_2 - platform: xpt2046 xpt2046_id: touchscreen id: touch_key3 x_min: 0 x_max: 119 y_min: 90 y_max: 169 on_press: - if: condition: and: - display.is_displaying_page: page1 - light.is_on: back_light then: - logger.log: "Key3 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.living_room_lights - if: condition: and: - display.is_displaying_page: page2 - light.is_on: back_light then: - logger.log: "Key11 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.smart_bulb - platform: xpt2046 xpt2046_id: touchscreen id: touch_key4 x_min: 120 x_max: 239 y_min: 90 y_max: 169 on_press: - if: condition: and: - display.is_displaying_page: page1 - light.is_on: back_light then: - logger.log: "Key4 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.hall_and_landing_lights - platform: xpt2046 xpt2046_id: touchscreen id: touch_key5 x_min: 0 x_max: 119 y_min: 170 y_max: 249 on_press: - if: condition: and: - display.is_displaying_page: page1 - light.is_on: back_light then: - logger.log: "Key5 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.smart_lighting_tunable_white_and_color - if: condition: and: - display.is_displaying_page: page2 - light.is_on: back_light then: - logger.log: "Key13 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.smart_lighting_tunable_white_and_color_3_2 - platform: xpt2046 xpt2046_id: touchscreen id: touch_key6 x_min: 120 x_max: 239 y_min: 170 y_max: 249 on_press: - if: condition: and: - display.is_displaying_page: page1 - light.is_on: back_light then: - logger.log: "Key6 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.smart_lighting_tunable_white_and_color_2 - if: condition: and: - display.is_displaying_page: page2 - light.is_on: back_light then: - logger.log: "Key14 was touched" - homeassistant.service: service: light.toggle data: entity_id: light.smart_lighting_tunable_white_and_color_4 - platform: xpt2046 xpt2046_id: touchscreen id: touch_key7 x_min: 0 x_max: 119 y_min: 250 y_max: 320 on_press: - if: condition: - light.is_on: back_light then: - logger.log: "Key7 was touched" - display.page.show_previous: touch_display - platform: xpt2046 xpt2046_id: touchscreen id: touch_key8 x_min: 120 x_max: 239 y_min: 250 y_max: 320 on_press: - if: condition: - light.is_on: back_light then: - logger.log: "Key8 was touched" - display.page.show_next: touch_display - platform: xpt2046 xpt2046_id: touchscreen id: touch_key14 x_min: 0 x_max: 240 y_min: 0 y_max: 320 on_press: - if: condition: - light.is_off: back_light then: - logger.log: "Key14 was touched" - light.turn_on: back_light - delay: 30 sec - light.turn_off: back_light
A**Y
Nice little screen
The media could not be loaded. Simple Demo to test touch screen :-Ensure you have installed the TFT_eSPI library in the library manager and set up the User_Setup.h as per the instructions.Important Values :-#define ILI9341_DRIVER#define TFT_BL 15 // LED back-light control pin#define TFT_BACKLIGHT_ON LOW // Level to turn ON back-light (HIGH or LOW)#define TFT_MISO 19 // Miso Pin#define TFT_MOSI 23 // Mosi Pin#define TFT_SCLK 18 // Clock Pin#define TFT_CS 5 // TFT Chip select control pin#define TFT_DC 4 // Data Command control pin#define TFT_RST 22 // Reset pin#define TOUCH_CS 14 // Touch Chip select control pin// Example of drawing a graphical "switch" and using// the touch screen to change it's state.// This sketch does not use the libraries button drawing// and handling functions.// Based on Adafruit_GFX library onoffbutton example.// Touch handling for XPT2046 based screens is handled by// the TFT_eSPI library.// Calibration data is stored in SPIFFS so we need to include it#include "FS.h"#include <SPI.h>#include <TFT_eSPI.h> // Hardware-specific libraryTFT_eSPI tft = TFT_eSPI(); // Invoke custom library// This is the file name used to store the touch coordinate// calibration data. Change the name to start a new calibration.#define CALIBRATION_FILE "/TouchCalData3"// Set REPEAT_CAL to true instead of false to run calibration// again, otherwise it will only be done once.// Repeat calibration if you change the screen rotation.#define REPEAT_CAL falsebool SwitchOn = false;// Comment out to stop drawing black spots#define BLACK_SPOT// Switch position and size#define FRAME_X 100#define FRAME_Y 64#define FRAME_W 120#define FRAME_H 50// Red zone size#define REDBUTTON_X FRAME_X#define REDBUTTON_Y FRAME_Y#define REDBUTTON_W (FRAME_W/2)#define REDBUTTON_H FRAME_H// Green zone size#define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)#define GREENBUTTON_Y FRAME_Y#define GREENBUTTON_W (FRAME_W/2)#define GREENBUTTON_H FRAME_H//------------------------------------------------------------------------------------------//------------------------------------------------------------------------------------------void setup(void){ Serial.begin(115200); tft.init(); // Set the rotation before we calibrate tft.setRotation(1); // call screen calibration touch_calibrate(); // clear screen tft.fillScreen(TFT_BLUE); // Draw button (this example does not use library Button class) redBtn();}//------------------------------------------------------------------------------------------//------------------------------------------------------------------------------------------void loop(){ uint16_t x, y; // See if there's any touch data for us if (tft.getTouch(&x, &y)) { // Draw a block spot to show where touch was calculated to be #ifdef BLACK_SPOT tft.fillCircle(x, y, 2, TFT_BLACK); #endif if (SwitchOn) { if ((x > REDBUTTON_X) && (x < (REDBUTTON_X + REDBUTTON_W))) { if ((y > REDBUTTON_Y) && (y <= (REDBUTTON_Y + REDBUTTON_H))) { Serial.println("Red btn hit"); redBtn(); } } } else //Record is off (SwitchOn == false) { if ((x > GREENBUTTON_X) && (x < (GREENBUTTON_X + GREENBUTTON_W))) { if ((y > GREENBUTTON_Y) && (y <= (GREENBUTTON_Y + GREENBUTTON_H))) { Serial.println("Green btn hit"); greenBtn(); } } } Serial.println(SwitchOn); }}//------------------------------------------------------------------------------------------void touch_calibrate(){ uint16_t calData[5]; uint8_t calDataOK = 0; // check file system exists if (!SPIFFS.begin()) { Serial.println("Formatting file system"); SPIFFS.format(); SPIFFS.begin(); } // check if calibration file exists and size is correct if (SPIFFS.exists(CALIBRATION_FILE)) { if (REPEAT_CAL) { // Delete if we want to re-calibrate SPIFFS.remove(CALIBRATION_FILE); } else { File f = SPIFFS.open(CALIBRATION_FILE, "r"); if (f) { if (f.readBytes((char *)calData, 14) == 14) calDataOK = 1; f.close(); } } } if (calDataOK && !REPEAT_CAL) { // calibration data valid tft.setTouch(calData); } else { // data not valid so recalibrate tft.fillScreen(TFT_BLACK); tft.setCursor(20, 0); tft.setTextFont(2); tft.setTextSize(1); tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.println("Touch corners as indicated"); tft.setTextFont(1); tft.println(); if (REPEAT_CAL) { tft.setTextColor(TFT_RED, TFT_BLACK); tft.println("Set REPEAT_CAL to false to stop this running again!"); } tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15); tft.setTextColor(TFT_GREEN, TFT_BLACK); tft.println("Calibration complete!"); // store data File f = SPIFFS.open(CALIBRATION_FILE, "w"); if (f) { f.write((const unsigned char *)calData, 14); f.close(); } }}void drawFrame(){ tft.drawRect(FRAME_X, FRAME_Y, FRAME_W, FRAME_H, TFT_BLACK);}// Draw a red buttonvoid redBtn(){ tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, TFT_RED); tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, TFT_DARKGREY); drawFrame(); tft.setTextColor(TFT_WHITE); tft.setTextSize(2); tft.setTextDatum(MC_DATUM); tft.drawString("ON", GREENBUTTON_X + (GREENBUTTON_W / 2), GREENBUTTON_Y + (GREENBUTTON_H / 2)); SwitchOn = false;}// Draw a green buttonvoid greenBtn(){ tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, TFT_GREEN); tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, TFT_DARKGREY); drawFrame(); tft.setTextColor(TFT_WHITE); tft.setTextSize(2); tft.setTextDatum(MC_DATUM); tft.drawString("OFF", REDBUTTON_X + (REDBUTTON_W / 2) + 1, REDBUTTON_Y + (REDBUTTON_H / 2)); SwitchOn = true;}
R**Y
Extremely hard work but is worth every penny once you get it working.
The media could not be loaded. This has great potential if only the manuals were available in English (The old version in English is for a very different board) and the ESP32 libraries worked so don't expect an easy ride. I started by asking AZ for the latest manual which they did promptly mail me but it was not in English. With about an hours work converting the PDF to English using google translate and then copy and pasting in the pictures that were lost I ended up with a document that was vaguely of some use. I will be using the ESP32 Dev C module which with my electronics engineering hat on is plugged into the board such that the receiving socket is on the other side (IE push module pins through board into the sockets on the opposite side which with an English manual would be very difficult to figure out, let alone one in German. Now I am into heavy library debugging as the HTTP libraries for the ESP32 clearly have issues despite compiling ok. In summary, a bit of kit with great potential but don't expect an easy ride to get any value out of it so I would leave it to electronics engineers with serious software debugging skills. As the say in England, a fantastic sailing ship ruined because of a halfpenny of tar missing! Meanwhile I will keep debugging the software and I may make an update if I get it working... Update: After correctly installing all the correct libraries in the Arduino IDE as system libs and compiling the example "codelock" sample on their website and making a few debugging code changes it all worked well so very happy in the end (see attached demo) but it was hard work getting there and not a job for a novice coder.
J**T
Works fine
I can actually run everything via power from the USB port on my ESP8266 D1 Mini but have done no measurement or long time test. Someone also mentioned that the two I2C pins where occupied by the display pins but you can change it like this: Wire.begin([SDA], [SCL]);
M**O
tolles Produkt dennoch Verbesserungen möglich
Das Display zeigt an was man programmiert, einfach alles. Per ESP-Easy ist es sehr leicht Texte/Daten sowie Grafik Kurvendiagramme darzustellen. Auch die Soll Temperatur per Touch einstellen, ist leicht zu programmieren. Einzelne Pixel oder Kreise können sogar per WEB zum Display geschickt werden, falls man die Homematic Daten darstellen möchte oder ein anderer ESP Daten per Wlan zum Display schickt.
N**V
ok
ok
L**S
Kit de qualidade e uma caixa para guardar componentes
The media could not be loaded. Antes de mais, um obrigado à AZ-Delivery pela rapidez na entrega.Chegou tudo muito bem acondicionado.Fisicamente tanto a caixa como a board é de muita qualidade, onde permite a integração com o display (2.8") ILI9143.Visualmente tem um acabamento profissional.Pontos negativos que deu para identificar algumas situações.Infelizmente o kit não permite a utilização do I2C, pois uma das linhas, está a ser utilizada pelo reset do display e a outra pelo Led do LCD.Outro ponto negativo é a "tomada" onde entram os pinos do ESP32. Um mau contacto e o display não passa do branco.Como tenho o projeto, basicamente a identificar/medir certos parâmetros em casa e a enviar via Wi-Fi para o ThingSpeak de 30 em 30 segundos, sobre (24h/24h),com apresentação gráfica e base de dados, estava em falta uma caixa de proteção, e este kit veio mesmo a calhar.Resumindo, fazendo umas pequenas alterações nas pistas da board, lá consegui integrar a comunicação I2C.(seria bem mais fácil se fosse entregue com o kit um diagrama elétrico da board).A informação disponibilizada é de uma placa diferente.De salientar também a versatilidade da biblioteca TFT_eSPI.Tem a possibilidade de ser alterada (User_Setup.h). Boa informação e com exemplos extraordinários.Para o meu projeto visitei os seguintes sites:A nível de software um obrigado ao Rui Santos (https://randomnerdtutorials.com/), e ao Fernando K (https://www.fernandok.com/).A nível de hardware um obrigado a AZ-Delivery (https://www.az-delivery.de). Bom hardware a preços muito acessíveis.
A**C
Bon produit
Un peu chère, le boîtier est parfait.Reste plus qu'à le programmer selon ces envies.
TrustPilot
1天前
3 周前