Membuat Alat Monitor Kualitas Air Akuarium ESP32 dan sensor TDS

Pada project arduino kali ini, kita akan mempelajari cara membuat alat monitor kualitas air akuarium dengan Sensor TDS, Sensor Suhu, Modul WIFI ESP32 & Layar LCD TFT. Kita perlu memantau kualitas air serta penggantian air otomatis dan juga pemberian makan otomatis pada akuarium. Parameter kualitas air meliputi pH Air, TDS, Kekeruhan, Oksigen Terlarut, Suhu, Konduktivitas Listrik, dll.

Untuk akuarium & kehidupan akuatik termasuk ikan, parameter terpenting adalah Suhu Air dan TDS. Untuk akuarium, kisaran suhu yang baik adalah 76° hingga 80°F (25° hingga 27°C). TDS 400PPM~450PPM di dalam air direkomendasikan untuk sebagian besar ikan air tawar yang hidup.

Kenapa kita harus memonitor Kualitas Air Akuarium ?

Ikan membutuhkan lingkungan yang stabil yang memiliki tingkat TDS dan PH yang sama dengan habitat aslinya di akuarium atau tangki. Ikan yang berbeda membutuhkan air dengan TDS yang berbeda. 400PPM~450PPM TDS di dalam air direkomendasikan untuk sebagian besar ikan air tawar yang hidup.

Jika kadar TDS terlalu tinggi, akan menyebabkan kematian ikan dan memungkinkan pertumbuhan alga dalam jumlah besar. Rendahnya kadar TDS di dalam air akan mempengaruhi pertumbuhan ikan

Pengaruh TDS terhadap Kehidupan Ikan?

Nilai TDS (Total Dissolved Solids) memberikan jumlah padatan terlarut dalam air. Padatan ini termasuk misalnya garam, mineral, dan ion logam konduktif. Nilai ini juga disebut konduktivitas air. Karena semakin banyak padatan atau ion seperti itu di dalam air, semakin tinggi ia menghantarkan listrik.

TDS meter biasanya mengukur konduktivitas ini dalam siemens mikro atau ppm. Yang terakhir adalah singkatan dari bagian per juta, yaitu jumlah partikel padat per juta partikel campuran air. Nilai 40 ppm berarti dari sejuta partikel terdapat 40 ion terlarut dan sisanya (= 999.960) adalah molekul air.

Komponen Alat Monitor Kualitas Air Akuarium

Untuk membuat Sistem Monitoring Kualitas Air Aquarium, kita membutuhkan komponen-komponen sebagai berikut.

Diagram Alat Monitor Kualitas Air Akuarium

Sekarang kita akan menghubungkan sensor Gravity TDS, DS18B20 Temperature Sensor,ESP32 Board dan Touch Display. Sensor suhu digunakan karena parameter suhu diperlukan selama kompensasi TDS. Nilai TDS banyak berubah dengan naik turunnya suhu. Kita akan menambahkan tampilan layar menggunakan ILI9341 3.5″ TFT Touch Display. Layar dapat sangat berguna untuk memantau Monitor Air Akuarium untuk ikan dan kehidupan air lainnya.

Berikut adalah wiring diagram sederhana pada project ini.

Alat Monitor Kualitas Air Akuarium
  • Pin TDS & Sensor Suhu VCC & GND dihubungkan ke Pin ESP32 3.3V & GND.
  • Pin analog keluaran Sensor TDS dihubungkan ke Pin ESP32 IO35.
  • Output DS18B20 dihubungkan ke ESP32 IO25 Pin.
  • Resistor 4.7K diperlukan dan membutuhkan koneksi antara pin keluaran DS18B20 & VCC3.3V sebagai daya parasit.

Source Kode/Program

Pada program ini Layar LCD akan menampilkan nilai suhu & level TDS dalam format Gauge. Kode di bawah ini menggunakan dua file satu sebagai file.ino dan yang lainnya sebagai file .h. Salin kode berikut dan tempel di Arduino IDE Anda dan simpan dalam format .ino.

