Ball valve open close with oled

hi,

I have a ball valve with 2 limit switchesas an input, a button to control it (open or close) through an esp32. The 2 outputs are routed too 2 mosfet, one for open one for close. There's an OLED screen connected to the esp

When the button is HIGH the valve opens and the limit switch for open turns HIGH for the duration until fully open or when button LOW the limit switch for close stays HIGH for the duration until fully close

The problem i have that i cannot figure out how to present the different valve states on the oled screen. presenting open or close on the screen is not a problem, but if for example the valve fails, i want it to represent that on the screen as is shown in the program.

Valve operation is working without a problem. (open or close)

Any help would be appreciated

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET     -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const int Switch = 17;
const int PinOpen = 18;
const int PinClose = 19;
const int LOPEN = 23;
const int LCLOSE = 26;

long unsigned  previousMillis1 = 0;
long unsigned  previousMillis = 0;
long unsigned  interval = 8000;

boolean enabled;
boolean enabled1;

void setup() {

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
  pinMode(Switch, INPUT);
  pinMode(PinOpen, OUTPUT);
  pinMode(PinClose, OUTPUT);
  pinMode(LOPEN, INPUT);
  pinMode(LCLOSE, INPUT);

  display.clearDisplay();

}

void loop() {

  int button = digitalRead(Switch);
  int limitclose = digitalRead(LCLOSE);
  int limitopen = digitalRead(LOPEN);

  if (button == HIGH) {
    digitalWrite(PinOpen, HIGH); //
    digitalWrite(PinClose, LOW);  //
  } else {
    digitalWrite(PinOpen, LOW); //
    digitalWrite(PinClose, HIGH);  //
  }

    if (limitclose == HIGH && button == LOW) {
    enabled = true;
    previousMillis = millis();
  }

  if (limitclose == HIGH && button == LOW) {
         display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 14);
      display.println("closing");
      display.display();
  } else if (limitclose == LOW && button == LOW) {
            display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 14);
      display.println("close");
      display.display();
  } else if (enabled) {
    if (millis() - previousMillis >= interval) {
      previousMillis = millis();
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 14);
      display.println("fail to close");
      display.display();
    }
  }


  if (limitopen == HIGH && button == HIGH && zsh == LOW) {
    enabled1 = true;
    previousMillis1 = millis();
  }

  if (limitopen == HIGH && button == HIGH) {
         display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 14);
      display.println("opening");
      display.display();
  } else if (limitopen == LOW && button == HIGH) {
            display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 14);
      display.println("open");
      display.display();
  } else if (enabled1) {
    if (millis() - previousMillis1 >= interval) {
      previousMillis1 = millis();
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 14);
      display.println("fail to open");
      display.display();
    }
  }
  delay(100);
}

Is there anything keeping the inputs in a known state at all times or are they floating at an unknown voltage, maybe HIGH, maybe LOW, maybe changing ?

No, they're not floating, 0 volt or 3,3 volt

you need to monitor the state of both limit switches and the button, then update the display accordingly. Here's how you can modify your existing code to achieve this:

  1. Define variables to track the state of the valve (open, closed, opening, closing, fail to open, fail to close).
  2. Update these variables based on the readings from the limit switches and the button.
  3. Display the current state on the OLED screen.

Here's the modified part of your loop() function:

void loop() {
 int buttonState = digitalRead(Switch);
 int limitCloseState = digitalRead(LCLOSE);
 int limitOpenState = digitalRead(LOPEN);

 // Handle opening process
 if (buttonState == HIGH && limitOpenState == LOW) {
    digitalWrite(PinOpen, HIGH);
    digitalWrite(PinClose, LOW);
    displayStatus("Opening...");
 } else if (buttonState == HIGH && limitOpenState == HIGH) {
    displayStatus("Open");
 } else if (buttonState == HIGH && limitOpenState == HIGH && (millis() - previousMillis1) >= interval) {
    displayStatus("Fail to Open");
 }

 // Handle closing process
 if (buttonState == LOW && limitCloseState == LOW) {
    digitalWrite(PinOpen, LOW);
    digitalWrite(PinClose, HIGH);
    displayStatus("Closing...");
 } else if (buttonState == LOW && limitCloseState == HIGH) {
    displayStatus("Closed");
 } else if (buttonState == LOW && limitCloseState == HIGH && (millis() - previousMillis) >= interval) {
    displayStatus("Fail to Close");
 }

 delay(100);
}

// Function to display status on OLED
void displayStatus(String status) {
 display.clearDisplay();
 display.setTextSize(1);
 display.setTextColor(WHITE);
 display.setCursor(0, 14);
 display.println(status);
 display.display();
}

In this modification, I've added a new function displayStatus to encapsulate the logic for displaying the status text on the OLED screen. This function takes a string as input and displays it on the screen. This makes the code cleaner and easier to maintain.

Remember to declare previousMillis1 and interval variables at the beginning of your script, similar to how you've declared previousMillis.

This code should now properly reflect the state of the valve on the OLED screen, including any failure conditions.

I tried this variant but on the oled display it reads only opening.. or closing...

How long does it take for the valve to go from full closed to full open and vice versa?

Can you please provide a schematic to show how everything is wired.

8 seconds

i changed the resistor value afterwards, so instead of 3.3v i have now 4.8v but for operation it doesn't matter

There is no switch in your schematic.

You're right, the switch is connected the same way as the limit switch on D17

// Handle opening process
 if (buttonState == HIGH && limitOpenState == LOW) {
    digitalWrite(PinOpen, HIGH);
    digitalWrite(PinClose, LOW);
    displayStatus("Opening...");
 } else if (buttonState == HIGH && limitOpenState == HIGH) {
    displayStatus("Open");
 } else if (buttonState == HIGH && limitOpenState == HIGH && (millis() - previousMillis1) >= interval) {
    displayStatus("Fail to Open");
 }

If that is the case, I would focus on these two states and use some printing or other indication of the actual status.

int limitCloseState = digitalRead(LCLOSE);
 int limitOpenState = digitalRead(LOPEN);

Command the valve to open and start a 12 Second timer.
Display "valve opening",
Stop motor when valve open limit switch activates, display"valve open".
If timer expires before valve open limit switch activates, stop motor and display "valve fault".

Seems you use one logic on the "open" limit and the opposite logic on the "close" limit.
Is this correct or is it a drawing stuff up????
i.e. if the valve is open or closed (only 2 possibilities) then if the same logic were applied, one or the other limit would be shown as closed in the (standard) power down schematic.

Yes exactly, during opening or closing one of the limit switches is HIGH, while the other at the same time is LOW

I'm referring to your drawing .......... re-read my comment.
Appears drawing is wrong.

...and please learn how to present drawings ...left right ...top bottom.....power rail and ground locations. otherwise it's not a drawing, just a chook scratch.

Your code works perfect, until the part , fail to close or open. It just stay's closing or opening after the interval expired.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.