Communication SoftwareSerial using RS485 module with ESP32

Hey Guys. I'm trying to replicate the Arduino Nano implementation to ESP32 (Read the data of sensors, conect to WIFI and send to external Server). I am new to using RS485 module.

Circuit Scheme

RS485 ARUINO NANO

RE PIN(8)
DE PIN(7)
DI PIN(3)
RO PIN(2)

Hardware components:
RS485
Arduino Nano
Charger 9V (Only for soil sensor)
Soil moustiure (read 7 values)

IDE:
Arduino IDE

This is the code:

#include <SoftwareSerial.h>

#define RE 8
#define DE 7
const byte nitro = {0x01,0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c};
byte values[11];
SoftwareSerial mod(2, 3);

void setup() {
  Serial.begin(9600);
  mod.begin(9600);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
}

void loop() {
  byte val1;
  val1 = nitrogen();
  delay(250);
  Serial.print("Nitrogen: ");
  Serial.print(val1);
}

byte nitrogen() {
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  if (mod.write(nitro, sizeof(nitro)) == 8) {
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for (byte i = 0; i < 7; i++) {
      values[i] = mod.read();
      Serial.print(values[i], HEX);
    }
    Serial.println();
  }
  return values[4];
}

Please, I need your help, suggestions or similar examples that you have to implement with ESP32. I'll be very grateful for your help :slight_smile:

?

For an ESP32 it shouldn't be much different but you'll probably have to do some level shifting from 3.3 to 5V since the ESP32's GPIOs are not 5V tolerant.

1 Like

Thank you very much for your response dear @Blackfin . I will notify you when I have implemented.

I have been doing tests connecting to WIFI and through Serial Port the communication with the sensor to see if there is any interference.
However, the output is the same.

[SETUP] WAIT 2...
[SETUP] WAIT 1...
Conected to WIFI!
Conected to WIFI!
Message Timeout
.
.
.
Conected to WIFI!
Conected to WIFI!
Message Timeout

This is my code:

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>

WiFiMulti wifiMulti;
#include <HardwareSerial.h>

#define RXD2 16 //RO PIN
#define TXD2 17 //DI PIN
#define MAX485_RE_DE 33 //RE & DE PIN

#define RX_BUFF_SIZE 30

//Global
float humidity;
float temperature;
int ec;
float ph;
int nitrogen;
int phosphorus;
int potassium;

enum RS485States {
  ST_IDLE = 0,
  ST_RXDATA,
  ST_CHECKDATA
};

const uint16_t crc16_tab[] PROGMEM = {
  0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
  0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
  0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
  0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
  0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
  0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
  0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
  0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
  0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
  0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
  0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
  0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
  0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
  0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
  0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
  0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
  0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
  0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
  0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
  0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
  0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
  0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
  0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
  0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
  0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
  0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
  0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
  0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
  0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
  0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
  0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
  0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
//const byte
byte requestframe[] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x07 };   //CRC is added in TX logic

uint8_t values[RX_BUFF_SIZE];
char    szStr[10];

void setup() {
  pinMode(MAX485_RE_DE, OUTPUT);
  Serial.begin(4800);

  Serial2.begin(4800, SERIAL_8N1, RXD2, TXD2);
  Serial.println();

  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }
    wifiMulti.addAP("WIFI NAME", "PASSWORD");
}
void loop() {
  if ((wifiMulti.run() == WL_CONNECTED)) {
    Serial.println("Conected to WIFI!");
    if (!Serial2) { // If the object did not initialize, then its configuration is invalid
      Serial.println("Invalid SoftwareSerial pin configuration, check config");
      while (1) { // Don't continue with invalid configuration
        delay (1000);
      }
    } else {
      ModSM();//Request and response function using modbus protocol with rs485
    }

  } else {
    Serial.println("WiFi not connected!");
  }
  delay(5000);
}

