Buffer Issue with TFT/Wifi?

Hey all,

I'm not sure what problem I am experiencing but was looking to get some help. I have an ESP32-S3-TFT connected to 2x VL53L4CD sensors that are continuously reading, and a ESPAsync web server to provide the results. I also have a TFT display that I am trying to print the results onto at the same time.

The serial monitor works and prints out the 2 sensor readings flawlessly, however, on the TFT display it seems to print random characters where my sensor readings are supposed to be (unless the sensor is blocked and it is a constant 0). Additionally, on the web server it seems to also be experiencing issues where it just stays as 0 and does not respond to anything.

Does anyone know what's happening? (also my littleFS keeps failing to mount so I have just put the index.html code inside the main.cpp).

/* Includes ------------------------------------------------------------------*/
#include <Arduino.h>
#include <Wire.h>
#include <vl53l4cd_class.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <stdlib.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <LittleFS.h>

#define DEV_I2C Wire
#define SerialPort Serial
char report[64];
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// Replace with your network credentials
const char* ssid = "Laser Bucket Height Tool";
const char* password = "1234";
IPAddress IP;

// Create AsyncWebServer object on port 80
AsyncWebServer server (80);

//address we will assign if dual sensor is present
uint8_t sensor1add = 0x51;
uint8_t sensor2add = 0x28;

// set the pins to shutdown
#define xshut1 14 //14 is A0
#define xshut2 15 //15 is A1
#define GFX_BL DF_GFX_BL

//this holds the measurement
VL53L4CD_Result_t results1;
VL53L4CD_Result_t results2;
float sensor1, sensor2;

//Components.
VL53L4CD sensor1_vl53l4cd_sat(&DEV_I2C, A0);
VL53L4CD sensor2_vl53l4cd_sat(&DEV_I2C, A1);

int offset;
uint8_t NewDataReady1 = 0;
uint8_t NewDataReady2 = 0;
uint8_t status1;
uint8_t status2;

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
  <title>Laser Bucket Height Tool</title>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
  <link rel="stylesheet" type="text/css" href="style.css">
  <script src="https://kit.fontawesome.com/a30daafdec.js" crossorigin="anonymous"></script>
</head>
<body>
  <h2>Chuck Height Sensor</h2>
  <p>
    <i class="fa-solid fa-ruler-vertical" style="color: #f5e609;"></i> 
    <span class="sensor-labels">Distance 1</span> 
    <span id="distance1">%DISTANCE%</span>
    <span class="units"> mm</span>
  </p>
  <p>
    <i class="fa-solid fa-ruler-vertical" style="color: #f5e609;"></i> 
    <span class="sensor-labels">Distance 2</span> 
    <span id="distance2">%DISTANCE%</span>
    <span class="units"> mm</span>
  <p>
    <i class="fa-solid fa-minus" style="color: #f5e609;"></i> 
    <span class="sensor-labels">Offset</span> 
    <span id="offset">%OFFSET%</span>
    <span class="units"> mm</span>
  </p>
  <label><input class = "button" type="button" value="Zero" onclick="zero()" id="zero"></label>
  <label><input class = "button" type="button" value="Reset" onclick="reset()" id="reset"></label>
  <div id="error" style="display: none;">
  <p>
    <i class="fa-solid fa-triangle-exclamation" style="color: red;"></i>
    <span class="sensor-labels">Not connected to sensor!</span>
  </p>
</div>
<script src="script.js"></script>
</html>
)rawliteral";

// Initialize LittleFS
void initLittleFS() {

  if(!LittleFS.begin(true)){
    Serial.println("An Error has occurred while mounting LittleFS");
    return;
  }
  Serial.println("LittleFS mounted successfully");
}

//init Wifi
void initWifi(){
  Serial.print("Setting AP (Access Point)...");
  // No password
  WiFi.softAP(ssid);
  // Start WiFi Access Point
  IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.print(IP);
  Serial.println();
}

