Adding rotary dip switches

I’m using a state machine to monitor two sensors in a fish tank automatic topoff system, there are a number of outcomes based on the states of these sensors.

It works brilliantly, (better than I deserve), but is only good enough for normal use.
If I want to top the tank up after a water change, I’d like to put the auto-top off into a maintenance mode which lets the pump run until the tank is full without warning. I’d also like to be able to change pump on time and max pump count. So I’ve added two rotary dip switches (each has 4 positions which I have set to be logic high when the address is selected and low when not selected).

How do I read the state of the dips and update the max_pump_count and pump_on_time? I would like to update these values in real time and not need to reset the system for them to be updated, so I think they’ll have to be in the main loop.

Will quote my code in the next post because I don’t know how to do this neatly

Many thanks in advance

I’ve had a crack at adding the dips with a long line of if statements, I can post that code here as well if it helps?

Because of its layout some of your code has had code tags added to it by the forum software

Please follow the advice given in the link below and post all of it in code tags

1 Like

Thank you UKHeliBob,
This is my working code (without the dip switches in.

#define tlPin 2                                      // digital pin 2 has top tank level sensor attached to it.
#define roPin 3                                      // digital pin 3 has the water barrel water level sensor attached to it.
#define pumpPin 4                                    // digital pin 4 has pump control attached to it.
#define hornPin 5                                    // digital pin 5 has the horn control attached to it.

int state_wl = 0;
int roState = 0;
int tlState = 0;
int m_dash = 900;
int m_dot = 300;
int m_space = 300;
int m_word = 2100;
int cCount = 0;
int pump_on_time = 5000;                            // variable, set how long the pump should run for
int listen_delay_time = 1000;                       //variable, set how long the listen should delay before moving on
int max_pump_count = 3;                             //variable, set how maximum number of pump cycles before the system calls a halt
int max_pump_time = max_pump_count * pump_on_time;  // fixed
unsigned long start_time = 0;
unsigned long new_time = 0;

void setup() {
  Serial.begin(9600);                               // initialize serial communication at 9600 bits per second.
  pinMode(tlPin, INPUT);                            // make the top tank water level sensor's pin an input.
  pinMode(roPin, INPUT);                            // make the bottom tank water level sensor's pin an input.
  pinMode(pumpPin, OUTPUT);                         // make the pump control pin an output.
  pinMode(hornPin, OUTPUT);                         // make the horn control pin an output.
}

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

void SM_wl () {
  
  switch (state_wl) {
    case 0: //RESET
      Serial.println("Reset");
      cCount = 0;
      digitalWrite(pumpPin, LOW);
      start_time = millis();
      state_wl = 1;
    break;

    case 1: //LISTEN Mode
      Serial.println("Listen");    
      delay(listen_delay_time);
      roState = digitalRead(roPin);
      tlState = digitalRead(tlPin);      

      if (roState == HIGH && tlState == LOW) {state_wl = 0;}      //RESET
      if (roState == HIGH && tlState == HIGH) {state_wl = 2;}     //FILL
      if (roState == LOW && tlState == LOW) {state_wl = 3;}     //RO LOW
      if (roState == LOW && tlState == HIGH) {state_wl = 4;}    //TANK LOW
    break;

    case 2: //FILL Mode
      new_time = millis();
      if (cCount < max_pump_count) {state_wl = 5;}  
      if (cCount >= max_pump_count && new_time - start_time <= max_pump_time)   {state_wl = 0;}  
      if (cCount >= max_pump_count && new_time - start_time > max_pump_time)  {state_wl = 6;}  
    break;

    case 3: //RO LOW Mode
      Serial.println("RO LOW");  
      //Morse Code for R
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_space);

      //Morse Code for O
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_word);
      state_wl = 1;
    break;

    case 4: //TANK LEVEL LOW Mode
      Serial.println("TANK LOW");      
      digitalWrite(pumpPin, LOW);
      //Morse Code for T
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);

      //Morse Code for L
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);      
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_word);      
      state_wl = 1;
    break;

    case 5: //PUMP ON Mode
      Serial.println("PUMP ON");      
      cCount ++;
      digitalWrite(pumpPin, HIGH);
      delay(pump_on_time);
      state_wl = 1;
    break;    

    case 6: //MALFUNCTION
      Serial.println("MALFUNCTION");
      digitalWrite(pumpPin, LOW);      
      while (true) {
        //Morse Code for S
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
  
        //Morse Code for O
        digitalWrite(hornPin, HIGH);
        delay (m_dash);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dash);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dash);
        digitalWrite(hornPin, LOW);
        delay (m_space);
  
        //Morse Code for S
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_word);      
      }
    break;    
  }
}

