ILI9341 won't show texts

I am creating a flow meter with arduino mega and ILI9341 as the display. But, I have a trouble because the display can't show the strings. I already test the component with an example code and it was fine. can you help me to find where's the problem in my code?


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

const int pinMerah[] = {22, 24, 26, 28};
const int pinHijau[] = {30, 32};
const int pinTombol = 5;
const int pinFlowMeter = 2;
const int pinBuzzer = 4;

#define TFT_CLK 13
#define TFT_MISO 12
#define TFT_MOSI 11
#define TFT_DC 9
#define TFT_CS 10
#define TFT_RST 8

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

bool statusTombol = false;
bool statusTombolSebelumnya = false;
int pengambilanDataKe = 0;
bool sistemSiap = false;
volatile int hitungPulsaFlow = 0;
float lajuAliran = 0.0;
float totalLajuAliran = 0.0;
float rataRataAliran = 0.0;
float volume = 0.0;
int hitunganSampel = 0;
unsigned long waktuLama = 0;
int ledAktif = 0;
unsigned long waktuLED = 0;
unsigned long waktuTombolTekan = 0;
unsigned long startTime = 0;
unsigned long endTime = 0;
unsigned long duration = 0;

void flowISR() {
  hitungPulsaFlow++;
}

void setup() {
  for (int i = 0; i < 4; i++) {
    pinMode(pinHijau[i], OUTPUT);
    pinMode(pinMerah[i], OUTPUT);
    digitalWrite(pinHijau[i], LOW);
    digitalWrite(pinMerah[i], LOW);
  }
  pinMode(pinTombol, INPUT_PULLUP);
  pinMode(pinBuzzer, OUTPUT);
  pinMode(pinFlowMeter, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(pinFlowMeter), flowISR, RISING);

  Serial.begin(9600);
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(ILI9341_BLACK);
}

void persiapanAwal() {
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  tft.setCursor(50, 50);
  tft.print("Sistem Siap");

  Serial.println("Sistem siap menerima aliran.");
}

void tampilkanHasil() {
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);

  tft.setCursor(20, 50);
  tft.print("Vol: ");
  tft.print(volume * 1000);
  tft.print(" mL");

  tft.setCursor(20, 100);
  tft.print("Time: ");
  tft.print(duration);
  tft.print(" s");

  Serial.print("Hasil Ke-");
  Serial.print(pengambilanDataKe);
  Serial.print(" Volume: ");
  Serial.print(volume * 1000);
  Serial.println(" mL");
  Serial.print("Durasi: ");
  Serial.print(duration);
  Serial.println(" detik");
}

void abaAba() {
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);

  tft.setCursor(30, 50);
  tft.print("Siapkan Napas");

  for (int i = 0; i < 2; i++) {
    digitalWrite(pinHijau[i], HIGH);
  }
  ledAktif = 0;

  tft.setCursor(30, 100);
  tft.print("Ke-");
  tft.print(pengambilanDataKe);

  Serial.print("Siapkan Napas untuk Pengukuran Ke-");
  Serial.println(pengambilanDataKe);
  delay(3000);

  tft.fillScreen(ILI9341_BLACK);
  tft.setCursor(30, 50);
  tft.print("Mulai Meniup");

  Serial.println("Mulai Meniup...");
  delay(1000);
}

void resetSystem() {
  pengambilanDataKe = 0;
  sistemSiap = false;
  hitungPulsaFlow = 0;
  volume = 0.0;
  totalLajuAliran = 0.0;
  rataRataAliran = 0.0;
  hitunganSampel = 0;

  startTime = 0;
  endTime = 0;
  duration = 0;

  tft.fillScreen(ILI9341_BLACK);
  Serial.println("Sistem di-reset.");
}

void loop() {
  statusTombol = digitalRead(pinTombol) == LOW;

  if (statusTombol && !statusTombolSebelumnya) {
    if (!sistemSiap && pengambilanDataKe < 20) {
      pengambilanDataKe++;
      Serial.print("Pengambilan Data Ke-");
      Serial.println(pengambilanDataKe);

      if (pengambilanDataKe == 11) {
        tft.fillScreen(ILI9341_BLACK);
        tft.setTextColor(ILI9341_WHITE);
        tft.setTextSize(2);
        tft.setCursor(50, 50);
        tft.print("Hebat!");
        tft.setCursor(50, 100);
        tft.print("10 Data Lagi!");
        delay(3000);
      }

      persiapanAwal();
      abaAba();
      sistemSiap = true;
      hitungPulsaFlow = 0;
      volume = 0.0;
    } else if (pengambilanDataKe == 20) {
      Serial.println("Pengambilan data selesai.");
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_WHITE);
      tft.setTextSize(2);
      tft.setCursor(50, 50);
      tft.print("Selamat!");
      tft.setCursor(50, 100);
      tft.print("Semua Selesai!");
      delay(5000);

      tft.fillScreen(ILI9341_BLACK);
      sistemSiap = false;
      pengambilanDataKe = 0;
    }
  }

  statusTombolSebelumnya = statusTombol;

  if (sistemSiap) {
    if ((millis() - waktuLama) > 200) {
      if (hitungPulsaFlow > 0 && startTime == 0) {
        startTime = millis();
      }

      detachInterrupt(digitalPinToInterrupt(pinFlowMeter));
      lajuAliran = hitungPulsaFlow / 7.5 * 25;
      volume += (lajuAliran / 60.0) * 0.2;

      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_WHITE);
      tft.setTextSize(2);
      tft.setCursor(20, 50);
      tft.print("Laju: ");
      tft.print(lajuAliran, 2);
      tft.print(" L/m");

      tft.setCursor(20, 100);
      tft.print("Vol: ");
      tft.print(volume * 1000);
      tft.print(" mL");

      hitungPulsaFlow = 0;
      waktuLama = millis();
      attachInterrupt(digitalPinToInterrupt(pinFlowMeter), flowISR, RISING);
    }

    if (lajuAliran == 0 && volume > 0) {
      endTime = millis();
      duration = (endTime - startTime) / 1000;
      tampilkanHasil();
      sistemSiap = false;
    }
  }
}

