Go Down

Topic: funtion ausfürhung Fehler (Read 2929 times) previous topic - next topic

ChrisSand

Das sollte auch heißen:
Code: [Select]
if (value == LOW)

Und bei else ist ein o zuviel.

danke bein VBA ist man das einfache = gewohnt....

HotSystems

danke bein VBA ist man das einfache = gewohnt....
Ok, da muss man jetzt umdenken.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

combie

#17
Aug 19, 2017, 03:18 pm Last Edit: Aug 19, 2017, 03:21 pm by combie
Quote
if (value == LOW)
Ich möchte mich da (ein weiteres Mal) als Pingel outen!

Für mich gilt:
if (value == LOW)
tut man nicht!

Besser:
if (!value)
Wo kein = oder == da kann man sie auch nicht verwechseln


Alternativ:
Anders rum schreiben (die Konstante immer nach links setzen)
if (LOW == value)
Dann schreit der Kompiler, wenn man doch mal aus Versehen
if (LOW = value)
schreibt

Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

ChrisSand

guten Morgen zusammen,

ich schon wieder mit meiner Funtion, ich habe jetzt einen Sketch geschrieben der mit aufruf einer Funktion den Arlam ausführt.

Code: [Select]
//### Variablen Global ###   
    boolean value = LOW;                  // Buzzer an aus schalter
    boolean value2 = HIGH;                // buzzer hoch tief schalter
    unsigned long previousMillis = 0;     // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
    long frq = 500;                       // frequenz des buzze Start 500
//### Starte Setup ###
void setup() {
}
//### Starte Loop ###
void loop() {
  BuzzAlert(8,500); //func wird aufgerufen
}

//### Starte function ###
void BuzzAlert(byte BuzzPin,unsigned long interval) // function #BuzzPin = Ausgabe ping für lautsprecher #Interval Zeit zwischen den wecheln
{     
if (millis() - previousMillis > interval) { //wenn millis() Minus das Letztemalmillies größer als das Interval ist schleife durchlaufen
previousMillis = millis();        // aktuelle Zeit abspeichern für die nächste abfrage
if (LOW == value){          // wenn value Low dann ton ein
    if (LOW == value2){     // Abfrage für den frequenz wechsel 500/700
      frq = 500;
    }else{
      frq = 700;
    }
    value2 = !value2;       // dreht den schalter für frequenz wechsel
  tone(BuzzPin,frq);        // buzz on
}else{
  noTone(BuzzPin);          // buzz of
}   
  value = !value;           //der Wert wird gedreht damit bei jeder Loop anders ist
}
}


Das Funktioniert so weit auch, ich habe aber noch fragen zu der Variablen declaration

- so wie ich das jetzt gemacht habe sind die Global richtig und über all verfügbar. ?
- Im setup haben die nix zu suchen
- wenn ich die in den Loop() schreiben und vorbelege (bsp: byte value = LOW;) dann werden die in jedem durchlauf auch neu vorbelegt richtig?
- das gild auch für die Function ? Denn dann läuft das script nicht m :-)
- gibt es eine möglichlkeit die variablen auch in der Func zu belgen? byte hat ja immer eine vorbelegung dann kann ich ja nix machen... oder muss ich dann eine libray schriben ?

so das reicht für einen Sonntag Morgen !

combie

Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

ChrisSand


ChrisSand

so jetzt habe ich beide LedBlinen und BuzzAlert als funktionen fertig. puhh aber.... wenn ich beide im LOOP aufrufe Blinkt die LED schon mein Buzzer macht aber keinen wechsel... wo habe ich den denkfehler? einzeln angesprochen gehen beide....


Code: [Select]


//### Starte Setup ###
void setup() {
  Serial.begin(9600); //kann man immer brauchen!
  }
//### Starte Loop ###
void loop() {
  BuzzAlert(8,200); //func wird aufgerufen
  LedBlinken(4,10,200);
}