And this is my half baked attempt at getting the dips involved:

#define tlPin 2                                      // digital pin 2 has top tank level sensor attached to it.
#define roPin 3                                      // digital pin 3 has the water barrel water level sensor attached to it.
#define pumpPin 4                                    // digital pin 4 has pump control attached to it.
#define hornPin 5                                    // digital pin 5 has the horn control attached to it.
#define Pump_0 6                                      // digital pin 6 has Pump rotary DIP switch position 0 connected to it
#define Pump_1 7                                      // digital pin 7 has Pump rotary DIP switch position 1 connected to it
#define Pump_2 8                                      // digital pin 8 has Pump rotary DIP switch position 2 connected to it
#define Pump_3 9                                      // digital pin 9 has Pump rotary DIP switch position 3 connected to it
#define Time_0 10                                     // digital pin 10 has Time rotary DIP switch position 0 connected to it
#define Time_1 11                                     // digital pin 11 has Time rotary DIP switch position 1 connected to it
#define Time_2 12                                     // digital pin 12 has Time rotary DIP switch position 2 connected to it
#define Time_3 13                                     // digital pin 13 has Time rotary DIP switch position 3 connected to it

int state_wl = 0;
int roState = 0;
int tlState = 0;
int m_dash = 900;
int m_dot = 300;
int m_space = 300;
int m_word = 2100;
int cCount = 0;
int pump_on_time = 5000;                            // variable, set how long the pump should run for
int listen_delay_time = 1000;                       //variable, set how long the listen should delay before moving on
int max_pump_count = 3;                             //variable, set how maximum number of pump cycles before the system calls a halt
int max_pump_time = max_pump_count * pump_on_time;  // fixed
unsigned long start_time = 0;
unsigned long new_time = 0;

void setup() {
  Serial.begin(9600);                               // initialize serial communication at 9600 bits per second.
  pinMode(tlPin, INPUT);                            // make the top tank water level sensor's pin an input.
  pinMode(roPin, INPUT);                            // make the bottom tank water level sensor's pin an input.
  pinMode(pumpPin, OUTPUT);                         // make the pump control pin an output.
  pinMode(hornPin, OUTPUT);                         // make the horn control pin an output.
  pinMode(Pump_0, INPUT);                            // make Pump_0's pin an input.  
  pinMode(Pump_1, INPUT);                            // make Pump_1's pin an input.  
  pinMode(Pump_2, INPUT);                            // make Pump_2's pin an input.  
  pinMode(Pump_3, INPUT);                            // make Pump_3's pin an input.  
  pinMode(Time_0, INPUT);                            // make Time_0's pin an input.  
  pinMode(Time_1, INPUT);                            // make Time_1's pin an input.  
  pinMode(Time_2, INPUT);                            // make Time_2's pin an input.  
  pinMode(Time_3, INPUT);                            // make Time_3's pin an input.  
}

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