At the very least, your program contains code that will cause undefined behavior.

const int pinHijau[] = {30, 32};

The number of elements in the array pinHijau[] is two, while 4 elements are accessed and some unexpected GPIOs are configured in setup().

This may result in unexpected behavior.

When I compiled some of your code, I got the following warning something like this:

const int pinMerah[] = {22, 24, 26, 28};
const int pinHijau[] = {30, 32};
const int pinTombol = 5;
const int pinFlowMeter = 2;
const int pinBuzzer = 4;

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("");

  for (int i = 0; i < 4; i++) {
    Serial.println(pinHijau[i]);
    Serial.println(pinMerah[i]);
    Serial.println(pinHijau[i]);
    Serial.println(pinMerah[i]);
  }
}

void loop() {}

The warning:

/private/var/folders/12/mb_1z0bj731dzjd6j8h6t5zh0000gn/T/.arduinoIDE-unsaved202515-91579-1qc3e58.uik4/sketch_feb5a/sketch_feb5a.ino: In function 'void setup()':
/private/var/folders/12/mb_1z0bj731dzjd6j8h6t5zh0000gn/T/.arduinoIDE-unsaved202515-91579-1qc3e58.uik4/sketch_feb5a/sketch_feb5a.ino:13:30: warning: iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]
   13 |     Serial.println(pinHijau[i]);
      |                    ~~~~~~~~~~^
/private/var/folders/12/mb_1z0bj731dzjd6j8h6t5zh0000gn/T/.arduinoIDE-unsaved202515-91579-1qc3e58.uik4/sketch_feb5a/sketch_feb5a.ino:12:21: note: within this loop
   12 |   for (int i = 0; i < 4; i++) {
      |                   ~~^~~

I think you should try increasing the Compiler warning level in Preferences.

1 Like

This is not clear. Can you display data types other than strings or can't you display anything at all on the screen ?

In any case, you should reduce you code to the minimum necessary to demonstrate the problem.

Try this line to replace the object creation (using minimum arguments):

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

Is your code running, but "clear screen" is used when it should not be?

  tft.fillScreen(ILI9341_BLACK);

I didn't try for images, but the thing is I already try with the example code which contains strings (I found it on the internet)

Ah, thanks. I fixed it. But still the ILI9341 won't show anything

What do you mean "the component" ? Have you confirmed that the ILI9341 works by itself?
If yes, then there's clearly a problem with the rest of the logic.
If no, then you should first check that the ILI9341 itself works.

Unfortunately I don't have a Mega and I'm not familiar with cores other than the Renesas series, so please forgive me if I'm wrong.

When connecting peripherals to Arduino, I think it's best to use the hardware specific standard pinout defined in pins_arduino.h. (Of course, you can make other arrangements if necessary.)

For example, pins_arduino.h for the Mega 2560 defines as follows:

#define PIN_SPI_SS    (53)
#define PIN_SPI_MOSI  (51)
#define PIN_SPI_MISO  (50)
#define PIN_SPI_SCK   (52)

static const uint8_t SS   = PIN_SPI_SS;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK  = PIN_SPI_SCK;

On the other hand, for the ATmega4809 series, there are the variants nona4809 and uno2018, and your SPI definition looks the same as the nona4809.

#define PIN_SPI_MISO  (12)
#define PIN_SPI_SCK   (13)
#define PIN_SPI_MOSI  (11)
#define PIN_SPI_SS    (8)

static const uint8_t SS   = PIN_SPI_SS;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK  = PIN_SPI_SCK;

Anyway, all I can say here is:

  1. Set your board type correctly,
  2. Use the standard pinout defined in pins_arduino.h, and check the basic examples for each component,
  3. Debug your logic when you put it all together.

In particular, in step 2, if you use SS, MOSI, MISO, SCK, etc. instead of numerical values, it will be easier to port the settings to other boards.

Good luck.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.