//init TFT
void initTFT(){
  // turn on backlite
  pinMode(TFT_BACKLITE, OUTPUT);
  digitalWrite(TFT_BACKLITE, HIGH);

  // turn on the TFT / I2C power supply
  pinMode(TFT_I2C_POWER, OUTPUT);
  digitalWrite(TFT_I2C_POWER, HIGH);
  delay(10);

  // initialize TFT
  tft.init(135, 240); // Init ST7789 240x135
  tft.setRotation(3);
  tft.fillScreen(ST77XX_BLACK);
}

//init sensors
void initSensors(VL53L4CD sensorX, VL53L4CD sensorY, uint8_t sensorXAdd, uint8_t sensorYAdd)
{
  VL53L4CD_ERROR err;
  
  sensor1_vl53l4cd_sat.begin();
  sensor1_vl53l4cd_sat.VL53L4CD_Off();

  sensor2_vl53l4cd_sat.begin();
  sensor2_vl53l4cd_sat.VL53L4CD_Off();

  do{
    err = sensor1_vl53l4cd_sat.InitSensor(sensorXAdd);
    delay(10);
    Serial.println("InitSensor 1");
  }while(err != VL53L4CD_ERROR_NONE);

  do{
    err = sensor2_vl53l4cd_sat.InitSensor(sensorYAdd);
    delay(10);
    Serial.println("InitSensor 2");
  }while(err != VL53L4CD_ERROR_NONE);

  sensor1_vl53l4cd_sat.VL53L4CD_SetRangeTiming(200, 0);
  sensor1_vl53l4cd_sat.VL53L4CD_SetOffset(-10);
  sensor1_vl53l4cd_sat.VL53L4CD_StartRanging();

  sensor2_vl53l4cd_sat.VL53L4CD_SetRangeTiming(200, 0);
  sensor2_vl53l4cd_sat.VL53L4CD_SetOffset(-10);
  sensor2_vl53l4cd_sat.VL53L4CD_StartRanging();
}

//getSensor1Reading
void getSensor1Reading(uint8_t status, uint8_t NewDataReady)
{
  digitalWrite(xshut1, HIGH);
  //Serial.println("Sensor 1 is on");
  if ((!status) && (NewDataReady != 0)) {
    // (Mandatory) Clear HW interrupt to restart measurements
    sensor1_vl53l4cd_sat.VL53L4CD_ClearInterrupt();
    // Read measured distance. RangeStatus = 0 means valid data
    sensor1_vl53l4cd_sat.VL53L4CD_GetResult(&results1);
    snprintf(report, sizeof(report), "Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
             results1.range_status,
             results1.distance_mm,
             results1.signal_per_spad_kcps);
    sensor1 = results1.distance_mm;
    Serial.println((String)"This is Sensor1 " + (float)sensor1 + (String)"mm");
  }
  digitalWrite(xshut1, LOW);
}

//getSensor2Reading
void getSensor2Reading(uint8_t status, uint8_t NewDataReady)
{
  digitalWrite(xshut2, HIGH);
  //Serial.println("Sensor 2 is on");
  if ((!status) && (NewDataReady != 0)) {
    // (Mandatory) Clear HW interrupt to restart measurements
    sensor2_vl53l4cd_sat.VL53L4CD_ClearInterrupt();
    // Read measured distance. RangeStatus = 0 means valid data
    sensor2_vl53l4cd_sat.VL53L4CD_GetResult(&results2);
    snprintf(report, sizeof(report), "Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n",
             results2.range_status,
             results2.distance_mm,
             results2.signal_per_spad_kcps);
    sensor2 = results2.distance_mm;
    Serial.println((String)"This is Sensor2 " + (float)sensor2 + (String)"mm");
  }
  digitalWrite(xshut2, LOW);
}

void zero(int newZero)
{
  offset = newZero;
  sensor1_vl53l4cd_sat.VL53L4CD_SetOffset(offset);
  sensor2_vl53l4cd_sat.VL53L4CD_SetOffset(offset);
}

