Example Code for Arduino-Read Dissolved Oxygen, Saturation, and Temperature
This project demonstrates how to use an Arduino board to read dissolved oxygen concentration, dissolved oxygen saturation, temperature, atmospheric pressure, and salinity from the RS485 Dissolved Oxygen Sensor using the ModBus-RTU protocol. Users will learn how to communicate with RS485 devices, parse ModBus-RTU data frames, and interpret the sensor's measurements.
Hardware Preparation
- DFRduino UNO R3 (or similar) x 1
- Gravity: Active Isolated RS485 to UART Signal Adapter Module x1
- RS485 Dissolved Oxygen Sensor x1
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
No additional preparation work is required beyond the hardware and software setup and wiring.
Sample Code
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); //TX,RX
uint8_t Com[8] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0xC5, 0xC8 };
uint8_t Com1[8] = { 0x01, 0x03, 0x10, 0x22, 0x00, 0x01, 0x20, 0xC0 };
uint8_t Com2[8] = { 0x01, 0x03, 0x10, 0x20, 0x00, 0x01, 0x81, 0x00 };
float sal, ap;
void setup() {
Serial.begin(9600);
mySerial.begin(4800);
}
void loop() {
readDO_DOS_TEM();
Atmospheric_pressure();
Serial.print("AP = ");
Serial.print(ap, 2);
Serial.print("Kpa ");
Salinity();
Serial.print("Salinityt = ");
Serial.print(sal,0);
Serial.println("% ");
Serial.println(" ");
delay(1000);
}
void readDO_DOS_TEM(void) {
uint32_t val = 0, val1 = 0, val2 = 0;
uint8_t Data[18] = { 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 == 0x0C) {
Data[2] = ch;
if (readN(&Data[3], 14) == 14) {
if (CRC16_2(Data, 15) == (Data[15] * 256 + Data[16])) {
val = Data[3];
val = (val << 8) | Data[4];
val = (val << 8) | Data[5];
val = (val << 8) | Data[6];
float *dos = (float *)&val;
float Dos = *dos * 100.00;
Serial.print("DO Sat = ");
Serial.print(Dos, 1);
Serial.print("% ");
val1 = Data[7];
val1 = (val1 << 8) | Data[8];
val1 = (val1 << 8) | Data[9];
val1 = (val1 << 8) | Data[10];
float *Do = (float *)&val1;
Serial.print("DO = ");
Serial.print(*Do, 2);
Serial.print(" mg/L ");
val2 = Data[11];
val2 = (val2 << 8) | Data[12];
val2 = (val2 << 8) | Data[13];
val2 = (val2 << 8) | Data[14];
float *tem = (float *)&val2;
Serial.print("TEM = ");
Serial.print(*tem, 1);
Serial.println("°C");
flag = 0;
}
}
}
}
}
}
}
}
}
}
void Atmospheric_pressure(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 out2");
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 == 0x02) {
Data[2] = ch;
if (readN(&Data[3], 4) == 4) {
if (CRC16_2(Data, 5) == (Data[5] * 256 + Data[6])) {
ap = (Data[3] * 256 + Data[4]) / 100.0;
flag = 0;
}
}
}
}
}
}
}
}
}
}
void Salinity(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(Com2, 8);
timeStart1 = millis();
}
if ((millis() - timeStart) > 1000) {
Serial.println("Time out3");
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 == 0x02) {
Data[2] = ch;
if (readN(&Data[3], 4) == 4) {
if (CRC16_2(Data, 5) == (Data[5] * 256 + Data[6])) {
sal = Data[3] * 256 + Data[4];
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 port prints the dissolved oxygen concentration, dissolved oxygen saturation, temperature, atmospheric pressure, and salinity values collected by the sensor.
Was this article helpful?
