Go Down

Topic: Startknopf (Read 3034 times) previous topic - next topic

strohhirn

Sep 14, 2012, 02:22 pm Last Edit: Sep 14, 2012, 02:26 pm by strohhirn Reason: 1
Guten Tag,
Ich arbeite gerade an einem Programm das beim anschließen des arduino nicht gleich starten soll.
Dafür habe ich mir gedacht baue ich einen Startknopf ein.
Wenn ich ihn kurz drücke soll das programm1 starten und wenn ich nochmal drauf drücke soll es anhalten.
Das programm soll unter anderem am anfang ein relais einschalten und bei 27°C ausschalten.
Doch irgenwie klappt es nicht. Hier einmal mein sketch :
Code: [Select]
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>

#define ONE_WIRE_BUS 30  // Temperatursensor pin 30
LiquidCrystal lcd(22, 23, 24, 25, 26, 27, 28);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress Sensor1 = {0x28, 0xCD, 0x9B, 0xDA, 0x03, 0x00, 0x00, 0xF2};
DeviceAddress Sensor2 = {0x28, 0x1F, 0xA3, 0xDA, 0x03, 0x00, 0x00, 0xE2};
DeviceAddress Sensor3 = {0x28, 0x2D, 0xB9, 0xDA, 0x03, 0x00, 0x00, 0xA0};
DeviceAddress Sensor4 = {0x28, 0x37, 0x88, 0xDA, 0x03, 0x00, 0x00, 0x7D};

int backLight = 29;
int k1 = 31;   //relais
int k2 = 32;   //relais
int k3 = 33; //relais

int knopf1 = 34;
int buttonState = 0; //knopf
int buttonPushCounter = 0;
int lastButtonState = 0;


void setup() {
 pinMode(backLight, OUTPUT);
 digitalWrite(backLight, HIGH);
 lcd.begin(20, 4);
 sensors.begin();
 pinMode(k1, OUTPUT);
 pinMode(k2, OUTPUT);
 pinMode(k3, OUTPUT);
 pinMode(knopf1, INPUT);
}

void loop(){
   sensors.requestTemperatures();
 if (sensors.isConnected(Sensor1)){
 lcd.setCursor(0, 0);
 lcd.print("T1:");
 lcd.print(sensors.getTempC(Sensor1));
 lcd.print("C");
 }else {
 lcd.setCursor(0, 0);
 lcd.print("T1:");
 lcd.print("AUS   ");}
   
 if (sensors.isConnected(Sensor2)){
   lcd.setCursor(0, 1);
 lcd.print("T2:");
 lcd.print(sensors.getTempC(Sensor2));
 lcd.print("C");
 }else {
   
 lcd.setCursor(0, 1);
 lcd.print("T2:");
 lcd.print("AUS   ");}
 
 if (sensors.isConnected(Sensor3)){
   lcd.setCursor(0, 2);
 lcd.print("T3:");
 lcd.print(sensors.getTempC(Sensor3));
 lcd.print("C");
 }else {
 
 lcd.setCursor(0, 2);
 lcd.print("T3:");
 lcd.print("AUS   ");}
 
 if (sensors.isConnected(Sensor4)){
   lcd.setCursor(0, 3);
 lcd.print("T4:");
 lcd.print(sensors.getTempC(Sensor4));
 lcd.print("C");
 }else {
 lcd.setCursor(0, 3);
 lcd.print("T4:");
 lcd.print("AUS   ");}

 buttonState = digitalRead(knopf1);
 if (buttonState != lastButtonState) {
   if (buttonState == HIGH) {
     buttonPushCounter++;
   }
   else {}
 }
 lastButtonState = buttonState;
 if (buttonPushCounter % 2 == 0) {
   programm1 ();
 } else {
   
 }
}

void programm1 (){
 digitalWrite(k1, HIGH);
if (sensors.getTempC(Sensor3) == 27){
  digitalWrite(k1, LOW);}
 
 else {
digitalWrite(k1, HIGH);
 }
}
 


Was mache ich falsch und wie mache ich das was ich will richtig?

Mfg

strohhirn
Gruß

strohhirn

erni-berni