void displayMeasurements(){
  // Print local IP address
  tft.setTextSize(1.5);
  tft.setCursor(0, 0);
  tft.println("Local IP: " + IP.toString());
  
  // Print battery level
  /*tft.setTextSize(2);
  tft.setCursor(0, 16);
  tft.println("Battery: " + String(getBatteryLevel()) + "%");*/
  
  // Print additional values
  tft.setTextSize(1);
  tft.setCursor(0, 40);
  tft.print("Sensor 1 Reading: "/* + (int)sensor1 + (String)" mm"*/);
  delay(100);
  tft.print(sensor1);
  tft.print(" mm");
  tft.setCursor(0, 50);
  tft.print("Sensor 2 Reading: " /*+ (int)sensor2 + (String)" mm"*/);
  delay(100);
  tft.print(sensor2);
  tft.print(" mm");
}

// Replaces placeholder with sensor values
String processor(const String& var){
  //Serial.println(var);
  getSensor1Reading(status1, NewDataReady1);
  if(var == "DISTANCE"){
    return String(sensor1);
  }
  else if(var =="OFFSET"){
    return String(offset);
  }
  return String();
  getSensor2Reading(status2, NewDataReady2);
  if(var == "DISTANCE"){
    return String(sensor2);
  }
  else if(var =="OFFSET"){
    return String(offset);
  }
  return String();
}

/* Setup ---------------------------------------------------------------------*/
void setup()
{
  // Initialize serial for output.
  SerialPort.begin(115200);
  while(!Serial) {}
  SerialPort.println("Starting...");
  LittleFS.begin();
  initLittleFS();
  initWifi(); 
  initTFT();
  // Route for root / web page
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });
  /*server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/index.html", String(), false, processor);
  });*/

  // Route to load style.css file, and script.js file
  server.serveStatic("/style.css", LittleFS, "/text/css");

  server.on("/distance1", HTTP_GET, [](AsyncWebServerRequest *request){
    getSensor1Reading(status1, NewDataReady1);
    request->send_P(200, "text/plain", String(sensor1).c_str());
  });

  server.on("/distance2", HTTP_GET, [](AsyncWebServerRequest *request){
    getSensor1Reading(status1, NewDataReady1);
    request->send_P(200, "text/plain", String(sensor2).c_str());
  });

    server.on("/offset", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(offset).c_str());
  });

  server.on("/zero", HTTP_GET, [] (AsyncWebServerRequest *request){
  zero(sensor1);
  Serial.println("Sensor Zeroed");
  });

  server.on("/reset", HTTP_GET, [] (AsyncWebServerRequest *request){
  offset = 0;
  Serial.println("Offset Reset");
  });

  server.begin();
  
  // Initialize I2C bus.
  DEV_I2C.begin();
  
  initSensors(sensor1_vl53l4cd_sat, sensor2_vl53l4cd_sat, sensor1add, sensor2add);
}

void loop()
{
  do {
    status1 = sensor1_vl53l4cd_sat.VL53L4CD_CheckForDataReady(&NewDataReady1);
    status2 = sensor2_vl53l4cd_sat.VL53L4CD_CheckForDataReady(&NewDataReady2);
  } while (!NewDataReady1 || !NewDataReady2);
  getSensor1Reading(status1, NewDataReady1);
  getSensor2Reading(status2, NewDataReady2);
  Serial.println(IP);

  displayMeasurements();

  delay(100);
}

Try just an example for the display.
Does it work?

Yes, the display example works, and the printed text that I have that is constant works, just not the constantly updating sensor result variable.

could be part of it..

~q

Hmm, would constantly pinging it to an async web server cause issues with also displaying it on the TFT display?

Also, It seems like the web server does receive the data, but only when refreshing the web page. It doesn't constantly update (it seems like the web page is just one instance at one time). How would I loop this?

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