Druksensor programmeren

Hoi, ik probeer een systeem te laten werken met een druksensor(freescale).
Ik weet nog niet heel veel van het programmeren dus het wilt nog niet bepaald lukken.

  • Ik gebruik een Arduino Uno

Setup

  • green led
  • blue led
  • valve
  • switch (pushbutton)
  • Pressure sensor

Switch = niet ingedrukt
Green led = aan
Blue led = uit
Valve = dicht

Switch = ingedrukt
Green led = uit
Blue led = knipperen (moet automatisch na 5 seconden stoppen met knipperen, waarna het groene ledje weer aan gaat en blauwe ledje uit >>>> ook al blijft de switch ingedrukt!!)
Valve = open (moet sluiten zodra de pressure sensor een waarde van 450 bereikt)
Pressure sensor = blijft waardes lezen van 0-5 bar (0 - 1023)

Probleem
hoe kan ik het systeem zo instellen dat de valve sluit zodra de gespecificeerde waarde behaald is?

Mijn huidige code:

//========================================
const byte greenLed = 9;
const byte blueLed = 11;
const byte buttonSwitch = 2;
const byte valve = 3;
int sensorPin = A0;    // Select input pin for the potentiometer
int sensorValue;   // Variable stores value coming from the sensor
int sensorLow = 1023;
int sensorHigh = 0;