#include <OneWire.h>
#include <DallasTemperature.h>
#include "alert.h"
#include <TFT_eSPI.h> 
#include <SPI.h>
const int oneWireBus = 25;
#define TdsSensorPin 35
#define VREF 3.3
#define SCOUNT  30 // jumlah titik sampel
#define RED2RED 0
#define GREEN2GREEN 1
#define BLUE2BLUE 2
#define BLUE2RED 3
#define GREEN2RED 4
#define RED2GREEN 5
#define TFT_GREY 0x2104 // Warna abu-abu tua 16 bit
TFT_eSPI tft = TFT_eSPI(); // Pemanggil library khusus lebar dan tinggi default
uint32_t runTime = -99999; // waktu untuk pembaruan berikutnya
int analogBuffer[SCOUNT];    // simpan nilai analog dalam array, dibaca dari ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0;
int copyIndex = 0;
float averageVoltage = 0;
float tdsValue = 0;
float temperature = 0;
int reading = 0; // Nilai yang akan ditampilkan
int d = 0;  // Variabel yang digunakan untuk menguji gelombang sinus
boolean range_error = 0;
int8_t ramp = 1;
 
OneWire oneWire(oneWireBus); 
DallasTemperature sensors(&oneWire);    
void setup(void)
{
  Serial.begin(115200);
  sensors.begin();
  pinMode(TdsSensorPin, INPUT);
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.drawString("Aquarium Monitoring", 120, 10, 4);
  //tft.drawString("Weather", 350, 10, 2);
  tft.drawString("TDS Value", 80, 270, 2);
  tft.drawString("Temperature", 320, 270, 2);
}
 
void loop()
{
  tdstemp_read();
  if (millis() - runTime >= 0L)
  { // Execute every TBD ms
    runTime = millis();
   
 // Uji dengan nilai yang berubah secara perlahan dari fungsi Sinus
    d += 4;
    if (d >= 360)
      d = 0;
 
    // Atur posisi, jarak antar meter, dan radius bagian dalam meter
    int xpos = 0, ypos = 5, gap = 4, radius = 52;
    xpos = 60, ypos = 90, gap = 50, radius = 80;
   
 //reading = 800 + 150 * sineWave(d + 90);
    xpos = gap + ringMeter(tdsValue, 0, 1000, xpos, ypos, radius, "ppm", BLUE2RED); 
 
    //reading = 15 + 15 * sineWave(d + 150);
    xpos = gap + ringMeter(temperature, -20, 50, xpos, ypos, radius, "C", GREEN2GREEN); 
  }
}
 
