Automatische Druckluftbox

Moin,
hab da ein kleines Projekt, bei dem ich nun etwas fest stecke.

Ich plane eine Automatische Druckluftbox:
16x2 LCD Display zur Anzeige von Soll Druck und Ist Druck,
Taster 1 Soll Druck +0,1bar,
Taster 2 Soll Druck -0,1bar,
Taster 3 Start/Stop (befüllen Starten/ Luft ablassen).

Verbaut:
Arduino Nano,
LCD Display mit I2C Schnittstelle,
2 Magnetventile 12V 2,5W,
3 Taster,
Drucksensor 0-10V (-1 bis 10bar Relativdruck),
2 Fach Relaiskarte.

Spannungsversorgung über 12V Akku mit 5V Festspannungsregler zur Versorgung vom Arduino.

Hier mein Aktueller Code:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

//=============================================================================

#define Sensor_PIN 0 //==> Daten-Pin für Drucksensor

#define Relais_PIN 6 //==> Pin Druck auffüllen

#define ablass_PIN 7 //==> Pin Druck ablassen

#define Plus_PIN 3 //==> Pin für den Knopf +

#define Minus_PIN 4 //==> Pin für den Knopf -

#define start 0 //==> Start/Soll Druck

#define min -1 //==> MinimalDruck

#define max 10 //==> MaximalDruck
//=============================================================================

int plus;
int minus;
float soll_Druck;

void setup(){
  lcd.begin(16, 2);
  lcd.backlight();
  Serial.begin(9600);
  Serial.println(F("Start"));
  pinMode(Relais_PIN, OUTPUT);
  digitalWrite(Relais_PIN,HIGH);
  digitalWrite(ablass_PIN,HIGH);
  pinMode(Plus_PIN,INPUT_PULLUP);
  pinMode(Minus_PIN,INPUT_PULLUP);

}

void loop()
  {
  if (soll_Druck == 0){
      soll_Druck = start;
  } 
  plus = digitalRead(Plus_PIN); 
  if (plus == 0)
  {
  soll_Druck = soll_Druck + 0.1;
  }
  if (soll_Druck > max)
  {
      soll_Druck = max;
  }
  minus = digitalRead(Minus_PIN); 
  if (minus == 0)
  {
  soll_Druck = soll_Druck - 0.1;
  }
  if (soll_Druck < min)
  {
      soll_Druck = min;
  }

int sensorVal=analogRead(A0);
    Serial.print("Sensor Value: ");
    Serial.print(sensorVal);
    Serial.print(" ");

float voltage = (sensorVal*5.0)/1024.0;
float pressure_pascal = (2.0*((float)voltage))*1000000.0;                       //calibrate here
float pressure_bar = pressure_pascal/10e5;

  Serial.print("Druck = ");
  Serial.print(pressure_bar);
  Serial.print("  bar  ");  
  Serial.print("Soll: ");
  Serial.print(soll_Druck);
  Serial.print("  bar  ");
  Serial.println();
  lcd.setCursor(0,0);
  lcd.print("Ist:  ");
  lcd.print(String(pressure_bar,1));
  lcd.print(" bar ");
  lcd.setCursor(0,1);
  lcd.print("Soll: ");
  lcd.print(String(soll_Druck,1));
  lcd.print(" bar ");
   if(pressure_bar <= soll_Druck){

    digitalWrite(Relais_PIN,HIGH);
    
   }else{

    digitalWrite(Relais_PIN,LOW);
    
   }
    
  delay(500);
}

Aktuell habe ich das Problem das beim erreichen vom Soll Druck das Magnetventil zum befüllen im Zustand etwas hin und herspringt.

Start/Stop und ablassen sind dann meine nächsten Baustellen.

Jemand einen Tipp wie ich das beim befüllen raus bekomme ?

Gruß Toroggur

Bist Du Dir sicher?

