Linear actuator

Hello community,

i have a little Problem with my project/ code.

I have an linearactuator and the direction is changed by two relays. It is like a wipe and i have 3 switches, one for middel position, one the the top and one for the button.

The actuator should stop when a contact is reached and then wait there for a Interval until it moves in the other direction again.
I have tried many ways but i always have the problem, that the relay/actuator stops. Have somebody an idea where my problem is, or has a better way to programm it?

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <Wire.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "...";
char ssid[] = "....";
char pass[] = "....";

int relais1 = 13;  //13
int relais2 = 12;
//int luefter = 4;  //D4 Lüfterrelee wenn D16 geschlossen ist.
int kontakt = 16;
//int Wert; // für Türkontakt
int oben = 4;  // Reed Mitte
int unten = 14; //D5 // Reed Außen
int mittel = 5;  //d3 Pin 5 Reed Innen
const int wendung = 0; // Hauptschalter Wendung Pullup nötig
bool wendungstaste;

bool obenstatus = false;
bool untenstatus = false;
bool mittelstatus = false;
unsigned long currentMillis;
unsigned long previousMillis=0;
const long Interval = 10000;  //30 Sek
int obenflag;
int untenflag;
int mittelflag;

SimpleTimer timer;

void linearantrieb()
{
 //Start Türkontakt auslesen...
 currentMillis = millis();
 wendungstaste = digitalRead(wendung);
 obenstatus = digitalRead(oben);
 untenstatus = digitalRead(unten);
 mittelstatus = digitalRead(mittel);

 // 0 geschlossen, 1 ist offen  Low = ON HIGH = OFF

 // Start nach rechts, unten wenn Wendung eingeschaltet wird.
 if (wendungstaste == HIGH) {
   digitalWrite (relais1, LOW);
   digitalWrite (relais2, LOW);
 }
 // false = Schalter aktiviert  // true = geöffnet

 // Wenn Mittelstellung aktiv dann Wendung einschalten
 if (mittelstatus == false && wendungstaste == LOW) {
   mittelflag = true;
   digitalWrite (relais1, HIGH);
   digitalWrite (relais2, LOW);
   mittelstatus = true;
  // obenflag = false;
  // untenflag = false;
  }
     
 // Wenn Unten aktiv Relais Stromlos schalten.
 if (untenstatus == false && wendungstaste == LOW) {
   digitalWrite (relais1, LOW);
   digitalWrite (relais2, LOW);
   untenflag = true;
 }
 // Wenn Unten Aktiv und Zeit Abgelaufen ist // Richtung ändern
 if (untenflag == true && wendungstaste == LOW && (currentMillis - previousMillis >= Interval)) {
   digitalWrite (relais1, LOW);
   digitalWrite (relais2, HIGH);
   untenflag = false;
 }

 // Wenn oben aktiviert Relais Stromlos schalten.
 if (obenstatus == false && wendungstaste == LOW) {
   digitalWrite (relais1, LOW);
   digitalWrite (relais2, LOW);
   obenflag = true;
 }

 // Wenn Unten Aktiv und Zeit Abgelaufen ist // Richtung ändern
 if (obenflag == true && wendungstaste == LOW && (currentMillis - previousMillis >= Interval)) {
   digitalWrite (relais1, HIGH);
   digitalWrite (relais2, LOW);
   obenflag = false;
 }

// Zurück zur Mittelstellung über Blynk Button?!
}

void setup() {
 // put your setup code here, to run once:
 pinMode (relais1, OUTPUT);
 pinMode (relais2, OUTPUT);
 pinMode (oben, INPUT);
 pinMode (unten, INPUT);
 pinMode (wendung, INPUT_PULLUP);
 pinMode (mittel, INPUT);

 timer.setInterval(500L, linearantrieb);
}

void loop() {
 Blynk.run();
 timer.run();
}

Thank you in advance :slight_smile:

You appear to be using a NodeMCU and have three reed switches which indicate the top, middle and bottom positions of the actuator.
I’m not clear from your description what the significance of the middle position sensor is in the desired process.

Personally, I’d attach interrupts to these three reed switches and have three different functions that are called when the interrupts change to do three different actions.

You may also need to read the condition of these three reed switches at startup so that you know I’d the actuator is at one of the three positions and use this information in your logic.

To be honest, you’ve probably reached (or exceeded) the limit of the useable number of GPIO pins available in the NodeMCU, especially when you consider that pulling some of these pins HIGH or LOW at boot-up will put the NodeMCU into programming mode rather than code execution mode…

As a result, you may be better using an ESP32 board for this instead.

Also, mixing BlynkTimer and millis comparison techniques in the same sketch isn’t really a great idea. I’d stick with BlynkTimer and use timeout timers in a lambda function if necessary (but it’s probably not necessary with the correct use of the reed switches).

It’s easy to get confused with the coding process with something like this, so maybe you should sit down with a piece of paper and draw/write out the various scenarios that could occur and what you want the system to do in each situation.

Pete.

Hello Pete,

thank you for the qick answer. And you are still right, first a had many problems with the using of the Pins, but now i hope i have the right wirering. And sorry for the missing information, i usw a Wemos D1 R1.

The program shoud be like this:

The program should go something like this:

When the main switch is activated and the middle contact switch is activated, drive down.
When you get down, wait.
After the time go up.
When you get to the top, wait.

If the main switch is deactivated, move up / down until the middle position is reached.

And when this will work, i would like to see in the blynk app, which status /up / down is set at the moment…