//  Draw the meter on the screen, returns x coord of righthand side kembalikan x koordinat sisi kanan layar
int ringMeter(int value, int vmin, int vmax, int x, int y, int r, const char *units, byte scheme)
{ 
  x += r;
  y += r; // Hitung koordinat pusat cincin
  int w = r / 3; // Lebar lingkar luar adalah 1/4 jari-jari
  int angle = 150; // Setengah sudut sapuan meter (300 derajat)
  int v = map(value, vmin, vmax, -angle, angle); // Petakan nilainya ke sudut v
  byte seg = 3; // Segments are 3 degrees wide = 100 segmen untuk 300 derajat
  byte inc = 6;
  // Variabel untuk menyimpan warna teks "nilai" dari skema dan mengatur default
  int colour = TFT_BLUE;
  // Draw colour blocks every inc degrees
  for (int i = -angle + inc / 2; i < angle - inc / 2; i += inc)
  {
    // Hitung pasangan koordinat untuk awal segmen
    float sx = cos((i - 90) * 0.0174532925);
    float sy = sin((i - 90) * 0.0174532925);
    uint16_t x0 = sx * (r - w) + x;
    uint16_t y0 = sy * (r - w) + y;
    uint16_t x1 = sx * r + x;
    uint16_t y1 = sy * r + y;
 
    // Hitung pasangan koordinat untuk ujung segmen
    float sx2 = cos((i + seg - 90) * 0.0174532925);
    float sy2 = sin((i + seg - 90) * 0.0174532925);
    int x2 = sx2 * (r - w) + x;
    int y2 = sy2 * (r - w) + y;
    int x3 = sx2 * r + x;
    int y3 = sy2 * r + y;
 
    if (i < v)
    { // Isi segmen berwarna dengan 2 segitiga
      switch (scheme)
      {
        case 0:
          colour = TFT_RED;
          break; 
        case 1:
          colour = TFT_GREEN;
          break; 
        case 2:
          colour = TFT_BLUE;
          break; 
        case 3:
          colour = rainbow(map(i, -angle, angle, 0, 127));
          break;
        case 4:
          colour = rainbow(map(i, -angle, angle, 70, 127));
          break; 
        case 5:
          colour = rainbow(map(i, -angle, angle, 127, 63));
          break; 
        default:
          colour = TFT_BLUE;
          break; // Fixed colour
      }
      tft.fillTriangle(x0, y0, x1, y1, x2, y2, colour);
      tft.fillTriangle(x1, y1, x2, y2, x3, y3, colour);
      //text_colour = colour; // Save the last colour drawn
    }
    else // Fill in blank segments
    {
      tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREY);
      tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREY);
    }
  }
  // Ubah nilai menjadi string
  char buf[10];
  byte len = 3;
  if (value > 999)
    len = 5;
  dtostrf(value, len, 0, buf);
  buf[len] = ' ';
  buf[len + 1] = 0; 

  tft.setTextSize(1);
 
  if (value < vmin || value > vmax)
  {
    drawAlert(x, y + 90, 50, 1);
  }
  else
  {
    drawAlert(x, y + 90, 50, 0);
  }
 
  tft.setTextColor(TFT_WHITE, TFT_BLACK); 
  tft.setTextColor(colour, TFT_BLACK);
  tft.setTextDatum(MC_DATUM);
  // Nilai cetak, jika meteran besar maka gunakan font besar 8, jika tidak gunakan 4
  if (r > 84)
  {
    tft.setTextPadding(55 * 3);   // 3 digit masing-masing lebar 55 piksel
    tft.drawString(buf, x, y, 8); // Nilai di tengah
  }
  else
  {
    tft.setTextPadding(3 * 14);  
    tft.drawString(buf, x, y, 4); 
  }
  tft.setTextSize(1);
  tft.setTextPadding(0);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  if (r > 84)
    tft.drawString(units, x, y + 60, 4); // Units display
  else
    tft.drawString(units, x, y + 15, 2); // Units display
  // Hitung dan kembalikan ruas kanan x koordinat
  return x + r;
}
void drawAlert(int x, int y, int side, boolean draw)
{
  if (draw && !range_error)
  {
    drawIcon(alert, x - alertWidth / 2, y - alertHeight / 2, alertWidth, alertHeight);
    range_error = 1;
  }
  else if (!draw)
  {
    tft.fillRect(x - alertWidth / 2, y - alertHeight / 2, alertWidth, alertHeight, TFT_BLACK);
    range_error = 0;
  }
}
unsigned int rainbow(byte value)
{
  // Nilai diharapkan berada di kisaran 0-127
  // Nilai diubah menjadi warna spektrum dari 0 = biru hingga 127 = merah
  byte red = 0;   // Merah adalah 5 bit teratas dari nilai warna 16 bit
  byte green = 0; 
  byte blue = 0;  
  byte quadrant = value / 32;
 
  if (quadrant == 0)
  {
    blue = 31;
    green = 2 * (value % 32);
    red = 0;
  }
  if (quadrant == 1)
  {
    blue = 31 - (value % 32);
    green = 63;
    red = 0;
  }
  if (quadrant == 2)
  {
    blue = 0;
    green = 63;
    red = value % 32;
  }
  if (quadrant == 3)
  {
    blue = 0;
    green = 63 - 2 * (value % 32);
    red = 31;
  }
  return (red << 11) + (green << 5) + blue;
}
 