Was für einen Controller verwendest Du?
So wie ich das sehe, verwendest Du Pin 0 3Mal.

Du solltest da eine Hysterese einbauen. Am einfachsten im Hysterese-Bereich gar nichts machen.

const float hyst = 0.4;
if(pressure_bar <= soll_Druck)   digitalWrite(Relais_PIN,HIGH);
else if (pressure_bar >= soll_Druck + hyst)  digitalWrite(Relais_PIN,LOW);

Ist im Beispiel soll_Druck 4.5 , wird das Relais unter 4.5 eingeschaltet, und bei 4.9 ausgeschaltet, aber erst wenn der Druck wieder auf 4.5 gesunken ist, erneut eingeschaltet.
(Vorausgesetzt, HIGH schaltet das Relais ein. Wie in deiner Vorgabe)

Kannst die Rechnung und Bedeutung von soll und hyst nach Geschmack anpassen.

Kannst auch einiges überflüssige aus deinem Sketch entfernen. Wird dann für alle (auch dich selber) leichter verständlich.

Das delay(500) ist zur Zeit nötig, damit erst bei längerem Tastendruck sich der soll_Druck stufenweise ändert. Dadurch reagiert aber auch die Relais-Steuerung langsam. Nicht schön...

Hab den Seonsor_PIN mal raus genommen, hab ja weiter unten

int sensorVal=analogRead(A0);
    Serial.print("Sensor Value: ");
    Serial.print(sensorVal);
    Serial.print(" ");

float voltage = (sensorVal*5.0)/1024.0;
float pressure_pascal = (2.0*((float)voltage))*1000000.0;                       //calibrate here
float pressure_bar = pressure_pascal/10e5;

Beim Display stand das so schon im Sketch für I2C

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

Die Serielle Ausgabe ist derzeit nur zur Kontrolle.

Super funktioniert :slight_smile: Hab den Wert auf 0.02 da fällt die Schwankung im Display nicht gleich auf.

Jetzt die nächste Hürde, Start und Stop.
Hatte überlegt das mit einer while schleife zu machen aber wo ansetzen oder doch anders ?
Hier der geänderte Code:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

//=============================================================================

#define Relais_PIN 6 //==> Pin Druck auffüllen

#define ablass_PIN 7 //==> Pin Druck ablassen

#define Plus_PIN 3 //==> Pin für den Knopf +

#define Minus_PIN 4 //==> Pin für den Knopf -

#define start 0 //==> Start/Soll Druck

#define min -1 //==> MinimalDruck

#define max 10 //==> MaximalDruck
//=============================================================================

int plus;
int minus;
float soll_Druck;

void setup(){
  lcd.begin(16, 2);
  lcd.backlight();
  Serial.begin(9600);
  Serial.println(F("Start"));
  pinMode(Relais_PIN, OUTPUT);
  digitalWrite(Relais_PIN,HIGH);
  digitalWrite(ablass_PIN,HIGH);
  pinMode(Plus_PIN,INPUT_PULLUP);
  pinMode(Minus_PIN,INPUT_PULLUP);

}

void loop()
  {
  if (soll_Druck == 0){
      soll_Druck = start;
  } 
  plus = digitalRead(Plus_PIN); 
  if (plus == 0)
  {
  soll_Druck = soll_Druck + 0.1;
  }
  if (soll_Druck > max)
  {
      soll_Druck = max;
  }
  minus = digitalRead(Minus_PIN); 
  if (minus == 0)
  {
  soll_Druck = soll_Druck - 0.1;
  }
  if (soll_Druck < min)
  {
      soll_Druck = min;
  }

int sensorVal=analogRead(A0);
    Serial.print("Sensor Value: ");
    Serial.print(sensorVal);
    Serial.print(" ");

float voltage = (sensorVal*5.0)/1024.0;
float pressure_pascal = (2.0*((float)voltage))*1000000.0;                       //calibrate here
float pressure_bar = pressure_pascal/10e5;

  Serial.print("Druck = ");
  Serial.print(pressure_bar);
  Serial.print("  bar  ");  
  Serial.print("Soll: ");
  Serial.print(soll_Druck);
  Serial.print("  bar  ");
  Serial.println();
  lcd.setCursor(0,0);
  lcd.print("Ist:  ");
  lcd.print(String(pressure_bar,1));
  lcd.print(" bar ");
  lcd.setCursor(0,1);
  lcd.print("Soll: ");
  lcd.print(String(soll_Druck,1));
  lcd.print(" bar ");
  
const float hyst = 0.02;
   if(pressure_bar <= soll_Druck)
    digitalWrite(Relais_PIN,HIGH);
   else if (pressure_bar >= soll_Druck + hyst)
    digitalWrite(Relais_PIN,LOW);
    
  delay(500);
}