//========================================
void setup()
{
  Serial.begin(9600);

pinMode(valve, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
pinMode(buttonSwitch, INPUT_PULLUP);
}

//========================================
void loop()
{
int switchState = digitalRead(buttonSwitch);

sensorValue = analogRead(sensorPin);  // Read sensor
  Serial.println(sensorValue, DEC);     // Display result
  delay(400);         // Wait 400 milliseconds

if (switchState == HIGH) {
 // the button is not pressed  
  digitalWrite(greenLed, HIGH);
  digitalWrite(blueLed, LOW);
  digitalWrite(valve, LOW);
}
else {
 // the button is pressed
  digitalWrite(greenLed, LOW);
  digitalWrite(blueLed, HIGH);
  delay(400);
  digitalWrite(blueLed, LOW);
  delay(400);
  digitalWrite(valve, HIGH);

}  
  
}

Reza_O:
Probleem
hoe kan ik het systeem zo instellen dat de valve sluit zodra de gespecificeerde waarde behaald is?

Een beetje op dezelfde manier als in de echte wereld.
Je kijkt constant op het metertje en als je de gewenste druk/volume/hoogte/waarde bereikt hebt stop je de aktie die de verandering bewerkstelligt.

if (analogRead(sensorPin) >= 450)   // kijk steeds op het metertje  ' 0 ' of ' 1 ' hangt van de schakeling af
{
      digitalWrite(valve,0)                  // sluit de valve als meter >= 450
}
else
{
      digitalWrite(valve,1)                 // open de valve zolang meter onder 450
}

cartoonist:
Een beetje op dezelfde manier als in de echte wereld.
Je kijkt constant op het metertje en als je de gewenste druk/volume/hoogte/waarde bereikt hebt stop je de aktie die de verandering bewerkstelligt.

TOP ! ! ik zie inderdaad dat de valve nu continu opent en sluit rond deze waarde.
Echter reageert hij nu al constant terwijl de buttonSwitch nog niet ingedrukt is.

Pas als de buttonSwitch ingedrukt is dient hij tot 450 te pompen en te stoppen zodra deze bereikt is.
Wel moet hij ook stoppen wanneer de knop losgelaten wordt.

De valve mag alleen openen en sluiten wanneer de buttonSwitch ingedrukt is, en de waarde inderdaad onder de 450 ligt.
Momenteel negeert hij de buttonSwitch en opent en sluit ie gewoon door continu te meten.

Momenteel is dit de code:

//========================================
const byte buttonSwitch = 2;
const byte greenLed = 10;
const byte blueLed = 11;
const byte valve = 9;

const byte buttonSwitch2 = 4;
const byte greenLed2 = 5;
const byte blueLed2 = 6;
const byte valve2 = 3;

int sensorPin = A0;    // Select input pin for the potentiometer
int sensorValue;   // Variable stores value coming from the sensor
int sensorLow = 1024;
int sensorHigh = 0;

const float baseline = 38.0;

//========================================
void setup()
{
  Serial.begin(9600);

pinMode(valve, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
pinMode(buttonSwitch, INPUT_PULLUP);

pinMode(valve2, OUTPUT);
pinMode(greenLed2, OUTPUT);
pinMode(blueLed2, OUTPUT);
pinMode(buttonSwitch2, INPUT_PULLUP);
}

//========================================
void loop()
{
int switchState = digitalRead(buttonSwitch);

sensorValue = analogRead(sensorPin);  // Read sensor
  Serial.println(sensorValue, DEC);     // Display result
  delay(400);         // Wait 400 milliseconds

if (switchState == HIGH) {
 // the button is not pressed  
  digitalWrite(greenLed, HIGH);
  digitalWrite(blueLed, LOW);
  digitalWrite(valve, LOW);
}
else {
 // the button is pressed
  digitalWrite(greenLed, LOW);
  digitalWrite(blueLed, HIGH);
  delay(400);
  digitalWrite(blueLed, LOW);
  delay(400);
  digitalWrite(valve, HIGH);

}  

{
int switchState = digitalRead(buttonSwitch2);

if (switchState == HIGH) {
 // the button is not pressed  
  digitalWrite(greenLed2, HIGH);
  digitalWrite(blueLed2, LOW);
  digitalWrite(valve2, LOW);
}
else {
 // the button is pressed
  digitalWrite(greenLed2, LOW);
  digitalWrite(blueLed2, HIGH);
  delay(400);
  digitalWrite(blueLed2, LOW);
  delay(400);
  digitalWrite(valve2, HIGH);

}  

}



{
float pressure = (sensorValue/1024.0) * 5.0;
Serial.print(", bar: ");
Serial.println(pressure);



if (analogRead(sensorPin) >= 450)   // kijk steeds op het metertje  ' 0 ' of ' 1 ' hangt van de schakeling af
{
      digitalWrite(valve,0);                  // sluit de valve als meter >= 450
}
else
{
      digitalWrite(valve,1);                 // open de valve zolang meter onder 450
}



}




}

Probeer eens om dat stukje nieuwe code tussen de { } van je else statement te plaatsen, dat wordt immers uitgevoerd als de drukknop ingedrukt is, enkel en alleen als de knop is ingedrukt.

Zo moeilijk is dat toch niet.?

Ik zou het probleem omdraaien in de code. Je zegt zelf alleen ALS de switch is ingedrukt DAN moet de er gereageerd worden.
Dus eerst kijken of de knop ingedrukt is kijken of de sensor de juiste waarden heeft.
Wil je altijd de sensor waarde zien wijzigen, dan in de loop gewoon de waarde lezen en displayen en geen delays oid gebruiken.
In het tweede deel lees je de knop. Als deze is ingedrukt EN de waarde zit in het gebied, dan reageren.

cartoonist:
Probeer eens om dat stukje nieuwe code tussen de { } van je else statement te plaatsen, dat wordt immers uitgevoerd als de drukknop ingedrukt is, enkel en alleen als de knop is ingedrukt.

Ah, werkt inderdaad op die manier. Bedankt :slight_smile:

//========================================
const byte buttonSwitch = 2;
const byte greenLed = 10;
const byte blueLed = 11;
const byte valve = 9;

const byte buttonSwitch2 = 4;
const byte greenLed2 = 5;
const byte blueLed2 = 6;
const byte valve2 = 3;

int sensorPin = A0;    // Select input pin for the potentiometer
int sensorValue;   // Variable stores value coming from the sensor
int sensorLow = 1024;
int sensorHigh = 0;

const float baseline = 38.0;
int Cutout = (5000);
unsigned long startTime = 0;

//========================================
void setup()
{
  Serial.begin(9600);

pinMode(valve, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
pinMode(buttonSwitch, INPUT_PULLUP);

pinMode(valve2, OUTPUT);
pinMode(greenLed2, OUTPUT);
pinMode(blueLed2, OUTPUT);
pinMode(buttonSwitch2, INPUT_PULLUP);
startTime=millis();
}

//========================================
void loop()
{
int switchState = digitalRead(buttonSwitch);

sensorValue = analogRead(sensorPin);  // Read sensor
  Serial.println(sensorValue, DEC);     // Display result
  delay(400);         // Wait 400 milliseconds

if (switchState == HIGH) {
 // the button is not pressed  
  digitalWrite(greenLed, HIGH);
  digitalWrite(blueLed, LOW);
  digitalWrite(valve, LOW);
}
else {
 // the button is pressed

if (analogRead(sensorPin) >= 440)   // kijk steeds op het metertje  ' 0 ' of ' 1 ' hangt van de schakeling af
{
      digitalWrite(valve,0);                  // sluit de valve als meter >= 450
      digitalWrite(greenLed,1);
}
else
{
      digitalWrite(valve,1);                 // open de valve zolang meter onder 450
      digitalWrite(greenLed,0);
      digitalWrite(blueLed,1);
      delay(200);
      digitalWrite(blueLed,0);
      delay(200);
}
if ( millis()-startTime > Cutout ){
   digitalWrite(greenLed,HIGH);
   digitalWrite(blueLed,LOW);
   digitalWrite(valve,LOW);
   startTime=millis();
 }
}  

{
int switchState = digitalRead(buttonSwitch2);

if (switchState == HIGH) {
 // the button is not pressed  
  digitalWrite(greenLed2, HIGH);
  digitalWrite(blueLed2, LOW);
  digitalWrite(valve2, LOW);
}
else {
 // the button is pressed
  digitalWrite(greenLed2, LOW);
  digitalWrite(blueLed2, HIGH);
  delay(200);
  digitalWrite(blueLed2, LOW);
  delay(200);
  digitalWrite(valve2, HIGH);
}  
if ( millis()-startTime > Cutout ){
   digitalWrite(greenLed2,HIGH);
   digitalWrite(blueLed2,LOW);
   digitalWrite(valve2,LOW);
   startTime=millis();
 }
}

{
float pressure = (sensorValue/1024.0) * 5.0;
Serial.print(", bar: ");
Serial.println(pressure);
}

}

als de knop ingedrukt is gaat de blauwe led uit en de groene weer aan, maar dit blijft zich continu herhalen zolang je de knop ingedrukt houdt.

hoe kan ik het zo programmeren dat hij na max. 5 seconden zichzelf niet herhaald totdat de knop opnieuw ingedrukt wordt?

Bekend probleem.

in C achtige taal (dan kun je het verder uitwerken :grin: )

//
// kijk of knop is ingedrukt
//
if knop is ingedrukt dan
   //
   // kijk of hij sinds de laatste actie is losgelaten
   // 
   if knop_mag_geserviced_worden dan
      //
      // kijk of de timer is verlopen (in dit voorbeeld 5 seconden)
      //
      if millis - timer > 5000 dan
         //
         // actie is toegestaan
         //
         actieToegestaan = true
         //
         // start de timer
         //
         timer = millis
         //
         // en deze knop mag pas weer geserviced worden als hij eerst is losgelaten
         //
         knop_mag_geserviced_worden = false
      einde if
   einde if
else
   //
   // de knop is niet meer ingedrukt dus mag hij mogelijk de volgende keer geserviced worden
   //
   knop_mag_geserviced_worden = true
einde if
//
// kijk of er wat moet gebeuren
//  
if actieToegestaan = true dan
   //
   // voer de actieve actie uit
   //
else
   //
   // voer de inactieve actie uit
   //
einde if

nicoverduin:
Bekend probleem.

in C achtige taal (dan kun je het verder uitwerken :grin: )

top, zal even kijken wat ik ervan kan maken :slight_smile:

nicoverduin:

//

// kijk of knop is ingedrukt
//
if knop is ingedrukt dan
  //
  // kijk of hij sinds de laatste actie is losgelaten
  //
  if knop_mag_geserviced_worden dan
      //
      // kijk of de timer is verlopen (in dit voorbeeld 5 seconden)
      //
      if millis - timer > 5000 dan
        //
        // actie is toegestaan
        //
        actieToegestaan = true
        //
        // start de timer
        //
        timer = millis
        //
        // en deze knop mag pas weer geserviced worden als hij eerst is losgelaten
        //
        knop_mag_geserviced_worden = false
      einde if
  einde if
else
  //
  // de knop is niet meer ingedrukt dus mag hij mogelijk de volgende keer geserviced worden
  //
  knop_mag_geserviced_worden = true
einde if
//
// kijk of er wat moet gebeuren
// 
if actieToegestaan = true dan
  //
  // voer de actieve actie uit
  //
else
  //
  // voer de inactieve actie uit
  //
einde if

Ik kom er eerlijk gezegd niet helemaal uit, snap nog niet helemaal hoe de programmeertaal precies werkt.

Bijv. if knop_mag_geserviced_worden >> wat voor code zou je hiervoor moeten schrijven?
(excuus, ben nog iets te nieuw met arduino. Merk met dit project wel dat het snel vooruit gaat)

anybody die dit kan uitleggen?
Neem aan dat ik met een boolean moet werken?

Reza_O:
anybody die dit kan uitleggen?
Neem aan dat ik met een boolean moet werken?

Yep,
Een boolean is gewoon waar of niet waar. En ergens in de setup moet je de begin toestand neerzetten.

"knop_mag_geserviced_worden"
Als deze waar is dan moet je misschien iets met de knop doen. Is hij false dan mag je knop gewoon negeren of deze nu ingedrukt is of niet. Als de knop is ingedrukt, dan moet hij eerst losgelaten worden voor dat je weer op een knop indruk actie reageert. Daarnaast hed je ook nog een 2e eis dat het 5 seconden weer moet duren voordat je op een ingedrukte knop reageert.
En als je dan uiteindelijk hebt goedgekeurd dat de knop ingedrukt is, dan kun je een toestaan de actie uit te voeren die je wilt doen als de knop "legitiem" is ingedrukt.

In feite is het gewoon het probleem uit elkaar trekken. Eerst vragen of een knop-indruk behandeld of genegeert moet worden. En als je dan uiteindelijk hebt besloten dat deze indruk geldig is, hem afhandelen. Als je het laatste ook nog eens in je code gaat proppen, dan wordt het, in simpel Nederlands :), een puinzooi.