void ModSM( void ) {
  static uint32_t
  tFrameTimeout = 0ul,
  tSM = 0ul;
  static uint8_t
  dataLen,
  rxIdx,
  state = ST_IDLE;
  uint16_t
  crc;
  uint32_t
  tNow = millis();
  uint32_t timedelay = 0;
  uint8_t
  ch;

  switch ( state ) {
    case    ST_IDLE:
      if ((tNow - tSM) >= 3000ul ) {
        //flush any stray characters from RX buffer
        while ( Serial2.available() )
          Serial2.read();

        tSM = tNow;
        digitalWrite(MAX485_RE_DE, HIGH);
        //                digitalWrite(DE, HIGH);
        //                digitalWrite(RE, HIGH);
        delayMicroseconds(100);

        crc = CRC16_Modbus( requestframe, sizeof( requestframe ) );
        Serial2.write( requestframe, sizeof(requestframe) );
        Serial2.write( crc & 0xff );
        Serial2.write( (crc >> 8) & 0xff );
        delay(20);  //allow msg to go before switching DE & RE
        digitalWrite(MAX485_RE_DE, LOW);
        //                digitalWrite(DE, LOW);
        //                digitalWrite(RE, LOW);

        tFrameTimeout = tNow;    //init message timeout
        rxIdx = 0;
        dataLen = 0;
        state = ST_RXDATA;
      }

      break;

    case    ST_RXDATA:
      if ( Serial2.available() )
      {
        ch = Serial2.read();
        switch ( rxIdx )
        {
          case    0:  //address code
            //an attempt to filter leading zeros in reply
            //look for 0x01 address code
            if ( ch == 0x01 )
            {
              Serial.print( "Time to address code: " ); // added
              Serial.println( tNow - tFrameTimeout ); // added
              //got the address code
              values[rxIdx++] = ch;

            }//if
            break;

          case    1:  //function code
            //if function code is not 0x03, we're misaligned
            if ( ch != 0x03 )
              rxIdx = 0;
            else {
              Serial.print( "Time to function code: " ); // added
              Serial.println( tNow - tFrameTimeout ); // added
              values[rxIdx++] = ch;
            }

            break;

          case    2:
            //number of data + CRC bytes to follow
            dataLen = ch +  2;
            values[rxIdx++] = ch;
            break;

          default:
            //RX data and CRC
            values[rxIdx++] = ch;
            if ( rxIdx == RX_BUFF_SIZE )
              rxIdx--;

            dataLen--;
            if ( dataLen == 0 ) {
              Serial.print( "Time to end of message: " ); // added
              Serial.println( tNow - tFrameTimeout ); // added
              state = ST_CHECKDATA;
            }

            break;

        }//switch rx index

      }//if available
      //if we haven't completed the message after 1.5-seconds just return to idle state
      if ( (tNow - tFrameTimeout) >= 1500ul )
      {
        Serial.println( "Message Timeout" );
        state = ST_IDLE;
      }//if
      break;

    case    ST_CHECKDATA:

      crc = CRC16_Modbus( values, values[2] + 3 );  //+2 for header, +1 for value[2] itself
      if ( ((uint8_t)(crc & 0x0ff) == values[rxIdx - 2]) && ((uint8_t)((crc >> 8) & 0x0ff) == values[rxIdx - 1]) ) {
        //msg is good; print results
        PrintData();
      } else {
        Serial.println( "Bad CRC" );
      }//else
      state = ST_IDLE;
      break;
  }//switch
}//ModSM

uint16_t CRC16_Modbus( uint8_t *pData, uint8_t Len ) {
  //CRC16 calculation
  uint16_t crc = 0xFFFF;
  while ( Len-- )
    crc = (crc >> 8) ^ (pgm_read_word(&crc16_tab[(crc ^ *pData++) & 0xFF]) );
  return crc;

}//CRC16_Modbus

void PrintData( void ) {
  int16_t val;

  //0 index 3     moisture content
  val = (values[3] << 8) + values[4];
  humidity = val / 10.0;
  Serial.print( "Humidity....: " ); Serial.print( humidity ); Serial.println("%");

  //1 index 5     temperature
  val = (values[5] << 8) + values[6];
  temperature = val / 10.0;
  Serial.print( "Temperature.: " ); Serial.print(temperature); Serial.println(" ºC");

  //2 index 7     conductivity
  val = (values[7] << 8) + values[8];
  ec = val;
  Serial.print( "Conductivity: " ); Serial.print(ec); Serial.println("us/cm");

  //3 index 9     PH
  val = (values[9] << 8) + values[10];
  ph = (float)val / 10.0;
  Serial.print( "pH..........: " ); Serial.print((float)val / 10.0); Serial.println("");

  //4 index 11    nitrogen content
  val = (values[11] << 8) + values[12];
  nitrogen = val;
  Serial.print( "Nitrogen....: " ); Serial.print(val); Serial.println("mg/kg");

  //5 index 13    phosphorus content
  val = (values[13] << 8) + values[14];
  phosphorus = val;
  Serial.print( "Phosphorus..: " ); Serial.print(val); Serial.println("mg/kg");

  //6 index 15    potassium content
  val = (values[15] << 8) + values[16];
  potassium = val;
  Serial.print( "Potassium...: " ); Serial.print(val); Serial.println("mg/kg");
  delay(10);

  //  Serial.print("H: ");
  //  Serial.print(humidity);
  //  Serial.print(" temperature: ");
  //  Serial.print(temperature);
  //  Serial.print(" ec: ");
  //  Serial.print(ec);
  //  Serial.print(" ph: ");
  //  Serial.print(ph);
  //  Serial.print(" nitrogen: ");
  //  Serial.print(nitrogen);
  //  Serial.print(" phosphorus: ");
  //  Serial.print(phosphorus);
  //  Serial.print(" potassium: ");
  //  Serial.print(potassium);
}