Das ist eine der unnötigen aber Menschen verwirrenden Zeilen. Stört den Compiler überhaupt nicht. Die Pin Angaben bei I2C Displays beziehen sich auf die Slave Seite, wo das Display angeschlossen ist. Hat mit den Arduino Pins nichts zu tun.

Würde gerne den SollWert vorgeben und wenn ich start drücke soll das Programm den Wert ansteuern, wie könnte ich das im Code umsetzen ?

Zeile 23:

float soll_Druck = 4.5;

Mit was?
Ich sehe nirgend einen StartButton.

Wobei der Code aus #5 erstmal aufgeräumt gehört.. :wink:

Hatte mir überlegt wenn ich den Arduino starte soll er erst mal nur im Display anzeigen, das er auf Eingabe des SollDrucks wartet. Dann mit + und - den SollDruck angeben und mit drücken auf Start das befüllen beginnen. Beim 2. mal Start drücken soll das befüllen abgebrochen werden und
das Ablassventil angesteuert werden.

Eine Baustelle nach der anderen :slight_smile:
Habe das nicht gelernt und bis jetzt immer nur Code Schnipsel zusammenkopiert :see_no_evil:
Start/Stop PIN muss ich noch definieren.

Keine Ahnung wonach man einen Code aufräumt :woozy_face:

  • Unnötige Anweisungen raus.
  • Hier im Forum sind unnötige Leerzeilen eher hinderlich.
  • Evtl. Kommentare aktualisieren. Bei Variablendefinitionen deren Bedeutung und mögliche Werte wäre optimal

Plan ist das Projekt immer mehr zu erweitern.

  • Zeiteingabe (wie lange der Druck gehalten werden soll)
  • Eingabe gewünschter Soll_Druck
  • Start/Stop über Taste
  • Werte auf SD Speichern
    (RTC/SD Modul ist schon vorhanden und ein Datenlogging hab ich schon getestet)

Hab schon mit der LCDMenuLib2 getestet aber noch keine Idee wie ich die gestalte.
Werte wurden schon erfolgreich mit dem RTC/SD modul gesichert, möchte aber zu erst das Hauptprogramm am laufen haben.

Hallo,
wozu soll das gut sein? Wenn Du einen Sollwert eingegeben hast dann lass den Arduion doch entscheiden ob er nachfüllt oder ablässt.
Vorschlag Du hast 3 buttons plus , minus, mode,
mode schaltet die Betriebsart um mit jedem Tastendruck gehts eins weiter
1 maunell -> plus minus schalten direkt die Ventile
2 Sollwert -> mit plus, miuns kannst Du den Sollwerte eingeben.
3 Auto -> mit einem der Taster plus oder minus wird der automatische Vorgang gestartet.

Die Sollwerte und aktuelle Betriebsart kannst Du im EEprom ablegen , dann ist beim nächsten Einschalten alles erhalten.

Du kannst auch noch überlegen ob Du was mit Taster lange drücken, kurz drücken, festhalten was machen willst. Das kann man manuell machen, ich empfehle jedoch zu so was die Lib OneButon.
Heinz

