Display ILI9341 monitoring level Water

Hi everyone
I would like to do water level monitoring. I am using a 2.8 TFT display library ILI9341
I already have bitmaps created.
Could someone help me with what the code should look like in the loop to have the same effect as in the link?
I'm not sure whether I need to create the entire bitmap or just a fragment?


#define STATUS_LED_GPIO 2
#define BUTTON_CFG_RELAY_GPIO 4
#define TFT_RST  14
#define TFT_DC   15
#define TFT_CS   17

#include <Arduino.h>
#include <WiFi.h>

#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "SPI.h"
#include <Adafruit_ILI9341.h>



Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// If using the breakout, change pins as desired
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);






void setup() {

  Serial.begin(115200);

  tft.begin();
  tft.fillScreen(ILI9341_BLACK);

  tft.drawBitmap(6, 6, logo32_glcd_bmp, 32, 32, ILI9341_GREEN);



}

void loop() {


  if (water_value < 10) {
    Serial.println("Empty");
    tft.drawBitmap(25, 26, epd_bitmap_lvl_0, 190, 254, ILI9341_YELLOW);

  }
  if ((water_value >= 10) && (water_value < 20)) {
    Serial.println("Level 10 %");
    tft.drawBitmap(25, 26, epd_bitmap_lvl_10, 190, 254, ILI9341_YELLOW);

  }
  if ((water_value >= 20) && (water_value < 30)) {
    Serial.println("Level 20 %");
    tft.drawBitmap(25, 26, epd_bitmap_lvl_20, 190, 254, ILI9341_YELLOW);


  }
  if ((water_value >= 30) && (water_value < 40)) {
    Serial.println("Level 30 %");
    tft.drawBitmap(25, 26, epd_bitmap_lvl_30, 190, 254, ILI9341_YELLOW);

  }
  if ((water_value >= 40) && (water_value < 50)) {
    Serial.println("Level 40 %");
    tft.drawBitmap(25, 26, epd_bitmap_lvl_40, 190, 254, ILI9341_YELLOW);

  }
}

Try.

fillRect(0, 0, _width, _height, color);

width will be fixed and _height will be "water_value" .

You should also use fillRect (back ground color ) before drawing a new value.

EDIT: Where do you get the "water_value".

1 Like

Yes, that's exactly what I meant.
I did the test and it should be fine.
I'm wondering how to make corners.
I am very grateful to you for your help. You helped me a lot.
The value will be taken from the water sensor

  tft.fillRect(48, 277, 150, -40, ILI9341_BLACK);
  tft.fillRect(48, 277, 150, 20, ILI9341_BLUE);

  delay(2000);

  tft.fillRect(48, 277, 150, -40, ILI9341_BLUE);

 delay(2000);

I came up with the following but the corners are 45° instead of an arc. You would need to change the values and colors when being used.

void drawTheThing() {
  int n = 10;     // determines how long the corners are
  int x = 45;     // horizontal starting position
  int y = 10;     // verticle starting postion
  int w = 150;    // width
  int h = 1;      // height of each line
  int g = 280;    // body of the main rectangle
  int i = 0;

  for (i = 0; i < n; i ++) {
  tft.fillRect((x - i), (y + i), w + (2 * i), h, ILI9341_RED);
  tft.fillRect((x - (n - i)), (y + i + n + g), w + (2 * (n - i)), h, ILI9341_RED);
 }
tft.fillRect((x - i), (y + i), w + (2 * i), g, ILI9341_RED);
i = 0;
}

Then I decided to look in the Adafruit_GFX.h to see what other options there are for drawing stuff and found:

fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
                     int16_t radius, uint16_t color);
1 Like

Ok, so I had a little more fun with this. My goal was to create rounded corners like the GFX function.

After I made my equations I simplified them down so they really don't tell you much, but it works decently well. I couldn't get the radius quite the same as the GFX function per value, but you can make them the same by choosing a slightly different value. Also mine starts to fall apart if you make the radius too big vs the size of the rectangle where the GFX constrains some of the variables. Maybe I will fix that some other time...

In the end I did this just to do it. I am trying to practice some of my coding. This was compiled and tested in Wokwi with an Uno and a tft display.

#include <Adafruit_ILI9341.h>
#include <Adafruit_GFX.h>
#include <SPI.h>


#define TFT_RST  6
#define TFT_DC   5
#define TFT_CS   10
#define TFT_MOSI 11
#define TFT_MISO 12
#define TFT_CLK 13


Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);

int16_t r;   // determines the radius of the corner
int16_t x;   // horizontal starting position
int16_t y;   // verticle starting postion
int16_t w;   // width
int16_t h;  // height
int color;

void drawTheThing(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, int color) {
  int i = 0;
  int lH = 1;
  tft.fillRect((x + r - 1), y, (w - 2 * r + 2), lH, color);
  for (i = 1; i < (r - 2); i++) {
    tft.fillRect((x + r - 2 - i), (y + i), (w + 2 * i - 2 * r + 4), lH, color);
    tft.fillRect((x + i), (y + i + h - r + 1), (w - 2 * i), lH, color);
  }
  tft.fillRect((x + r - i - 1), (y + i), (w + 2 * i - 2 * r + 2), lH, color);
  tft.fillRect((x + r - i - 2), (y + i + 1), (w + 2 * i - 2 * r + 4), lH, color);
  tft.fillRect((x + r - 2 - i), (y + i + 2), (w + 2 * i - 2 * r + 4), (h - 2 * r + 1), color);
  tft.fillRect((x + 1), (y + h - r + 1), (w - 2), lH, color);
  tft.fillRect((x + i + 1), (y + i - r + h + 1), (w - 2 * i - 2), lH, color);
  i = 0;
}



void setup() {
  // put your setup code here, to run once:

  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  drawTheThing(20, 50, 60, 20, 7, ILI9341_GREEN); // Custom function
  tft.fillRoundRect(100, 50, 60, 20, 8, ILI9341_RED); // Builtin to Adafruit_GFX


}

void loop() {
  // put your main code here, to run repeatedly:

}

https://wokwi.com/projects/406166899512378369

1 Like

Great!
You did a lot of coding - that's the best way to learn.

Oh wow!
Great example, very nicely explained.
trilerian Thank you very much. I will learn according to your example.
I did such a simulation. I'm trying to clear the screen after the last water level, but I can't clear the entire screen before displaying the new level.

https://drive.google.com/drive/u/2/folders/1jxVVJd3XYM1YxVfdvhSDkxHeXnk9MjFP

void loop() {
c = random(20, 150);
delay(200);

if(c != c2){
  c2=c;


  tft.fillRect(38, 277, 162, -c2, ILI9341_BLACK);
  delay(2000);
}

  
 tft.fillRect(38, 277, 162, -c2, ILI9341_BLUE);
  
  
  delay(2000);
}

EDIT

It works, it looks like this.
Thank you again for your help

void loop() {
  c = random(20, 185);
  delay(200);


if (c != c2) {
    c2 = c;

    tft.fillRect(38, 277, 162, -c2, ILI9341_BLACK);
    tft.fillRect(38, 277, 162, -c3, ILI9341_BLACK);
    delay(700);
  }

if(c2 != c3){
  c3=c2;
  
  tft.fillRect(38, 277, 162, -c3, ILI9341_BLUE);


  delay(700);
}
}