Datalogging with alarm? Input from current sensing switch?

Hello amazing people.

I am mostly clueless on this idea and it's feasibility to use an Arduino to accomplish my goal, so i'm looking for assistance before I get too deep into it.

The goal would be to determine the amount of time between motor starts, and trigger an alarm relay if the time between starts decreases past a set threshold. Logging start and stop time or duration could potentially be helpful as well, but not necessary. To keep it simple, lets stick with just start.

After about 4 hours of searching/reading my thoughts are that a NO current sensing switch could be a way to get input from the motor to an Arduino, but maybe there is a better option?
Surely based on a switch closing an Arduino could log the time this event happened and if the next event happened in less time than X minutes, trigger Alarm relay?

In a nutshell, that's the goal.

Thoughts?

Details, details..

What kind of motor, what turns it on, what modifications can you do to it?

What I am looking to use this on is a "Dry" Fire sprinkler system. Life-Safety and all, can't do anything to it directly.

This system works by having air pressure maintained above a certain PSI. Once it falls below, it opens flow to the system and this happens too regularly from holes developing in the pipes from standing water.
Once that leak becomes bad enough it becomes an expensive and time consuming mess.

I am looking to monitor the air compressor for increase in frequency which would indicate a leak somewhere.

I've been playing around with code (which I still know almost nothing about) since posting earlier and think I might be getting somewhere with a basic timer function. The current sensing switch would be a start button (I got that far) and the thought is IF the "start button" is activated again before the timer is up, it triggers the alarm. I need to learn more programming before I could make that alone happen, but ideally I would still like to have logging capabilities to be able to look at to know if something might be coming even before the alarm is tripped.

Additional complications to that are the seasons cause the compressors to run different times at different times of the year. I don't think it's enough to be a problem, but it might cause me to have to adjust the timer regularly.

Worst part of this system is recent changes have been made to reduce the standing pressure from 32-40 PSI down to 9-13 PSI. Compressor comes on at 9 and off at 13. 7 PSI and it's game on. Very small window to work with, hence my desire to know something is up before it's actually UP.

If it was me I would use a WeMos D1 mini, or a similar ESP8266 board, assuming you have WiFi near.
Then all you need is the "compressor on/off" information.
The rest, including local and/or remote logging, automatic internet time, summer/winter, email etc. all can be done in software.
Advanced coding though.
Leo..

You have a dry sprinkler system - the pipes are filled with air until a sprinkler head breaks (or there is a massive air leak for which the air pressure is overcome by the water pressure). In the US, we have a high pressure switch (image left switch)- used to detect water flowing; and we have a low pressure switch (image right switch- actually, no switch present but, air gauge is) - to detect low air pressure before the flap releases water.

All that said, you should be able place an input from the arduino across the normally open contacts of the low air pressure switch; this will alert you to a low air instance predetermined by the setting (adjustable) of the low air switch.

To monitor the run-time of the compressor, you may, or may not, have secondary switch contacts the compressor switch.

If you don't have secondary contacts on your compressor to indicate run-time, google "current sensing relays" or "current sensing switches".

Any arduino will do, but Wawa's Wifi suggestion is the best option.

Thanks for the replies guys.

I looked into that board that was suggested, it looks like a great board.
However, if I can get the monitoring of the compressor figured out right, I will also add a voltage detection in case power goes out, breaker is tripped etc. Personally I think having it local with a battery backup tied to our emergency call system it should be pretty full proof.

As said at the start, using a Current Sensing Switch with an Arduino was the main question, and it's ability to log the data to be pulled manually when needed. That said, I am not sure if the compressor might have a 2nd set of contacts that could be tied into, that's something I will need to check on. Still, that would have me physically tying into the system and I'm not sure how much I can do that without risking being carted off to Guantanamo bay or something.. this is at an assisted living community.
Same thing goes for tying into low pressure switches existing in the system currently.
I'm sure If we contacted Simplex to come do the work for us the would happily do so for a hefty fee, but since they screw up every-other thing they touch on our property, I would rather opt for a stand-alone form of redundancy.

I can tell you, on a few of our buildings it hasn't required any massive air leak for water to be released. with a window of only 2 PSI we have had multiple areas flooded in the past 6 months, over a pin-hole you couldn't see. The leaks are in the attic so i'm sure you know how much damage is done before we finally see water.