// Kembalikan nilai dalam rentang -1 hingga +1 untuk sudut fase tertentu dalam derajat
float sineWave(int phase)
{
  return sin(phase * 0.0174532925);
}
 
// fungsi untuk menggambar ikon yang disimpan sebagai array di memori program (FLASH)
#define BUFF_SIZE 64
void drawIcon(const unsigned short *icon, int16_t x, int16_t y, int8_t width, int8_t height)
{
  uint16_t pix_buffer[BUFF_SIZE]; // Pixel buffer (16 bits per pixel)
  tft.startWrite();
  tft.setAddrWindow(x, y, width, height);
 
  uint16_t nb = ((uint16_t)height * width) / BUFF_SIZE;
  for (int i = 0; i < nb; i++)
  {
    for (int j = 0; j < BUFF_SIZE; j++)
    {
      pix_buffer[j] = pgm_read_word(&icon[i * BUFF_SIZE + j]);
    }
    tft.pushColors(pix_buffer, BUFF_SIZE);
  }
 
  // Hitung jumlah piksel yang belum dikirim
  uint16_t np = ((uint16_t)height * width) % BUFF_SIZE;
  if (np)
  {
    for (int i = 0; i < np; i++)
      pix_buffer[i] = pgm_read_word(&icon[nb * BUFF_SIZE + i]);
    tft.pushColors(pix_buffer, np);
  }
 
  tft.endWrite();
}
 
void tdstemp_read()
{
  sensors.requestTemperatures();
  temperature = sensors.getTempCByIndex(0);
  static unsigned long analogSampleTimepoint = millis();
  if (millis() - analogSampleTimepoint > 40U)  
  {
    analogSampleTimepoint = millis();
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); 
    analogBufferIndex++;
    if (analogBufferIndex == SCOUNT)
      analogBufferIndex = 0;
  }
  static unsigned long printTimepoint = millis();
  if (millis() - printTimepoint > 800U)
  {
    printTimepoint = millis();
    for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; 
    float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
    float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; // ubah nilai tegangan menjadi nilai tds
 
    Serial.print("TDS Value:");
    Serial.print(tdsValue, 0);
    Serial.println("ppm");
    Serial.print("Temperature:");
    Serial.print(temperature);
    Serial.println("ºC");
  }
}
 
