In diesem Video möchten wir Ihnen die 1,77" und 1,8" TFT Displays vorstellen. Im Rahmen des Videos werden die technischen Spezifikationen und Unterschiede beider Varianten erklärt. Zusätzlich zeigen wir mehrere Beispielschaltungen, um darzustellen, wie die Displays eingesetzt werden können und wie die Verkabelung funktioniert.
! Achtung: Wenn das Video bei Ihnen nicht angezeigt wird, sollten Sie Ihre Cookie Einstellungen überprüfen. Sie müssen alle Cookies akzeptieren, damit das Video sichtbar ist!
Hier finden Sie die vorgestellten Displays:
Verdrahtung 1,77 Zoll Display:
Code 1,77 Zoll Display:
/* ___ _____ ____ ___ / /__ / / __ \___ / (_) _____ _______ __ / /| | / / ______/ / / / _ \/ / / | / / _ \/ ___/ / / / / ___ |/ /_/_____/ /_/ / __/ / /| |/ / __/ / / /_/ / /_/ |_/____/ /_____/\___/_/_/ |___/\___/_/ \__, / /____/ Produkt, Datenblatt und Pinout unter: https://www.az-delivery.de/ Projekt: 1,77 TFT Display 160 x 128 Datum: 03/2022 Library: TFT_eSPI Link: https://github.com/Bodmer/TFT_eSPI Adaptierte Version aus den Beispielen der Bibliothek TFT_eSPI -> 160x120 - > TFT_METER 5 ------------------------- BEISPIELDATEI ----------------------------------------- An example analogue meter using a ST7735 TFT LCD screen This example uses the hardware SPI only Needs Font 2 (also Font 4 if using large scale label) Updated by Bodmer for variable meter size */ #include "DHT.h" #define DHTPIN 17 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); // Define meter size #define M_SIZE 0.667 #include <TFT_eSPI.h> // Hardware-specific library #include <SPI.h> TFT_eSPI tft = TFT_eSPI(); // Invoke custom library #define TFT_GREY 0x5AEB #define TFT_ORANGE 0xFD20 /* 255, 165, 0 */ float ltx = 0; // Saved x coord of bottom of needle uint16_t osx = M_SIZE*120, osy = M_SIZE*120; // Saved x & y coords uint32_t updateTime = 0; // time for next update int old_analog = -999; // Value last displayed int value[6] = {0, 0, 0, 0, 0, 0}; int old_value[6] = { -1, -1, -1, -1, -1, -1}; int d = 0; void setup(void) { Serial.begin(115200); // For debug dht.begin(); tft.init(); tft.setRotation(3); tft.fillScreen(TFT_BLACK); analogMeter(); // Draw analogue meter updateTime = millis(); // Next update time } void loop() { /* if (updateTime <= millis()) { updateTime = millis() + 35; // Update meter every 35 milliseconds // Create a Sine wave for testing d += 4; if (d >= 360) d = 0; value[0] = 50 + 50 * sin((d + 0) * 0.0174532925); //value[0] = random(0,100); //unsigned long tt = millis(); plotNeedle(value[0], 0); // It takes between 2 and 14ms to replot the needle with zero delay //Serial.println(millis()-tt); }*/ if(millis()%100==0){ int t = dht.readTemperature(); Serial.println(t); plotNeedle(t, 0); } } // ######################################################################### // Draw the analogue meter on the screen // ######################################################################### void analogMeter() { // Meter outline tft.fillRect(0, 0, M_SIZE*239, M_SIZE*131, TFT_GREY); tft.fillRect(1, M_SIZE*3, M_SIZE*234, M_SIZE*125, TFT_WHITE); tft.setTextColor(TFT_BLACK); // Text colour // Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing) for (int i = -50; i < 51; i += 5) { // Long scale tick length int tl = 15; // Coodinates of tick to draw float sx = cos((i - 90) * 0.0174532925); float sy = sin((i - 90) * 0.0174532925); uint16_t x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120; uint16_t y0 = sy * (M_SIZE*100 + tl) + M_SIZE*150; uint16_t x1 = sx * M_SIZE*100 + M_SIZE*120; uint16_t y1 = sy * M_SIZE*100 + M_SIZE*150; // Coordinates of next tick for zone fill float sx2 = cos((i + 5 - 90) * 0.0174532925); float sy2 = sin((i + 5 - 90) * 0.0174532925); int x2 = sx2 * (M_SIZE*100 + tl) + M_SIZE*120; int y2 = sy2 * (M_SIZE*100 + tl) + M_SIZE*150; int x3 = sx2 * M_SIZE*100 + M_SIZE*120; int y3 = sy2 * M_SIZE*100 + M_SIZE*150; // Yellow zone limits //if (i >= -50 && i < 0) { // tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_YELLOW); // tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_YELLOW); //} // Green zone limits if (i >= 0 && i < 25) { tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREEN); tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREEN); } // Orange zone limits if (i >= 25 && i < 50) { tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_ORANGE); tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_ORANGE); } // Short scale tick length if (i % 25 != 0) tl = 8; // Recalculate coords incase tick lenght changed x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120; y0 = sy * (M_SIZE*100 + tl) + M_SIZE*150; x1 = sx * M_SIZE*100 + M_SIZE*120; y1 = sy * M_SIZE*100 + M_SIZE*150; // Draw tick tft.drawLine(x0, y0, x1, y1, TFT_BLACK); // Check if labels should be drawn, with position tweaks if (i % 25 == 0) { // Calculate label positions x0 = sx * (M_SIZE*100 + tl + 10) + M_SIZE*120; y0 = sy * (M_SIZE*100 + tl + 10) + M_SIZE*150; switch (i / 25) { case -2: tft.drawCentreString("0", x0+4, y0-4, 1); break; case -1: tft.drawCentreString("25", x0+2, y0, 1); break; case 0: tft.drawCentreString("50", x0, y0, 1); break; case 1: tft.drawCentreString("75", x0, y0, 1); break; case 2: tft.drawCentreString("100", x0-2, y0-4, 1); break; } } // Now draw the arc of the scale sx = cos((i + 5 - 90) * 0.0174532925); sy = sin((i + 5 - 90) * 0.0174532925); x0 = sx * M_SIZE*100 + M_SIZE*120; y0 = sy * M_SIZE*100 + M_SIZE*150; // Draw scale arc, don't draw the last part if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK); } tft.drawString("°C", M_SIZE*(3 + 230 - 40), M_SIZE*(119 - 20), 2); // Units at bottom right tft.drawCentreString("°C", M_SIZE*120, M_SIZE*75, 4); // Comment out to avoid font 4 tft.drawRect(1, M_SIZE*3, M_SIZE*236, M_SIZE*126, TFT_BLACK); // Draw bezel line plotNeedle(0, 0); // Put meter needle at 0 } // ######################################################################### // Update needle position // This function is blocking while needle moves, time depends on ms_delay // 10ms minimises needle flicker if text is drawn within needle sweep area // Smaller values OK if text not in sweep area, zero for instant movement but // does not look realistic... (note: 100 increments for full scale deflection) // ######################################################################### void plotNeedle(float value, byte ms_delay) { tft.setTextColor(TFT_BLACK, TFT_WHITE); char buf[8]; dtostrf(value, 4, 0, buf); tft.drawRightString(buf, 33, M_SIZE*(119 - 20), 2); if (value < -10) value = -10; // Limit value to emulate needle end stops if (value > 110) value = 110; // Move the needle until new value reached while (!(value == old_analog)) { if (old_analog < value) old_analog++; else old_analog--; if (ms_delay == 0) old_analog = value; // Update immediately if delay is 0 float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle // Calculate tip of needle coords float sx = cos(sdeg * 0.0174532925); float sy = sin(sdeg * 0.0174532925); // Calculate x delta of needle start (does not start at pivot point) float tx = tan((sdeg + 90) * 0.0174532925); // Erase old needle image tft.drawLine(M_SIZE*(120 + 24 * ltx) - 1, M_SIZE*(150 - 24), osx - 1, osy, TFT_WHITE); tft.drawLine(M_SIZE*(120 + 24 * ltx), M_SIZE*(150 - 24), osx, osy, TFT_WHITE); tft.drawLine(M_SIZE*(120 + 24 * ltx) + 1, M_SIZE*(150 - 24), osx + 1, osy, TFT_WHITE); // Re-plot text under needle tft.setTextColor(TFT_BLACK, TFT_WHITE); tft.drawCentreString("Temp", M_SIZE*120, M_SIZE*75, 4); // // Comment out to avoid font 4 // Store new needle end coords for next erase ltx = tx; osx = M_SIZE*(sx * 98 + 120); osy = M_SIZE*(sy * 98 + 150); // Draw the needle in the new postion, magenta makes needle a bit bolder // draws 3 lines to thicken needle tft.drawLine(M_SIZE*(120 + 24 * ltx) - 1, M_SIZE*(150 - 24), osx - 1, osy, TFT_RED); tft.drawLine(M_SIZE*(120 + 24 * ltx), M_SIZE*(150 - 24), osx, osy, TFT_MAGENTA); tft.drawLine(M_SIZE*(120 + 24 * ltx) + 1, M_SIZE*(150 - 24), osx + 1, osy, TFT_RED); // Slow needle down slightly as it approaches new postion if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5; // Wait before next update delay(ms_delay); } }
Verdrahtung 1,8 Zoll Display:
Code 1,8 Zoll Display:
/* ___ _____ ____ ___ / /__ / / __ \___ / (_) _____ _______ __ / /| | / / ______/ / / / _ \/ / / | / / _ \/ ___/ / / / / ___ |/ /_/_____/ /_/ / __/ / /| |/ / __/ / / /_/ / /_/ |_/____/ /_____/\___/_/_/ |___/\___/_/ \__, / /____/ Produkt, Datenblatt und Pinout unter: https://www.az-delivery.de/ Projekt: 1,8 TFT Display 160 x 128 Datum: 03/2022 Library: TFT_eSPI Link: https://github.com/Bodmer/TFT_eSPI Adaptierte Version aus den Beispielen der Bibliothek TFT_eSPI -> ESP32_SDcard_jpg ___________ TEXT VON ORIGINAL LIBRARY____________________________________ // This sketch if for an ESP32, it draws Jpeg images pulled from an SD Card // onto the TFT. // As well as the TFT_eSPI library you will need the JPEG Decoder library. // A copy can be downloaded here, it is based on the library by Makoto Kurauchi. // https://github.com/Bodmer/JPEGDecoder // Images on SD Card must be put in the root folder (top level) to be found // Use the SD library examples to verify your SD Card interface works! // The example images used to test this sketch can be found in the library // JPEGDecoder/extras folder //---------------------------------------------------------------------------------------------------- */ #include <SPI.h> #include <FS.h> #include <SD.h> #include <TFT_eSPI.h> TFT_eSPI tft = TFT_eSPI(); // JPEG decoder library #include <JPEGDecoder.h> //#################################################################################################### // Setup //#################################################################################################### void setup() { Serial.begin(115200); // Set all chip selects high to avoid bus contention during initialisation of each peripheral digitalWrite(22, HIGH); // Touch controller chip select (if used) digitalWrite(15, HIGH); // TFT screen chip select digitalWrite( 5, HIGH); // SD card chips select, must use GPIO 5 (ESP32 SS) tft.begin(); if (!SD.begin()) { Serial.println("Card Mount Failed"); return; } uint8_t cardType = SD.cardType(); if (cardType == CARD_NONE) { Serial.println("No SD card attached"); return; } Serial.print("SD Card Type: "); if (cardType == CARD_MMC) { Serial.println("MMC"); } else if (cardType == CARD_SD) { Serial.println("SDSC"); } else if (cardType == CARD_SDHC) { Serial.println("SDHC"); } else { Serial.println("UNKNOWN"); } uint64_t cardSize = SD.cardSize() / (1024 * 1024); Serial.printf("SD Card Size: %lluMB\n", cardSize); Serial.println("initialisation done."); } //#################################################################################################### // Main loop //#################################################################################################### void loop() { int delay_time(6000); tft.setRotation(2); // tft.fillScreen(random(0xFFFF)); drawSdJpeg("/azdelivery.jpg", 0, 0); // This draws a jpeg pulled off the SD Card delay(delay_time); tft.setRotation(2); //tft.fillScreen(random(0xFFFF)); drawSdJpeg("/landschaft1.jpg", 0, 0); // This draws a jpeg pulled off the SD Card delay(delay_time); tft.setRotation(0); // tft.fillScreen(random(0xFFFF)); drawSdJpeg("/EagleEye.jpg", 0, 0); // This draws a jpeg pulled off the SD Card delay(delay_time); } //#################################################################################################### // Draw a JPEG on the TFT pulled from SD Card //#################################################################################################### // xpos, ypos is top left corner of plotted image void drawSdJpeg(const char *filename, int xpos, int ypos) { // Open the named file (the Jpeg decoder library will close it) File jpegFile = SD.open( filename, FILE_READ); // or, file handle reference for SD library if ( !jpegFile ) { Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!"); return; } Serial.println("==========================="); Serial.print("Drawing file: "); Serial.println(filename); Serial.println("==========================="); // Use one of the following methods to initialise the decoder: bool decoded = JpegDec.decodeSdFile(jpegFile); // Pass the SD file handle to the decoder, //bool decoded = JpegDec.decodeSdFile(filename); // or pass the filename (String or character array) if (decoded) { // print information about the image to the serial port jpegInfo(); // render the image onto the screen at given coordinates jpegRender(xpos, ypos); } else { Serial.println("Jpeg file format not supported!"); } } //#################################################################################################### // Draw a JPEG on the TFT, images will be cropped on the right/bottom sides if they do not fit //#################################################################################################### // This function assumes xpos,ypos is a valid screen coordinate. For convenience images that do not // fit totally on the screen are cropped to the nearest MCU size and may leave right/bottom borders. void jpegRender(int xpos, int ypos) { //jpegInfo(); // Print information from the JPEG file (could comment this line out) uint16_t *pImg; uint16_t mcu_w = JpegDec.MCUWidth; uint16_t mcu_h = JpegDec.MCUHeight; uint32_t max_x = JpegDec.width; uint32_t max_y = JpegDec.height; bool swapBytes = tft.getSwapBytes(); tft.setSwapBytes(true); // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs) // Typically these MCUs are 16x16 pixel blocks // Determine the width and height of the right and bottom edge image blocks uint32_t min_w = jpg_min(mcu_w, max_x % mcu_w); uint32_t min_h = jpg_min(mcu_h, max_y % mcu_h); // save the current image block size uint32_t win_w = mcu_w; uint32_t win_h = mcu_h; // record the current time so we can measure how long it takes to draw an image uint32_t drawTime = millis(); // save the coordinate of the right and bottom edges to assist image cropping // to the screen size max_x += xpos; max_y += ypos; // Fetch data from the file, decode and display while (JpegDec.read()) { // While there is more data in the file pImg = JpegDec.pImage ; // Decode a MCU (Minimum Coding Unit, typically a 8x8 or 16x16 pixel block) // Calculate coordinates of top left corner of current MCU int mcu_x = JpegDec.MCUx * mcu_w + xpos; int mcu_y = JpegDec.MCUy * mcu_h + ypos; // check if the image block size needs to be changed for the right edge if (mcu_x + mcu_w <= max_x) win_w = mcu_w; else win_w = min_w; // check if the image block size needs to be changed for the bottom edge if (mcu_y + mcu_h <= max_y) win_h = mcu_h; else win_h = min_h; // copy pixels into a contiguous block if (win_w != mcu_w) { uint16_t *cImg; int p = 0; cImg = pImg + win_w; for (int h = 1; h < win_h; h++) { p += mcu_w; for (int w = 0; w < win_w; w++) { *cImg = *(pImg + w + p); cImg++; } } } // calculate how many pixels must be drawn uint32_t mcu_pixels = win_w * win_h; // draw image MCU block only if it will fit on the screen if (( mcu_x + win_w ) <= tft.width() && ( mcu_y + win_h ) <= tft.height()) tft.pushImage(mcu_x, mcu_y, win_w, win_h, pImg); else if ( (mcu_y + win_h) >= tft.height()) JpegDec.abort(); // Image has run off bottom of screen so abort decoding } tft.setSwapBytes(swapBytes); showTime(millis() - drawTime); // These lines are for sketch testing only } //#################################################################################################### // Print image information to the serial port (optional) //#################################################################################################### // JpegDec.decodeFile(...) or JpegDec.decodeArray(...) must be called before this info is available! void jpegInfo() { // Print information extracted from the JPEG file Serial.println("JPEG image info"); Serial.println("==============="); Serial.print("Width :"); Serial.println(JpegDec.width); Serial.print("Height :"); Serial.println(JpegDec.height); Serial.print("Components :"); Serial.println(JpegDec.comps); Serial.print("MCU / row :"); Serial.println(JpegDec.MCUSPerRow); Serial.print("MCU / col :"); Serial.println(JpegDec.MCUSPerCol); Serial.print("Scan type :"); Serial.println(JpegDec.scanType); Serial.print("MCU width :"); Serial.println(JpegDec.MCUWidth); Serial.print("MCU height :"); Serial.println(JpegDec.MCUHeight); Serial.println("==============="); Serial.println(""); } //#################################################################################################### // Show the execution time (optional) //#################################################################################################### // WARNING: for UNO/AVR legacy reasons printing text to the screen with the Mega might not work for // sketch sizes greater than ~70KBytes because 16 bit address pointers are used in some libraries. // The Due will work fine with the HX8357_Due library. void showTime(uint32_t msTime) { //tft.setCursor(0, 0); //tft.setTextFont(1); //tft.setTextSize(2); //tft.setTextColor(TFT_WHITE, TFT_BLACK); //tft.print(F(" JPEG drawn in ")); //tft.print(msTime); //tft.println(F(" ms ")); Serial.print(F(" JPEG drawn in ")); Serial.print(msTime); Serial.println(F(" ms ")); }
4 Kommentare
Andreas Wolter
@Uwe: die DHT Bibliothek können Sie i.d.R aus dem Bibliotheksverwalter heraus installieren.
Wie die Bibliotheken eingebunden werden (ob mit Anführungszeichen, oder den Pfeilklammern) hängt davon ab, wie die Arduino IDE und die Bibliotheken installiert sind. In Standard C werden mit den <> Symbolen die global installierten Bibliotheken geladen. Mit den "" werden lokale Headerdateien eingebunden. In der Arduino IDE ist das noch ein wenig anders.
Ich habe dazu noch das hier gefunden: https://forum.arduino.cc/t/unterschied-bei-include/385413/16
Wenn Sie die DHT Bibliothek installiert haben, finden Sie im Menü ein fertiges Beispiel, wie die header-Datei einzubinden ist.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Uwe
Was ist die DHT.h wo finde ich diese und wieso "" und nicht<> ?
Uli
interessant: Das Video-Fenster mit dem lauffähigen Video nur mit Edge angezeigt, ist mit Opera, Firefox, Avast-Secure-Browsern nicht einmal als Fenster sichtbar – gibt es da evtl. Sicherheitsprobleme? Ich habe bei den vorgenannten browsern die Sicherheitsrichtlinien nicht verändert :-)
Uli
Vor paar Tagen schon versucht das “Vergleichsvideo” anzuschauen – ging nicht. Heute, nachdem die Mail zum Video ankam, erneut versucht… vergeblich.