Hallo strohhirn,
was genau macht denn dein Programm "falsch" oder zumindest unerwartet?
Folgendes fällt mir spontan auf:
Du solltest auf jeden Fall den PushButton entprellen, schau dir dazu mal die Bounce Library an.
Nach dem zweiten Betätigen des Buttons springt das Programm in "programm1", arbeitet es ab und geht dann wieder in die Haupt-loop.
In prgramm1 wird das Relais immer wieder eingeschaltet und nur wenn Sensor3 genau 27 ist wieder abgeschaltet. Hier musst du auf >27 testen.
Was heißt für dich "soll das Programm anhalten"? Anhalten wird das Programm nie, du kannst es höchstens in eine Endlosscheife zwingen, das ist aber sehr unschöne Programmierung.
else{} macht so ziemlich gar nichts, kannst du auch weglassen.
Code: [Select]
if (sensors.isConnected(Sensor1)){
  lcd.setCursor(0, 0);
  lcd.print("T1:");
  lcd.print(sensors.getTempC(Sensor1));
  lcd.print("C");
  }else {
  lcd.setCursor(0, 0);
  lcd.print("T1:");
  lcd.print("AUS   ");}

das zweimalige positionieren des Cursors kannst du einmal einsparen, wenn du den Befehl lcd.setCursor vor die if-Abfrage setzt.
Es kann sein, dass die Anzeigen auf dem Display sehr schnell wechseln und du dadurch nichts mehr erkennen kannst. Was spricht dagegen die Anzeige nur alle 500ms zu aktualisieren, Während das Programm in dieser Warteschleife loopt, kannst du den Button Status prüfen.
Soviel erst mal als Gedankenanregung. 
Gruß
Reinhard

strohhirn

#2
Sep 14, 2012, 07:32 pm Last Edit: Sep 14, 2012, 07:35 pm by strohhirn Reason: 1
@erni-berni

Also das Programm soll, wenn der arduino an eine stromzufuhr angeschlossen wird, einfach nur dei 4 Temps. anzeigen und wenn ein sensor nicht drin ist soll es aus schreiben.
Wenn ich denn den knopf1 einmal drücke soll das programm1 starten. Es soll erstmal nur das relais k1 einschalten und es bei 27°C(oder höher) ausschalten.Die Temperaturen sollen immer angezeigt werden.
Wenn ich denn während das programm1 läuft nochmal auf den Knopf drücke soll alles wieder aus gehen und das display soll weiterhin die Temps. anzeigen.
Mein problem ist ,dass das relais, wenn ich den arduino anschliese, kurz an und denn wieder aus geht und bei mehrfachem oder einfachem knopfdruck nichts passiert, es bleibt aus.
Und das mit dem Pushbutten entprellen und bounc habe ich auch nicht verstanden.(Bin noch nicht so erfahren im bereich dieser technik und skriptschreibung)

Mfg

strohhirn
Gruß

strohhirn

Udo Klein

Das mit dem Bounce bzw. Prellen ist ein Effekt den ein Schalter eher nicht haben sollte, der aber in der Realität nicht einfach vermieden werden kann. Wenn Du einen Schalter drückst, dann werden die Kontakte aufeinander (oder auseinander) gedrückt. Weil das Kontaktmaterial etwas federt geht dabei der Kontakt in der Regel mehrfach auf und zu. Das kann je nach Schalter eine knappe Millisekunde dauern manchmal aber auch mehr als 10 Millisekunden oder noch viel länger. Wenn Dein Programm schnell genug auf einen Zustandswechsel am IO PIn reagiert wird es deshalb mehr als einen Tastendruck erkennen.

Die Lösungen dagegen nennt man auch "debouncen" oder "entprellen". Eine der einfachsten Lösungen ist es vor dem Auslesen des nächsten Tastendrucks ein paar Millisekunden zu warten (also delay(100)). Das hat allerdings Nachteile wenn man mehr als einen Schalter ausliest oder schnell reagieren können muss.

-Udo
Check out my experiments http://blog.blinkenlight.net

strohhirn

Irgendwie klappts einfach nicht . Wenn das arduino startet geht komischerweise das relais an aber bei 27°C geht es nicht aus wenn ich denn den knopf drücke geht das relais aus und ich kann es nicht wieder anmachen.
Ich hätt nicht gedacht das es so schwer ist einen Startknopf in das programm einzufügen.
Gruß

strohhirn

o_lampe

Was genau macht denn dein Startknopf? Ist der Eingang mit einem pulldown-Widerstand auf LOW gezogen und der Schalter verbindet kurzzeitig mit 5V, wenn er gedrückt wird? Dann wäre evtl. ein Interupt-Eingang besser.
Oder ist es ein 'richtiger' Schalter?

Vielleicht hilfts, den Startknopf erstmal mit einer simplen Routine auf seine Funktion zu testen...
It's not my fault when my Posts are full of Errors. This stupid autocorrection from my browser is set up for german grammar.

Chris72622

Lass Dir doch den Zustand des Knopfes über Serial.println anzeigen.

Gruß Chris
https://github.com/jeffThompson/DarkArduinoTheme

strohhirn