I have tried connecting RE y DE to PIN 33 and then with 4.
But I'm still there without the sensor printing data.
Please dear @Blackfin I need your help to achieve.

You have a delay(5000) in your loop that allows the ModSM() function to be called only once every 5-seconds. That's a problem. The state machine must be called pretty quickly, especially when a message transaction is underway.

Try this to see if you get a different result (didn't attempt to compile as I don't have your WiFiMulti library so YMMV):

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>

WiFiMulti wifiMulti;
#include <HardwareSerial.h>

const uint8_t RXD2 = 16;            //RO PIN
const uint8_t TXD2 = 17;            //DI PIN
const uint8_t MAX485_RE_DE = 33;    //RE & DE PIN

#define RX_BUFF_SIZE 30

//Global
float 
    humidity,
    temperature,
    ph;
int 
    ec,
    nitrogen,
    phosphorus,
    potassium;

enum RS485States 
{
    ST_IDLE = 0,
    ST_RXDATA,
    ST_CHECKDATA
};

const uint16_t crc16_tab[] PROGMEM = 
{
    0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
    0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
    0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
    0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
    0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
    0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
    0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
    0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
    0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
    0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
    0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
    0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
    0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
    0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
    0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
    0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
    0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
    0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
    0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
    0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
    0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
    0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
    0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
    0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
    0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
    0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
    0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
    0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
    0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
    0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
    0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
    0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};

byte 
    grRequestframe[] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x07 };   //CRC is added in TX logic

uint8_t 
    grValues[RX_BUFF_SIZE];
char    
    szStr[10];

void setup() 
{
    pinMode(MAX485_RE_DE, OUTPUT);
    Serial.begin(4800);
    
    Serial2.begin(4800, SERIAL_8N1, RXD2, TXD2);
    Serial.println();
    
    for (uint8_t t = 4; t > 0; t--) 
    {
        Serial.printf("[SETUP] WAIT %d...\n", t);
        Serial.flush();
        delay(1000);
    }//for
    
    wifiMulti.addAP("WIFI NAME", "PASSWORD");
    
}//setup

void loop() 
{
    static uint32_t
        tLoop = 0ul;
    uint32_t
        tNow = millis();

    if( tNow - tLoop >= 5000ul )
    {
        tLoop = tNow;
        
        if ((wifiMulti.run() == WL_CONNECTED)) 
        {
            Serial.println("Conected to WIFI!");
            if (!Serial2) 
            {   
                // If the object did not initialize, then its configuration is invalid
                Serial.println("Invalid SoftwareSerial pin configuration, check config");
                while(1);
                
            }//if
    
        }//if
        else 
        {
            Serial.println("WiFi not connected!");
            
        }//else
        
    }//if

    ModSM();
            
}//loop

