To detect if 230V AC is on, you can use a voltage detection circuit with a step-down transformer or optocoupler for isolation. This ensures safety while providing a signal to indicate the presence of voltage, which can be used for further processing in your system.
Sensor has VCC: Use 5 or 3.3V?
Dout: Is that I2C? or something else
Aout: Analog out, to a analog GPIO?
"Code":
SSR always on
if 230V AC = HIGH more than 2 min switch OFF SSR, switch ON SSR after 10 min
Repeat
By the way, the pump is for a cleaning system of my Koi pond. If it runs to long, the pond will be dry. So this is kind of important, I hope to have this running in a day or 2.
I see. Can you make or find something to go between the controller outlet and the pump plug so you can tell if the pump is off or not? A box or and extension cord or a transformer or?
I'd tend to focus initially on solving the problem of the existing controller keeping the motor running for "too long". Is it a timing adjustment issue or is there a level switch somewhere or what?
There is a sensor (floater that triggers a read relay). I cant find errors on it when I test it....
When I test it, the system works, if pump runs too long it stops the system. But this is not happening all the time, this is what my system tries to fix.
After I take the power of the system, it starts working.... until it hick up one more time....
Filtreau is obviously an unreliable product. Buy a different unit from a different manufacturer.
Your choice but you are treating the symptom and the the real cause of the problem.
The function calculateRMS is the one I'm not sure about, I have a 1 phase 230V 50Hz, IT net (Norway+Albania...) no neutral.
Any input from you to my code?
#define SSR_PIN 5 // GPIO pin connected to the SSR
#define WCS1500_PIN 34 // ADC pin connected to the WCS1500 current sensor - marked Aout on sensor
#define WCS_ZERO_POINT 2048 // Middle point of WCS1500 sensor (approx 2.5V mapped to 12-bit ADC)
// Timing constants
#define SAMPLE_DURATION 200 // Sampling duration in milliseconds
#define RMS_THRESHOLD 100 // Adjust based on expected current (RMS value from ADC)
// Timers
unsigned long powerSenseStartTime = 0; // Timer for detecting x minutes of continuous power
unsigned long ssrOffStartTime = 0; // Timer for the 10-minute off delay
unsigned long offDuration = 10*1000; // test 10 sec //10 * 60 * 1000; // 10 minutes in milliseconds
unsigned long pumpMaxRuntime = 10*1000; // test 10 sec // 2 * 60 * 1000;
bool isSSROn = true;
void setup() {
pinMode(SSR_PIN, OUTPUT);
digitalWrite(SSR_PIN, HIGH); // Default state: SSR is ON
Serial.begin(115200);
}
void loop() {
float rmsValue = calculateRMS(); // Calculate RMS current
bool currentDetected = (rmsValue > RMS_THRESHOLD);
// Debugging: Log the RMS value
Serial.print("RMS Value: ");
Serial.println(rmsValue);
// Handle SSR control based on current detection
if (currentDetected) {
if (powerSenseStartTime == 0) {
powerSenseStartTime = millis(); // Start timing the 2-minute power sense
}
if (millis() - powerSenseStartTime >= pumpMaxRuntime) {
if (isSSROn) {
Serial.println("Power detected for 2 minutes. Turning off SSR for 10 minutes.");
digitalWrite(SSR_PIN, LOW); // Turn off SSR
isSSROn = false;
ssrOffStartTime = millis(); // Start the 10-minute off timer
}
}
} else {
// Reset the power sensing timer if no current is detected
powerSenseStartTime = 0;
}
// Manage the 10-minute off duration
if (!isSSROn && millis() - ssrOffStartTime >= offDuration) {
Serial.println("10 minutes elapsed. Turning SSR back ON.");
digitalWrite(SSR_PIN, HIGH); // Turn SSR back ON
isSSROn = true;
powerSenseStartTime = 0; // Reset power sensing timer
}
}
// Function to calculate RMS current
float calculateRMS() {
unsigned long startTime = millis();
unsigned long sumOfSquares = 0;
unsigned int sampleCount = 0;
while (millis() - startTime < SAMPLE_DURATION) {
int adcValue = analogRead(WCS1500_PIN);
int offsetValue = adcValue - WCS_ZERO_POINT; // Center the waveform around zero
sumOfSquares += offsetValue * offsetValue; // Accumulate the square of the value
sampleCount++;
delayMicroseconds(1000); // Sample every 1 ms (adjust as needed)
}
float meanSquare = (float)sumOfSquares / sampleCount; // Mean of squared values
return sqrt(meanSquare); // RMS value
}
#define SSR_PIN 5 // GPIO pin connected to the SSR
#define WCS1500_PIN 34 // ADC pin connected to the WCS1500 current sensor
#define WCS_ZERO_POINT 2048 // Middle point of WCS1500 sensor (adjust based on calibration)
// Constants
#define SAMPLE_FREQUENCY 2000 // Sampling rate in Hz (2000 samples per second)
#define SAMPLE_DURATION 1000 // Integration window in milliseconds (1 second)
#define RMS_THRESHOLD 1500 // Adjust based on motor's typical current in ADC units
// Timers
unsigned long powerSenseStartTime = 0; // Timer for detecting 2 minutes of continuous power
unsigned long ssrOffStartTime = 0; // Timer for the 10-minute off delay
unsigned long offDuration = 10 * 1000; // test 10 sec //10 * 60 * 1000; // 10 minutes in milliseconds
unsigned long pumpMaxRuntime = 10 * 1000; // test 10 sec // 2 * 60 * 1000;
bool isSSROn = true;
// for å lese 2 siffer i filnavn (versjonsnr
#include <cstring>
#include <cstdlib>
#include <iostream>
void setup() {
pinMode(SSR_PIN, OUTPUT);
digitalWrite(SSR_PIN, HIGH); // Default state: SSR is ON
Serial.begin(115200);
PrintFileNameDateTime();
}
void loop() {
float rmsCurrent = calculateRMS(SAMPLE_DURATION, SAMPLE_FREQUENCY); // Calculate RMS current
bool currentDetected = (rmsCurrent > RMS_THRESHOLD); // org >
// Debugging: Log the RMS current
// Serial.print("RMS treshold: "); Serial.println(RMS_THRESHOLD);
Serial.print("RMS Current: "); Serial.println(rmsCurrent);
// Handle SSR control based on current detection
if (currentDetected) {
//Serial.print(".");
if (powerSenseStartTime == 0) {
powerSenseStartTime = millis(); // Start timing the 2-minute power sense
}
if (millis() - powerSenseStartTime >= pumpMaxRuntime) {
if (isSSROn) {
Serial.println("Current detected for 2 minutes. Turning off SSR for 10 minutes.");
digitalWrite(SSR_PIN, LOW); // Turn off SSR
isSSROn = false;
ssrOffStartTime = millis(); // Start the 10-minute off timer
}
}
} else {
// Reset the power sensing timer if no current is detected
powerSenseStartTime = 0;
}
// Manage the 10-minute off duration
if (!isSSROn && millis() - ssrOffStartTime >= offDuration) {
Serial.println("10 minutes elapsed. Turning SSR back ON.");
digitalWrite(SSR_PIN, HIGH); // Turn SSR back ON
isSSROn = true;
powerSenseStartTime = 0; // Reset power sensing timer
}
}
// ******************************************************
// Function to calculate RMS current over a specified duration
float calculateRMS(unsigned long durationMs, unsigned int frequencyHz) {
unsigned long sampleInterval = 1000000 / frequencyHz; // Microseconds between samples
unsigned long startTime = millis();
unsigned long sumOfSquares = 0;
unsigned int sampleCount = 0;
while (millis() - startTime < durationMs) {
int adcValue = analogRead(WCS1500_PIN);
int offsetValue = adcValue - WCS_ZERO_POINT; // Center the waveform around zero
sumOfSquares += offsetValue * offsetValue; // Accumulate the square of the value
sampleCount++;
delayMicroseconds(sampleInterval); // Wait for the next sample
}
float meanSquare = (float)sumOfSquares / sampleCount; // Mean of squared values
return sqrt(meanSquare); // RMS value
}
void PrintFileNameDateTime() {
Serial.println(" Kompileringsinformasjon:");
Serial.print (" Filnavn kode: "); Serial.println(__FILE__); // Makroer
Serial.print (" Kompileringsdato: "); Serial.println(__DATE__);
Serial.print (" Klokkeslett: "); Serial.println(__TIME__);
int mottagerVersjon = getVersionNumber(__FILE__);
// Serial.print (" MotagerVersjon print file: "); Serial.println(mottagerVersjon);
}
// Funksjon som henter versjonsnummeret fra filnavnet
int getVersionNumber(const char* filePath) {
const char* dotPos = strrchr(filePath, '.'); // Finn posisjonen til det siste punktumet i filbanen
if (dotPos != nullptr && (dotPos - filePath) >= 2) { // Hvis punktumet finnes og det er minst to tegn før punktumet
char versionStr[3]; // 2 sifre + nullterminator
versionStr[0] = *(dotPos - 2);
versionStr[1] = *(dotPos - 1);
versionStr[2] = '\0';
return atoi(versionStr); // Konverter til heltall
}
return 0; // Returner 0 hvis versjonsnummeret ikke kan bestemmes
}