Due to paranoia of 1 of our buildings in particular, our maintenance manager checks all compressors every morning. 2 weeks ago he was checking the most problematic one of the 5 and noticed it cycling every 30 seconds or so. As the compressor had been replaced twice in the past 3 months once due to OEM defect, he assumed it was the compressor again. He returned to the office to call Simplex for a service call then we returned to check on it 5 minutes later. while standing there for 30 seconds the water valve opened. Only because we were right there were we able to prevent major damage from that instance. I would like to see all the pipes replaced with SS or something. The buildings are only 20 years old, seems like these kinds of problems shouldn't be happening at all.

But if something like this would work, i'd be happy!

SparkFun Current Sensor Breakout

A clip-on or pass-through (non-invasive) CT would be ok, a galvanically coupled ACS712 sensor is not.
Many $5 clip-on current transformers on ebay.
Leo..

Thanks WaWa. I was just gonna delete those last 2 for what I think is a better option, and exactly what you just said.

Non-Invasive Current Sensor - 30A

Reviewers saying it's good for detecting on/off conditions. Cheap enough i'll order 1 tomorrow with the jack and do some tests.

Thanks again.

ScaleGurus:
I'm sure If we contacted Simplex to come do the work for us ...

LOL! Oh, the irony.

ScaleGurus:
Logging start and stop time or duration could potentially be helpful as well, but not necessary. To keep it simple, lets stick with just start.

ScaleGurus:
I've been playing around with code (which I still know almost nothing about) since posting earlier and think I might be getting somewhere with a basic timer function.

#include <TimeLib.h>          //https://github.com/PaulStoffregen/Time //Time Library - Time-master


char compressorSTART[17]; //2018/10/05 08:15 '\0';  //or save space by saving UNIX epoch via <TimeLib.h>
char compressorSTOP[17];  //2018/10/05 08:25 '\0';  //or save space by saving UNIX epoch via <TimeLib.h>
char compressorHISTORY [30][34];  //2-dimensional array-FIFO (30 historical entries containing 34 characters each; //or save space by saving UNIX epoch via <TimeLib.h>
//[0]= 2018/11/05 09:15 '\0'; 2018/11/05 09:25 '\0';
//[1]= 2018/11/05 08:15 '\0'; 2018/11/05 08:25 '\0';
// ...
// [29]= 2018/10/05 09:15 '\0'; 2018/10/05 09:25 '\0';

long intervalSTART;
long intervalSTOP;
long intervalSTORED;
long intervalFLAG = 20000;  //20 seconds


void setup() {
  Serial.begin(115200);

  memset(compressorSTART, '\0', sizeof(compressorSTART));  //clear array
  memset(compressorSTOP, '\0', sizeof(compressorSTOP)); // clear array

  //sensor senses current (switch closure)
  strcpy(compressorSTART, "2018/10/05 08:15");
  intervalSTART = millis();

  delay(3000); //delay to simulate compressor cycle

  //sensor senses no current (switch open)
  strcpy(compressorSTOP, "2018/10/05 08:25");
  intervalSTOP = millis();
  intervalSTORED = intervalSTOP - intervalSTART;


  
  // both compressorSTART & compressorSTOP can now be written to SD card and/or stored in compressorHISTORY[x]
  strcpy(compressorHISTORY[0], compressorSTART);  //copy start time to history array
  strcat(compressorHISTORY[0], " - ");
  strcat(compressorHISTORY[0], compressorSTOP);  // concantenate stop time to start time in history array


  //Diagnostic printing
  Serial.println(compressorSTART);
  Serial.println(compressorSTOP);
  Serial.println();
  Serial.print(intervalSTORED / 1000); Serial.println(" seconds");
  Serial.println(compressorHISTORY[0]);

  //Raise a flag
  if (intervalSTORED < intervalFLAG) {
    // raise alarm
  }


}

void loop() {
  // put your main code here, to run repeatedly:

}

The above should be a solid foundation; best of luck!

Wow, Thanks a lot for that, JMeller.

When I gave up last night I had too many time elements in a code, but that's part of learning the hard way.

#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
#include <elapsedMillis.h>
#include <Bounce2.h>

Figured one of them would be in the right neighborhood.

I have managed to be able to get a time stamp in serial monitor when I press a button, and release the button but the interval was missing. I'm just copy and pasting parts from multiple codes I'm finding and seeing what screws up then try to find why and find a fix for it. Probably not the best way to learn, but it is A way to learn, I suppose. lol

Your code certainly has a lot of the elements I was missing. Thank you, Thank you, Thank you!