Das mit der OneButton Lib werd ich mir mal genauer ansehen.

Die Druckbox soll später für verschiedene Druckluftkissen benutzt werden.
Jedes Kissen hat einen anderen Arbeitsdruck, dieser soll vorher eingestellt werden.
Wenn das Kissen dann an Position liegt soll die Druckbox per Knopfdruck mit dem befüllen anfangen. Es muss aber auch möglich sein wenn ein augenscheinlicher Fehler/Defekt vorliegt das dann sofort druck abgelassen werden kann.

Gruß Toroggur

So habe das Programm mal ein wenig geändert und etwas aus der OneButton Lib übernommen.

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#include "OneButton.h"

#define Ventil1_PIN 7  //==> Magnetventil befüllen
#define Ventil2_PIN 8  //==> Magnetventil ablassen
#define Plus_INPUT 3    //==> Taster Druck erhöhen
#define Minus_INPUT 4   //==> Taster Druck verringern
#define Start_INPUT 5   //==> Taster Start
#define Stop_INPUT 6   //==> Taster Stop
#define min -1        //==> MinimalDruck
#define max 10        //==> MaximalDruck

OneButton button1(Plus_INPUT, false);
OneButton button2(Minus_INPUT, false);
OneButton button3(Start_INPUT, false);
OneButton button4(Stop_INPUT, false);

int Ventil1State = LOW;
int Ventil2State = LOW;
int Plus_PIN;
int Minus_PIN;
int Start_PIN;
float soll_Druck;



void setup() {
  lcd.begin(16, 2);
  lcd.backlight();
  pinMode(Ventil1_PIN, OUTPUT);
  pinMode(Ventil2_PIN, OUTPUT);
  button1.attachClick(mehr_Druck);
  button1.attachDoubleClick(schnellerplus);
  button2.attachClick(weniger_Druck);
  button2.attachDoubleClick(schnellerminus);
  button3.attachClick(start);
  button4.attachClick(abbruch);
  button1.setClickTicks(100);
  button2.setClickTicks(100);
  button3.setClickTicks(100);
  button4.setClickTicks(100);
}

void loop() {
  int sensorVal=analogRead(A0);
  float voltage = (sensorVal*5.0)/1024.0;
  float pressure_pascal = (2.0*((float)voltage))*1000000.0;   
  float pressure_bar = pressure_pascal/10e5;
  const float hyst = 0.02;
  button1.tick();
  button2.tick();
  button3.tick();
  button4.tick();
  lcd.setCursor(0,0);
  lcd.print("Soll: ");
  lcd.print(String(soll_Druck,1));
  lcd.print(" bar ");
  lcd.setCursor(0,1);
  lcd.print("Ist:  ");
  lcd.print(String(pressure_bar,1));
  lcd.print(" bar ");
delay(10);
}
void mehr_Druck(){
  soll_Druck = soll_Druck + 0.1;
  if (soll_Druck > max)
  {
      soll_Druck = max;
  }
}
void schnellerplus(){
  soll_Druck = soll_Druck + 0.5;
  if (soll_Druck > max)
  {
      soll_Druck = max;
  }
}
void weniger_Druck(){
  soll_Druck = soll_Druck - 0.1;
  if (soll_Druck < min)
  {
      soll_Druck = min;
  }
}
void schnellerminus(){
  soll_Druck = soll_Druck - 0.5;
  if (soll_Druck < min)
  {
      soll_Druck = min;
  }
}
void start(){
  digitalWrite(Ventil1_PIN,HIGH);
  digitalWrite(Ventil2_PIN,LOW);
}
void abbruch(){
  soll_Druck = 0;
  digitalWrite(Ventil1_PIN,LOW);
  digitalWrite(Ventil2_PIN,HIGH);
}

Soweit alles gut, aber wie füge ich nun den folgenden Teil mit ein ?