Jetzt hab ich den Fehler gefunden.
Es liegt nicht am knopf sondern am relais. Ich muss ihm den Befehl HIGH geben damit er aus ist und andersrum ansonten klappt alles wie gewollt.
Trotzdem Danke an alle die geantwortet und mitgedacht haben.

Mfg

strohhirn
Gruß

strohhirn

strohhirn

Hallo,
ich hab jetz ne zeitlang am programm gearbeitet (mit hilfe).
Dabei ist mir aufgefallen das meine variante des startknopfes nicht die beste ist also habe ich versucht das ganze mit bounce umzusetzen, das sieht bei mir so aus:
Code: [Select]
#include <Bounce.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>


#define ONE_WIRE_BUS 30  // Temperatursensor pin 30
#define FADE_DELAY 3 // Verzögerung beim Faden
LiquidCrystal lcd(22, 23, 24, 25, 26, 27, 28);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress Sensor[] = {{0x28, 0xCD, 0x9B, 0xDA, 0x03, 0x00, 0x00, 0xF2},
                          {0x28, 0x1F, 0xA3, 0xDA, 0x03, 0x00, 0x00, 0xE2},
                          {0x28, 0x2D, 0xB9, 0xDA, 0x03, 0x00, 0x00, 0xA0},
                          {0x28, 0x37, 0x88, 0xDA, 0x03, 0x00, 0x00, 0x7D}};

int backLight = 29;
uint8_t k[] = {31, 32, 33, 35};   //relais HIGH = Aus; LOW = An

uint8_t knopf1 = 34;
uint8_t buttonState = 0; //knopf
int buttonPushCounter = 0;
uint8_t lastButtonState = 0;
Bounce bouncer = Bounce( knopf1, 5 );

uint32_t previousMillis = 0;


int   mpxPin =  5; //drucksensor
int   mpx;
float pkPa;

uint8_t ledPin = 9; // (kemo)
uint8_t fade;
uint8_t status;

uint32_t nextMillis = 0;
uint32_t thresholdMillis = 0;

void setup() {
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH);
  lcd.begin(20, 4);
  sensors.begin();
  uint8_t i;
  for (i = 0; i < 4; i++) {
    pinMode(k[i], OUTPUT);
    digitalWrite(k[i], HIGH);
  }
  pinMode(knopf1, INPUT);
 
  status=0;
  sensors.setWaitForConversion(false);
  sensors.requestTemperatures();
}

void loop(){
  // check if conversion is done
  if (oneWire.read_bit()) {
   
    uint8_t i;
    for (i = 0; i < 4; i++) {
      lcd.setCursor(0, i);
      lcd.print("T");
      lcd.print(i+1, DEC);
      lcd.print(":");
      if (sensors.isConnected(Sensor[i])) {
        lcd.print(sensors.getTempC(Sensor[i]));
        lcd.print("C");
      } else {
        lcd.print("AUS   ");
      }
    }
    // start next conversion
    sensors.requestTemperatures();
 
    mpx = analogRead(mpxPin);
    pkPa = (mpx/1023.0-0.04)/0.0018;
    lcd.setCursor(10, 0);
    lcd.print(pkPa);
    lcd.print("mb   ");
    lcd.setCursor(10, 1);
  lcd.print(fade);
  }
   
 
 
  if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       if ( buttonState == LOW ) {
         programm1();
         buttonState = HIGH;
       } else {
         uint8_t i;
  for (i = 0; i < 4; i++) {
    digitalWrite(k[i], HIGH);
  }
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    status = 0;
   
         buttonState = LOW;
       
      }
   }
}
}

void programm1() {
 
if (status == 0){
    digitalWrite(k[0], LOW);
    status = 1;
  } else if (sensors.getTempC(Sensor[0]) >= 22.5 && status == 1) {
    digitalWrite(k[0], HIGH);
    status = 2;
    nextMillis = millis() + 30000L;
  } else if (status == 2 && millis() > nextMillis) {
    digitalWrite(k[1], LOW);
    digitalWrite(k[2], LOW);
    digitalWrite(k[3], LOW);
    fade = 0;
    analogWrite(ledPin, fade);
    fade = 51;
    analogWrite(ledPin, fade);
 
status = 3;
nextMillis = millis() + 30000L;

  } else if (status == 3 && millis() > nextMillis) {
    fade = 102;
    analogWrite(ledPin, fade);
      status = 4;
      nextMillis = millis() + 30000L;
  } else if (status == 4 && millis() > nextMillis) {
    fade = 153;
    analogWrite(ledPin, fade);
 
      status = 5;
      nextMillis = millis() + 30000L;
   
  } else if (status == 5 && millis() > nextMillis) {
    fade = 255;
      status = 6;
   
  }
  if (sensors.getTempC(Sensor[0]) >= 22.7 && thresholdMillis == 0) {
    digitalWrite(k[1], HIGH);
    thresholdMillis = millis() + 30000L;
  } else if (thresholdMillis && millis() > thresholdMillis) {
    digitalWrite(k[2], HIGH);
    digitalWrite(k[3], HIGH);
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    status = 0;
    fade = 0;
  }   
}


