OK, got the sensor and after chatting with chatGPT for a while, this is what I got:
#include <SoftwareSerial.h>
SoftwareSerial rainSensor(10, 11); // RX, TX (TX not used)
int sensorPin = A0; // Potentiometer for delay control
int motorPin = 2; // Wiper relay control
int calibrationButtonPin = 7; // Calibration button pin
int rainState = 0; // Current rain state (0: no rain, 1: light rain, etc.)
bool calibrationMode = false;
void setup() {
Serial.begin(115200); // Start serial communication for debug
rainSensor.begin(115200); // Start communication with the rain sensor
pinMode(motorPin, OUTPUT); // Set motor relay pin as output
pinMode(calibrationButtonPin, INPUT_PULLUP); // Set the calibration button pin as input with pullup
digitalWrite(motorPin, HIGH); // Initially keep the motor off
}
void loop() {
// Read the potentiometer to control the wiper delay dynamically
int sensorValue = analogRead(sensorPin);
int interval = 0; // Interval controlled by rain state & potentiometer
// Check for calibration button press
if (digitalRead(calibrationButtonPin) == LOW) {
initiateCalibration();
}
// Check for rain sensor data
if (rainSensor.available()) {
byte receivedByte = rainSensor.read();
if (receivedByte == 0x3A) { // Frame start header
byte data[5]; // Array to hold data bytes
int i = 0;
data[i++] = receivedByte; // Store the header byte
while (rainSensor.available() && i < 5) {
data[i++] = rainSensor.read(); // Read the rest of the data frame
}
// Ensure we have a full 5-byte frame
if (i == 5) {
// Print raw data for debugging
Serial.print("Raw data: ");
for (int j = 0; j < 5; j++) {
Serial.print(data[j], HEX);
Serial.print(" ");
}
Serial.println();
// Check if the header is correct (0x3A) and handle the rain state
if (data[0] == 0x3A) {
byte rainLevel = data[2]; // Extract rain level (third byte)
Serial.print("Received data: Header: ");
Serial.print(data[0], HEX);
Serial.print(" Rain State: ");
Serial.print(rainLevel, HEX);
// Assign rain state
rainState = rainLevel;
switch (rainLevel) {
case 0x00:
Serial.println("No rain");
rainState = 0;
break;
case 0x01:
Serial.println("Light rain");
rainState = 1;
break;
case 0x02:
Serial.println("Moderate rain");
rainState = 2;
break;
case 0x03:
Serial.println("Heavy rain");
rainState = 3;
break;
case 0x06: // New case to handle post-calibration state
Serial.println("Calibration in progress... (Temporary state)");
break;
default:
Serial.print("Unknown rain state received: 0x");
Serial.println(rainLevel, HEX);
break;
}
} else {
Serial.println("Invalid header byte, ignoring data");
}
}
}
}
// Determine wiper interval based on rain state and potentiometer
if (rainState != 0) { // Only adjust interval if rain is detected
switch (rainState) {
case 1: // Light rain
interval = map(sensorValue, 0, 1023, 5000, 20000); // 5s to 20s
break;
case 2: // Moderate rain
interval = map(sensorValue, 0, 1023, 3000, 10000); // 3s to 10s
break;
case 3: // Heavy rain
interval = map(sensorValue, 0, 1023, 1000, 5000); // 1s to 5s
break;
}
}
// Control the wiper motor based on interval
static unsigned long lastTime = 0;
if (rainState != 0 && millis() - lastTime >= interval) {
lastTime = millis();
digitalWrite(motorPin, LOW); // Activate wiper motor
delay(400); // Pulse the motor
digitalWrite(motorPin, HIGH); // Deactivate wiper motor
}
}
// Function to initiate sensor calibration
void initiateCalibration() {
Serial.println("Starting calibration...");
// Calibration command sequence
byte calibrationCommand[5] = { 0x3A, 0x08, 0x00, 0x00, 0x33 };
// Send each byte of the calibration command
for (int i = 0; i < 5; i++) {
rainSensor.write(calibrationCommand[i]);
}
// Wait for the calibration process to complete
delay(3000); // Adjust this delay based on the module's calibration time
Serial.println("Calibration complete.");
}
I am using an Arduino Nano for this project...
Basically, the sensor detects 4 rain states: No rain, Light rain, Moderate rain and Heavy rain.
A potentiometer is used to modify the wiper motor intervals for each rain states like this:
No Rain: Wipers remain OFF.
Light Rain: Potentiometer adjusts delay between 5s to 20s.
Moderate Rain: Potentiometer adjusts delay between 3s to 10s.
Heavy Rain: Potentiometer adjusts delay between 1s to 5s.
(I will modify these value for real life scenarios)
This seems to work OK as I see accurate output on serial when testing on the bench with rain sensor on the other side of 5mm glass and spraying water into it.
I designed and 3D printed a case for the sensor so it is almost touching the glass. The case also has a small Tact Switch used for the calibration.
I am not sure, however, if the calibration is really being performed and saved.
Can anyone help with this?
Here are the links for the Manual and Datasheet:
https://raw.githubusercontent.com/May-DFRobot/DFRobot/master/SEN0545User%20Manual.pdf
https://raw.githubusercontent.com/May-DFRobot/DFRobot/master/SEN0545Datasheet.pdf
If anyone want the 3D file for the case, let me know and I can upload the stl file here...
I will update this post when testing in real life to see if it will also detect snow...
Any inputs would be appreciated
Cheers