🔧 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: esp32devframework:type: arduino# Enable logginglogger:# Enable Home Assistant APIapi:ota:password: ####wifi:ssid: !secret wifi_ssidpassword: !secret wifi_passwordmanual_ip:static_ip: ###.###.###.###subnet: 255.255.255.0dns1: ###.###.###.####dns2: #.#.#.#gateway: ###.###.###.#### Enable fallback hotspot (captive portal) in case wifi connection failsap:ssid: ######password: ########captive_portal:spi:clk_pin: GPIO18mosi_pin: GPIO23miso_pin: GPIO19xpt2046:id: touchscreencs_pin: GPIO14irq_pin: GPIO27update_interval: 50msreport_interval: 1sthreshold: 400dimension_x: 240dimension_y: 320calibration_x_min: 3860calibration_x_max: 280calibration_y_min: 340calibration_y_max: 3860swap_x_y: Falseoutput:# backlight- platform: ledcpin: 15id: gpio_15_backlight_pwminverted: truelight:# backlight for HA- platform: monochromaticoutput: gpio_15_backlight_pwmname: "ILI9341 Display Backlight"id: back_lightrestore_mode: ALWAYS_OFFtext_sensor:- platform: homeassistantid: mblightgroupentity_id: light.bedside_lights- platform: homeassistantid: emmabedsideentity_id: light.smart_lighting_tunable_white_and_color_3- platform: homeassistantid: jonbedsideentity_id: light.smart_lighting_tunable_white_and_color_2_2- platform: homeassistantid: kitchenlightsentity_id: light.kitchen_lights- platform: homeassistantid: kitchenlight1entity_id: light.smart_bulb_2- platform: homeassistantid: kitchenlight2entity_id: light.smart_bulb_3- platform: homeassistantid: kitchenlight3entity_id: light.smart_bulb_4- platform: homeassistantid: livingroomlightsentity_id: light.living_room_lights- platform: homeassistantid: livingroomlight1entity_id: light.mk_smart_led_bulb_rgbpro- platform: homeassistantid: livingroomlight2entity_id: light.mk_smart_led_bulb_rgbpro_2- platform: homeassistantid: porchlightentity_id: light.smart_bulb- platform: homeassistantid: toiletlightentity_id: light.smart_lighting_tunable_white_and_color- platform: homeassistantid: landinglightentity_id: light.smart_lighting_tunable_white_and_color_3_2- platform: homeassistantid: hallandlandinglightsentity_id: light.hall_and_landing_lights- platform: homeassistantid: halllightentity_id: light.smart_lighting_tunable_white_and_color_4- platform: homeassistantid: girlslightentity_id: light.smart_lighting_tunable_white_and_color_2display:- platform: ili9341model: TFT 2.4id: touch_displaycs_pin: GPIO5dc_pin: GPIO4reset_pin: GPIO22rotation: 180pages:- id: page1lambda: |-it.fill(Color::WHITE);if (id(mblightgroup).state == "on") // KEY1{ it.image(27, 10, id(bulb_on)); } // Bulb on Iconelse{ it.image(27, 10, id(bulb_off)); } // Bulb off Iconit.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 Iconelse{ it.image(147, 10, id(bulb_off)); } // Bulb off Iconit.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 Iconelse{ it.image(27, 90, id(bulb_off)); } // Bulb off Iconit.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 Iconelse{ it.image(147, 90, id(bulb_off)); } // Bulb off Iconit.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 Iconelse{ it.image(27, 170, id(bulb_off)); } // Bulb off Iconit.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 Iconelse{ it.image(147, 170, id(bulb_off)); } // Bulb off Iconit.print(145, 230, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Girls Light");it.image(37, 260, id(prev)); // Previous Iconit.image(157, 260, id(next)); // Next Icon- id: page2lambda: |-it.fill(Color::WHITE);if (id(emmabedside).state == "on") // KEY1{ it.image(27, 10, id(bulb_on)); } // Bulb on Iconelse{ it.image(27, 10, id(bulb_off)); } // Bulb off Iconit.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 Iconelse{ it.image(147, 10, id(bulb_off)); } // Bulb off Iconit.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 Iconelse{ it.image(27, 90, id(bulb_off)); } // Bulb off Iconit.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 Iconelse{ it.image(27, 170, id(bulb_off)); } // Bulb off Iconit.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 Iconelse{ it.image(147, 170, id(bulb_off)); } // Bulb off Iconit.print(145, 230, id(RobotoMed), id(COLOR_CSS_PURPLE), TextAlign::TOP_LEFT, "Hall Light");it.image(37, 260, id(prev)); // Previous Iconit.image(157, 260, id(next)); // Next Iconfont:- file: '/config/fonts/Roboto-Medium.ttf'id: RobotoMedsize: 14# - file: 'fonts/materialdesignicons-webfont.ttf'# id: font_icon# size: 75# glyphs:# - "\U000F0E4F" # mdi-lightbulb_off# - "\U000F06E8" # mdi_lightbulb_oncolor:- id: COLOR_CSS_PURPLEred: 41%green: 13%blue: 55%white: 100%image:- file: "/config/images/slide-on.png"id: slide_onresize: 100x53type: RGB24- file: "/config/images/slide-off.png"id: slide_offresize: 100x53type: RGB24- file: "/config/images/bulb-icon-on.png"id: bulb_onresize: 65x65type: RGB24- file: "/config/images/bulb-icon-off.png"id: bulb_offresize: 65x65type: RGB24- file: "/config/images/next-icon.png"id: nextresize: 45x45type: RGB24- file: "/config/images/previous-icon.png"id: prevresize: 45x45type: RGB24binary_sensor:- platform: xpt2046xpt2046_id: touchscreenid: touch_key1x_min: 0x_max: 119y_min: 0y_max: 89on_press:- if:condition:and:- display.is_displaying_page: page1- light.is_on: back_lightthen:- logger.log: "Key1 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.bedside_lights- if:condition:and:- display.is_displaying_page: page2- light.is_on: back_lightthen:- logger.log: "Key9 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.smart_lighting_tunable_white_and_color_3- platform: xpt2046xpt2046_id: touchscreenid: touch_key2x_min: 120x_max: 239y_min: 0y_max: 89on_press:- if:condition:and:- display.is_displaying_page: page1- light.is_on: back_lightthen:- logger.log: "Key2 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.kitchen_lights- if:condition:and:- display.is_displaying_page: page2- light.is_on: back_lightthen:- logger.log: "Key10 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.smart_lighting_tunable_white_and_color_2_2- platform: xpt2046xpt2046_id: touchscreenid: touch_key3x_min: 0x_max: 119y_min: 90y_max: 169on_press:- if:condition:and:- display.is_displaying_page: page1- light.is_on: back_lightthen:- logger.log: "Key3 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.living_room_lights- if:condition:and:- display.is_displaying_page: page2- light.is_on: back_lightthen:- logger.log: "Key11 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.smart_bulb- platform: xpt2046xpt2046_id: touchscreenid: touch_key4x_min: 120x_max: 239y_min: 90y_max: 169on_press:- if:condition:and:- display.is_displaying_page: page1- light.is_on: back_lightthen:- logger.log: "Key4 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.hall_and_landing_lights- platform: xpt2046xpt2046_id: touchscreenid: touch_key5x_min: 0x_max: 119y_min: 170y_max: 249on_press:- if:condition:and:- display.is_displaying_page: page1- light.is_on: back_lightthen:- logger.log: "Key5 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.smart_lighting_tunable_white_and_color- if:condition:and:- display.is_displaying_page: page2- light.is_on: back_lightthen:- logger.log: "Key13 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.smart_lighting_tunable_white_and_color_3_2- platform: xpt2046xpt2046_id: touchscreenid: touch_key6x_min: 120x_max: 239y_min: 170y_max: 249on_press:- if:condition:and:- display.is_displaying_page: page1- light.is_on: back_lightthen:- logger.log: "Key6 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.smart_lighting_tunable_white_and_color_2- if:condition:and:- display.is_displaying_page: page2- light.is_on: back_lightthen:- logger.log: "Key14 was touched"- homeassistant.service:service: light.toggledata:entity_id: light.smart_lighting_tunable_white_and_color_4- platform: xpt2046xpt2046_id: touchscreenid: touch_key7x_min: 0x_max: 119y_min: 250y_max: 320on_press:- if:condition:- light.is_on: back_lightthen:- logger.log: "Key7 was touched"- display.page.show_previous: touch_display- platform: xpt2046xpt2046_id: touchscreenid: touch_key8x_min: 120x_max: 239y_min: 250y_max: 320on_press:- if:condition:- light.is_on: back_lightthen:- logger.log: "Key8 was touched"- display.page.show_next: touch_display- platform: xpt2046xpt2046_id: touchscreenid: touch_key14x_min: 0x_max: 240y_min: 0y_max: 320on_press:- if:condition:- light.is_off: back_lightthen:- 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 calibratetft.setRotation(1);// call screen calibrationtouch_calibrate();// clear screentft.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 usif (tft.getTouch(&x, &y)){// Draw a block spot to show where touch was calculated to be#ifdef BLACK_SPOTtft.fillCircle(x, y, 2, TFT_BLACK);#endifif (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 existsif (!SPIFFS.begin()) {Serial.println("Formatting file system");SPIFFS.format();SPIFFS.begin();}// check if calibration file exists and size is correctif (SPIFFS.exists(CALIBRATION_FILE)) {if (REPEAT_CAL){// Delete if we want to re-calibrateSPIFFS.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 validtft.setTouch(calData);} else {// data not valid so recalibratetft.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 dataFile 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.
Trustpilot
2 days ago
1 month ago