Example Code for Arduino - EC, Temperature, Salinity & TDS Monitoring

This project demonstrates how to connect the RS485 Water Quality Electrical Conductivity Sensor to an Arduino development board, read real-time EC (electrical conductivity), temperature, salinity, and TDS (total dissolved solids) data via the ModBus-RTU protocol, and display the data on the Arduino IDE serial monitor. Users will learn how to implement RS485 communication with ModBus-RTU, parse sensor data, and leverage built-in temperature compensation for accurate measurements.

Hardware Preparation

Software Preparation

Wiring Diagram

If the power of the RS485 device is small and the required current is less than 12V-160mA, the RS485 to UART signal conversion module does not require a 12V external power supply, making wiring more convenient.

Other Preparation Work

  1. Ensure the sensor is installed correctly using either submersible or pipe installation methods as described in the Getting Started section.
  2. If the sensor has been stored in a dry place for extended periods, immerse the electrodes in distilled water for several hours before use to activate them.
  3. The sensor's default communication parameters are: baud rate 4800bps, device address 0x01, 8 data bits, no parity, 1 stop bit, CRC error checking.

Sample Code

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);                                         //TX,RX
uint8_t Com[8] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B };   //EC、Temperature
uint8_t Com1[8] = { 0x01, 0x03, 0x00, 0x02, 0x00, 0x02, 0x65, 0xCB };  //Salinity、TDS
float ec, tem;
int tds, sal;

void setup() {
  Serial.begin(9600);
  mySerial.begin(4800);
}
void loop() {
  EC_Temperature();
  Serial.print("EC = ");
  Serial.print(ec, 1);
  Serial.print(" us/cm  ");
  Serial.print(" Temperature = ");
  Serial.print(tem, 1);
  Serial.println("°C");
  Salinity_TDS();
  Serial.print(" Salinity = ");
  Serial.print(sal);
  Serial.print(" PPM  ");
  Serial.print(" TDS = ");
  Serial.print(tds);
  Serial.println(" PPM");
  Serial.println(" ");
  delay(1000);
}

void EC_Temperature(void) {
  uint8_t Data[12] = { 0 };
  uint8_t ch = 0;
  bool flag = 1;
  long timeStart = millis();
  long timeStart1 = 0;
  while (flag) {

    if ((millis() - timeStart1) > 100) {
      while (mySerial.available() > 0) {
        mySerial.read();
      }
      mySerial.write(Com, 8);
      timeStart1 = millis();
    }

    if ((millis() - timeStart) > 1000) {
      Serial.println("Time out");
      return -1;
    }

    if (readN(&ch, 1) == 1) {
      if (ch == 0x01) {
        Data[0] = ch;
        if (readN(&ch, 1) == 1) {
          if (ch == 0x03) {
            Data[1] = ch;
            if (readN(&ch, 1) == 1) {
              if (ch == 0x04) {
                Data[2] = ch;
                if (readN(&Data[3], 6) == 6) {
                  if (CRC16_2(Data, 7) == (Data[7] * 256 + Data[8])) {
                    ec = (Data[3] * 256 + Data[4]) / 10.0;
                    tem = (Data[5] * 256 + Data[6]) / 10.0;
                    flag = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}


void Salinity_TDS(void) {
  uint8_t Data[12] = { 0 };
  uint8_t ch = 0;
  bool flag = 1;
  long timeStart = millis();
  long timeStart1 = 0;
  while (flag) {

    if ((millis() - timeStart1) > 100) {
      while (mySerial.available() > 0) {
        mySerial.read();
      }
      mySerial.write(Com1, 8);
      timeStart1 = millis();
    }

    if ((millis() - timeStart) > 1000) {
      Serial.println("Time out1");
      return -1;
    }

    if (readN(&ch, 1) == 1) {
      if (ch == 0x01) {
        Data[0] = ch;
        if (readN(&ch, 1) == 1) {
          if (ch == 0x03) {
            Data[1] = ch;
            if (readN(&ch, 1) == 1) {
              if (ch == 0x04) {
                Data[2] = ch;
                if (readN(&Data[3], 6) == 6) {
                  if (CRC16_2(Data, 7) == (Data[7] * 256 + Data[8])) {
                    sal = Data[3] * 256 + Data[4];
                    tds = Data[5] * 256 + Data[6];
                    flag = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}


uint8_t readN(uint8_t *buf, size_t len) {
  size_t offset = 0, left = len;
  int16_t Tineout = 500;
  uint8_t *buffer = buf;
  long curr = millis();
  while (left) {
    if (mySerial.available()) {
      buffer[offset] = mySerial.read();
      offset++;
      left--;
    }
    if (millis() - curr > Tineout) {
      break;
    }
  }
  return offset;
}

unsigned int CRC16_2(unsigned char *buf, int len) {
  unsigned int crc = 0xFFFF;
  for (int pos = 0; pos < len; pos++) {
    crc ^= (unsigned int)buf[pos];
    for (int i = 8; i != 0; i--) {
      if ((crc & 0x0001) != 0) {
        crc >>= 1;
        crc ^= 0xA001;
      } else {
        crc >>= 1;
      }
    }
  }

  crc = ((crc & 0x00ff) << 8) | ((crc & 0xff00) >> 8);
  return crc;
}

Result

The serial monitor displays the EC value, temperature, salinity, and TDS data collected by the sensor.

Was this article helpful?

TOP