RS485 Sensor with Arduino

Hello everyone,

I am trying to connect my Soil Moisture sensor (Truebner SMT100) to my Arduino and get the readings but I keep receiving a question mark (?) on the serial monitor.

Could someone tell me what I am doing wrong so I could fix it myself ?

I appreciate everybody’s time to read this and I am looking forward to your replies.

#include "Arduino.h"

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

// SD Card shield
#include <SPI.h>
#include <SD.h>

const int chipSelect = 10; // Uno shield
String dataStringnames =""; // holds the names of the data to be written to the SD card
String dataString =""; // holds the data to be written to the SD card


#include <SoftwareSerial.h>

// pins talking to RS485 device
#define RS485rx     2 // RS485 Receive pin
#define RS485Tx     3 // RS485 Transmit pin
#define RS485inout   4 // RS485 Transmit or Receive status

#define RS485Transmit HIGH
#define RS485Receive  LOW
#define ledPin      13
#define baudRate    9600

#define serialdelay  500

// Define the RS485 object
SoftwareSerial mySerial(RS485rx, RS485Tx);

String AddValue;
String SMValue;
String TemValue;
String PermValue;
char Add[] = "GetAddress!";
char SM[] = "GetWaterContent!FFFFFF";
char Tem[] = "GetTemperature!FFFFFF";
char Perm[] = "GetPermittivity!FFFFFF";


int rtc_year = 0;
int rtc_month = 0;
int rtc_day = 0;
int rtc_hour = 0;
int rtc_min = 0;
int rtc_sec = 0;

// -----------------------------------------------------------------
// SETUP         SETUP         SETUP         SETUP         SETUP
// -----------------------------------------------------------------
void setup()
{

  Serial.begin(9600);

  rtc.begin();

  SD.begin(chipSelect);
  
  // Set modes for pins
  pinMode(ledPin, OUTPUT);
  pinMode(RS485inout, OUTPUT);

  // Ensure the on-board LED is off
  digitalWrite(ledPin, LOW);

  // Set RS485 device to read initially
  digitalWrite(RS485inout, RS485Receive);

  mySerial.begin(baudRate);

  dataStringnames =  String("SM") + ";" + String("Temp") + ";"+ String("Perm") + ";"
                                     + String("year")+ ";" + String("month")+ ";" + String("day")+ ";" 
                                     + String("hour")+ ";" + String("min")+ ";" + String("sec");
                    
  File dataFile = SD.open("DATALOG.txt", FILE_WRITE);                                  
    if (dataFile) {
    dataFile.println(dataStringnames);
    dataFile.close();
    // print to the serial port too:
    //Serial.println("SD working");
    Serial.println(dataStringnames);
                  }
  // if the file isn't open, pop up an error:
  else            {
    Serial.println("error opening DATALOG.txt");
                  } 

}

// -----------------------------------------------------------------
// LOOP     LOOP     LOOP     LOOP     LOOP     LOOP     LOOP
// -----------------------------------------------------------------
void loop()
{

    // RTC
    DateTime now = rtc.now();
    
    rtc_year = now.year();
    rtc_month = now.month();
    rtc_day = now.day();
    rtc_hour = now.hour();
    rtc_min =  now.minute();
    rtc_sec =  now.second();

//    //////////////////// Sensor Address
    Serial.print("Sending:");
    Serial.println(Add);
//
//    // Set the RS485 to transmit mode and send the value
    digitalWrite(RS485inout, RS485Transmit);
    mySerial.println(Add);
    mySerial.flush();//Wait for everything to be transmitted, before disabling transmitter.
//   
//    // Switch RS485 to receive mode
 digitalWrite(RS485inout, RS485Receive);
//
    delay(serialdelay);
//    
//    // After each characters are sent look for a received answer
    if (mySerial.available())
                      {
      AddValue = mySerial.readStringUntil('\n');
//      
//      // Display it on the Serial Monitor as a char (not an integer value)
      Serial.print("                 Got back:"); 
      Serial.println(AddValue);
                      
                      }

    else              {
    Serial.println("no response from sensor");
                      }

    


 //////////////////// Soil Moisture  
    Serial.print("Sending:");
    Serial.println(SM);

    // Set the RS485 to transmit mode and send the value
    digitalWrite(RS485inout, RS485Transmit);
    mySerial.println(SM);
    mySerial.flush();//Wait for everything to be transmitted, before disabling transmitter.
    
        // Switch RS485 to receive mode
    digitalWrite(RS485inout, RS485Receive);

    delay(serialdelay);


    // After each characters are sent look for a received answer
    if (mySerial.available())
                {
      
      SMValue = mySerial.readStringUntil('\n');
      // Display it on the Serial Monitor as a char (not an integer value)
      Serial.print("                 Got back:"); Serial.println(SMValue);

                } 
    else        {
             Serial.println("no response from sensor");
                }

    
//////////////////// Temperature
    //Serial.print("Sending:");Serial.println(Tem);

    // Set the RS485 to transmit mode and send the value
    digitalWrite(RS485inout, RS485Transmit);
    mySerial.println(Tem);
    mySerial.flush();//Wait for everything to be transmitted, before disabling transmitter.
   
    // Switch RS485 to receive mode
    digitalWrite(RS485inout, RS485Receive);

    delay(serialdelay);
    
    // After each characters are sent look for a received answer
    if (mySerial.available())
              {
      TemValue = mySerial.readStringUntil('\n');
      
      // Display it on the Serial Monitor as a char (not an integer value)
      Serial.print("                 Got back:"); Serial.println(AddValue);

              }
       else {
       Serial.println("no response from sensor");
              }


//////////////////// Permitivitty
    Serial.print("Sending:");
    Serial.println(Perm);

    // Set the RS485 to transmit mode and send the value
    digitalWrite(RS485inout, RS485Transmit);
    mySerial.println(Perm);
    mySerial.flush();//Wait for everything to be transmitted, before disabling transmitter.
   
    // Switch RS485 to receive mode
    digitalWrite(RS485inout, RS485Receive);

    delay(serialdelay);
    
    // After each characters are sent look for a received answer
    if (mySerial.available())
            {
      PermValue = mySerial.readStringUntil('\n');
      
      // Display it on the Serial Monitor as a char (not an integer value)
      Serial.print("                 Got back:"); Serial.println(AddValue);

            }
    
    else {
       Serial.println("no response from sensor");
            }

   

    dataString = String(SMValue)+ ";"+ String(TemValue) + ";" + String(PermValue)+ ";"
                                     + String(rtc_year)+ ";" + String(rtc_month)+ ";" + String(rtc_day)+ ";" 
                                     + String(rtc_hour)+ ";" + String(rtc_min)+ ";" + String(rtc_sec);

File dataFile = SD.open("DATALOG.txt", FILE_WRITE);                                  
    if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println("SD working");
    Serial.println(dataString);
    Serial.println("");
    dataString = -9999;
                  }
  // if the file isn't open, pop up an error:
 else {
    Serial.println("error opening DATALOG.txt");

         }
    flushReceive();
    Serial.println("new cycle ----------------------------------------------------");   
    delay(9000);        
} 


void flushReceive()
{
while(Serial.available())
  Serial.read();
//
while(mySerial.available())
  mySerial.read();
}

Is the baud rate (9600) correct for that sensor? Which protocol variant do you own? Where is the link to the devices manual?

I have some sample code for SMT100 on my website http://www.gardenergranny.de/bludit/smt100-rs485-with-arduino Could you give it a try?

Please check also the application note on the manufacturer website: http://www.truebner.de/sites/default/files/AN005.pdf