Any .ino ported to PIO gives black screen on TTGO-T

I am trying to move from Arduino IDE to VSC-PIO.
I have setup environment, all looks good, but after uploading
.cpp code to the board I get only black screen.
binwalk / diff shows that dump files differ.
What causes that PIO using same tools, produce different code ?
How can I fix it ?

Show your full platformio.ini, code and settings that you use within th Arduino IDE as well as the installed package versions in the Arduino IDE board manager for the target board.

1 Like

Is there any top level, all encompassing platformio.ini ?
Find indicates that I have here a bunch of platformio.ini
with some examples and a few with the projects that I have
created yesterday. Anyhow, here is platformio.ini from the
last one. Is complete as you requested:
indent preformatted text by 4 spaces

;PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:ttgo-t1]
lib_extra_dirs = ~/Documents/Arduino/libraries
board = ttgo-t1
platform = espressif32
framework = arduino
upload_port = /dev/ttyUSB0
monitor_speed = 115200
upload_speed = 921000

Arduino 1.8.9
boards.txt (relevant excerpt)
indent preformatted text by 4 spaces
ttgo-t1.name=TTGO T1

ttgo-t1.upload.tool=esptool_py
ttgo-t1.upload.maximum_size=1310720
ttgo-t1.upload.maximum_data_size=327680
ttgo-t1.upload.wait_for_upload_port=true

ttgo-t1.serial.disableDTR=true
ttgo-t1.serial.disableRTS=true

ttgo-t1.build.mcu=esp32
ttgo-t1.build.core=esp32
ttgo-t1.build.variant=ttgo-t1
ttgo-t1.build.board=TTGO_T1

ttgo-t1.build.f_cpu=240000000L
ttgo-t1.build.flash_size=4MB
ttgo-t1.build.flash_freq=40m
ttgo-t1.build.flash_mode=dio
ttgo-t1.build.boot=dio
ttgo-t1.build.partitions=default
ttgo-t1.build.defines=

library
TFT_espi 1.4.16

As for the code, any example from TFT_espi library I tried yields the same outcome. Here is one (dunno how to activate code in your forum’s editor).

//The Game of Life, also known simply as Life, is a cellular automaton
//devised by the British mathematician John Horton Conway in 1970.
// https://en.wikipedia.org/wiki/Conway's_Game_of_Life

// See license at end of file.

// Adapted by Bodmer
#include <Arduino.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>

TFT_eSPI tft = TFT_eSPI();       // Invoke custom library

// Maximum number of generations until the screen is refreshed
#define MAX_GEN_COUNT 500

// The ESP8266 has plenty of memory so we can create a large array
// 2 x 2 pixel cells, array size = 5120 bytes per array, runs fast
#define GRIDX 240
#define GRIDY 135
#define CELLXY 2

// 1 x 1 pixel cells, array size = 20480 bytes per array
//#define GRIDX 160
//#define GRIDY 128
//#define CELLXY 1

#define GEN_DELAY 10 // Set a delay between each generation to slow things down

//Current grid and newgrid arrays are needed
uint8_t grid[GRIDX][GRIDY];

//The new grid for the next generation
uint8_t newgrid[GRIDX][GRIDY];

//Number of generations
uint16_t genCount = 0;



void drawGrid(void);
void initGrid(void);
void computeCA();
int getNumberOfNeighbors(int x, int y);




void setup()   {

  //Set up the display
  tft.init();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);
  tft.setTextSize(1);
  tft.setTextColor(TFT_WHITE);
  tft.setCursor(0, 0);

}

void loop() {

  //Display a simple splash screen
  tft.fillScreen(TFT_BLACK);
  tft.setTextSize(2);
  tft.setTextColor(TFT_WHITE);
  tft.setCursor(40, 5);
  tft.println(F("Arduino"));
  tft.setCursor(35, 25);
  tft.println(F("Cellular"));
  tft.setCursor(35, 45);
  tft.println(F("Automata"));

  delay(1000);

  tft.fillScreen(TFT_BLACK);

  initGrid();

  genCount = MAX_GEN_COUNT;

  drawGrid();

  //Compute generations
  for (int gen = 0; gen < genCount; gen++)
  {
    computeCA();
    drawGrid();
    delay(GEN_DELAY);
    for (int16_t x = 1; x < GRIDX-1; x++) {
      for (int16_t y = 1; y < GRIDY-1; y++) {
        grid[x][y] = newgrid[x][y];
      }
    }

  }
}

//Draws the grid on the display
void drawGrid(void) {

  uint16_t color = TFT_WHITE;
  for (int16_t x = 1; x < GRIDX - 1; x++) {
    for (int16_t y = 1; y < GRIDY - 1; y++) {
      if ((grid[x][y]) != (newgrid[x][y])) {
        if (newgrid[x][y] == 1) color = 0xFFFF; //random(0xFFFF);
        else color = 0;
        tft.fillRect(CELLXY * x, CELLXY * y, CELLXY, CELLXY, color);
      }
    }
  }
}

