Okay, I am back. As I already said, I want the the motor to shut down when one of the eight flowrates is more than 2 liters/minute different to all the others. Therefore I just have to open an relay. If I had only two meters, I'd do something like this:
But I have no idea how I can compare all eight among themselves without a reference.
I'll attach my whole code, the interesting stuff is in the FLOWMETER section.
Code: Select all
//Pump durability tester code
//includes:
//-thermal shutdown circuit
//-motor speed control via relay
//-pump flowrate monitoring
// include the library code for I2C and the LCD shield:
#include "Adafruit_MAX31855.h"
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
#define PIN_ESTOP 8 // connects to the NC E-Stop button
//#define PIN_I2C_1 A4 // these pins provide serial communication with the LCD shield
//#define PIN_I2C_2 A5 // these pins provide serial communication with the LCD shield
#define THRESHOLD_TEMPERATURE_MOTOR 100 // maximum pump temperature for normal operation
#define THRESHOLD_TEMPERATURE_AMBIENT 60 // maximum ambient temperature for normal operation
#define STATE_ESTOP_ACTIVE HIGH // E-stop pin is pulled high internally, then grounded through E-stop button
// the button is NC, thus pressed means open means not grounded means HIGH
#define Relay_STOP 12 // Relay control output
#define Relay1 22 // Relay speed1
#define Relay2 24 // Relay speed2
#define Relay3 26 // Relay speed3
#define thermoDO 2 // Data out (shared)
#define thermoCS1 3 // Chip select for thermocouple 1
#define thermoCLK 4 // Clock (shared)
#define thermoCS2 5 // Chip select for thermocouple 2
#define time double (millis()/1000)/60 // Program runtime.
// Variables will change:
long previousMillis = 0;
// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
// this creates an LCD object that is controlled using the Adafruit library
Adafruit_MAX31855 thermocouple1(thermoCLK, thermoCS1, thermoDO);
Adafruit_MAX31855 thermocouple2(thermoCLK, thermoCS2, thermoDO);
//FLOWMETERS-------------------------------------------------------------------------------------
typedef struct Meter_t
{
uint8_t pin;
uint16_t pulses;
uint8_t lastflowpinstate;
uint32_t lastflowratetimer;
float flowrate;
float wert;
float lmin;
};
volatile Meter_t meters[] = { // initialize meter array
{ 28, 0, 0, 0, 0.0 }, // meter 1: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 30, 0, 0, 0, 0.0 }, // meter 2: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 32, 0, 0, 0, 0.0 }, // meter 3: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 34, 0, 0, 0, 0.0 }, // meter 2: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 36, 0, 0, 0, 0.0 }, // meter 1: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 38, 0, 0, 0, 0.0 }, // meter 2: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 40, 0, 0, 0, 0.0 }, // meter 3: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 42, 0, 0, 0, 0.0 } // meter 2: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
// add more meters as needed
};
#define NUM_METERS (sizeof(meters) / sizeof(Meter_t))
SIGNAL(TIMER0_COMPA_vect) {
for (int m = 0; m < NUM_METERS; m++)
{
uint8_t x = digitalRead(meters[m].pin);
if (x == meters[m].lastflowpinstate) {
meters[m].lastflowratetimer++;
}
else
{
if (x == HIGH) {
//low to high transition!
meters[m].pulses++;
}
meters[m].lastflowpinstate = x;
meters[m].flowrate = 1000.0;
meters[m].flowrate /= meters[m].lastflowratetimer; // in hertz
meters[m].lastflowratetimer = 0;
}
}
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
}
else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
}
//FLOWMETERS-------------------------------------------------------------------------------------
}
void setup() {
Serial.begin(9600);
Serial.print("Flow sensor test!");
// declare the number of columns and rows for the LCD:
lcd.begin(16, 2);
//FLOWMETERS-------------------------------------------------------------------------------------
for (int m = 0; m < NUM_METERS; m++)
{
pinMode(meters[m].pin, INPUT);
digitalWrite(meters[m].pin, HIGH);
meters[m].lastflowpinstate = digitalRead(meters[m].pin);
}
useInterrupt(true);
//FLOWMETERS-------------------------------------------------------------------------------------
//pinMode(PIN_ESTOP, INPUT_PULLUP);
pinMode(Relay_STOP, OUTPUT);
digitalWrite(Relay_STOP, LOW);
lcd.setCursor(0,0);
lcd.print("Motor ON");
lcd.setCursor(0,1);
lcd.print("VFD Enabled");
//SPEEDCONTROL-------------------------------------------------------------------------------------
pinMode(Relay1, OUTPUT);
digitalWrite(Relay1, HIGH);
pinMode(Relay2, OUTPUT);
digitalWrite(Relay2, HIGH);
pinMode(Relay3, OUTPUT);
digitalWrite(Relay3, HIGH);
//SPEEDCONTROL-------------------------------------------------------------------------------------
} //end of setup()
void loop()
{
// checkEStop();
// checkThermocouples();
//FLOWMETERS-------------------------------------------------------------------------------------
for (int m = 0; m < NUM_METERS; m++)
{
//average filter
int i;
meters[m].wert = 0;
for(i = 0; i < 50; i++) {
meters[m].wert += meters[m].flowrate;}
meters[m].wert /= 50;
meters[m].lmin = meters[m].wert;
meters[m].lmin *=0.12;
//FLOWMETERS-------------------------------------------------------------------------------------
//SPEEDCONTROL-------------------------------------------------------------------------------------
unsigned long currentMillis = millis();
if(currentMillis - previousMillis < 20000) {
digitalWrite(Relay1, LOW);
}
else {
digitalWrite(Relay1, HIGH);
}
if(currentMillis - previousMillis > 20000 && currentMillis - previousMillis < 40000) {
digitalWrite(Relay2, LOW);
}
else {
digitalWrite(Relay2, HIGH);
}
if(currentMillis - previousMillis > 40000 && currentMillis - previousMillis < 60000) {
digitalWrite(Relay3, LOW);
}
else {
digitalWrite(Relay3, HIGH);
}
if(currentMillis - previousMillis >= 60000) {// reset the timer and start again
previousMillis = currentMillis;
}
//SPEEDCONTROL-------------------------------------------------------------------------------------
//lcd.print(flowrate);
Serial.print("Meter ");
Serial.print(m+1);
Serial.print(" FLowrate: ");
Serial.println(meters[m].flowrate);
Serial.print("Pulses: ");
Serial.println(meters[m].pulses, DEC);
}
} // end of loop()
//void checkEStop()
//{
// digitalWrite (PIN_ESTOP, HIGH);
// if ( digitalRead(PIN_ESTOP) == STATE_ESTOP_ACTIVE ) // if Estop button is pressed
// {
// digitalWrite(PIN_RELAY, LOW); // turn off relay to shut down VFD
// digitalWrite(PIN_RELAY, LOW); // shut down VFD
// lcd.setBacklight(RED); // display warning on LCD
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print("E-Stop pressed");
// lcd.setCursor(0,1);
// lcd.print("RT: ");
// lcd.println(time);
// lcd.println( " (min)");
// while(1) {} // wait for Arduino reset
// }
//} // end checkEStop
//void checkThermocouples()
//{
// double temperatureMotor = thermocouple1.readCelsius(); // read motor temperature from thermocouple
// double temperatureAmbient = thermocouple2.readCelsius();// read ambiant temperature from thermocouple
// lcd.setCursor(0,0); // display data on LCD
// lcd.print("Motor: ");
// lcd.print(temperatureMotor);
// lcd.print(" C");
// lcd.setCursor(0,1); // display data on LCD
// lcd.print("Ambient: ");
// lcd.print(temperatureAmbient);
// lcd.print(" C");
// if (temperatureMotor >= THRESHOLD_TEMPERATURE_MOTOR) // if temperature is too high
// {
// digitalWrite(PIN_RELAY, LOW); // shut down VFD
// lcd.setBacklight(RED); // display warning on LCD
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print("T_Motor Limit Reached");
// lcd.setCursor(0,1);
// lcd.print("RT: ");
// lcd.println(time);
// lcd.println( " (min)");
// while(1) {} // wait for reset
// }
// if (temperatureAmbient > THRESHOLD_TEMPERATURE_AMBIENT) // if temperature is too high
// {
// digitalWrite(PIN_RELAY, LOW); // shut down VFD
// lcd.setBacklight(RED); // display warning on LCD
// lcd.clear();
// lcd.setCursor(0,0);
// lcd.print("T_AMB Limit Reached");
// lcd.setCursor(0,1);
// lcd.print("RT: ");
// lcd.println(time);
// lcd.println( " (min)");
// while(1) {} // wait for reset
// }
// delay (1000);
//} // end checkThermocouples