void ModSM( void ) 
{
    static uint32_t
        tFrameTimeout = 0ul,
        tSM = 0ul;
    static uint8_t
        dataLen,
        rxIdx,
        state = ST_IDLE;
    uint16_t
        crc;
    uint32_t
        tNow = millis(),
        timedelay = 0;
    uint8_t
        ch;

    switch ( state ) 
    {
        case    ST_IDLE:
            if ((tNow - tSM) >= 3000ul ) 
            {
                //flush any stray characters from RX buffer
                while ( Serial2.available() )
                    Serial2.read();
    
                tSM = tNow;
                digitalWrite(MAX485_RE_DE, HIGH);
                delayMicroseconds(100);
    
                crc = CRC16_Modbus( grRequestframe, sizeof( grRequestframe ) );
                Serial2.write( requestframe, sizeof(requestframe) );
                Serial2.write( crc & 0xff );
                Serial2.write( (crc >> 8) & 0xff );
                delay(20);  //allow msg to go before switching DE & RE
                digitalWrite(MAX485_RE_DE, LOW);
    
                tFrameTimeout = tNow;    //init message timeout
                rxIdx = 0;
                dataLen = 0;
                state = ST_RXDATA;
                
            }//if

        break;

        case    ST_RXDATA:
            if ( Serial2.available() )
            {
                ch = Serial2.read();
                switch ( rxIdx )
                {
                    case    0:  //address code
                        //an attempt to filter leading zeros in reply
                        //look for 0x01 address code
                        if ( ch == 0x01 )
                        {
                            Serial.print( "Time to address code: " ); // added
                            Serial.println( tNow - tFrameTimeout ); // added
                            //got the address code
                            grValues[rxIdx++] = ch;

                        }//if
                        
                    break;

                    case    1:  //function code
                        //if function code is not 0x03, we're misaligned
                        if ( ch != 0x03 )
                            rxIdx = 0;
                        else 
                        {
                            Serial.print( "Time to function code: " ); // added
                            Serial.println( tNow - tFrameTimeout ); // added
                            grValues[rxIdx++] = ch;
                        }

                    break;

                    case    2:
                        //number of data + CRC bytes to follow
                        dataLen = ch +  2;
                        grValues[rxIdx++] = ch;
                        
                    break;

                    default:
                        //RX data and CRC
                        grValues[rxIdx++] = ch;
                        if ( rxIdx == RX_BUFF_SIZE )
                            rxIdx--;

                        dataLen--;
                        if ( dataLen == 0 ) 
                        {
                            Serial.print( "Time to end of message: " ); // added
                            Serial.println( tNow - tFrameTimeout ); // added
                            state = ST_CHECKDATA;
                        }

                    break;

                }//switch rx index

            }//if available
      
            //if we haven't completed the message after 1.5-seconds just return to idle state
            if ( (tNow - tFrameTimeout) >= 1500ul )
            {
                Serial.println( "Message Timeout" );
                state = ST_IDLE;
            }//if
      
        break;

        case    ST_CHECKDATA:
            crc = CRC16_Modbus( grValues, grValues[2] + 3 );  //+2 for header, +1 for value[2] itself
            if ( ((uint8_t)(crc & 0x0ff) == grValues[rxIdx - 2]) && ((uint8_t)((crc >> 8) & 0x0ff) == grValues[rxIdx - 1]) ) 
            {
                //msg is good; print results
                PrintData();
            } 
            else 
            {
                Serial.println( "Bad CRC" );
            }//else
            state = ST_IDLE;
            
        break;
        
    }//switch
    
}//ModSM

uint16_t CRC16_Modbus( uint8_t *pData, uint8_t Len ) 
{
    //CRC16 calculation
    uint16_t crc = 0xFFFF;
    while ( Len-- )
        crc = (crc >> 8) ^ (pgm_read_word(&crc16_tab[(crc ^ *pData++) & 0xFF]) );
  
    return crc;

}//CRC16_Modbus

void PrintData( void ) 
{
    int16_t val;

    //0 index 3     moisture content
    val = (values[3] << 8) + values[4];
    humidity = val / 10.0;
    Serial.print( "Humidity....: " ); Serial.print( humidity ); Serial.println("%");

    //1 index 5     temperature
    val = (values[5] << 8) + values[6];
    temperature = val / 10.0;
    Serial.print( "Temperature.: " ); Serial.print(temperature); Serial.println(" ºC");
    
    //2 index 7     conductivity
    val = (values[7] << 8) + values[8];
    ec = val;
    Serial.print( "Conductivity: " ); Serial.print(ec); Serial.println("us/cm");
    
    //3 index 9     PH
    val = (values[9] << 8) + values[10];
    ph = (float)val / 10.0;
    Serial.print( "pH..........: " ); Serial.print((float)val / 10.0); Serial.println("");
    
    //4 index 11    nitrogen content
    val = (values[11] << 8) + values[12];
    nitrogen = val;
    Serial.print( "Nitrogen....: " ); Serial.print(val); Serial.println("mg/kg");
    
    //5 index 13    phosphorus content
    val = (values[13] << 8) + values[14];
    phosphorus = val;
    Serial.print( "Phosphorus..: " ); Serial.print(val); Serial.println("mg/kg");
    
    //6 index 15    potassium content
    val = (values[15] << 8) + values[16];
    potassium = val;
    Serial.print( "Potassium...: " ); Serial.print(val); Serial.println("mg/kg");
    delay(10);
    
    //  Serial.print("H: ");
    //  Serial.print(humidity);
    //  Serial.print(" temperature: ");
    //  Serial.print(temperature);
    //  Serial.print(" ec: ");
    //  Serial.print(ec);
    //  Serial.print(" ph: ");
    //  Serial.print(ph);
    //  Serial.print(" nitrogen: ");
    //  Serial.print(nitrogen);
    //  Serial.print(" phosphorus: ");
    //  Serial.print(phosphorus);
    //  Serial.print(" potassium: ");
    //  Serial.print(potassium);
    
}//PrintData

