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);
}