Go Down

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

ChrisSand

Hallo zusammen,

Mein Name ist Christian ich komme aus dem nähe von Düsseldorf und beschäftige mich seit einem Geburtstags Geschenk mit dem Thema Adruino. 
Ich bin noch etwas frisch im Arduino Thema, ich habe bis dato nur VBA Programmiert und diverse E-Bausätze verbaut/bastelt.
Ich habe aus dem StarterKid einige Schaltungen nachgebaut die auch allesamt funktioniert haben, jetzt möchte ich mich mit der Programmierung beschäftigen. Ich möchte die Codes so einfach wie möglich halten und deswegen einige dinge wie das blinken und Meldungen in Funktionen packen (die dann auch in eine eigene Libraries (Vielleicht hat noch wer einen link wo da beschrieben ist eine eigene Libraries zu schrieben?)

Ich denke mein Problem ist eher etwas logisches und ich verstehe die Programmierung des Sketch noch nicht richtig ( Das mit dem dauerhaften Loop ist schon gewöhnungbedürftig ist man es von VBA doch gewohnt immer auf eine Usereingabe oder einen Klick zu reagieren), ich habe zwei Funktionen geschrieben die ich gerne verwenden möchte das beepAlert() funktioniert auch schon nur wenn ich blinkenLED() ausführe wird die LED nicht mehr ausgeschaltet sondern bleibt während des beepAlter() an. 
was mache ich falsch?

Code: [Select]

// setupCode
void setup() {
}
// start codeloop
void loop() {
beepAlert(2); //Funktion aufrufen
delay(2000); //2sec wait
LEDblinken(3); //Funktion aufrugen
delay(4000); // 2sec wait
}

Code: [Select]
// start functioncode
Code: [Select]
void beepAlert(int buzzPin){ //gibt am übergeben Pin einen Alarm ab
  for(int i=0;i<3;i++){ 
tone(buzzPin,500);
delay(1000);
tone(buzzPin,700);
delay(1000);
noTone(buzzPin);}
}

Code: [Select]
void LEDblinken(int blinkenPin){  // lässt eine LED am übergenen Pin leuchten
  pinMode(blinkenPin, OUTPUT);
  digitalWrite(blinkenPin, HIGH);
  delay(50);
  digitalWrite(blinkenPin, LOW);
  delay(50);
}



Danke
Christian

uwefed

Beide Funktionen blockeren den Sketch.

Laß das Blinken im loop() und verwende millis() für die Zeiten.

Grüße Uwe

combie

Quote
(die dann auch in eine eigene Libraries (Vielleicht hat noch wer einen link wo da beschrieben ist eine eigene Libraries zu schrieben?)
Klar!
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

ChrisSand

Danke Combi.

danke Uwe... jetzt habe ich millis() gelesen (und hoffentlich verstanden) wenn ich das Blinken jetzt im Loop{} mache und das buzzAlert über eine Funktion aufrufe stoppt er natürlich das Blinken :-( Klar den delay() unterbricht ja den Code.
Geht Millis() nicht in Funktionen? habe das jetzt noch nicht ausprobiert wollte zuert das buzzAlert mit Mills() lösen damit der nicht immer unterbricht :-)

Code: [Select]
    byte blinkenPin = 3;                  // LED liegt am (digitalen) Pin 13
    boolean value = LOW;                  // Startwert der LED
    unsigned long previousMillis = 0; // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
    unsigned long interval = 1000;    // Interval zwischen zwei Änderungen
    int anzahlBlink = 10; // Anzahl der Blink vorgänge
   
     
    void setup()
    {
      pinMode(blinkenPin, OUTPUT);      // Setzt den ledPin (Pin 3) als Ausgang
      Serial.begin(9600);
    }
     
    void loop()
    {
        if (millis() - previousMillis > interval) {
        previousMillis = millis();   // aktuelle Zeit abspeichern
        Serial.print(anzahlBlink);
     
        // LED Zustand wecheln.
        value = !value;
       
        digitalWrite(blinkenPin, value); // Wert auf den Ausgang schreiben
          }
          beepAlert(2);
      }

    void beepAlert(int buzzPin){ //gibt am übergeben Pin einen Alarm ab
  for(int i=0;i<3;i++){ 
tone(buzzPin,500);
delay(1000);
tone(buzzPin,700);
delay(1000);
noTone(buzzPin);}
}

michael_x

Quote
Geht Millis() nicht in Funktionen?
Natürlich geht das.

Quote
Das mit dem dauerhaften Loop ist schon gewöhnungbedürftig
Stimmt! Gilt natürlich auch für Funktionen. Vergiss doch erstmal einfach die Funktion delay(), und loop() sowie die darin aufgerufenen Funktionen wird keine Zeit brauchen und dafür unendlich oft drankommen (fast, jedenfalls)

Gibt noch mehr Sachen, die eine Verzögerung eingebaut haben, und nur verwendet werden sollten, wenn man das weiss und es einem egal ist. (tone() gehört nicht dazu)

Mindestens so wichtig wie die Funktion millis() ist natürlich die zugehörige Vergleichsvariable. Da brauchst du für jede der gleichzeitig laufenden Aktionen eine eigene. Erst wenn dir das klar ist, hast du BlinkWithoutDelay verstanden.

uwefed

millis() funktioniert auch in Funktionen. Damit Du aber kontrollieren kannst ob die Zeit verstrichen ist und etwas gemacht werden muß mußt Du die Funktion dauernd aufrufen. Da kann der Code auch in der loop() bleiben.

Basic läuft ja auch nur einmal durch und nach Ausführung aller Befehle wird es geschlossen. Da ist C nicht anders. Da im Microcontroller des Arduino (außer dem Bootloader der nur beim Einschalten aktiv ist und Interruptroutinen die über ein Ereignis gestartet werden) nichts anderes als Dein Sketch ist, der abgearbeitet wird kann das progeamm nicht irgendwann mal fertig sein. Es muß eine schleife geben damit der Microkontroller immer was zu arbeiten hat.

Grüße Uwe


ChrisSand

#6
Aug 19, 2017, 12:31 pm Last Edit: Aug 19, 2017, 12:57 pm by ChrisSand
Natürlich geht das.
 Stimmt! Gilt natürlich auch für Funktionen. Vergiss doch erstmal einfach die Funktion delay(), und loop() sowie die darin aufgerufenen Funktionen wird keine Zeit brauchen und dafür unendlich oft drankommen (fast, jedenfalls)

Gibt noch mehr Sachen, die eine Verzögerung eingebaut haben, und nur verwendet werden sollten, wenn man das weiss und es einem egal ist. (tone() gehört nicht dazu)

Mindestens so wichtig wie die Funktion millis() ist natürlich die zugehörige Vergleichsvariable. Da brauchst du für jede der gleichzeitig laufenden Aktionen eine eigene. Erst wenn dir das klar ist, hast du BlinkWithoutDelay verstanden.
thx. Ich glaube ich werde es erst mal wieder ohne funktion versuchen mit Millis() wenn ich das richtig verstanden habe mit der vergleich variablen speichere ich ihn ihr das letzte mal wenn etwas ausgeführt worden ist und vergleiche das dann immer wenn das größer ist als Millis()-Interval soll er einen Code ausführen.  Das geht aber nur bis 49,2 (,2?) Tage denn dann ist die Variable voll und er beginnt immer wieder von vorne, mit den unsignet  long "Millisletzteausführung" streibe ich denn dann wieder auf null... bei meinen ein zwei sec. Sketch sollte das kein Problem sein.

edit:die logik noch mal geändern mit der if Schleife für millis()


ChrisSand

millis() funktioniert auch in Funktionen. Damit Du aber kontrollieren kannst ob die Zeit verstrichen ist und etwas gemacht werden muß mußt Du die Funktion dauernd aufrufen. Da kann der Code auch in der loop() bleiben.
okay in das leuchtet mit ein, also lieber eine gute strucktur mit der ich das visualisiert bekomme

Basic läuft ja auch nur einmal durch und nach Ausführung aller Befehle wird es geschlossen. Da ist C nicht anders. Da im Microcontroller des Arduino (außer dem Bootloader der nur beim Einschalten aktiv ist und Interruptroutinen die über ein Ereignis gestartet werden) nichts anderes als Dein Sketch ist, der abgearbeitet wird kann das progeamm nicht irgendwann mal fertig sein. Es muß eine schleife geben damit der Microkontroller immer was zu arbeiten hat.

Grüße Uwe


So langsam blicke ich das, deswegen sehe ich immer so wenige Funktionen sondern viel im LOOP stehen... da muss ich mich mal drann gewöhnen.
chris

combie

#8
Aug 19, 2017, 12:55 pm Last Edit: Aug 19, 2017, 12:56 pm by combie
Quote
deswegen sehe ich immer so wenige Funktionen sondern viel im LOOP stehen...
Bitte nicht das falsche lernen!

Wurstbildung in loop() ist unübersichtlich
Es muss nicht alles in loop() gepfercht werden.

Man kann in loop() auch Funktionen aufrufen.
Muss dann aber dafür Sorge tragen, dass sie möglichst schnell wieder verlassen werden, sollten also möglichst kein delay() enthalten.

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

Quelle: Joseph Joubert

Serenifly

Quote
So langsam blicke ich das, deswegen sehe ich immer so wenige Funktionen sondern viel im LOOP stehen... da muss ich mich mal drann gewöhnen.
Das ist eher ein schlechter Programmier Stil wenn es sich um ein längeres Program handelt. Es hindert dich nichts daran Dinge in Funktionen auszulagern und diese in loop() aufzurufen

combie

#10
Aug 19, 2017, 01:16 pm Last Edit: Aug 19, 2017, 01:17 pm by combie
Quote
edit:die logik noch mal geändern mit der if Schleife für millis()
If Schleife
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

uwefed

#11
Aug 19, 2017, 01:37 pm Last Edit: Aug 19, 2017, 01:41 pm by uwefed
Das geht aber nur bis 49,2 (,2?) Tage denn dann ist die Variable voll und er beginnt immer wieder von vorne, mit den unsignet  long "Millisletzteausführung" streibe ich denn dann wieder auf null... bei meinen ein zwei sec. Sketch sollte das kein Problem sein.
Wenn die Kontrolle der verstrichenen Zeit richtig gemacht wird dann ist die Differenz der beiden Zeiten (Beginnzeit und Jetztzeit) auch über einen Überlauf auch richtig berechnet und somit funktioniert die Zeitkontrolle mit millis() richtig. Die einzige Begrenzung ist daß der Intervall nicht größer als ca 49,5 Tage (2^32-1 Millisekunden))sein kann. 

Grüße Uwe


ChrisSand

so eine LED schaffe ich schon mal...

Code: [Select]
   byte blinkenPin = 4;                  // LED liegt am (digitalen) Pin 3
    byte buzzPin = 6; //Digital pin an dem der buzer angeschlossen ist
    boolean value = LOW;                  // Startwert der LED
    boolean valuebuzz = HIGH; //start der buzzers
    unsigned long previousMillis = 0; // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
    unsigned long previousMillisbuzz = 0; //speichert wie viele Sekunden seit derletzten Änderung vergangen sind
    unsigned long interval = 1000;    // Interval zwischen zwei Änderungen
   
     
    void setup()
    {
      pinMode(blinkenPin, OUTPUT);      // Setzt den ledPin (Pin 3) als Ausgang
    Serial.begin(9600);
 
Serial.println("Gestartet");
    }
     
    void loop()
    {
      //LED Blinken
        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

          digitalWrite(blinkenPin, value); // das low oder High auf den Ausgang schreiben
       

 
        }}


jetzt würde ich gerne auch den buzzer jedesmal an und aus schalten lassen

dazu möchte ich "value" noch mal mit if abfragen (@combie nicht schleifen  :) ) und dann ob LOW oder HIGH den buzzer an oder ausschalten

if (value = LOW){
tone(buzzerPin,500);
}elseo{
notone(buzzerPin);
}

das macht er aber nicht weil der Wert von "value" nach dem schreiben auf den pin dann immer 1 ist...

wo ist der Fehler?

HotSystems

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

Und bei else ist ein o zuviel.
Gruß Dieter

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

Go Up