Elektroda.com
Elektroda.com
X
Elektroda.com

A thermometer for the bedroom in the form of a frame

krzbor 3987 9
This content has been translated flag-pl » flag-en View the original version here.
  • A thermometer for the bedroom in the form of a frame
    At the beginning, an explanation to the title - it is not a typical thermometer, because it does not measure anything, but simply displays the temperature taken by other sensors. However, I found the "temperature display" to sound strange. But "to the bedroom" has its justification, which I will write about later.

    Some history

    Indications of the outside temperature in the bedroom make sense - after all, it is there that we decide how to dress. Initially, the temperature was displayed by an old Lenovo tablet - thanks to the Chrome browser and the ability to display it in full screen, it looked pretty decent. The problem was the brightness of the light - at night the bedroom is supposed to be dark. The browser does not have the ability to control the backlight. I partially solved the problem by overlaying a semi-transparent "div" based on astronomical clock data. It even worked quite well, but the Wi-Fi or power icons shone brightly anyway. However, it was enough to turn the screen so that it could not be seen from the position of the pillow and it was OK. One time, however, I noticed that the display bulged, and after a while, as the bulge increased, the display began to malfunction. I've read about batteries swelling on constant power, but I thought it wouldn't affect Lenovo. The problem arose - to get a new tablet or to do it "your way". Once, thinking about my own temperature display, I bought a TFT module 480x320px. Basically, I wanted a large display, not a high resolution, but then I couldn't find anything more interesting than this 4 "display. So I decided to build my own structure based on ESP8266.

    Frame construction

    The basic problem when building a device "in sight" is of course the casing. I decided to make the whole thing in the form of a picture frame. There are also other frames with real photos on the chest of drawers, where the "thermometer" is located - I thought that everything would fit nicely:
    A thermometer for the bedroom in the form of a frame
    It was my first project with a TFT display - that's why I did some tests first:
    A thermometer for the bedroom in the form of a frame
    I usually build circuits on a universal board, but I had a ready board for ESP-12 for a completely different project (known problem - you have to order a few pieces) - I decided to do "recycling". I will not draw a diagram, because the appropriate ESP pins (SPI interface) are simply connected to the display. Additional pins are:
    Code: c
    Log in, to see the code

    and GPIO15 to control the TFT backlight. The choice of GPIO15 was not accidental. During startup, this pin is forced low (ESP8266 requires it). As a result, the screen is not backlit for the entire duration of the ESP start, and only when everything is ready, the backlight is turned on.
    As I mentioned, dimming was important, so the frame was equipped with a photoresistor:
    A thermometer for the bedroom in the form of a frame
    The only ADC input of the ESP8266 processor came in handy. The high resistance of R4 may be surprising. It results from the fact that the system was supposed to have good resolution at very low illumination.

    Construction

    After buying the frame and tearing off the back foot, I cut a hole for the display:
    A thermometer for the bedroom in the form of a frame
    The precision of the cut is not particularly important - there will be a passe partout in the front that will mask everything. However, it is important to place the hole vertically - the active part of the display is not in its center, which should be taken into account when cutting the hole.
    After mounting the display on the front, it looks like this:
    A thermometer for the bedroom in the form of a frame
    The screws are conical and have their sockets so that there is one even plane at the front. Because the plate is thin, I added a little drop of glue under the screw heads to strengthen the whole thing. Side view:
    A thermometer for the bedroom in the form of a frame
    The thickness of the plate and nut matched the thickness of the display perfectly.
    And this is what it looks like after assembly:
    A thermometer for the bedroom in the form of a frame
    The top screws from the board are not attached to the display - they only act as spacers.
    Rear view of the finished frame:
    A thermometer for the bedroom in the form of a frame
    Because I do not use the touch panel, I left the original plexiglass in the frame.

    Software

    ESP programming I did as usual in Arduino. To support the display, I decided to use the TFT_eSPI library, which works very well with my display. The authors of the library solved the problem of configuring the control pins and the type of display in an interesting way - everything is in the "User_Setup.h" file. This solution has the advantage that after a one-time configuration, you can build sample projects that work right away! The "first fire" was the example of displaying a JPG image - it worked very well, and I found out that I have a well-connected and functional display. The next step is to display subtitles - examples are also available here. I decided to modify them a bit and check what about Polish characters. Unfortunately, they weren't. Later I read that it can be done, but it's not easy. This cooled my enthusiasm a bit, especially since I wanted to use nice, big characters.
    I decided to solve the problem differently - I decided that the frame would only display the entire image, which would be created on the server side using PHP and the GD library. The GD library gives me access to writing using TrueType, and since PHP is an interpreted language, it's very easy to modify - I don't have to compile, upload, etc.
    The problem remained how to upload an image from PHP to ESP. I rejected JPEG compression - it's a lossy compression, and I didn't want to have a blurry image at the edges. The PNG compression module did not work (probably requires more RAM). I was still thinking about GIF, but in the end I decided on my own solution with my own compression.
    I decided that PHP will immediately prepare the image for display, i.e. it will encode it to 65k colors (RGB 565), which is required by the TFT display. Initially, the data was sent uncompressed - each row consisted of 320 pixels or 640 bytes. The entire image was thus 307,200 bytes in size. It worked very nicely and interestingly, but slowly. I found the wifi on the ESP8266 to be very slow. The redraw took over 2 seconds. Because they can be done without erasing the previous content, an interesting "blind" transition effect was created, which can be useful when someone wants to make an electronic photo frame.
    However, I wanted speed, so I added RLE-based compression. Below is a description of the method used.

    Compression

    Since one pixel is 2 bytes, I decided to encode everything on two bytes - in the further description I will call it a "word", which can contain numbers or an RGB color (in the 565 system). The basic assumption was easy reading on the ESP side. Therefore, the first word contains the number of words in the line. The next word is the control word (let's call it n) - if it is less than 10000, it means that the next n words should be rewritten as pixels. If n is greater than 10000, then the next word (pixel) should be repeated (n-10000) times. We use such encoding to the end of the line - that is, the next control word and data, etc. After encoding the line, the PHP code checks whether the encoded string (row of pixels) is not longer than uncompressed. In this case, compression is canceled for that row, and ESP, when it reads that the row is 320 words long, knows that it is not compressed. For the picture below:
    A thermometer for the bedroom in the form of a frame
    Compression yields a resulting size of 43,160 bytes, which is 14% of the original. I considered it a very decent result.

    Arduino code

    [syntax=c]// Flash 4MB esp8266

    #include
    #include
    #include
    #include
    #include

    #include
    #include

    // WiFi

    const char* APname = "TERMOMETR";
    const char* APpassword = "moje_haslo";

    const char* host = "192.168.0.24";
    const char* privateKey = "termometr1";
    #define LED 2 //wewnętrzny LED
    #define BACK 15 //podświetlanie ekranu
    #define WERSJA "1" // która wersja

    #define WIDTH 320
    #define HEIGHT 480

    #define WIDTH2 (2*(WIDTH))

    TFT_eSPI tft = TFT_eSPI();

    void setup() {
    pinMode(BACK, OUTPUT);
    digitalWrite(BACK,LOW);
    analogWriteRange(10000);
    analogWriteFreq(40);

    pinMode(LED, OUTPUT);
    digitalWrite(LED,LOW); //sygnalizacja startu
    delay(2000);
    digitalWrite(LED,HIGH);
    delay(300);

    WiFiManager wifiManager;

    wifiManager.setDebugOutput(false);//wyłączenie debuga
    wifiManager.setConfigPortalTimeout(180);
    if(!wifiManager.autoConnect(APname,APpassword)) {
    ESP.reset();
    delay(5000);
    }
    digitalWrite(LED,LOW); //połączono 2 błyski
    delay(300);
    digitalWrite(LED,HIGH);
    delay(300);
    digitalWrite(LED,LOW);
    delay(300);
    digitalWrite(LED,HIGH);
    ESPhttpUpdate.update(host, 80, "/www/OTA.php", String(APname)+":"+WERSJA+":"+WiFi.localIP().toString());

    tft.begin();
    tft.setRotation(2);
    tft.fillScreen(TFT_NAVY);
    }

    WiFiClient client;
    int back=10000;
    int licznik=0; //30*2s=1min
    int analog=1024;
    int popanalog;

    void loop() {
    delay(2000);
    popanalog=analog;
    analog=analogRead(A0);
    if (abs(analog-popanalog)>100)
    licznik=0;
    if (licznik>0){
    licznik--;
    return;
    }

    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
    licznik=10;
    return;
    }
    String url = "/lcd/term.php";
    url += "?private_key=";
    url += privateKey;
    url +="&foto="+String(analog);

    client.print(String("GET ") + url + " HTTP/1.0\r\n" +
    "Host: " + host + "\r\n" +
    "Connection: close\r\n\r\n");
    unsigned long timeout = millis();
    while (client.available() == 0) {
    if (millis() - timeout > 15000) {
    client.stop();
    return;
    }
    delay(1);
    }
    client.setTimeout(15000);
    String odp;
    String comm="";
    String s;
    while (true) {
    odp=client.readStringUntil('\n');
    odp.trim();
    if (odp=="")
    break;
    if (odp.indexOf("X-Command:")==0){
    comm=odp.substring(10);
    comm.trim();
    }
    if (odp.indexOf("X-PWM:")==0){
    s=odp.substring(6);
    s.trim();
    back=s.toInt();
    }
    }
    if (comm=="Restart"){
    ESP.reset();
    delay(5000);
    }

    if (comm!="IMG"){
    client.stop();
    licznik=10;
    return;
    }

    analogWrite(BACK,back);
    licznik=30;

    //odczyt obrazu
    uint8_t buf[WIDTH2];
    uint8_t buf2[WIDTH2];

    uint16_t ile;
    tft.startWrite();
    for (int i = 0; i < HEIGHT; i++) {
    yield();
    timeout = millis();
    while (client.available() 1000) {
    tft.endWrite();
    client.stop();
    return;
    }
    yield();
    }

    ile=client.read()*256+client.read();
    int len = client.readBytes(buf,ile * 2);
    tft.setAddrWindow(0, i, WIDTH, 1);
    if (ile==WIDTH)
    tft.pushPixels(buf, WIDTH);
    else {
    int w=0;
    int d=0;
    while (d

    Cool? Ranking DIY
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
    About Author
    krzbor
    Level 24  
    Offline 
    krzbor wrote 973 posts with rating 533, helped 20 times. Been with us since 2004 year.
  • #2
    gulson
    System Administrator
    Thank you very much for presenting the DIY construction and inserting the electrode logotype. It turned out great. I think that the frame is always problematic to make it look aesthetically pleasing and fit everything in it.
    Write to me for a modest gift! :)
  • #3
    error105
    Level 14  
    Cool design.
    The only thing that bothers me is this poor TFT with no viewing angles :( it hurts a bit that there are basically no good quality SPI displays, or they cost more than 27" monitors :(
  • #4
    ADI-mistrzu
    Level 30  
    Haven't you thought about replacing TFT with e-ink? Even colorful.
  • #5
    krzbor
    Level 24  
    error105 wrote:
    Cool design.
    The only thing that bothers me is this poor TFT with no viewing angles :( it hurts a bit that there are basically no good quality SPI displays, or they cost more than 27" monitors :(

    The angles aren't that bad. However, it is worth checking, because vertically they seem to be different depending on how we turn the screen. There is practically no cheap display with SPI over 4 inches, or as you write, they are at a cosmic price.

    ADI-mistrzu wrote:
    Haven't you thought about replacing TFT with e-ink? Even colorful.

    The photo of the frame was taken in the evening - hence the high contrast between the frame and the content displayed on the TFT. Normally it looks much better during the day. In addition, the camera enhances the contrast between the frame and the TFT.
    I agree that the applied solution is well suited for e-ink - although in this case I would add a checksum of the transmitted image. When the checksum does not change, there will be no refresh. I just had TFT, e-ink had to be bought. I also wanted visibility at night.
  • #6
    ADI-mistrzu
    Level 30  
    @krzbor there are e-ink with the possibility of backlighting, but unfortunately I don't know how to access them.
  • #7
    ArturAVS
    Moderator HP/Truck/Electric
    @krzbor And what exactly is the display?
  • #8
    krzbor
    Level 24  
    Chinese :) Accurate "Polish" Description: ''3.95"/4.0" inch 320*480 ST7796S TFT Color LCD Display Module with Touch Panel for Arduino UNO Mega2560 8/16 Bit". Connector Picture:
    A thermometer for the bedroom in the form of a frame
    I attach User_Setup.h:
  • #9
    pier
    Level 24  
    Beautiful from the front, but not from the back.
  • #10
    krzbor
    Level 24  
    No frame looks beautiful from the back. If the back was somehow visible, I would add a housing or some kind of cover. However, I knew that with the size of the frame in relation to the display and electronics, nothing would be visible. I tried to make it as flat as possible - hence the not very aesthetically inclined stabilizer. Of course, the ideal would be a nice board, designed from scratch, preferably with a socket that matches the pins of the display - such a sandwich. However, I think others will go the other way - just use a NodeMCU - there they have a power jack, stabilizer and easier programming. A minor problem, however, will be the need to rework the ADC input.