void LedBlinken (byte LedPin, long anzahl, long intervalLB){    //function diese lässt an #LedPin pin der LED #anzhal der blinkens #interval lange der Pause
//Variablem deklaration   
static unsigned long previousMillisLB = 0;                      // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
static byte valueLB = HIGH;                                     // schalter für an aus.
pinMode(LedPin, OUTPUT);                                        // LED Pin zum Ausgang machen
//Strat code
for (int i=0; i <= ((anzahl*2)+1);){                            //die led muss immer an und aus deswegen *2 und +1 damit immer auf low steht (start ist HIGH)
if (millis() - previousMillisLB > intervalLB) {                 //wenn millis() Minus das Letztemalmillies größer als das Interval ist schleife durchlaufen
    previousMillisLB = millis();                                // aktuelle Zeit abspeichern für die nächste abfrage
    digitalWrite(LedPin, valueLB);                              // pin mit LOW/HIGH belegen
    valueLB = !valueLB;                                         // wechsel von valueLB für die nächste runde
    i++;                                                        // schleife eines höher zählen
}
}
}


//### Starte function ###
void BuzzAlert(byte BuzzPin,unsigned long interval) // function #BuzzPin = Ausgabe ping für lautsprecher #Interval Zeit zwischen den wecheln
{   
    // Variablen statisch nur in der func   
   static  boolean value = LOW;                  // Buzzer an aus schalter
   static  boolean value2 = HIGH;                // buzzer hoch tief schalter
   static  unsigned long previousMillis = 0;     // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
   static  long frq = 500;                       // frequenz des buzze Start 500
if (millis() - previousMillis > interval) { //wenn millis() Minus das Letztemalmillies größer als das Interval ist schleife durchlaufen
previousMillis = millis();        // aktuelle Zeit abspeichern für die nächste abfrage
value = !value; //der Wert wird gedreht damit bei jeder Loop anders ist
Serial.println(value);
if (LOW == value){          // wenn value Low dann ton ein

    if (LOW == value2){     // Abfrage für den frequenz wechsel 500/700
      frq = 500;
    }else{
      frq = 700;
    }
    value2 = !value2;       // dreht den schalter für frequenz wechsel
  tone(BuzzPin,frq);        // buzz on
}else{
  noTone(BuzzPin);          // buzz of
}   

}
}


danke euch

combie

#22
Aug 20, 2017, 10:51 am Last Edit: Aug 20, 2017, 10:58 am by combie
Einfach gesagt:
Du denkst noch nicht in Nebenläufigkeiten.

Darum bekommst du dein Programm auch noch nicht nebenläufig.

Hier mal deine vorherige Version, in etwa so wie ich sie für mich schreiben würde...
Die Hupe als eigene Task(nach meinem TaskModell)
Und den AlarmSchlager, so wie es hier im Forum häufig gemacht wird.

Der  AlarmSchlager veranlasst alle 10 Sekunden ein kleines Hupkonzert, indem er dem Horn eine Nachricht sendet.

Code: [Select]

#include <TaskMacro.h>
// https://forum.arduino.cc/index.php?topic=415229



class Horn
{
  protected:
  const unsigned long freqHigh = 750; // Hz
  const unsigned long freqLow  = 500; // Hz
  unsigned long interval;
  byte hornPin;
  unsigned int zyklen;

  public:
  Horn(byte hornPin, unsigned long interval): hornPin(hornPin),interval(interval),zyklen(0) {}
  void update()
  {
    taskBegin();
    while(1)
    {
      // Start
      noTone(hornPin);

      taskWaitFor(zyklen);

      while(zyklen)
      {
          tone(hornPin,freqHigh);
          taskPause(interval);   
               
          tone(hornPin,freqLow);
          taskPause(interval);       

          zyklen--;
      }
    }
    taskEnd();
  }
 
  void addAlarmZyklen(unsigned int zyklen = 1)
  {
      this->zyklen += zyklen;
  } 
};


Horn horn(8,500);


void alarmSchlager()
{
  static unsigned long  previousMillis = 0;

  if (millis() - previousMillis > 10000) // alle 10 Sec
  {
     previousMillis = millis();
     horn.addAlarmZyklen(2); // anzahl Tonfolgen setzen
  }
}

// -------------------------------------------

void setup()
{
}