int getMedianNum(int bArray[], int iFilterLen)
{
  int bTab[iFilterLen];
  for (byte i = 0; i < iFilterLen; i++)
    bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++)
  {
    for (i = 0; i < iFilterLen - j - 1; i++)
    {
      if (bTab[i] > bTab[i + 1])
      {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0)
    bTemp = bTab[(iFilterLen - 1) / 2];
  else
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  return bTemp;
}

Buka tab baru di Arduino IDE. Salin kode berikut dan simpan sebagai Alert. berkas h.

#include <pgmspace.h>
const uint16_t alertWidth = 32;
const uint16_t alertHeight = 32;
const unsigned short  alert[1024] PROGMEM={
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0840,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 0, 32 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1080,0xAC66,0xEDE8,0xFE69,0xC4C6,0x2901,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 1, 64 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xBCC6,0xFE68,0xFE68,0xFE6A,0xFE68,0xEDE8,0x18A1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 2, 96 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8344,0xFE48,0xFE8C,0xFFDD,0xFFFF,0xFEF0,0xFE48,0xB466,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 3, 128 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1880,0xEDC7,0xFE48,0xFF99,0xFFBC,0xFF9B,0xFFBD,0xFE6A,0xFE48,0x5A23,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 4, 160 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x9BE5,0xFE28,0xFED0,0xFFBC,0xFF7A,0xFF9A,0xFF9B,0xFF35,0xFE28,0xBCA6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 5, 192 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3962,0xFE28,0xFE28,0xFF9A,0xFF79,0xFF9A,0xFF9B,0xFF9A,0xFFBD,0xFE6B,0xFE28,0x72E3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 6, 224 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xB465,0xFE28,0xFEF2,0xFF7A,0xFF79,0xFF7A,0xFF9A,0xFF7A,0xFF7A,0xFF78,0xFE28,0xDD67,0x0860,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 7, 256 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5A22,0xFE07,0xFE29,0xFF9B,0xFF37,0xFF58,0xFF79,0xFF79,0xFF79,0xFF58,0xFF9B,0xFEAE,0xFE07,0x93A4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 8, 288 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xC4A5,0xFE07,0xFF15,0xFF37,0xFF36,0xAD11,0x2965,0x2965,0xCDF4,0xFF37,0xFF37,0xFF79,0xFE07,0xFE07,0x2901,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 9, 320 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7B03,0xFDE7,0xFE4B,0xFF79,0xFEF4,0xFF15,0xB552,0x2945,0x2945,0xDE55,0xFF16,0xFF15,0xFF58,0xFED1,0xFDE7,0xAC25,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 10, 352 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0840,0xDD26,0xFDE7,0xFF57,0xFED3,0xFED2,0xFEF4,0xBD93,0x2124,0x2124,0xDE75,0xFF14,0xFED3,0xFED3,0xFF7A,0xFE08,0xFDE7,0x49A2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 11, 384 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x9BA4,0xFDC6,0xFE6E,0xFF36,0xFE90,0xFEB1,0xFED3,0xC592,0x2124,0x2124,0xE675,0xFED3,0xFEB2,0xFEB1,0xFEF3,0xFEF3,0xFDC6,0xBC45,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 12, 416 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3141,0xF5C6,0xF5C7,0xFF58,0xFE90,0xFE6F,0xFE8F,0xFEB1,0xCDB2,0x2104,0x2104,0xF6B4,0xFEB1,0xFE90,0xFE8F,0xFE90,0xFF58,0xFE0A,0xF5C6,0x72A3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 13, 448 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xABE4,0xF5A6,0xFEB1,0xFED3,0xFE4E,0xFE6E,0xFE6F,0xFE90,0xD5F2,0x18E3,0x18E3,0xFED4,0xFE90,0xFE6F,0xFE6F,0xFE6E,0xFE91,0xFF36,0xF5A6,0xCCA5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 14, 480 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0x5202,0xF5A6,0xF5C7,0xFF58,0xFE4D,0xFE4D,0xFE4D,0xFE4E,0xFE6F,0xDE11,0x18C3,0x18C3,0xFED3,0xFE6F,0xFE6E,0xFE4E,0xFE4D,0xFE4D,0xFF16,0xFE2C,0xF5A6,0x9363,0x0000,0x0000,0x0000,0x0000,0x0000, // row 15, 512 pixels
0x0000,0x0000,0x0000,0x0000,0x0000,0xBC44,0xF585,0xFED3,0xFE6F,0xFE2C,0xFE2C,0xFE2D,0xFE4D,0xFE4E,0xE630,0x10A2,0x2104,0xFED1,0xFE4E,0xFE4D,0xFE4D,0xFE2D,0xFE2C,0xFE4D,0xFF37,0xF586,0xF585,0x28E1,0x0000,0x0000,0x0000,0x0000, // row 16, 544 pixels
0x0000,0x0000,0x0000,0x0000,0x7282,0xF565,0xF5EA,0xFF16,0xFE0B,0xFE0B,0xFE0B,0xFE2C,0xFE2C,0xFE4D,0xF670,0x1082,0x2924,0xFEB0,0xFE2D,0xFE2C,0xFE2C,0xFE2C,0xFE0B,0xFE0B,0xFEB2,0xFE6F,0xF565,0xA383,0x0000,0x0000,0x0000,0x0000, // row 17, 576 pixels
0x0000,0x0000,0x0000,0x0840,0xD4C4,0xF565,0xFEF5,0xFE0C,0xFDE9,0xFDEA,0xFE0A,0xFE0B,0xFE0B,0xFE2C,0xFE8F,0x0861,0x2964,0xFE8F,0xFE2C,0xFE0B,0xFE0B,0xFE0B,0xFE0A,0xFDEA,0xFE0B,0xFF37,0xF586,0xF565,0x4181,0x0000,0x0000,0x0000, // row 18, 608 pixels
0x0000,0x0000,0x0000,0x9343,0xF545,0xF60C,0xFED3,0xFDC8,0xFDC8,0xFDC9,0xFDE9,0xFDEA,0xFDEA,0xFE0B,0xFE8E,0x0861,0x3184,0xFE6D,0xFE0B,0xFE0A,0xFDEA,0xFDEA,0xFDE9,0xFDC9,0xFDC9,0xFE4E,0xFEB2,0xF545,0xB3E3,0x0000,0x0000,0x0000, // row 19, 640 pixels
0x0000,0x0000,0x28E0,0xF544,0xF545,0xFF17,0xFDC8,0xFDA7,0xFDA7,0xFDC8,0xFDC8,0xFDC9,0xFDC9,0xFDE9,0xFE6C,0x10A2,0x39C4,0xFE4C,0xFDEA,0xFDE9,0xFDC9,0xFDC9,0xFDC8,0xFDC8,0xFDA7,0xFDA8,0xFF16,0xF588,0xF544,0x6222,0x0000,0x0000, // row 20, 672 pixels
0x0000,0x0000,0xA383,0xF524,0xF64E,0xFE4E,0xFD86,0xFD86,0xFD87,0xFDA7,0xFDA7,0xFDA8,0xFDC8,0xFDC8,0xFE2A,0xA469,0xB4EA,0xFE2A,0xFDC9,0xFDC8,0xFDC8,0xFDA8,0xFDA7,0xFDA7,0xFD87,0xFD86,0xFDEA,0xFED3,0xF524,0xC443,0x0000,0x0000, // row 21, 704 pixels
0x0000,0x51C1,0xF504,0xF546,0xFF16,0xF565,0xFD65,0xFD65,0xFD86,0xFD86,0xFD86,0xFDA7,0xFDA7,0xFDA7,0xFDE8,0xFE6A,0xFE4A,0xFDE8,0xFDA7,0xFDA7,0xFDA7,0xFDA7,0xFD86,0xFD86,0xFD86,0xFD65,0xFD65,0xFEB2,0xF5CA,0xF504,0x8AE2,0x0000, // row 22, 736 pixels
0x0000,0xB3A2,0xED03,0xFE92,0xFDC9,0xF543,0xF544,0xFD44,0xFD65,0xFD65,0xFD65,0xFD86,0xFD86,0xFD86,0xFDA7,0xFDC7,0xFDC7,0xFDA7,0xFD86,0xFD86,0xFD86,0xFD86,0xFD65,0xFD65,0xFD65,0xFD44,0xF544,0xFD86,0xFEF5,0xED03,0xE4C3,0x1880, // row 23, 768 pixels
0x7241,0xECE3,0xF567,0xFED3,0xF523,0xF523,0xF523,0xF543,0xF544,0xF544,0xFD65,0xFD65,0xFD65,0xFD65,0xD4E6,0x39C5,0x39A5,0xD4E6,0xFD86,0xFD65,0xFD65,0xFD65,0xFD65,0xF544,0xF544,0xF543,0xF523,0xF523,0xFE2E,0xF5EC,0xECE3,0x9B42, // row 24, 800 pixels
0xD443,0xECE3,0xFED4,0xF565,0xF502,0xF502,0xF522,0xF523,0xF523,0xF543,0xF544,0xF544,0xF544,0xFD65,0x8B64,0x18C3,0x18C3,0x8344,0xFD85,0xFD44,0xF544,0xF544,0xF544,0xF543,0xF523,0xF523,0xF522,0xF502,0xF523,0xFEF5,0xED04,0xECE3, // row 25, 832 pixels
0xECC3,0xF5AB,0xFE6F,0xF501,0xF4E1,0xF501,0xF502,0xF502,0xF522,0xF522,0xF523,0xF523,0xF523,0xFD84,0xC504,0x20E1,0x18E1,0xC4E4,0xFD84,0xF543,0xF523,0xF523,0xF523,0xF522,0xF522,0xF502,0xF502,0xF501,0xF501,0xFDC9,0xF62F,0xECC3, // row 26, 864 pixels
0xECC2,0xFE92,0xF523,0xF4E0,0xF4E0,0xF4E1,0xF4E1,0xF501,0xF501,0xF502,0xF502,0xF522,0xF522,0xF543,0xFDE3,0xFEA5,0xF6A4,0xFE04,0xF543,0xF522,0xF522,0xF522,0xF502,0xF502,0xF501,0xF501,0xF4E1,0xF4E1,0xF4E0,0xF4E1,0xFED4,0xECC2, // row 27, 896 pixels
0xECA2,0xF5EC,0xF4E0,0xF4C0,0xF4E0,0xF4E0,0xF4E0,0xF4E1,0xF4E1,0xF501,0xF501,0xF501,0xF502,0xF502,0xF542,0xFDA2,0xFDA2,0xF542,0xF502,0xF502,0xF502,0xF501,0xF501,0xF501,0xF4E1,0xF4E1,0xF4E0,0xF4E0,0xF4E0,0xF4C0,0xF5A9,0xECA2, // row 28, 928 pixels
0xECA2,0xECA2,0xECC2,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4E1,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E2,0xF4E1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xF4C1,0xECC2,0xECC3,0xECA2, // row 29, 960 pixels
0x8AC1,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0xEC82,0x9B01, // row 30, 992 pixels
0x0000,0x1880,0x51A0,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x8AA1,0x61E0,0x28E0,0x0000}; // row 31, 1024 pixels

Dari menu alat pilih ESP32 Wrover Module dan sambungkan Board ESP32 dengan Kabel USB Tipe-C lalu unggah kodenya.

Hasil Monitoring Alat Kualitas Air Akuarium

Setelah mengupload kode, tekan tombol rest pada ESP32 Board. Anda sekarang dapat Memantau nilai TDS & Suhu Akuarium di widget .

Untuk menguji sensor, Anda dapat menuangkan garam ke dalam cairan. Penambahan garam akan meningkatkan nilai TDS dengan cepat. Hal ini karena garam merupakan senyawa ionik. Jadi larutan garam adalah kabel untuk meningkatkan konduktivitas larutan apa pun.

Anda dapat menggunakan air panas untuk memeriksa nilai TDS sesuai suhu. Ketika nilai suhu meningkat nilai TDS naik. Hal ini karena dengan kenaikan suhu maka terjadi peningkatan konduktivitas listrik.

Alat Monitor Kualitas Air Akuarium

Pada suhu 21°C nilai TDS sebesar 344 ppm tetapi pada suhu 49°C nilai TDS mencapai 404 ppm. Untuk akuarium, kisaran suhu yang baik adalah 76° hingga 80°F (25° hingga 27°C). TDS 400PPM~450PPM di dalam air baik untuk sebagian besar ikan air tawar yang hidup.

Tinggalkan Balasan

Ads Blocker Image Powered by Code Help Pro

Pemblokir Iklan Terdeteksi!!!

Kami mendeteksi bahwa Anda menggunakan ekstensi untuk memblokir iklan. Silahkan menonaktifkan pemblokir iklan ini. Lalu refresh halaman ini untuk membuka konten ini !!!

Scroll to Top