//Initialise Grid
void initGrid(void) {
  for (int16_t x = 0; x < GRIDX; x++) {
    for (int16_t y = 0; y < GRIDY; y++) {
      newgrid[x][y] = 0;

      if (x == 0 || x == GRIDX - 1 || y == 0 || y == GRIDY - 1) {
        grid[x][y] = 0;
      }
      else {
        if (random(3) == 1)
          grid[x][y] = 1;
        else
          grid[x][y] = 0;
      }

    }
  }
}

//Compute the CA. Basically everything related to CA starts here
void computeCA() {
  for (int16_t x = 1; x < GRIDX; x++) {
    for (int16_t y = 1; y < GRIDY; y++) {
      int neighbors = getNumberOfNeighbors(x, y);
      if (grid[x][y] == 1 && (neighbors == 2 || neighbors == 3 ))
      {
        newgrid[x][y] = 1;
      }
      else if (grid[x][y] == 1)  newgrid[x][y] = 0;
      if (grid[x][y] == 0 && (neighbors == 3))
      {
        newgrid[x][y] = 1;
      }
      else if (grid[x][y] == 0) newgrid[x][y] = 0;
    }
  }
}

// Check the Moore neighborhood
int getNumberOfNeighbors(int x, int y) {
  return grid[x - 1][y] + grid[x - 1][y - 1] + grid[x][y - 1] + grid[x + 1][y - 1] + grid[x + 1][y] + grid[x + 1][y + 1] + grid[x][y + 1] + grid[x - 1][y + 1];
}

/*
   The MIT License (MIT)

   Copyright (c) 2016 RuntimeProjects.com

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in all
   copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   SOFTWARE.
*/

So next we’d need to see the library dependency tree which is displayed at the start of the compilation to know whether or not is has detected the correct library folder to use, otherwise it won’t use your correct User_Setup_Select.h.

However it also seems that this library has specific PlatformIO instructions which are not followed by your project

Which is further explained here

https://github.com/Bodmer/TFT_eSPI/blob/master/Tools/PlatformIO/Configuring%20options.txt

What is the exact header file you’re using from TFT_eSPI/User_Setups at master · Bodmer/TFT_eSPI · GitHub? The “TTGO-T1” doesn’t seem to have an on-board display by itself.

That one.

My whole post went making love when I have attached that pic.
Nice =/

Anyways, here is the compilation record from PIO:

