Example Code for Arduino-9-in-1 Weather Station Monitoring

Collect ultrasonic wind speed and direction values, temperature values, humidity values, atmospheric pressure values, light values, noise values, PM2.5, PM10 and print them through the serial port.

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

Ensure the power supply of the RS485 device meets the requirements and the wiring is correct.

Sample Code

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
uint8_t Com[8] = { 0x01, 0x03, 0x01, 0xF4, 0x00, 0x04, 0x04, 0x07 }; //Wind speed and direction
uint8_t Com1[8] = { 0x01, 0x03, 0x01, 0xF8, 0x00, 0x03, 0x85, 0xC6 }; //Temperature, humidity, noise
uint8_t Com2[8] = { 0x01, 0x03, 0x01, 0xFE, 0x00, 0x02, 0xA4, 0x07 }; //Light
uint8_t Com3[8] = { 0x01, 0x03, 0x01, 0xFB, 0x00, 0x03, 0x75, 0xC6 }; //PM2.5, PM10, atmospheric pressure
float tem, hum, ws, ap, db;
int wd, wdangle, pm2_5, pm10;

void setup() {
  Serial.begin(9600);
  mySerial.begin(4800);
}
void loop() {
  readHumiture_Noise();
  Serial.print("TEM = ");
  Serial.print(tem, 1);
  Serial.print("°C  ");
  Serial.print("HUM = ");
  Serial.print(hum, 1);
  Serial.print("%RH  ");
  Serial.print("dbValue = ");
  Serial.print(db, 1);
  Serial.print("dB  ");
  uint32_t lux = readLight();
  Serial.print("Lux = ");
  Serial.print(lux);
  Serial.println("(lux)  ");

  readPM2_5_10_AtmosphericPressure();
  Serial.print("PM2.5 = ");
  Serial.print(pm2_5);
  Serial.print("ug/m³  ");
  Serial.print("PM10 = ");
  Serial.print(pm10);
  Serial.print("ug/m³ ");
  Serial.print("AP = ");
  Serial.print(ap, 1);
  Serial.println("kPa ");

  readWindSpeed_WindDirection();
  Serial.print("Wind Speed = ");
  Serial.print(ws, 1);
  Serial.print("m/s  ");
  Serial.print("Wind Direction = ");
  Serial.print(wd);
  Serial.print(" WindDirection_Angle = ");
  Serial.print(wdangle);
  Serial.println("° ");
  Serial.println(" ");
  delay(2000);
}

void readWindSpeed_WindDirection(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 == 0x08) {
                Data[2] = ch;
                if (readN(&Data[3], 10) == 10) {
                  if (CRC16_2(Data, 11) == (Data[11] * 256 + Data[12])) {
                    ws = (Data[3] * 256 + Data[4]) / 100.00;
                    wd = Data[7] * 256 + Data[8];
                    wdangle = Data[9] * 256 + Data[10];
                    flag = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}


void readHumiture_Noise(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 == 0x06) {
                Data[2] = ch;
                if (readN(&Data[3], 8) == 8) {
                  if (CRC16_2(Data, 9) == (Data[9] * 256 + Data[10])) {
                    hum = (Data[3] * 256 + Data[4]) / 10.00;
                    tem = (Data[5] * 256 + Data[6]) / 10.00;
                    db = (Data[7] * 256 + Data[8]) / 10.00;
                    flag = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}


uint32_t readLight(void) {
  uint8_t Data[15] = { 0 };
  uint8_t ch = 0;
  long timeStart = millis();
  long timeStart1 = 0;
  bool flag = 1;
  uint32_t data = 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 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 == 0x04) {
                Data[2] = ch;
                if (readN(&Data[3], 6) == 6) {
                  if (CRC16_2(Data, 7) == (Data[7] * 256 + Data[8])) {
                    data = Data[3] << 24 | Data[4] << 16 | Data[5] << 8 | Data[6];
                    flag = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  return data;
}

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

    if ((millis() - timeStart1) > 100) {
      while (mySerial.available() > 0) {
        mySerial.read();
      }
      mySerial.write(Com3, 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 == 0x06) {
                Data[2] = ch;
                if (readN(&Data[3], 8) == 8) {
                  if (CRC16_2(Data, 9) == (Data[9] * 256 + Data[10])) {
                    pm2_5 = Data[3] * 256 + Data[4];
                    pm10 = Data[5] * 256 + Data[6];
                    ap = (Data[7] * 256 + Data[8]) / 10.00;
                    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

Print the collected ultrasonic wind speed and direction values, temperature values, humidity values, atmospheric pressure values, light values, noise values, PM2.5, PM10.

Was this article helpful?

TOP