Fumbling my way through you code, I think I have an understanding of what's going on.
Looks like I need to add the input for the sensor, along with maybe a threshold of when to active the compressorSTART/STOP. The sensor will be voltage coming into the UNO instead of a switch best I can tell. Maybe i'm thinking of this incorrectly.

The sensor should arrive Tuesday. I almost went to pick it up Friday afternoon as SparkFun is only about 45 minutes away from me but figured that would give me the weekend to mess up a bunch of peoples codes before I start messing up the hardware.

With what I've managed to get from what i've been messing with, I think i'm going to try to add the 16x2 LCD I have to it, maybe with 3 buttons: Setpoint up, setpoint down and scroll, to see last X number of intervals between starts.

Thanks again, JMeller!
Time to see what damage I can do today.

Took longer than expected to get the CT sensor in, but it finally arrived today. I have been playing around with it, by starting with everything I have found which says to install a 10 ohm burden resistor.
after installing the 10 ohm resistor, the voltage signal is so low that the cheap multimeter I have can't even read it with an estimated 12 amps running through it from a 1500 watt space heater.
I managed to get 1 code to work and give me a signal of .01 whatever (too many codes and pages come and gone since then), but only when I put the heater on high. low setting which is roughly 800 watts, 6-ish watts, nothing. I can't help but think the resistor is too high, so I dug and dug and came across the following:

Cuts from: CT sensors - Interfacing with an Arduino | Archived Forum

"Calculating a suitable burden resistor size"

  1. Choose the current range you want to measure
    The YHDC SCT-013-000 CT has a current range of 0 to 100 A. For this example, let's choose 100 A as our maximum current.

A) 30 A

  1. Convert maximum RMS current to peak-current by multiplying by √2.
    Primary peak-current = RMS current × √2 = 100 A × 1.414 = 141.4A

A) SEN-11005: 30A x √2= 42.4264068 A

  1. Divide the peak-current by the number of turns in the CT to give the peak-current in the secondary coil.
    Secondary peak-current = Primary peak-current / no. of turns = 141.4 A / 2000 = 0.0707

A) 42.4264068 A / 2000 = 0.02121320

  1. To maximise measurement resolution, the voltage across the burden resistor at peak-current should be equal to one-half of the Arduino analog reference voltage. (AREF / 2)
    Ideal burden resistance = (AREF/2) / Secondary peak-current = 2.5 V / 0.0707 A = 35.4 Ω

A) 2.5 / 0.02121320 = 117.851149 Ω

Not having any clue about any of this, I have no idea if any of that is relevant or not. Do I install a 100 ohm resistor instead of the 10 ohm or will I be risking life-and-limb by doing so?
Maybe a heater doesn't produce the right wave(?). No clue.
I've tried it wired directly to gnd and A0, as well as the 2.5v method shown on openenergymonitor, though I don't have the capacitor, but sounds like that's just for over-voltage protection and I should never exceed 10-12 amps in reality while the calculations are based on 30 A.

What do y'all think?
I'm hoping not to need anything more than I have, but I will be going to a job on Monday that brings me within a few miles of SparkFun if I need to get something else to make this work.

Spec Sheet on CT

By the way, Since starting this project the compressor this is going on has AGAIN had issues resulting in simples/johnson controls coming out again, now it is removed from the system and a normal garage compressor is in it's place. It was short cycling ever 47 seconds and they want to continue throwing parts at it without addressing the cause. Always just saying it's leaks in the pipes.
I have reached out to the manufacturer to find out what about the installation is causing this. Shameful, I know.. Probably $10,000 spend already just on this 1 dry system in under a year solely from the compressor, or as I think it will be proven to be, the installation. /end rant.

I think you can use any burden resistor value you like.
A low value just improves linearity, at the cost of a lower output voltage.
I also calculate about 116ohm for 5volt peak/peak at 30Amp.
100ohm could be a good starting value.
You do need to float the pin mid-voltage, as in the openenergymonitor diagram.
Arduino pins don's like to be used outside their limits.
Leo..

Very good, Thanks WaWa.

I have chopped up and cut down this code from Richard Steele

Not sure why using analogRead I can't seem to get the resolution that I can from this code, but I think it could serve the purpose.
I installed 2 resistors in series to get 110 ohms at the plug for the CT sensor and wired it back through with the 2.5 vdc from the arduino.
I multiplied result by 1000 and subtracted the "deadload"(?) to get near but above 0 as I assume it would be easier and maybe cleaner to look for an increase of >100 or something, instead of from 2500 to 2600. If that is wrong, please let me know.
Zero reading with this code as is fluctuates from 5 to 20 and with the 1500w heater on it reads around 142 immediately upon power-up and continues to climb up to 330.
It does seem to lock-up after a period of time or if I cycle power multiple times. Not sure what's going on there either..
Now that I look at it, i'll have to do those calculations elsewhere, couldn't reference them to find signal greater than X where they are..