if(pressure_bar <= soll_Druck)
    digitalWrite(Ventil1_PIN,HIGH);
   else if (pressure_bar >= soll_Druck + hyst)
    digitalWrite(Ventil1_PIN,LOW);

Gruß Toroggur

Einfach im loop()
Allerdings würde ich überlegen die Schaltbedingungen zu ändern.

if(pressure_bar <= soll_Druck - hyst)
    digitalWrite(Ventil1_PIN,HIGH);
   else if (pressure_bar >= soll_Druck)
    digitalWrite(Ventil1_PIN,LOW);

Was genau würdest du verändern ?

Hab ich doch reingeschrieben.
Nicht + sondern - zum SollDruck. Das sieht sonst komisch aus, wenn Du ständig mehr hast als eingestellt.

Super wenn einem eine änderung am eigenen Code nicht mehr auffällt :crazy_face:

Super funktioniert

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#include "OneButton.h"

#define Ventil1_PIN 7  //==> Magnetventil befüllen
#define Ventil2_PIN 8  //==> Magnetventil ablassen
#define Plus_INPUT 3    //==> Taster Druck erhöhen
#define Minus_INPUT 4   //==> Taster Druck verringern
#define Start_INPUT 5   //==> Taster Start
#define Stop_INPUT 6   //==> Taster Stop
#define min -1        //==> MinimalDruck
#define max 10        //==> MaximalDruck

OneButton button1(Plus_INPUT, false);
OneButton button2(Minus_INPUT, false);
OneButton button3(Start_INPUT, false);
OneButton button4(Stop_INPUT, false);

int Ventil1State = LOW;
int Ventil2State = LOW;
int Plus_PIN;
int Minus_PIN;
int Start_PIN;
float soll_Druck;



void setup() {
  lcd.begin(16, 2);
  lcd.backlight();
  pinMode(Ventil1_PIN, OUTPUT);
  pinMode(Ventil2_PIN, OUTPUT);
  button1.attachClick(mehr_Druck);
  button1.attachDoubleClick(schnellerplus);
  button2.attachClick(weniger_Druck);
  button2.attachDoubleClick(schnellerminus);
  button3.attachClick(start);
  button4.attachClick(abbruch);
  button1.setClickTicks(10);
  button2.setClickTicks(10);
  button3.setClickTicks(10);
  button4.setClickTicks(10);
}

void loop() {
  int sensorVal=analogRead(A0);
  float voltage = (sensorVal*5.0)/1024.0;
  float pressure_pascal = (2.0*((float)voltage))*1000000.0;   
  float pressure_bar = pressure_pascal/10e5;
  const float hyst = 0.02;
  button1.tick();
  button2.tick();
  button3.tick();
  button4.tick();
  lcd.setCursor(0,0);
  lcd.print("Soll: ");
  lcd.print(String(soll_Druck,1));
  lcd.print(" bar ");
  lcd.setCursor(0,1);
  lcd.print("Ist:  ");
  lcd.print(String(pressure_bar,1));
  lcd.print(" bar ");
  if(pressure_bar <= soll_Druck - hyst)
    digitalWrite(Ventil1_PIN,HIGH);
   else if (pressure_bar >= soll_Druck)
    digitalWrite(Ventil1_PIN,LOW);
delay(10);
}
void mehr_Druck(){
  soll_Druck = soll_Druck + 0.1;
  if (soll_Druck > max)
  {
      soll_Druck = max;
  }
}
void schnellerplus(){
  soll_Druck = soll_Druck + 0.5;
  if (soll_Druck > max)
  {
      soll_Druck = max;
  }
}
void weniger_Druck(){
  soll_Druck = soll_Druck - 0.1;
  if (soll_Druck < min)
  {
      soll_Druck = min;
  }
}
void schnellerminus(){
  soll_Druck = soll_Druck - 0.5;
  if (soll_Druck < min)
  {
      soll_Druck = min;
  }
}
void start(){
  digitalWrite(Ventil1_PIN,HIGH);
  digitalWrite(Ventil2_PIN,LOW);
}
void abbruch(){
  soll_Druck = 0;
  digitalWrite(Ventil1_PIN,LOW);
  digitalWrite(Ventil2_PIN,HIGH);
}