void loop()
{
  horn.update();
  alarmSchlager();
}




Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

MicroBahner

#23
Aug 20, 2017, 10:56 am Last Edit: Aug 20, 2017, 11:10 am by MicroBahner
Dein Fehler liegt in der for-Schleife in 'Led-Blinken'. Letzendlich hast Du da wieder ein delay() reinprogrammiert, in dem Du die Schleifenvariable erst hochzählst, wenn die Zeit abgelaufen ist. Dadurch blockierst Du hier wieder den Programmabllauf bis zum Ablauf der Zeiten - wie in delay().
Deine LedBlinken-Funktion kehrt erst nach dem gesamten Blinken wieder zurück. In der Zeit wird also der Buzzer gar nicht aufgerufen.
Es reicht nicht, die delays durch einen millis-Konstrukt zu ersetzten, der letztendlich das gleich macht wie delay. Der ganze Programmablauf muss auf 'blockadefrei' umgestellt werden.
Dazu eigenet sich auch der im Forum schon oft angesprochene  'endlcher Automat' (einfach mal danach suchen - es gibt einige Beiträge dazu )

N.B. Du solltest die angewöhnen, vernünftig einzurücken.
Gruß, Franz-Peter

ChrisSand

Dein Fehler liegt in der for-Schleife in 'Led-Blinken'. Letzendlich hast Du da wieder ein delay() reinprogrammiert, in dem Du die Schleifenvariable erst hochzählst, wenn die Zeit abgelaufen ist. Dadurch blockierst Du hier wieder den Programmabllauf bis zum Ablauf der Zeiten - wie in delay().
Deine LedBlinken-Funktion kehrt erst nach dem gesamten Blinken wieder zurück. In der Zeit wird also der Buzzer gar nicht aufgerufen.
Es reicht nicht, die delays durch einen millis-Konstrukt zu ersetzten, der letztendlich das gleich macht wie delay. Der ganze Programmablauf muss auf 'blockadefrei' umgestellt werden.
Dazu eigenet sich auch der im Forum schon oft angesprochene  'endlcher Automat' (einfach mal danach suchen - es gibt einige Beiträge dazu )

N.B. Du solltest die angewöhnen, vernünftig einzurücken.
gut das habe ich  verstanden ohne die for schleife funktioniert der Sketch auch, die "endliche Automation" habe ich aber noch nicht verstand bzw. weiß nicht ob ich es richtig verstanden habe...

Mit einem solchen sketch frage ich immer wieder zustände aber und reagiere darauf dann mit funtionen usw.... beispiel ob ein button gedrück wurde und dann rufe ich die funtion BuzzAlert auf... oder ein sensor liefert einen wert und ich rufe den auf...
die Abfrage kommt in den loop und darin werden dann funktionen aufgerufen?

oder bin ich da auf dem Holzweg?

Christian

combie

Quote
oder bin ich da auf dem Holzweg?
Ich verstehe dich nicht ganz...

Zumindest wirfst du 2 Sachen in einen Topf.
1. Der endliche Automat
2. Multitasking

Es ist schon wahr, dass beide häufig gemeinsam anzutreffen sind, aber das ist kein Muss.

Zu 1:
Der endliche Automat kommt immer zu seiner Rolle, wenn bestimmte Abläufe eingehalten werden wollen.

Zu 2:
Damit man 2 oder auch mehr Dinge quasi gleichzeitig erledigen kann


Zu 1+2:
In der Regel müssen viele Dinge parallel abgearbeitet werden. Die Kombination tritt also gerne in Rudeln auf.


Goldene Regel:
Jede Funktion sollte möglichst sofort zurückkehren, damit die anderen Funktionen auch ein Chance haben ihr Ding zu erledigen. Und das ist völlig unabhängig davon, ob diese Funktion einen endlichen Automaten abbildet/implementiert.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

MicroBahner

#26
Aug 20, 2017, 04:19 pm Last Edit: Aug 20, 2017, 04:20 pm by MicroBahner
Goldene Regel:
Jede Funktion sollte möglichst sofort zurückkehren, damit die anderen Funktionen auch ein Chance haben ihr Ding zu erledigen. Und das ist völlig unabhängig davon, ob diese Funktion einen endlichen Automaten abbildet/implementiert.