int sensorMS01 = A0; // Analog input pin that sensor is attached to
float nVPP;   // Voltage measured across resistor

void setup()
 {
   Serial.begin(9600);
   pinMode(sensorMS01, INPUT);
 }
   
 void loop()
 {  
   nVPP = getVPP();
   Serial.print("Volts Through Resistor (Peak) : ");
   Serial.println(nVPP*1000-2568,0);
  }
float getVPP()
{
  float result;
  int readValue;             //value read from the sensor
  int maxValue = 0;          // store max value here
   uint32_t start_time = millis();
   while((millis()-start_time) < 1000) //sample for 1 Sec
   {
       readValue = analogRead(sensorMS01);
       // see if you have a new maxValue
       if (readValue > maxValue)
       {
           //record the maximum sensor value/
           maxValue = readValue;
       }
   }
   result = (maxValue * 5.0)/1024.0;//maxValue x Arduino Supply Voltage 5v or 3.3v change to suit your arduino board
   return result;
 }

beyond that for the censor, I have spent probably 60+ hours screwing up all kinds of codes, mostly with the goal of getting JMellers' Code to work, learned soo much while attempting this, but to no avail.
I did however manage to get a code that functions as intended, only thing I would like to change is:

  • have time show on the LCD as XX hours - XX minutes instead of just XXX minutes
  • log the last 10 "durations" just to be able to scroll through them with a button, possibly saved to eeprom?
  • of course now "button" needs to be replaced to be the trigger from the CT.

If anyone see's any catastrophies in the making, feel free to scream and shout or throw objects.

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

const int numRows = 2;
const int numCols = 16;
const int button = 7;
const int button1 = 8;
const int ledPin = 13;
 
unsigned long startTime;
unsigned long endTime;
unsigned long duration;
byte timerRunning;
int alarm = 2000;
int buttonState = 0;

void setup(){
  lcd.begin(16, 2);
  Serial.begin(9600);
  lcd.print("Cycle Monitor  ");
  lcd.setCursor(0,1);
  lcd.print("First Run      ");
  pinMode (button, INPUT_PULLUP);
  pinMode (button1, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  }

void loop(){
  
  if (timerRunning == 0 && digitalRead(button) == HIGH)
     {
     startTime = millis();
     timerRunning = 1;
     delay(50);
     }
     if (timerRunning == 1 && digitalRead(button1) == LOW)
     {
     lcd.setCursor(0,0);
     lcd.print("Current Cycle  ");
     lcd.setCursor(0,1);   
     lcd.print(millis()/1000- endTime/1000);
     lcd.print(" Minutes       ");
     }else{
     lcd.setCursor(0,0);
     lcd.print("Comp Cycle Time");
     lcd.setCursor(0,1);   
     lcd.print(duration/1000);
     lcd.print(" Minutes       "); 
     }
     
  if (timerRunning == 1 && digitalRead(button) == LOW)
     {
     endTime = millis();
     timerRunning = 0;
     duration = endTime - startTime;
     delay(50);
     Serial.println(duration);
     lcd.setCursor(0,0);
     lcd.print("Comp Cycle Time");
     lcd.setCursor(0,1);   
     lcd.print(duration/1000);
     lcd.print(" Minutes       ");
     
     if (duration < alarm){
       digitalWrite(ledPin, HIGH);
       delay(2000);
       digitalWrite(ledPin, LOW);
     }
    
     }
     }

You made comments about the system overall..

Here is my take on it, the pipes are being killed by the air compressor.

Your just pumping oxygen rich, moist air into the pipes promoting rapid rust conversion of the iron.

You're right Slumpert, plus with regular tests being done and low spots in the lines there is regularly small puddles left which is where it rusts a hole.
It would be nice if they could add something to the lines that would prevent rust and/or dry them after tests. The constant leaks is also why they reduced the operating pressure of the system from 40 psi down to 12.

Talking to the compressor manufacture it was also determined that some of the problems with the compressor are due to it being the lowest point in the system and the airlines go straight up from the compressor so condensation runs back to it, plus there is no tank installed or any other means of draining moisture from the system.