Ciao a tutti,
questo weekend sono riuscito a finire il mio piccolo progettino (installazione a parte).
Ecco alcune foto:
E questo è il codice:
#include <Wire.h>
long pump2Delay = 60000; // Time (in millis) to delay pump2 activation
long sw1Delay = 180000;   // Time after which to enable pumps even if sw2 is not active
                       // Don't want water to rest there unnecessarily
int R0 = 4;
int R1 = 5;
int LEDSW1 = 6;
int LEDSW2 = 7;
int sw1State = 0;
int sw2State = 0;
int sw3State = 0;
int previousSW1State = 0;
int previousSW2State = 0;
int previousSW3State = 0;
int pump1Active=0;
int pump2Active=0;
int anomaly = 0;
long interval = 1500;           // interval at which to blink (milliseconds)
// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
long previousPump1ActiveMillis = 0;
long previousPump2ActiveMillis = 0;
long previousSW1StateMillis = 0;
long previousSW2StateMillis = 0;
long previousSW3StateMillis = 0;
const byte SlaveDeviceId = 1;
void blink(){
  int d = 250;
  for(int i = 1; i < 7; i++){
    digitalWrite(A3, i % 2);
    delay(d);
  }
}
// aCount is the number of bytes received.
void receiveCallback(int aCount)
{
  if(aCount == 2)
  {
    int receivedValue  = Wire.read() ;
    int receivedValue2 = Wire.read();
    Serial.print("Switch 1: ");
    Serial.println(receivedValue);
    Serial.print("Switch 2: ");
    Serial.println(receivedValue2);
  }
  else
  {
    Serial.print("Unexpected number of bytes received: ");
    Serial.println(aCount);
  }
  blink();
}
void requestCallback()
{
  // Contrived example - transmit a value from an analogue pin.
  // To send multiple bytes from the slave,
  // you have to fill your own buffer and send it all at once.
  uint8_t buffer[6];
  buffer[0] = sw1State;
  buffer[1] = sw2State;
  buffer[2] = sw3State;
  buffer[3] = pump1Active;
  buffer[4] = pump2Active;
  buffer[5] = anomaly;
  Wire.write(buffer, 6);
  blink();
}
// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(R0, OUTPUT);
  pinMode(R1, OUTPUT);
  pinMode(LEDSW1, OUTPUT);   //Use Relay 2 as SW1 telltale
  pinMode(LEDSW2, OUTPUT);   //Use Relay 3 as SW2 telltale
  pinMode(A3, OUTPUT);       //Use A3 to drive status led
  pinMode(A0, INPUT);        //A0 == SW1
  digitalWrite(A0, HIGH);
  pinMode(A1, INPUT);        //A1 == SW2
  digitalWrite(A1, HIGH);
  pinMode(A2, INPUT);        //A2 == SWITCH OVERRIDE
  digitalWrite(A2, HIGH);
  //pinMode(A3, INPUT);
  //digitalWrite(A3, HIGH);
  //I2c Init
  digitalWrite(A4, HIGH);
  digitalWrite(A5, HIGH);
  Wire.begin(SlaveDeviceId);
  // Set the callback to call when data is received.
  Wire.onReceive(receiveCallback);
  Wire.onRequest(requestCallback);
}
// the loop routine runs over and over again forever:
void loop() {
  unsigned long currentMillis = millis();
  /*
   if(currentMillis - previousMillis2 > interval2) {
      previousMillis2 = currentMillis;
      blink();
   }
  */
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    sw1State = !digitalRead(A0);
    sw2State = !digitalRead(A1);
    sw3State = !digitalRead(A2);
    digitalWrite(LEDSW1, sw1State);
    digitalWrite(LEDSW2, sw2State);
    if (sw1State != previousSW1State){
      previousSW1State = sw1State;
      previousSW1StateMillis = currentMillis;
    }
    if (sw2State != previousSW2State){
      previousSW2State = sw2State;
      previousSW2StateMillis = currentMillis;
    }
    if (sw3State != previousSW3State){
      previousSW3State = sw3State;
      previousSW3StateMillis = currentMillis;
    }
    if (!sw1State && !sw2State && !sw3State){
       pump1Active = 0;
       pump2Active = 0;
    }
    if (((sw1State && sw2State)
          ||sw3State
          ||sw2State
          ||(sw1State && (currentMillis -  previousSW1StateMillis > sw1Delay))
          ) && !pump1Active){
      pump1Active = 1;
      previousPump1ActiveMillis = currentMillis;
    }
    if (pump1Active && (currentMillis -  previousPump1ActiveMillis > pump2Delay)){
      pump2Active = 1;
      previousPump2ActiveMillis = currentMillis;
    }
    anomaly = 0;
    if ((sw2State | sw3State) && !sw1State ){
      anomaly = 1;
    }
    if (currentMillis -  previousPump1ActiveMillis > 600000){
      anomaly = 1;
    }
    digitalWrite(R0, pump1Active);
    digitalWrite(R1, pump2Active);
    // if the LED is off turn it on and vice-versa:
    ledState = !ledState;
    if (sw3State){
      ledState = HIGH;
    }
    // set the LED with the ledState of the variable:
    digitalWrite(A3, ledState);
  }
}
Hardware:
Una rboard, a cui sono collegati:
- tre interruttori (due a galleggiante, uno manuale)
- un led per segnalazioni di comunicazione (blink)/attivazione manuale(always on)
- due contattori attivati tramite relè R0 e R1
- un arduino con trasmittente wireless RFM12 per comunicazione stato interruttori e pompe
La logica di funzionamento è questa:
Due interruttori a galleggiante in un tombino (più uno per attivazione manuale), uno di livello minimo , uno di livello massimo.
Quando l'interruttore di livello massimo è on, accensione di una pompa (e eventualmente la seconda dopo pump2Delay millisecondi) fino a che l'interruttore di livello minimo non è off. Se livello massimo è on e livello minimo no ho un anomalia che viene segnalata su comunicazione I2C
Se il livello minimo è on per più di sw1Delay attiviamo le pompe per svuotare fino sotto al livello minimo
Se le pompe sono accese per più di 10 minuti, segnalo anomalia
Se l'interruttore manuale è on, accendo le pompe con la stessa logica
Componenti aggiuntivi:
Trasformatore 220v/5v per alimentare i due arduino e il lato relè della rboard (con ground separata .. non sono sicuro basti a isolare da eventuali kickback ma mi evita di dover usare anche un trasformatore da 9v per alimentare la rboard)
Edit: Immagini link