void SM_wl () {
  
  switch (state_wl) {
    case 0: //RESET
      Serial.println("Reset");
      cCount = 0;
      digitalWrite(pumpPin, LOW);
      start_time = millis();
      state_wl = 1;
    break;

    case 1: //LISTEN Mode
      Serial.println("Listen");    
      delay(listen_delay_time);
      roState = digitalRead(roPin);
      tlState = digitalRead(tlPin);
      if (digitalRead(Pump_0) == HIGH){
        Serial.println("Maintenance Mode");
        max_pump_count = 100;
      }  
      if (digitalRead(Pump_1) == HIGH){
        Serial.println("Max 2 Pump");
        max_pump_count = 2;       
      }
      if (digitalRead(Pump_2) == HIGH){
        Serial.println("Max 4 Pump");
        max_pump_count = 4;       
      }
     if (digitalRead(Pump_3) == HIGH){
        Serial.println("Max 8 Pump");
        max_pump_count = 8;       
      }
      if (digitalRead(Time_0) == HIGH){
        Serial.println("2 Second Pump Time");
        pump_on_time = 2000;
      }  
      if (digitalRead(Time_1) == HIGH){
        Serial.println("4 Second Pump Time");
        pump_on_time = 4000;
      }
      if (digitalRead(Time_2) == HIGH){
        Serial.println("6 Second Pump Time");
        pump_on_time = 6000;
      }
     if (digitalRead(Time_3) == HIGH){
        Serial.println("8 Second Pump Time");
        max_pump_count = 8000;       
      }
      if (roState == HIGH && tlState == LOW) {state_wl = 0;}      //RESET
      if (roState == HIGH && tlState == HIGH) {state_wl = 2;}     //FILL
      if (roState == LOW && tlState == LOW) {state_wl = 3;}     //RO LOW
      if (roState == LOW && tlState == HIGH) {state_wl = 4;}    //TANK LOW
    break;

    case 2: //FILL Mode
      new_time = millis();
      if (cCount < max_pump_count) {state_wl = 5;}  
      if (cCount >= max_pump_count && new_time - start_time <= max_pump_time)   {state_wl = 0;}  
      if (cCount >= max_pump_count && new_time - start_time > max_pump_time)  {state_wl = 6;}  
    break;

    case 3: //RO LOW Mode
      Serial.println("RO LOW");  
      //Morse Code for R
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_space);

      //Morse Code for O
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_word);
      state_wl = 1;
    break;

    case 4: //TANK LEVEL LOW Mode
      Serial.println("TANK LOW");      
      digitalWrite(pumpPin, LOW);
      //Morse Code for T
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);

      //Morse Code for L
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dash);
      digitalWrite(hornPin, LOW);
      delay (m_space);      
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_space);
      digitalWrite(hornPin, HIGH);
      delay (m_dot);
      digitalWrite(hornPin, LOW);
      delay (m_word);      
      state_wl = 1;
    break;

    case 5: //PUMP ON Mode
      Serial.println("PUMP ON");      
      cCount ++;
      digitalWrite(pumpPin, HIGH);
      delay(pump_on_time);
      state_wl = 1;
    break;    

    case 6: //MALFUNCTION
      Serial.println("MALFUNCTION");
      digitalWrite(pumpPin, LOW);      
      while (true) {
        //Morse Code for S
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
  
        //Morse Code for O
        digitalWrite(hornPin, HIGH);
        delay (m_dash);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dash);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dash);
        digitalWrite(hornPin, LOW);
        delay (m_space);
  
        //Morse Code for S
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_space);
        digitalWrite(hornPin, HIGH);
        delay (m_dot);
        digitalWrite(hornPin, LOW);
        delay (m_word);      
      }
    break;    
  }
}

More details of your switches please. The phrase “rotary DIP switch” is confusing. Have they got 5 pins, one of which can be connected to any one of the other pins ?

1 Like

6 pins, 2 are common and I’ve linked these to 5V, the other 4 each go to digital pins on the nano. datasheet here: https://www.ctscorp.com/wp-content/uploads/220.pdf

I would be less confused if you explained the addressing.

I would be less confused if you posted even a hand drawn schematic of your wiring, all of it, but at least the rotary dips.

THX

a7

1 Like

image

image

I’m happy to give the whole circuit if you need it, but I imagine you won’t be interested in the bits that work

Tried to get the entire schematic in one image for you

GIATO.pdf (84.6 KB)

Copy and paste error here:

        max_pump_count = 8000;
1 Like

didnt spot that, thank you

in my half baked attempt the code updates the max_pump_count, but it doesnt update the pump_on_time

I can’t see why not, unless you have a wiring issue.

One problem I do see though is that max_pump_time is fixed at startup. You will need to recalculate it after you read the rotary settings.

1 Like