Thanks for your reply @Blackfin
Output prints:

Message Timeout
Conected to WIFI!
Message Timeout
Conected to WIFI!
.
.
.
Message Timeout
Message Timeout
Conected to WIFI!

Please verify your RS485 connections.

You have:

const uint8_t RXD2 = 16;            //RO PIN
const uint8_t TXD2 = 17;            //DI PIN

where the RO output pin of the MAX485 is connected to pin 16 of the Mega. However, pin 16 of the Mega is TX2; so you have an output connected to an output.

See if that helps.

I've changed RE & DE to PIN 4 and I'm still getting the same output.

ESP32 PINOUT

Ah, okay, it's an ESP32. For some reason I thought it was a Mega. I guess the WiFi should have tipped me off. Switch it back.

FWIW, if that RS485 hardware is based on a MAX485 it probably isn't operating properly at just 3.3V. There are 3.3V transceivers (e.g. MAX3485E) but you need to make sure the sensor is happy operating at low voltage too.

I'm powering the soil sensor and RS485 module with external battery 5V.
The external power supply is 8.4V with the power adapter I use 5V.
When I worked with arduino uno I powered the sensor with 5v and it worked normally.

I checked the connection of the cables.
I continue with the same. I don't know what I am missing.

In your Fritzing diagram you show 3.3V going from an ESP32 to the RS485 VCC pin.

Sorry for that diagram is for reference only. In my case the module the requirement to powering is with 5V

I've used the Adafruit ESP32 Feather with an LTC1480 (the 3.3v version of RS485 chip) and the following (snippets):

//** definitions **
// pins - RS485
//	rs485 tx-> the Feather's "TX" pin...the additional Serial1 pin <-- note the "1" suffix
//	rs485 rx-> the Feather's "RX" pin...the additional Serial1 pin <-- note the "1" suffix
const byte RS485_enable = 21;  // digital output to enable rs485 = General purpose IO pin #21 (output)

//** in setup **
// init pins
pinMode(RS485_enable, OUTPUT); //default state = LOW = receive (A and B high Z)

//** more in setup **
// RS485
// https://learn.adafruit.com/adafruit-huzzah32-esp32-feather/pinouts
// From that pinout GPIO rx=16  tx=17
// Serial1.begin(28800, SERIAL_8N1, 16, 17); <--not needed TF03 lidar worked fine w/o this & loopback w/ a different ESP32 shows ok
Serial1.begin(28800); // works fine.  Note the "1" suffix.

// ** communicate via RS485 **
digitalWrite(RS485_enable, HIGH); // tx
// do stuff
digitalWrite(RS485_enable, LOW); // rx
// do stuff

FWIW, this 3.3v LTC1480 communicates with a remote 5.0v MAX485 or equivalent.

Note this is NOT using SoftwareSerial (whereas the post title includes SoftwareSerial).

Thank you for your answer. I'm still the same. Someone who has implemented communication through the port Serial like Serial2.begin (4800, SERIAL_8N1, 16, 17); with ESP32 ? Thanks in advance :slight_smile:

Someone who has implemented communication through the port Serial like Serial2.begin (4800, SERIAL_8N1, 16, 17); with ESP32 ?

That syntax looks correct when using the Arduino IDE with the esp32.

I suggest that you separate out the reading of the sensor from the wifi. Can you get the sketch from the nano reading the sensor correctly when adapted for the esp32?

Changing from software serial to Serial2 should be straight forward.