The level converter because the ESP32 has logic values with a 3.3V base, while the MAX485 chip is powered at 5V, therefore with 5V logic values, for the rest of your communication it is not clear to me ... master- sketch attached
/*
Progetto 17 - MASTER - maschera con Logo per TFT ILI9341 2,8" SPI
* MASTER
Coil Read-write 1 bit 00001 β 09999
Discrete input Read-only 1 bit 10001 β 19999
Input register Read-only 16 bits 30001 β 39999
Holding register Read-write 16 bits 40001 β 49999
*/
#include "SPI.h"
#include "TFT_eSPI.h"
#include <PNGdec.h>
#include "logo.h"
PNG png; // PNG decoder inatance
#define MAX_IMAGE_WDITH 240 // Adjust for your images
// Use hardware SPI
TFT_eSPI tft = TFT_eSPI();
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#define PinRicezione 16 // collegare l'RO della RS485
#define PinTrasmissione 17 //collegare il DI della RS485
#define PinControllo 27 //collegare il DE e l'RE della RS485
#define MODBUS_SERIAL_BAUD 9600 // Baud rate for esp32 and max485 communication
SoftwareSerial RS485Serial(PinRicezione, PinTrasmissione); // RX, TX
ModbusMaster node; //Creo l'oggetto node
int16_t xpos = 80;
int16_t ypos = 10;
//variabili dove memorizzo le letture provenienti dagli slave
int S1_dato1 =0; int S1_dato2 =0; int S1_dato3 =0; int S1_dato4 =0; int S1_dato5 =0; int S1_dato6 =0;
int S2_dato1 =0; int S2_dato2 =0; int S2_dato3 =0; int S2_dato4 =0; int S2_dato5 =0; int S2_dato6 =0;
int S3_dato1 =0; int S3_dato2 =0; int S3_dato3 =0; int S3_dato4 =0; int S3_dato5 =0; int S3_dato6 =0;
int S4_dato1 =0; int S4_dato2 =0; int S4_dato3 =0; int S4_dato4 =0; int S4_dato5 =0; int S4_dato6 =0;
//variabili di servizio
int result = 0; //variabile di lettura del buffer
int p = 0; //contatore
void preTransmission()
{
digitalWrite(PinControllo, 1); //abilito il DE/RE della RS485 alla trasmissione
}
void postTransmission()
{
digitalWrite(PinControllo, 0); //disabilito il DE/RE della RS485 alla trasmissione
}
void setup() {
Serial.begin(9600);
tft.begin(); //Inizializzazione schermo
tft.setRotation(0); //Rotazione schermo 0=verticale 1=orizzontale
tft.fillScreen(TFT_BLUE); //cancella lo schermo e lo colora di blu
tft.setTextColor(TFT_YELLOW); //setta il colore del testo
tft.setTextSize(3); //setta la dimensione del carattere
tft.setCursor(50, 80); //posiziona il cursore alle coordinate indicate
tft.println("BE MAKER"); //scrive il testo nella posizione del cursore
tft.setTextColor(TFT_WHITE);
tft.setTextSize(2);
tft.setCursor(20, 110);
tft.println("INIZIALIZZAZIONE");
tft.drawLine(5, 130, 235, 130, TFT_WHITE); //disegna una linea con parametri: coordinate di inizio e di fine e colore
pinMode(PinControllo, OUTPUT); //settaggio pin di abilitazione della trasmissione e ricezione
// Init in receive mode
digitalWrite(PinControllo, 0); //setto il pin inizialmente in ricezione
//Serial2.begin(baud-rate, protocol, RX pin, TX pin);.
//Serial2.begin(MODBUS_SERIAL_BAUD, SERIAL_8E1, PinRicezione, PinTrasmissione);
//Serial2.setTimeout(200);
RS485Serial.begin(9600);
// Modbus slave ID 1
tft.setTextSize(2);
tft.setCursor(5, 140);
tft.print("Iniz.RS485...");
tft.setCursor(5, 160);
tft.print("Iniz.Slave 1...");
node.setSlave(1);
node.begin(1, RS485Serial);
delay(100);
// Modbus slave ID 2
tft.setCursor(5, 180);
tft.println("Iniz.Slave 2...");
node.setSlave(2);
node.begin(2, RS485Serial);
delay(100);
// Modbus slave ID 3
tft.setCursor(5, 200);
tft.println("Iniz.Slave 3...");
node.setSlave(3);
node.begin(3, RS485Serial);
delay(100);
//Modbus slave ID 4
tft.setCursor(5, 220);
tft.println("Iniz.Slave 4...");
node.setSlave(4);
node.begin(4, RS485Serial);
delay(1000);
// Callbacks allow us to configure the RS485 transceiver correctly
tft.setCursor(5, 240);
tft.println("Iniz.Master...");
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
delay(2000);
maschera();
}
void maschera() {
tft.fillScreen(TFT_BLUE); //cancella lo schermo e lo colora di blu
tft.setRotation(0); //Rotazione schermo 0=verticale 1=orizzontale
tft.setTextColor(TFT_YELLOW); //setta il colore del testo
tft.setTextSize(3); //setta la dimensione del carattere
tft.setCursor(50, 80); //posiziona il cursore alle coordinate indicate
tft.println("BE MAKER"); //scrive il testo nella posizione del cursore
//Inserimento maschera dati
tft.setTextColor(TFT_WHITE);
tft.setTextSize(2);
tft.setCursor(5, 110);
tft.println("STATO SENSORI S");
tft.drawLine(5, 130, 235, 130, TFT_WHITE); //disegna una linea con parametri: coordinate di inizio e di fine e colore
tft.setTextSize(2);
tft.setCursor(5, 140);
tft.println("TEMP. STG [C]:");
tft.setCursor(5, 160);
tft.println("TEMP. EXT [C]:");
tft.setCursor(5, 180);
tft.println("SENS. ACQUA 1:");
tft.setCursor(5, 200);
tft.println("SENS. ACQUA 2:");
tft.setCursor(5, 220);
tft.println("SENS. ACQUA 3:");
tft.setCursor(5, 240);
tft.println("SENS. ACQUA 4:");
tft.drawLine(5, 260, 235, 260, TFT_WHITE);
}
int soglia_acqua_min = 470;
int soglia_acqua_max = 512;
float lungh = 1.0;
void loop() {
//inserimento logo
int16_t rc = png.openFLASH((uint8_t *)logo, sizeof(logo), pngDraw);
if (rc == PNG_SUCCESS) {
tft.startWrite();
rc = png.decode(NULL, 0);
tft.endWrite();
}
int t = 0;
t = p % 1; //Calcola il resto della divisione per il numero di slave e sarΓ un valore circolare 0, 1, 2, 3, 0, 1,...
//Serial.print("Contatore ");
//Serial.print(p);
//Serial.print(" Resto ");
//Serial.println(t);
//Lettura dati dagli Slave
//Lettura valori sensori S1
if(t == 0){
Serial.println("Intterrogo Slave 1...");
node.setSlave(1); //Seleziono Slave 1
result = node.readInputRegisters(0x7531, 16); //0x7531 in hex significa 30001 in decimale, il 16 indica che il buffer ha 16 posizioni
if (result == node.ku8MBSuccess) {
S1_dato1 = node.getResponseBuffer(0);
S1_dato2 = node.getResponseBuffer(1);
S1_dato3 = node.getResponseBuffer(2);
S1_dato4 = node.getResponseBuffer(3);
S1_dato5 = node.getResponseBuffer(4);
S1_dato6 = node.getResponseBuffer(5);
Serial.println("Dati ricevuti...");
}
pagina(1, S1_dato1, S1_dato2, S1_dato3, S1_dato4, S1_dato5, S1_dato6);
delay(2000);
}
//Lettura valori sensori S2
if(t == 1){
node.setSlave(2); //Seleziono Slave 2
result = node.readInputRegisters(0x7919, 16); //0x7919 in hex significa 31001 in decimale, il 16 indica che il buffer ha 16 posizioni
if (result == node.ku8MBSuccess) {
S2_dato1 = node.getResponseBuffer(0);
S2_dato2 = node.getResponseBuffer(1);
S2_dato3 = node.getResponseBuffer(2);
S2_dato4 = node.getResponseBuffer(3);
S2_dato5 = node.getResponseBuffer(4);
S2_dato6 = node.getResponseBuffer(5);
}
pagina(2, S2_dato1, S2_dato2, S2_dato3, S2_dato4, S2_dato5, S2_dato6);
delay(2000);
}
//Lettura valori sensori S3
if(t == 2){
node.setSlave(3); //Seleziono Slave 3
result = node.readInputRegisters(0x7D01, 16); //0x7D01 in hex significa 32001 in decimale, il 16 indica che il buffer ha 16 posizioni
if (result == node.ku8MBSuccess) {
S3_dato1 = node.getResponseBuffer(0);
S3_dato2 = node.getResponseBuffer(1);
S3_dato3 = node.getResponseBuffer(2);
S3_dato4 = node.getResponseBuffer(3);
S3_dato5 = node.getResponseBuffer(4);
S3_dato6 = node.getResponseBuffer(5);
}
pagina(3, S3_dato1, S3_dato2, S3_dato3, S3_dato4, S3_dato5, S3_dato6);
delay(2000);
}
//Lettura valori sensori S4
if(t == 3){
node.setSlave(4); //Seleziono Slave 3
result = node.readInputRegisters(0x80E9, 16); //0x80E9 in hex significa 33001 in decimale, il 16 indica che il buffer ha 16 posizioni
if (result == node.ku8MBSuccess) {
S4_dato1 = node.getResponseBuffer(0);
S4_dato2 = node.getResponseBuffer(1);
S4_dato3 = node.getResponseBuffer(2);
S4_dato4 = node.getResponseBuffer(3);
S4_dato5 = node.getResponseBuffer(4);
S4_dato6 = node.getResponseBuffer(5);
}
pagina(4, S4_dato1, S4_dato2, S4_dato3, S4_dato4, S4_dato5, S4_dato6);
delay(2000);
}
p++;
tft.setTextColor(TFT_WHITE,TFT_BLUE);
tft.setTextSize(3);
tft.setCursor(40, 285);
tft.print(" ");
}
void pagina (int pg, int s1, int s2, int s3, int s4, int s5, int s6){
//Serial.print("pagina ");
//Serial.println(pg);
tft.setTextSize(2); //setta la dimensione del carattere
tft.setCursor(200, 110);
tft.setTextColor(TFT_WHITE,TFT_BLUE); //setta il colore del testo
tft.print(pg); // Indica il sensore a cui la pagina fa riferimento
if (s1 > 5000) {
tft.setCursor(180, 140);
tft.setTextColor(TFT_WHITE,TFT_RED);
tft.println(" ");
tft.setCursor(180, 140);
tft.println(float (s1/100.0));
allarme(pg);
} else {
tft.setCursor(180, 140);
tft.setTextColor(TFT_WHITE,TFT_BLUE);
tft.println(" ");
tft.setCursor(180, 140);
tft.println(float (s1/100.0));
}
if (s2 > 5000) {
tft.setCursor(180, 160);
tft.setTextColor(TFT_WHITE,TFT_RED);
tft.println(" ");
tft.setCursor(180, 160);
tft.println(float (s2/100.0));
allarme(pg);
} else {
tft.setCursor(180, 160);
tft.setTextColor(TFT_WHITE,TFT_BLUE);
tft.println(" ");
tft.setCursor(180, 160);
tft.println(float (s2/100.0));
}
if (s3 > soglia_acqua_min) {
tft.setCursor(180, 180);
tft.setTextColor(TFT_WHITE,TFT_RED);
tft.println(" ");
tft.setCursor(180, 180);
float dist_1 = lungh - ((s3*1.0)/(soglia_acqua_max*1.0));
tft.println(dist_1);
allarme(pg);
} else {
tft.setCursor(180, 180);
tft.setTextColor(TFT_WHITE,TFT_BLUE);
tft.println(" ");
tft.setCursor(180, 180);
tft.println(s3);
}
if (s4 > soglia_acqua_min) {
tft.setCursor(180, 200);
tft.setTextColor(TFT_WHITE,TFT_RED);
tft.println(" ");
tft.setCursor(180, 200);
float dist_2 = lungh - ((s4*1.0)/(soglia_acqua_max*1.0));
tft.println(dist_2);
allarme(pg);
} else {
tft.setCursor(180, 200);
tft.setTextColor(TFT_WHITE,TFT_BLUE);
tft.println(" ");
tft.setCursor(180, 200);
tft.println(s4);
}
if (s5 > soglia_acqua_min) {
tft.setCursor(180, 220);
tft.setTextColor(TFT_WHITE,TFT_RED);
tft.println(" ");
tft.setCursor(180, 220);
float dist_3 = lungh - ((s5*1.0)/(soglia_acqua_max*1.0));
tft.println(dist_3);
allarme(pg);
} else {
tft.setCursor(180, 220);
tft.setTextColor(TFT_WHITE,TFT_BLUE);
tft.println(" ");
tft.setCursor(180, 220);
tft.println(s5);
}
if (s6 > soglia_acqua_min) {
tft.setCursor(180, 240);
tft.setTextColor(TFT_WHITE,TFT_RED);
tft.println(" ");
tft.setCursor(180, 240);
float dist_4 = lungh - ((s6*1.0)/(soglia_acqua_max*1.0));
tft.println(dist_4);
allarme(pg);
} else {
tft.setCursor(180, 240);
tft.setTextColor(TFT_WHITE,TFT_BLUE);
tft.println(" ");
tft.setCursor(180, 240);
tft.println(s6);
}
}
int g = 0;
void allarme(int f){
int j=0;
j = g % 2;
//Serial.print("Contatore allarme ");
//Serial.print(f);
//Serial.print(" Resto ");
//Serial.println(j);
if (j==0) {
tft.setTextColor(TFT_WHITE,TFT_RED);
tft.setTextSize(3);
tft.setCursor(40, 285);
tft.println("ALLARME !");
tft.setTextSize(2);
} else {
tft.setTextColor(TFT_WHITE,TFT_BLUE);
tft.setTextSize(3);
tft.setCursor(40, 285);
tft.println("ALLARME !");
tft.setTextSize(2);
}
g++;
}
//=========================================v==========================================
// pngDraw
//====================================================================================
// This next function will be called during decoding of the png file to
// render each image line to the TFT. If you use a different TFT library
// you will need to adapt this function to suit.
// Callback function to draw pixels to the display
void pngDraw(PNGDRAW *pDraw) {
uint16_t lineBuffer[MAX_IMAGE_WDITH];
png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
tft.pushImage(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer);
}