Executing task in folder 191019-173214-ttgo-t1: platformio run --target upload 
Processing ttgo-t1 (board: ttgo-t1; platform: espressif32; framework: arduino)
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: [link limit]
PLATFORM: Espressif 32 1.11.0 > TTGO T1
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (esp-prog) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES: framework-arduinoespressif32 2.10004.191002 (1.0.4), tool-esptoolpy 1.20600.0 (2.6.0), toolchain-xtensa32 2.50200.80 (5.2.0), tool-mkspiffs 2.230.0 (2.30)
LDF: Library Dependency Finder -> [link limit]
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 27 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <TFT_eSPI> 1.4.17
|   |-- <FS> 1.0
|   |-- <SPIFFS> 1.0
|   |   |-- <FS> 1.0
|   |-- <SPI> 1.0
|-- <SPI> 1.0
Compiling .pio/build/ttgo-t1/src/hello_world1.cpp.o
Generating partitions .pio/build/ttgo-t1/partitions.bin
Compiling .pio/build/ttgo-t1/lib8da/FS/FS.cpp.o
Compiling .pio/build/ttgo-t1/lib8da/FS/vfs_api.cpp.o
Archiving .pio/build/ttgo-t1/lib8da/libFS.a
Indexing .pio/build/ttgo-t1/lib8da/libFS.a
Compiling .pio/build/ttgo-t1/lib28a/SPIFFS/SPIFFS.cpp.o
Archiving .pio/build/ttgo-t1/lib28a/libSPIFFS.a
Indexing .pio/build/ttgo-t1/lib28a/libSPIFFS.a
Compiling .pio/build/ttgo-t1/lib55f/SPI/SPI.cpp.o
Archiving .pio/build/ttgo-t1/lib55f/libSPI.a
Indexing .pio/build/ttgo-t1/lib55f/libSPI.a
Compiling .pio/build/ttgo-t1/libf8b/TFT_eSPI_ID1559/TFT_eSPI.cpp.o
Archiving .pio/build/ttgo-t1/libf8b/libTFT_eSPI_ID1559.a
Indexing .pio/build/ttgo-t1/libf8b/libTFT_eSPI_ID1559.a
Archiving .pio/build/ttgo-t1/libFrameworkArduinoVariant.a
Indexing .pio/build/ttgo-t1/libFrameworkArduinoVariant.a
Compiling .pio/build/ttgo-t1/FrameworkArduino/Esp.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/FunctionalInterrupt.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/HardwareSerial.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/IPAddress.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/IPv6Address.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/MD5Builder.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/Print.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/Stream.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/StreamString.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/WMath.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/WString.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/base64.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/cbuf.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-adc.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-bt.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-cpu.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-dac.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-gpio.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-i2c.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-ledc.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-matrix.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-misc.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-psram.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-rmt.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-sigmadelta.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-spi.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-time.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-timer.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-touch.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/esp32-hal-uart.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/libb64/cdecode.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/libb64/cencode.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/main.cpp.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/stdlib_noniso.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/wiring_pulse.c.o
Compiling .pio/build/ttgo-t1/FrameworkArduino/wiring_shift.c.o
Archiving .pio/build/ttgo-t1/libFrameworkArduino.a
Indexing .pio/build/ttgo-t1/libFrameworkArduino.a
Linking .pio/build/ttgo-t1/firmware.elf
Building .pio/build/ttgo-t1/firmware.bin
esptool.py v2.6
Retrieving maximum program size .pio/build/ttgo-t1/firmware.elf
Checking size .pio/build/ttgo-t1/firmware.elf
Memory Usage -> [link limit]
DATA:    [          ]   4.8% (used 15772 bytes from 327680 bytes)
PROGRAM: [==        ]  22.7% (used 298131 bytes from 1310720 bytes)
Configuring upload protocol...
AVAILABLE: esp-prog, espota, esptool, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa
CURRENT: upload_protocol = esptool
Looking for upload port...
Use manually specified: /dev/ttyUSB0
Uploading .pio/build/ttgo-t1/firmware.bin
esptool.py v2.6
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: 24:6f:28:25:13:d8
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921000
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 17408 bytes to 11231...
Writing at 0x00001000... (100 %)
Wrote 17408 bytes (11231 compressed) at 0x00001000 in 0.2 seconds (effective 735.2 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 128...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (128 compressed) at 0x00008000 in 0.0 seconds (effective 699.6 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 1972.9 kbit/s)...
Hash of data verified.
Compressed 298240 bytes to 144212...
Writing at 0x00010000... (11 %)
Writing at 0x00014000... (22 %)
Writing at 0x00018000... (33 %)
Writing at 0x0001c000... (44 %)
Writing at 0x00020000... (55 %)
Writing at 0x00024000... (66 %)
Writing at 0x00028000... (77 %)
Writing at 0x0002c000... (88 %)
Writing at 0x00030000... (100 %)
Wrote 298240 bytes (144212 compressed) at 0x00010000 in 2.7 seconds (effective 893.6 kbit/s)...
Hash of data verified.

and here excerpts from User_Setup_Select.h:

#ifndef USER_SETUP_LOADED // Lets PlatformIO users define settings in // platformio.ini, see notes in "Tools" folder. #include // Setup file for ESP32 and TTGO T-Display ST7789V SPI bus TFT

Link to Bodmer’s document gives 404, but they are included in the library.

So what is the recommended set of -D switches to get it working on PIO ?

Don’t think it’s going to work for you… unless you have a completely different board to this… the pinout shows it to be a I2C interface, not SPI… but if it did… it should just be a matter stating that user settings are already loaded, what driver to use, and what pins, etc… i.e. for a TFT LCD I use

build_flags =
  -DUSER_SETUP_LOADED
  -DILI9341_DRIVER
  -DTFT_CS=15
  -DTFT_DC=0
  -DTFT_RST=-1
  ...
  ...

How did you get the display working on Arduino IDE?

  • selected correct board (TTGO-T1)
  • added libraries using Sketch → Include Library → Add ZIP Library
  • built project
    and off you go without any hitch.

Now for the posterity. If anyone encouter similar problem with black screen after uploading from PIO - what solved my issues:

  • got rid of old Workspace
  • created new Workspace
  • created new project
  • copied all needed libs to the local project’s lib folder
  • PlatformIO icon → Project Tasks → Clean, Update project libraries, Rebuid Intellisense index (all just in case)
  • Built (OK no err)
  • Uploaded
    display works, code is running just fine without adding any extra switches to platformio.ini

HTH

1 Like

Thanks for the update. :slight_smile:

Which library was it for the display… TFT_eSPI… or a different one? As I’m curious as to if TFT_eSPI does actually support I2C OLEDs also… or if this is one of the OLED displays that can be switched between I2C and SPI.

I did not touch anything OLED / I2C combo yet, so I am definitely not the best one to advise, but unless you require some very specific funcionality from TFT_espi why don’t you try U8g2/U8x8 lib instead ?

1 Like