Das sind mehrere Baustellen.
Sollte so gehen:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#include "OneButton.h"

#define Ventil1_PIN 7  //==> Magnetventil befüllen
#define Ventil2_PIN 8  //==> Magnetventil ablassen
#define Plus_INPUT 3    //==> Taster Druck erhöhen
#define Minus_INPUT 4   //==> Taster Druck verringern
#define Start_INPUT 5   //==> Taster Start
#define Stop_INPUT 6   //==> Taster Stop
#define min -1        //==> MinimalDruck
#define max 10        //==> MaximalDruck

OneButton button1(Plus_INPUT, false);
OneButton button2(Minus_INPUT, false);
OneButton button3(Start_INPUT, false);
OneButton button4(Stop_INPUT, false);

int Ventil1State = LOW;
int Ventil2State = LOW;
int Plus_PIN;
int Minus_PIN;
int Start_PIN;
float soll_Druck;

bool startausgeloest = false;

void setup()
{
  lcd.begin(16, 2);
  lcd.backlight();
  pinMode(Ventil1_PIN, OUTPUT);
  pinMode(Ventil2_PIN, OUTPUT);
  button1.attachClick(mehr_Druck);
  button1.attachDoubleClick(schnellerplus);
  button2.attachClick(weniger_Druck);
  button2.attachDoubleClick(schnellerminus);
  button3.attachClick(start);
  button4.attachClick(abbruch);
  button1.setClickTicks(10);
  button2.setClickTicks(10);
  button3.setClickTicks(10);
  button4.setClickTicks(10);
}

void loop()
{
  int sensorVal = analogRead(A0);
  float voltage = (sensorVal * 5.0) / 1024.0;
  float pressure_pascal = (2.0 * ((float)voltage)) * 1000000.0;
  float pressure_bar = pressure_pascal / 10e5;
  const float hyst = 0.02;
  button1.tick();
  button2.tick();
  button3.tick();
  button4.tick();
  lcd.setCursor(0, 0);
  lcd.print("Soll: ");
  lcd.print(String(soll_Druck, 1));
  lcd.print(" bar ");
  lcd.setCursor(0, 1);
  lcd.print("Ist:  ");
  lcd.print(String(pressure_bar, 1));
  lcd.print(" bar ");
  if (startausgeloest == true)
  {
    if (pressure_bar <= soll_Druck - hyst)
      digitalWrite(Ventil1_PIN, HIGH);
    else if (pressure_bar >= soll_Druck)
      digitalWrite(Ventil1_PIN, LOW);
  }
  delay(10);
}
void mehr_Druck()
{
  soll_Druck = soll_Druck + 0.1;
  if (soll_Druck > max)
  {
    soll_Druck = max;
  }
}
void schnellerplus()
{
  soll_Druck = soll_Druck + 0.5;
  if (soll_Druck > max)
  {
    soll_Druck = max;
  }
}
void weniger_Druck()
{
  soll_Druck = soll_Druck - 0.1;
  if (soll_Druck < min)
  {
    soll_Druck = min;
  }
}
void schnellerminus()
{
  soll_Druck = soll_Druck - 0.5;
  if (soll_Druck < min)
  {
    soll_Druck = min;
  }
}
void start()
{
  digitalWrite(Ventil1_PIN, HIGH);
  digitalWrite(Ventil2_PIN, LOW);
  startausgeloest = true;
}
void abbruch()
{
  soll_Druck = 0;
  digitalWrite(Ventil1_PIN, LOW);
  digitalWrite(Ventil2_PIN, HIGH);
  startausgeloest = false;
}