Das ist das A&O wie man den Arduino dazu bringt, mehrere Dinge 'quasi gleichzeitig' zu tun.
Und ein endlicher Automat ist eine elegante Möglichkeit dies zu erreichen: Er prüft bei jedem Durchlauf, ob im momentanen Zustand gerade was zu tun ist, und wenn nicht beendet er sich sofort wieder.

In deinem Beispiel könnte man den Beeper und den Led-Blinker jeweils als (sehr einfachen ;) ) endlichen Automaten realisieren, der bei jedem Durchlauf prüft, ob er nun gerade den Beeper bzw. die Led ein- oder ausschalten soll. Danach lässt er dann gleich wieder den anderen dran.
Gruß, Franz-Peter

ChrisSand

ich hoffe nichts das ihr die nerven mit mit verliert ich wollte jetzt zurst mal die endliche Maschiene verstehen und habe mich mal an eine eigene nachtwächter Version versucht

Code: [Select]
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
static unsigned long letzemalMillisLED = 0;
static unsigned long letzemalMillisBEEP = 0;
static int LedStatus = HIGH;
static int beepStatus = HIGH;
const int LedPin = 4;
const int beepPin = 8;
pinMode(LedPin, OUTPUT);
static int frqStatus = HIGH;
int frq = 500;

//###LED anaus
if(millis()-letzemalMillisLED >400){
  letzemalMillisLED = millis();
   // Serial.println("LED");
    //Serial.println(letzemalMillisLED);
      digitalWrite(LedPin, LedStatus);
        LedStatus = !LedStatus;
  }

//beep anaus
if(millis()-letzemalMillisBEEP >2000){
  letzemalMillisBEEP = millis();
    Serial.println("BEEP");
    Serial.println(letzemalMillisBEEP);
    Serial.println(frqStatus);
            if(frqStatus == HIGH){
              frq = 700;
            }else{
              frq = 500;
            }
      if(beepStatus == HIGH){
          Serial.println(frq);
        tone(beepPin,frq);
      }else{
        noTone(beepPin);
      }
     beepStatus = !beepStatus;
     frqStatus = !frqStatus;
}
}


der Sketch führt auch zwei verschiedene dinge auf einmal aus (Led blinken & beep) das einzige das nicht geht ist der wechsel der Frequenz da will er die else{} einfach nicht durchlaufen? Denkfehler?

Code: [Select]
if(frqStatus == HIGH){
              frq = 700;
            }else{
              frq = 500;
            }


@MicroBahner
 mehr eingerückt dafür keine kommentare :-) beim nächsten  mal beider, ich muss mal verstehen wie die IDE von alleine einrück bei schleifen und abfragen...

MicroBahner

das einzige das nicht geht ist der wechsel der Frequenz da will er die else{} einfach nicht durchlaufen? Denkfehler?
Doch, er durchläuft den else-Zweig schon. Aber Du schaltest  beepStatus und frqStatus immer gleichzeitig um. D.h. frq setzt Du immer dann auf 500, wenn Du gar keinen Ton ausgibst ...

Und die Einrückungen sollten schon auch zur Programmlogik passen. Du kannst die IDE deinen Sketch formatieren/einrückenlassen: Menü->Werkzeuge->Automatisch formatieren
Gruß, Franz-Peter

combie

#29
Aug 20, 2017, 09:44 pm Last Edit: Aug 20, 2017, 09:46 pm by combie
Zusätzlich:

1. Warum ist frqStatus ein int, obwohl du es doch als bool benutzen möchtest?
Oder habe ich was übersehen?


2.
Code: [Select]
if(frqStatus == HIGH){
              frq = 700;
            }else{
              frq = 500;
            }

Das ist gültig, aber tut mir in den Augen weh..  :smiley-evil:

Um solche Dinge abzuhandeln wurde der Ternary Operator erfunden.
Code: [Select]
frq = frqStatus?750:500;
 :o Macht das gleiche  :o

Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Go Up