Der nachteil beim alten sketch war das ich es nur 1mal anschalten konnte. Jetzt kann ich es beliebig oft an und aus schalten.
Das problem ist aber das sich das programm1 machmal von alleine an und ausschaltet,manchmal auch ganz schnell hintereinander.
Und ein weiterer Fehler ist ,dass  bei start nur relais 1 angeht(k[0]=LOW) also status 1 weiter geht das programm nicht( mit der anderen varieante des startknopfes schon).

Was habe ich falschgemacht? Wo liegt mein Fehler?

Mfg

strohhirn
Gruß

strohhirn

jurs


Das problem ist aber das sich das programm1 machmal von alleine an und ausschaltet,manchmal auch ganz schnell hintereinander.


Zeig mal die Schaltung, wie Du Taster und PullUp-Widerstand angeschlossen hast!

strohhirn

Hab ne fritzingdatei mitrangehängt.
Gruß

strohhirn

uwefed

Ein Bild ist einfacher anzusehen. Hab eins angehängt.
Hast Du den Taster richtig rum reingesteckt? (nicht um 90 grad verdreht)
Grüße Uwe

strohhirn

Danke,
den kann man doch garnicht falsch reinstecken sonst passt er nicht.
Ist den mit dem sketch (teil mit bounce) alles richtig?
Gruß

strohhirn

jurs

#13
Dec 08, 2012, 12:23 pm Last Edit: Dec 08, 2012, 12:24 pm by jurs Reason: 1

Hab ne fritzingdatei mitrangehängt.


OK, wenn das tatsächlich so geschaltet ist wie in der Datei gezeigt, hast Du einen korrekt beschalteten Taster mit PullDown-Widerstand. Der erste Verdacht, dass die unbeabsichtigten Schaltungen durch ein offenes Tasterende verursacht werden, kann damit ausgeschlossen werden, falls Deine Beschaltung tatsächlich die Verhältnisse des Schaltplans wiederspiegelt.

Bleibt also Deine Programmlogik.

Gibt ja nur zwei Fehlermöglichkeiten:
- Fehler in der Schaltung
- Fehler in der Programmlogik

Übrigens: Dein Relais klappert beim Anstecken des Stroms immer noch einmal klick-klack, oder?

Wenn Du es weghaben möchtest, dann versuche mal, diese Reihenfolge bei der Initialisierung in Deiner setup()-Routine:
Code: [Select]

 digitalWrite(relay1, HIGH); // verhindert Relais-Aktivierung nach Power-On
 pinMode(relay1, OUTPUT);    

bzw. mit Deinem Codeausschnitt:
Code: [Select]

 digitalWrite(k[i], HIGH); // verhindert Relais-Aktivierung nach Power-On
 pinMode(k[i], OUTPUT);    


Und schon sollte das Power-On Klackern des Relais weg sein, oder nicht?

Vielleicht kannst Du mal detalliert in Worten beschreiben,
- was genau in der loop() ständig passieren soll
- was genau beim Drücken des Buttons einmalig außerhalb der Loop passieren soll
Vielleicht kann man Dir dann Tipps für eine geeignete Strukturierung des Programms geben

Ich durchschaue das mit dem Geflecht von ifs und den ganzen Verzweigungen nicht so ganz.


strohhirn

Quote
Dein Relais klappert beim Anstecken des Stroms immer noch einmal klick-klack, oder?

Nein es klappert nicht denn im setup ist ja folgendes eingefügt:
Code: [Select]
uint8_t i;
  for (i = 0; i < 4; i++) {
    pinMode(k[i], OUTPUT);
    digitalWrite(k[i], HIGH);
  }


Im loop geht es nur drum, das die 4 Temp. sensoren ausgelesen werden und auf dem lcd angezeigt werden genauso wie der mpx drucksensor.
Desweiteren soll der wert "fade" angezeigt werden. Und wenn ich den knopf1 drücke soll das programm1 angehen und bei wiederholten drücken wieder aus gehen und wiederverwendbar sein.
Was nicht klappt ist der teil nach status1 wo eigentlich nach 30sec k[1-3] angehen sollen. Und das funktioniert nicht. Statdessen geht das programm1 an und aus wie es will und funktioniert ab status1 nicht.
Gruß

strohhirn

Go Up