Example Code for Arduino-UV Intensity and Index Reading

This project demonstrates how to use an Arduino UNO R3 and Gravity: Active Isolated RS485 to UART Signal Adapter Module to read UV intensity and index values from the RS485 UV Sensor. Users will learn Modbus-RTU communication integration and basic sensor data acquisition.

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. Remove the UV sensor's protective cover before use (refer to FAQ for details)
  2. Ensure RS485 A/B lines are correctly connected (A→A, B→B)
  3. Verify power supply matches DC5-30V requirements

Sample Code

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3);
uint8_t Com[8] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A };
uint8_t Com1[8] = { 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA };
void setup() {
  Serial.begin(9600);
  mySerial.begin(4800);
}
void loop() {
  float UV = readUV();
  Serial.print("UV = ");
  Serial.print(UV);
  Serial.print(" mW/cm² ");
  uint16_t UVI = readUVI();
  Serial.print("UVI = ");
  Serial.println(UVI);
  delay(1000);
}

float readUV(void) {
  uint8_t Data[10] = { 0 };
  uint8_t ch = 0;
  float data;
  bool flag = 1;
  while (flag) {
    delay(100);
    mySerial.write(Com, 8);
    delay(10);
    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])) {
                    data= (Data[3] * 256 + Data[4]) / 100.00;
                    flag = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
    mySerial.flush();
  }
  return data;
}

int readUVI(void) {
  uint8_t Data1[10] = { 0 };
  int16_t data1;
  uint8_t ch1 = 0;
  bool flag1 = 1;
  while (flag1) {
    delay(100);
    mySerial.write(Com1, 8);
    delay(10);
    if (readN(&ch1, 1) == 1) {
      if (ch1 == 0x01) {
        Data1[0] = ch1;
        if (readN(&ch1, 1) == 1) {
          if (ch1 == 0x03) {
            Data1[1] = ch1;
            if (readN(&ch1, 1) == 1) {
              if (ch1 == 0x02) {
                Data1[2] = ch1;
                if (readN(&Data1[3], 4) == 4) {
                  if (CRC16_2(Data1, 5) == (Data1[5] * 256 + Data1[6])) {
                    data1 = Data1[3] * 256 + Data1[4];
                    flag1 = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
    mySerial.flush();
  }
  return data1;
}

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

Print the collected UV intensity and index values, which cannot be collected by ordinary indoor light sources.

Was this article helpful?

TOP