Arduino Forum

International => Deutsch => Topic started by: Trace84 on Jun 09, 2019, 10:21 pm

Title: For Schleife geht nicht
Post by: Trace84 on Jun 09, 2019, 10:21 pm
Hallo zusammen.

Mit eurer Hilfe habe ich es bereits geschafft, im folgenden Lichteffekt-Code erfolgreich die Funktion einzufügen, dass gleichzeitig zu den Button-Funktionen auch ein Sound abgespielt wird.

Nun möchte ich den Code erweitern, so dass die "Torpedo"-Funktion 3 mal hintereinander ausgeführt wird. Also sozusagen 3 Torpedo-"Schüsse" nacheinander.

Habe es bereits mit einer for-Schleife versucht. Kompilierung funktioniert aber das Board macht nichts anderes als vorher. So als hätte die for-Schleife gar keine Auswirkung.

-> siehe Abschnitt "Torpedo Firing" im Sketch

PS: der Code wurde zwar von mir erweitert und leicht angepasst, ist aber nicht von mir


Code: [Select]
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);


// ===================== Variables =============================================================//
// -------  Declaring Pins ----------------------------------------------//
static byte disruptorPin = 9;
static byte enginePin = 6;
static byte pushButtonPin = 12;
static byte torpPin[] = { 2, 3 };

// -------  User Inputs ------------------------------------------------//
static unsigned long torpUpTime = 1680;
static unsigned long torpFlashTime = 200;
static unsigned long torpDownTime = 500;
static long double torpIdleBrightness = 20;
static long double torpMaxBrightness = 255;
static unsigned long engineFadePeriod = 3000;
static unsigned long disruptorFiringTime = 2400;

// -------  For the Button Pushing -------------------------------------//
unsigned long debounce = 50;
unsigned long holdTime = 1000;

// -------  Bookeeping ------------------------------------------------//
unsigned long currentMillis;
boolean buttonValue = false;
boolean buttonLast = true;
boolean ignoreUp = false;
unsigned long buttonUpTime;
unsigned long buttonDownTime;
unsigned int torpedoPushes = 0;
unsigned int disruptorPushes = 0;
unsigned long torpedoTime;
unsigned long disruptorTime;
unsigned long torpedoMillis;
unsigned long disruptorMillis;
unsigned long disruptorFlashTime;
boolean disruptorState = 0;
// ==================== End Variables ========================================================= //


// ===================== Setup ================================================================ //
void setup(){
  pinMode(disruptorPin,OUTPUT);
  pinMode(enginePin,OUTPUT);
  pinMode(pushButtonPin,INPUT_PULLUP);     // Enables internal pull-up resistor
  pinMode(torpPin[0],OUTPUT);
  pinMode(torpPin[1],OUTPUT);
  
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    while(true);
  }
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms
  myDFPlayer.volume(20);  //Set volume value (0~30).
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
  
}


// ===================== End Setup ============================================================ //



// ===================== Main Loop ============================================================ //
void loop() {
  currentMillis = millis();         // get current time
  
 // ---------- Push Buttoon Code --------------------------------------------------------//

  buttonValue = digitalRead(pushButtonPin);
  
    // Record Time of Push
  if (buttonValue == false && buttonLast == true && (millis() - buttonUpTime) > debounce){
    buttonDownTime = millis();
    }
  
  // Record Time of Release
  if (buttonValue == true && buttonLast == false && (millis() - buttonDownTime) > debounce){
        buttonUpTime = millis();
        if (ignoreUp == false){
      disruptorTime = millis();        // If released early, fire disruptor!
      disruptorPushes++;
      myDFPlayer.playMp3Folder(2);
      }
      else{
       ignoreUp = false;
      }
   }

  // If push time is longer than threshold, fire torpedo!
  if (buttonValue == false && (millis() - buttonDownTime) > long(holdTime)){
    buttonDownTime = millis();
    torpedoTime = millis();
    torpedoPushes++;
    ignoreUp = true;
    myDFPlayer.playMp3Folder(1);
        
   }
  
  // Record the button state for comparison in the next cycle
  buttonLast = buttonValue;    
 // -------------------------------------------------------------------------------------//
  
  
  
 // ---------- Torpedo Firing ----------------------------------------------------------//
 // Ramp Up Red LED, Flash White LED, then a Ramp Down of Red LED
  // Ramp Up

  for (int i = 0; i < 3; i++){
  
  if ((currentMillis-torpedoTime) < torpUpTime && torpedoPushes > 0){
    analogWrite(torpPin[1],torpIdleBrightness+(torpMaxBrightness-torpIdleBrightness)/torpUpTime*(currentMillis-torpedoTime));
    digitalWrite(torpPin[0], LOW);
    
    
  }  
  // Flash
  else if (((currentMillis-torpedoTime) > torpUpTime) && ((currentMillis-torpedoTime) < (torpUpTime+torpFlashTime)) && torpedoPushes > 0){
    analogWrite(torpPin[1], 0);
    digitalWrite(torpPin[0], HIGH);
    
  }
  // Ramp Down
  else if (((currentMillis-torpedoTime) > (torpUpTime+torpFlashTime)) && ((currentMillis-torpedoTime) < (torpUpTime+torpFlashTime+torpDownTime)) && torpedoPushes > 0){
    analogWrite(torpPin[1],torpMaxBrightness+(torpIdleBrightness-torpMaxBrightness)/torpDownTime*((currentMillis-torpedoTime)-(torpUpTime+torpFlashTime)));
    digitalWrite(torpPin[0], LOW);
    
  }  
  // Idle
  else{
    analogWrite(torpPin[1], torpIdleBrightness);
    digitalWrite(torpPin[0], LOW);
   }
  }

  
 // ---------- Engine Fading ----------------------------------------------------------- //
  // Slow Up and Down Fade with Shorter Pusations
  int fadeValue = int(127.0+127.0/2.0*(1+(0.75*sin(2*PI*currentMillis/engineFadePeriod)+0.25*cos(14*PI*currentMillis/engineFadePeriod))));
  analogWrite(enginePin,fadeValue);

 
 // ---------- Disruptor Firing -------------------------------------------------------- //
  // Get Random On or Off Time Using getRandom() Function Below
  disruptorFlashTime = fmod(getRandom(), 4000UL) + 60UL;
  if (((currentMillis - disruptorTime) < disruptorFiringTime) && (disruptorPushes > 0)){
    if(currentMillis - disruptorMillis > disruptorFlashTime) {
      disruptorMillis = currentMillis;  
      digitalWrite(disruptorPin, disruptorState = !disruptorState);
      }
   }
   else{
     analogWrite(disruptorPin,5);
 
    }
 // ------------------------------------------------------------------------------------ //


}
// ===================== End Main Loop ======================================================== //




// ===================== Pseduo-Random Generator ============================================== //
// Found This Online. I Take No Credit for It.
unsigned long m_w = 1;
unsigned long m_z = 2;

unsigned long getRandom()
{
    m_z = 36969L * (m_z & 65535L) + (m_z >> 16);
    m_w = 18000L * (m_w & 65535L) + (m_w >> 16);
    return (m_z << 16) + m_w;  /* 32-bit result */
}
// ===================== End Pseduo-Random Generator ========================================== //
Title: Re: For Funktion geht nicht
Post by: Tommy56 on Jun 09, 2019, 10:34 pm
Wo soll "Torpedo Firing" sein?

Gruß Tommy
Title: Re: For Funktion geht nicht
Post by: Finnlay on Jun 09, 2019, 11:04 pm
Zeile 115 ff
Title: Re: For Funktion geht nicht
Post by: Trace84 on Jun 10, 2019, 11:30 am
Wo soll "Torpedo Firing" sein?

Gruß Tommy

Wie Finnlay schon gesehen hat, ab Zeile 115.

Hatte auch schon daran gedacht die Funktion, dass 3 mal hintereinander ein Abschuss erfolgt, bei Zeile 99 einzufügen, weil hier die if-Abfrage des Buttons für den Torpedo Effekt erfolgt. Hat ab3er auch nicht funktioniert.
Title: Re: For Funktion geht nicht
Post by: HotSystems on Jun 10, 2019, 11:40 am
Wie Finnlay schon gesehen hat, ab Zeile 115.

Hatte auch schon daran gedacht die Funktion, dass 3 mal hintereinander ein Abschuss erfolgt, bei Zeile 99 einzufügen, weil hier die if-Abfrage des Buttons für den Torpedo Effekt erfolgt. Hat ab3er auch nicht funktioniert.
Das ist aber keine Funktion, sondern eine "for-Schleife".
Title: Re: For Funktion geht nicht
Post by: postmaster-ino on Jun 10, 2019, 11:54 am
Hi

Und: Innerhalb der Schleife wir die gleiche Zeit geprüft - 3x - an den Variablen, Die die Zeit beinhalten, tut Sich gar nichts.

Denke, Du willst in zeitlichen Versatz den Auslöse-Taster simulieren - der Rest 'Oha, der Taster wurde gedrückt, lass Mal Krach machen' sollte dann wieder von Alleine ablaufen.

MfG
Title: Re: For Funktion geht nicht
Post by: Trace84 on Jun 10, 2019, 12:23 pm
Das ist aber keine Funktion, sondern eine "for-Schleife".

Vielen Dank für den hilfreichen Hinweis. Damit bin ich dem Problem bereits ein Stück näher gekommen.



Hi

Und: Innerhalb der Schleife wir die gleiche Zeit geprüft - 3x - an den Variablen, Die die Zeit beinhalten, tut Sich gar nichts.

Denke, Du willst in zeitlichen Versatz den Auslöse-Taster simulieren - der Rest 'Oha, der Taster wurde gedrückt, lass Mal Krach machen' sollte dann wieder von Alleine ablaufen.

MfG
Bisher ist es so, dass der "Krach" mit dem Lichteffekt zusammen 1x bei längerem Drücken des Tasters ausgeführt wird. Ich hätte aber gern, dass diese Effekt 3x ausgeführt wird.
Title: Re: For Schleife geht nicht
Post by: HotSystems on Jun 10, 2019, 01:48 pm
.....
Bisher ist es so, dass der "Krach" mit dem Lichteffekt zusammen 1x bei längerem Drücken des Tasters ausgeführt wird. Ich hätte aber gern, dass diese Effekt 3x ausgeführt wird.
Dann musst du diese Schleife außerhalb deiner Button-Abfrage laufen lassen und eine Merker-Variable dazu einsetzen, wenn der Button gedrückt wurde.
Und das am besten in einer eigenen Funktion.
Title: Re: For Schleife geht nicht
Post by: Trace84 on Jun 10, 2019, 02:04 pm
Dann musst du diese Schleife außerhalb deiner Button-Abfrage laufen lassen und eine Merker-Variable dazu einsetzen, wenn der Button gedrückt wurde.
Und das am besten in einer eigenen Funktion.

Dir ist schon klar, dass ich diesen Topic erstellt habe, weil ich nicht weiß wie es geht, oder?
Title: Re: For Schleife geht nicht
Post by: HotSystems on Jun 10, 2019, 02:27 pm
Dir ist schon klar, dass ich diesen Topic erstellt habe, weil ich nicht weiß wie es geht, oder?
Neeee.....woher soll ich wissen, was du weist und was nicht.
Ich habe doch beschrieben, wie es geht. Was musst du noch wissen ?

Wie man eine Funktion schreibt ?
Title: Re: For Schleife geht nicht
Post by: Trace84 on Jun 10, 2019, 02:41 pm
Neeee.....woher soll ich wissen, was du weist und was nicht.
Ich habe doch beschrieben, wie es geht. Was musst du noch wissen ?

Wie man eine Funktion schreibt ?

Wenn du mal mit dem Auto stehen bleibst, den ADAC anrufst, der Typ aussteigt, die Motorhaube öffnet und sagt "Sie müssen nur die paar Schrauben entfernen, den Kolben und Ventile tauschen und dann können Sie weiterfahren" möchte ich mal dein Gesicht sehen.
Ist doch ganz einfach oder? Was musst du noch wissen? Woher soll denn der ADAC-Typ wissen was du weißt und was nicht?
Title: Re: For Schleife geht nicht
Post by: HotSystems on Jun 10, 2019, 02:52 pm
Hallo....du hast wohl nicht begriffen, wo du bist.

Der ADAC kosten Geld....falls du weist, was das ist.

Wir machen hier alles kostenlos in unserer Freizeit und sind nicht deine Grundschullehrer.
Also mitarbeiten sonst wird das nix.

Title: Re: For Schleife geht nicht
Post by: Trace84 on Jun 10, 2019, 03:23 pm
Hallo....du hast wohl nicht begriffen, wo du bist.

Der ADAC kosten Geld....falls du weist, was das ist.

Wir machen hier alles kostenlos in unserer Freizeit und sind nicht deine Grundschullehrer.
Also mitarbeiten sonst wird das nix.


Mich hat noch keiner aufgeklärt wo bin ich hier. Würdest du das bitte übernehmen?

Und es heißt "kostet Geld" nicht "kosten Geld" und wenn dein "weist" sich auf den Wortstamm "Wissen" und nicht auf weisen (im Sinne von jemanden leiten) bezieht, wird es mit ß geschrieben. Das schreibe ich dir, obwohl ich in meiner Freizeit bin und kein Grundschullehrer.

Oder wolltest du mir jetzt sagen, dass die Qualität deiner Antworten von einer Zahlung abhängig ist? Dann muss ich nochmal in den Forenregeln nachlesen und gucken, ob das überhaupt erlaubt ist.

Aber zurück zum Thema. Definitiv will ich hier keine vorgefertigte Lösung haben. Denn daraus lernt man nichts. Wenn man aber nicht einmal weiß, wo man anfangen soll, kann man sich sonst wieviele Seiten und Beispiele von Funktionen und Schleifen angucken wie man will und wird trotzdem nicht schlauer. Warum? Nun, weil die meisten Anwendungen sehr individuell sind und Beispiele und Erklärungen sich oft nur auf einfache Mechanismen wie das Blinken einer LED beziehen.


PS: mehr als Danke sagen kann ich hier leider nicht, wenn dir das nicht reicht um in deiner Freizeit als "Nicht-Grundschullehrer" Tips zu geben, möchte ich auf deine Hilfe verzichten. Denn keinesfalls möchte ich, dass du dich zu etwas genötigt fühlst, wenn man als blutiger Anfänger nicht sofort weiß wie man eine Wiederholungs-Schleife mit einer Merker-Variablen außerhalb der eigentlichen Button-Abfrage schreibt.
Title: Re: For Schleife geht nicht
Post by: HotSystems on Jun 10, 2019, 03:36 pm
OK....Glückwunsch, lesen kannst du ja.

Dann lies dir auch die Sprach-Referenz zum Arduino durch, die findest du hier im Menü.
Offensichtlich ist das aber zu schwer für dich, sonst würdest du nicht derartig reagieren.

Denn mit deiner Arroganz wirst du vermutlich nicht viel Hilfe bekommen.
Wenn doch, nochmals Glückwunsch.
Title: Re: For Schleife geht nicht
Post by: Trace84 on Jun 10, 2019, 03:44 pm
OK....Glückwunsch, lesen kannst du ja.

Dann lies dir auch die Sprach-Referenz zum Arduino durch, die findest du hier im Menü.
Offensichtlich ist das aber zu schwer für dich, sonst würdest du nicht derartig reagieren.

Denn mit deiner Arroganz wirst du vermutlich nicht viel Hilfe bekommen.
Wenn doch, nochmals Glückwunsch.

Mit meiner Arroganz (dir gegenüber) bekomme ich definitv keine Hilfe. Das stimmt! Und war ja auch genau meine Absicht, falls du das PS gelesen hast.



Hallo....du hast wohl nicht begriffen, wo du bist.

Der ADAC kosten Geld....falls du weist, was das ist.

Wir machen hier alles kostenlos in unserer Freizeit und sind nicht deine Grundschullehrer.
Also mitarbeiten sonst wird das nix.


Neeee.....woher soll ich wissen, was du weist und was nicht.
Ich habe doch beschrieben, wie es geht. Was musst du noch wissen ?

Wie man eine Funktion schreibt ?

Na zum Glück ist das nicht arrogant. Danke
Title: Re: For Schleife geht nicht
Post by: postmaster-ino on Jun 10, 2019, 04:09 pm
Hi

Meinst Du, SO bekommst Du wirklich mehr Hilfe?
Sofern die 84 in Deinem Nick kein Alter ist - ok, dann eigentlich auch - solltest Du aus der Trotz-Phase bereits draußen sein.

Uns ist durchaus klar, daß Du irgendwo ein Problem hast - sonst wärst Du wohl nicht hier aufgeschlagen (kommt aber schon selten vor, daß Wer nur zum Trollen vorbei schaut).
Auch können wir recht schnell erkennen, WER den Anfangs-Post geschrieben hat - keine große Kunst - also ist auch dieser Hinweis von Deiner Seite eher 'für die Doofen unter Euch' - was nun auch wieder nicht sonderlich toll ankommt.

Wollen wir uns nun auf das von Dir angedachte Niveau begeben, oder wieder wie halbwegs zivilisiertes Volk halbwegs erwachsen miteinander kommunizieren?

Zur aller größten Not hätte ich auch eigene Probleme mit meinen Arduinos ... Die mir eigentlich wesentlich wichtiger sind, als Deine!

MfG
Title: Re: For Schleife geht nicht
Post by: Trace84 on Jun 10, 2019, 05:00 pm
Hi

Meinst Du, SO bekommst Du wirklich mehr Hilfe?
Sofern die 84 in Deinem Nick kein Alter ist - ok, dann eigentlich auch - solltest Du aus der Trotz-Phase bereits draußen sein.

Uns ist durchaus klar, daß Du irgendwo ein Problem hast - sonst wärst Du wohl nicht hier aufgeschlagen (kommt aber schon selten vor, daß Wer nur zum Trollen vorbei schaut).
Auch können wir recht schnell erkennen, WER den Anfangs-Post geschrieben hat - keine große Kunst - also ist auch dieser Hinweis von Deiner Seite eher 'für die Doofen unter Euch' - was nun auch wieder nicht sonderlich toll ankommt.

Wollen wir uns nun auf das von Dir angedachte Niveau begeben, oder wieder wie halbwegs zivilisiertes Volk halbwegs erwachsen miteinander kommunizieren?

Zur aller größten Not hätte ich auch eigene Probleme mit meinen Arduinos ... Die mir eigentlich wesentlich wichtiger sind, als Deine!

MfG
Sätze wie "du hast wohl nicht begriffen wo du hier bist" und "wir sind nicht deine Grundschullehrer" ist also ein halbwegs zivilisiertes Niveau?

Auch die Anspielung auf mein Alter oder eines angeblichen Trotz und Troll-Verhaltens ist also das Niveau, welches hier gewünscht ist?

Wenn man bedenkt, dass ich lediglich darauf hingewiesen habe, dass ich keineswegs weiß, WIE der Vorschlag von HotSystems umzusetzen ist, sind solche Aussagen mehr als nur fehl am Platz.

Einem Anfänger vorzuschlagen er müsse einfach nur eine Merkervariable in eigener Funktion außerhalb der Buttonabfrage einsetzen hilft genauso wenig weiter wie vorzuschlagen für den Widestand nur die Spannung durch die Stromstärke zu teilen.

Beide Aussagen mögen per se richtig sein und total einfach. Helfen aber einem Anfänger nicht beim WIE weiter.
Title: Re: For Schleife geht nicht
Post by: postmaster-ino on Jun 10, 2019, 05:32 pm
Hi

Wie Du willst - zumindest eines meiner Probleme konnte ich in der Zwischenzeit lösen.

Gutes Gelingen auch Dir!

MfG
Title: Re: For Schleife geht nicht
Post by: Trace84 on Jun 10, 2019, 05:46 pm
Hi

Wie Du willst - zumindest eines meiner Probleme konnte ich in der Zwischenzeit lösen.

Gutes Gelingen auch Dir!

MfG
Ich als Anfänger wollte hier nur eine Hilfestellung und werde gleich angefeindet, weil ich nicht sofort sämtliche Fachbegriffe kenne und nicht weiß, wie diese in einem Sketch umzusetzen sind (ein Autofahrer kann das Auto bedienen, weiß aber noch lange nicht, wie es zu reparieren ist).

Und dann wird noch derjenige in Schutz genommen, der ohne Grund sofort herablassend und beleidigend antwortet. Und du selbst hast noch mitgemacht, indem du auf mein geistiges Alter anspielst.

Tolles Forum....Stichwort: Hetze im Netz

Das wars. Bin raus hier!

PS: ich habe übrigens nicht darauf hingewiesen WER den Anfangspost gemacht hat, sondern, dass ich ihn gemacht habe, weil ich nicht weiß, wie ich etwas umsetzen soll....das hatte also nichts mit deinem "für die Doofen unter euch" zu tun.
Title: Re: For Schleife geht nicht
Post by: HotSystems on Jun 10, 2019, 05:58 pm
Ich als Anfänger wollte hier nur eine Hilfestellung und werde gleich angefeindet,
.....
Es reicht jetzt.

Keiner hat dich angefeindet, du wirst allerdings beleidigend.
Das gehört hier tatsächlich nicht her, also gute Reise.
Title: Re: For Schleife geht nicht
Post by: Trace84 on Jun 10, 2019, 06:14 pm
Es reicht jetzt.

Keiner hat dich angefeindet, du wirst allerdings beleidigend.
Das gehört hier tatsächlich nicht her, also gute Reise.

Mich darauf hinzuweisen, dass ihr nicht meine Grundschullehrer seid ist kein anfeinden? Oder zu schreiben "Glückwunsch, lesen kannst du" oder dass ich eine Referenz lesen soll, dass aber "offensichtlich ist das aber zu schwer für dich" ist keine Beleidigung?

Von Geld zu reden und zu sagen "falls du weißt was das ist" auch nicht?

Mir zu sagen, ich müsste meines Alters entsprechend aus der Trotzphase raus sein oder dass mein Niveau nicht mal halbwegs zivilisiert ist, ist ebenfalls weder Anfeindung noch Beleidigung?

Was denn bitte dann?

Um es nochmal deutlich zu machen. Ich habe dir (HotSystems) geschrieben, dass ich hier keinen Topic erstellen würde, wenn ich wüsste, wie ich etwas umsetzen muss. Daraufhin hast DU den Spruch mit dem Grundschullehrer geschrieben und dass ich wohl nicht begriffen hätte wo ich hier bin!

Also rede nicht davon, dass mich keiner anfeindet, wenn DU derjenige bist, der mit diesen Sprüchen angefangen hat!

PS: werde nun meinen Account löschen, vielen Dank euch beiden!
Title: Re: For Schleife geht nicht
Post by: Nalp on Jun 12, 2019, 02:35 pm
Also um mal zur Fragestellung zurückzukommen:

Code: [Select]
for (int i = 0; i < 3; i++){
 
  if ((currentMillis-torpedoTime) < torpUpTime && torpedoPushes > 0){
   
    //Aktion
   
  } 


Kann so nicht klappen, da an die if-Bedingung den zeitlichen Abstand der drei Aktionen gar nicht berücksichtigt. Im Moment wird einfach nur in jedem Loop 3-mal geprüft, ob die Zeit erreicht ist und dann ggf. auch drei mal die gleiche Aktion ausgeführt. Das passiert jedoch quasi gleichzeitig und ist von außen nicht wahrnehmbar. Stattdessen müsste pro Loop getestet werden, ob noch eine Aktion gemacht werden muss, z.B. über eine passende Variable ("übrige Schüsse") oder so. Wenn die größer als 0 ist, soll er schießen und dann nach Ablauf der "Schusszeit" erneut prüfen.
Title: Re: For Schleife geht nicht
Post by: ElEspanol on Jun 12, 2019, 07:14 pm
So was macht man sowieso nicht mit einer for Schleife, weil blockierend.

Mit dem Taster eine Variable auf 1 setzen und am Ende des gewünschten Effektes (der mit if aktiviert wird) eins hochzählen. Wenn grösser 3 die Variable nullen. Fertisch. Dann muss man nur den Taster losgelassen haben, sonst geht der Effekt halt länger.
Notfalls eine state machine rein, falls man die Pausen, etc. Besser kontrollieren will.
Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 12, 2019, 08:27 pm
So was macht man sowieso nicht mit einer for Schleife, weil blockierend.

Mit dem Taster eine Variable auf 1 setzen und am Ende des gewünschten Effektes (der mit if aktiviert wird) eins hochzählen. Wenn grösser 3 die Variable nullen. Fertisch. Dann muss man nur den Taster losgelassen haben, sonst geht der Effekt halt länger.
Notfalls eine state machine rein, falls man die Pausen, etc. Besser kontrollieren will.
Hallo, da sich hier ja doch einige Leute Mühe geben, habe ich mich nochmal angemeldet um antworten zu können.

Erstmal vielen Dank für die Hilfe.

Mein größtes Problem ist eigentlich, dass ich nicht weiß, wie ich die Vorschläge umsetzen soll. Habe mir nun einige Seiten zum Thema "Variablen mit Taster setzen" durchgelesen und kann das alles nicht zu meinem Sketch adaptieren, da die meisten Beispiele oft sehr einfach dargestellt sind und meist nicht zu komplexen Codes passen.

Da es ein Taster mit Doppelfunktion ist (kurz Drücken, lang Drücken) habe ich bereits hier Schwierigkeiten über diese Funktion eine Variable auf 1 zu setzen. Ich weiß einfach nicht genau wo und leider auch nicht wie. Denn die Tasterabfrage ist ja dann über if-else an bestimmte Aktionen in einem anderen Teil des Sketches verknüpft.
Mir fehlen noch so einige Grundlagen und als Standmodellbauer fällt es sehr schwer tiefer in die Thematik einzudringen, wenn man eigentlich nur ein paar LEDs blinken lassen möchte.
Title: Re: For Schleife geht nicht
Post by: ElEspanol on Jun 12, 2019, 10:38 pm
Ich hab mir den Sketch mal kurz überflogen.
In den globalen Variablen Deklarationen static mit const verwechselt, das sagt schon was über den Urheber aus. Bin momentan aber nur am Tablet, um einen besseren Überblick zu bekommen, ist der PC besser. Weiss nicht, wann ich da mal etwas Zeit habe für. Sollte aber kein großes Ding werden.
Im Forum ist einiges zu finden für Standmodelle. Wenn du das öfter machst, solltest du dich ruhig etwas in die Programmierung einarbeiten. Zumindest die erweiterten Basics. Es lohnt sich. Weil, je mehr du weißt, desto mehr Spaß macht es.
Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 12, 2019, 11:19 pm
Hallo,

ich hatte meinen Beitrag gelöscht, weil du dich abgemeldest hattest.
In dem Thread ist einiges schief gelaufen. Schwamm drüber - Kopf hoch.

Also nochmal. Im Grunde ähnlich wie unser Spanier.
Das i der for Schleife wird bis 3 sturr hochgezählt und die if und else if sind dem i nicht von Interesse. Das wird 3x durchgerasselt und fertig. Es würde Zufall sein wenn zu dem Zeitpunkt ein Zeitenvergleich etc. gültig wäre.

Wenn das "Torpedo Firing" en fester Ablauf ist, dann schreibe es als switch-case und rufe es 3x auf. Counter einbauen. Sollte dann ähnlich wie hier sein. Ein Blinker mittels Zustandsautomaten. Der Taster setzt es nur in Gang. Der LED12 Blinker zeigt dir das nichts blockiert.


Code: [Select]

// https://forum.arduino.cc/index.php?topic=534115.0

const byte pin_Taster2 = 2;
const byte pin_LED12 = 28;
const byte pin_LED13 = 13;
const unsigned int BLINKPAUSE = 1000;


void setup() {
  pinMode(pin_Taster2, INPUT_PULLUP);
  pinMode(pin_LED12, OUTPUT);
  pinMode(pin_LED13, OUTPUT);
}

void loop() {
  
  steuerung();

  heartbeat(pin_LED12, 500);

}


void steuerung ()
{
  enum state {EIN, PAUSE_EIN, AUS, PAUSE_AUS, NICHTS};
  static state zustand = NICHTS;
  static unsigned long zeitmerker = 0;
  
  switch (zustand) {
    case NICHTS:
                if (update_Taster2() ) {
                  zustand = EIN;
                }
                break;

    case EIN:
                digitalWrite(pin_LED13, HIGH);
                zeitmerker = millis();
                zustand = PAUSE_EIN;
                break;

    case PAUSE_EIN:
                if ( millis() - zeitmerker > BLINKPAUSE) {
                  zustand = AUS;
                }
                break;

    case AUS:
                digitalWrite(pin_LED13, LOW);
                zeitmerker = millis();
                zustand = PAUSE_AUS;
                break;

    case PAUSE_AUS:
                if ( millis() - zeitmerker > BLINKPAUSE) {
                  zustand = NICHTS;
                }
                break;
                            
    default: zustand = AUS;
             break;
  }

}


bool update_Taster2()
{
  static unsigned long last_ms = 0;
  static bool state = false;

  if (millis() - last_ms > 30) {
    last_ms = millis();
    state = !(digitalRead(pin_Taster2));
  }
  return state;
}


void heartbeat (const byte led, unsigned int interval)           // Kontrolle ob Sketch blockiert
{
  static unsigned long last_ms = 0;
  static bool state = LOW;
  
  unsigned long ms = millis();
  
  if (ms - last_ms >= interval) {
    last_ms = ms;
    state = !state;
    digitalWrite(led, state);
  }
}



Du ersetzt den Taster durch eine bool Variable

Code: [Select]

void steuerung (bool run)
{
  enum state {EIN, PAUSE_EIN, AUS, PAUSE_AUS, NICHTS};
  static state zustand = NICHTS;
  static unsigned long zeitmerker = 0;
  
  switch (zustand) {
    case NICHTS:
                if (run) {
                  zustand = EIN;
                }
                break;


und zählst woanders einen Counter der ggf. "run" auf true setzt bzw. an die Funktion übergibt. Angedeutet ...

Code: [Select]

if (countZyklen < zyklen) {        // Anzahl der Zyklen noch nicht erreicht?
  pushed = true;
}

steuerung( pushed );


Ergänzung.
Den Counter zählst du im obigen Bsp. Sketch im case PAUSE_AUS hoch, wenn auf case NICHTS umgeschalten wird. Erst hier ist ein Durchlauf komplett und der nächste könnte beginnen. Jetzt musste das wie schon andere sagten alles durcharbeiten, verstehen lernen und für deine Zwecke anpassen.
Title: Re: For Schleife geht nicht
Post by: Nalp on Jun 13, 2019, 09:04 am
Und zur Ergänzung: Dein Code ist zwar recht lang, aber die Funktion, um die es geht, hängt nicht so stark am Rest. Ich empfehle dir, mal ein kleines Programm zu schreiben, in dem du wirklich nur das umsetzt: Irgendwas passiert zeitgesteuert dreimal hintereinander, zum Beispiel das Blinken einer eingebauten LED. Das hilft häufig, das Prinzip zu verstehen und im Kopf klar zu kriegen, was nun der eigentliche Ablauf ist.

Und wenn das auch nicht klappt, kannst du es noch "gröber" machen: Sobald die Aktion ausgelöst wird (z.B. durch deinen langen Druck auf den Button) berechnest du drei Startzeitpunkte. Dann guckst du in der Loop für jeden Zeitpunkt einzeln, ob der erreicht ist und löst die Funktion aus. Das ist nicht schön, aber sollte funktionieren und ist vllt. besser verständlich.
Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 13, 2019, 07:16 pm
Ich hab mir den Sketch mal kurz überflogen.
In den globalen Variablen Deklarationen static mit const verwechselt, das sagt schon was über den Urheber aus. Bin momentan aber nur am Tablet, um einen besseren Überblick zu bekommen, ist der PC besser. Weiss nicht, wann ich da mal etwas Zeit habe für. Sollte aber kein großes Ding werden.
Im Forum ist einiges zu finden für Standmodelle. Wenn du das öfter machst, solltest du dich ruhig etwas in die Programmierung einarbeiten. Zumindest die erweiterten Basics. Es lohnt sich. Weil, je mehr du weißt, desto mehr Spaß macht es.
Über den Urheber kann ich dir leider nix sagen. Ich weiß nur, dass der sich das meiste auch nur aus anderen Sketchen zusammengebastelt hat.

Verwirrend ist für mich auch, dass ja bekanntlich viele Wege nach Rom führen und somit auch ein Code auf viele verschiedene Arten geschrieben werden kann und am Ende das Gleiche rauskommt.
Wie dein Beispiel mit dem verwechselten static und const......es funktioniert trotzdem, obwohl es ja wohl anscheinend falsch ist. Da soll man noch durchblicken.


Hallo,

ich hatte meinen Beitrag gelöscht, weil du dich abgemeldest hattest.
In dem Thread ist einiges schief gelaufen. Schwamm drüber - Kopf hoch.

Also nochmal. Im Grunde ähnlich wie unser Spanier.
Das i der for Schleife wird bis 3 sturr hochgezählt und die if und else if sind dem i nicht von Interesse. Das wird 3x durchgerasselt und fertig. Es würde Zufall sein wenn zu dem Zeitpunkt ein Zeitenvergleich etc. gültig wäre.

Wenn das "Torpedo Firing" en fester Ablauf ist, dann schreibe es als switch-case und rufe es 3x auf. Counter einbauen. Sollte dann ähnlich wie hier sein. Ein Blinker mittels Zustandsautomaten. Der Taster setzt es nur in Gang. Der LED12 Blinker zeigt dir das nichts blockiert.


Du ersetzt den Taster durch eine bool Variable


Ergänzung.
Den Counter zählst du im obigen Bsp. Sketch im case PAUSE_AUS hoch, wenn auf case NICHTS umgeschalten wird. Erst hier ist ein Durchlauf komplett und der nächste könnte beginnen. Jetzt musste das wie schon andere sagten alles durcharbeiten, verstehen lernen und für deine Zwecke anpassen.
Vielen Dank, dass du dann doch nochmal hier etwas dazu geschrieben hast.

Vielleicht bin ich auch etwas naiv an die Sache rangegangen. Ich dachte, ich könnte einfach nur ein paar Zeilen Code ergänzen und muss nicht etwas um- bzw. neuschreiben.

Wenn ich das alles so lese, ist mir zwar schon bewusst, was so insgesamt passiert aber mir fehlen tatsächlich noch massiv die Grundlagen. Ich bekomme bei sowas hier einfach schon einen Knotzen im Kopf:

Code: [Select]

  switch (zustand) {
    case NICHTS:
                if (run) {
                  zustand = EIN;
                }
                break;


Oder bei sowas:

Code: [Select]

  if (millis() - last_ms > 30) {
    last_ms = millis();
    state = !(digitalRead(pin_Taster2));
  }
  return state;
}


Ich weiß zwar was da passieren soll, verstehe aber nicht warum das so und so geschrieben wird. Es ist meist wie mit einer Fremdsprache.....das sprechen geht recht schnell aber die Grammatik verstehen dauert ewig.

Werde mich da mal versuchen durchzuwühlen.



Und zur Ergänzung: Dein Code ist zwar recht lang, aber die Funktion, um die es geht, hängt nicht so stark am Rest. Ich empfehle dir, mal ein kleines Programm zu schreiben, in dem du wirklich nur das umsetzt: Irgendwas passiert zeitgesteuert dreimal hintereinander, zum Beispiel das Blinken einer eingebauten LED. Das hilft häufig, das Prinzip zu verstehen und im Kopf klar zu kriegen, was nun der eigentliche Ablauf ist.

Und wenn das auch nicht klappt, kannst du es noch "gröber" machen: Sobald die Aktion ausgelöst wird (z.B. durch deinen langen Druck auf den Button) berechnest du drei Startzeitpunkte. Dann guckst du in der Loop für jeden Zeitpunkt einzeln, ob der erreicht ist und löst die Funktion aus. Das ist nicht schön, aber sollte funktionieren und ist vllt. besser verständlich.
Das klingt so einleuchtend und logisch und schon beim berechnen von Startzeitpunkten fehlen mir bereits die Grundlagen um das umzusetzen. Also erstmal ordentlich mit millis umgehen lernen.

Wie gesagt, bisher habe ich fertige Sketche benutzt und meist nur "an-aus" Zeiten für das Blinken von LEDs geändert. Das war bisher auch nicht schwer. Aber einen Code umzuändern, so dass ich "mehr" davon habe, ist für mich momentan noch zum Kopf rauchen.

Werde mich aber mal etwas einlesen.

Danke euch allen!
Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 13, 2019, 11:11 pm
Hallo,

um dir etwas Mut zu machen. Jeder hat irgendwann klein angefangen. Ich beschäftige mich viel mit Details bevor ich aus vielem Kleinen etwas Größeres baue. Hin- und wieder verzettel ich mich dabei. Egal - auch dabei lernt man was.

Grundlage für alles ist der Umgang mit millis, deine ewige Armbanduhr. Die Nutzung bzw. Anwendung derer ist das A & O für nicht blockierende Programme. Der ganze Rest baut darauf auf. Dazu soviel wie möglich lokale Variablen verwenden, nicht alles in die loop werfen, sondern Aufgaben bezogene Funktionen schreiben und diese in der loop aufrufen. Das vereinfacht vieles.

Theseus erklärt millis()
http://forum.arduino.cc/index.php?topic=400102.msg2752141#msg2752141 (http://forum.arduino.cc/index.php?topic=400102.msg2752141#msg2752141)

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung
http://forum.arduino.cc/index.php?topic=423688.0 (http://forum.arduino.cc/index.php?topic=423688.0)
Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 15, 2019, 03:23 pm
Hallo,

um dir etwas Mut zu machen. Jeder hat irgendwann klein angefangen. Ich beschäftige mich viel mit Details bevor ich aus vielem Kleinen etwas Größeres baue. Hin- und wieder verzettel ich mich dabei. Egal - auch dabei lernt man was.

Grundlage für alles ist der Umgang mit millis, deine ewige Armbanduhr. Die Nutzung bzw. Anwendung derer ist das A & O für nicht blockierende Programme. Der ganze Rest baut darauf auf. Dazu soviel wie möglich lokale Variablen verwenden, nicht alles in die loop werfen, sondern Aufgaben bezogene Funktionen schreiben und diese in der loop aufrufen. Das vereinfacht vieles.

Theseus erklärt millis()
http://forum.arduino.cc/index.php?topic=400102.msg2752141#msg2752141 (http://forum.arduino.cc/index.php?topic=400102.msg2752141#msg2752141)

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung
http://forum.arduino.cc/index.php?topic=423688.0 (http://forum.arduino.cc/index.php?topic=423688.0)

Danke fürs Mut machen.

Ein einfaches Blinkprogramm mit millis ist für mich kein Problem. Aber sobald es komplexer wird, hab ich Schwierigkeiten.
Hab das mit dem 3fachen Torpedoschuss erstmal sein lassen und wollte jetzt "nur" beim längeren Betätigen des Tasters einen Sound abspielen und wenn der fertig ist einen anderen inklusive des Lichteffektes für den Torpedoschuss.....und auch hier verzweifle ich schon wieder :D

Dachte zuerst ich könnte einfach nur eine "Pause" zwischen beiden Sound-Triggern setzen und eine Pause, so dass nicht sofort mit dem Lichteffekt angefangen wird, sondern erst, nachdem der erste Sound fertig ist.
Title: Re: For Schleife geht nicht
Post by: ElEspanol on Jun 15, 2019, 06:59 pm
Programmiertechnisch setzt man keine Pausen, sondern macht eine Ablaufsteuerung. Oder mehrere, die sozusagen dadurch parallel laufen.
Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 16, 2019, 01:05 am
Programmiertechnisch setzt man keine Pausen, sondern macht eine Ablaufsteuerung. Oder mehrere, die sozusagen dadurch parallel laufen.
Darum hatte ich Pause ja auch in "" gesetzt.

Das Problem ist ja, dass der Taster den Sound auslöst während das Programm weiterläuft und den Lichteffekt auslöst. Das geschieht ja so schnell, dass man nicht merkt, dass es eigentlich 2 Abläufe hintereinander sind.

Nun wollte ich, dass der Tastendruck einen Sound auslöst und der Lichteffekt ebenfalls einen Sound auslöst. Während ich beim Taster einfach nur den Soundbefehl hinzufügen musste, klappt das beim Lichteffekt leider nicht, weil sich das Programm dann selbst aufhängt.

Der Lichteffekt startet, das Programm läuft weiter, startet den Sound, läuft weiter und unterbricht den Sound um den folgenden Lichteffekt auszulösen.
Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 16, 2019, 07:02 am
Hallo,

wie schon gesagt, ich sehe in großen Buchstaben eine Schrittkette vor mir. Stichtwort bleibt switch case. Entweder erfolgt der Schritt zum nächsten case mittels Zeitabfrage wie gezeigt. Oder ich könnte mir vorstellen beim Licht/Soundeffekt Ereignis gesteuert. Das heißt dein Licht/Soundeffekt gibt ein "bin fertig" zurück, daraufhin erfolgt dann der Sprung zum nächsten case.
Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 16, 2019, 11:42 am
Hallo,

wie schon gesagt, ich sehe in großen Buchstaben eine Schrittkette vor mir. Stichtwort bleibt switch case. Entweder erfolgt der Schritt zum nächsten case mittels Zeitabfrage wie gezeigt. Oder ich könnte mir vorstellen beim Licht/Soundeffekt Ereignis gesteuert. Das heißt dein Licht/Soundeffekt gibt ein "bin fertig" zurück, daraufhin erfolgt dann der Sprung zum nächsten case.
Aber es muss doch eine Möglichkeit geben, die von mir gewünsche Funktion zu implementieren, ohne den Code mit einer Schrittkette neuschreiben zu müssen.

Bin auch einer Lösung bereits recht nahe. Der erste Sound wird getriggert, sobald ich den Taster lange drücke (Zeile 102-103). Allerdings muss ich ihn jetzt so lange gedrückt halten, wie im unsigned long turnOnDelay angegeben. Währenddessen spielt der Sound mehrmals ab (so lange wie ich den Taster gedrückt halte). Lasse ich den Taster dann los, startet der Lichteffekt mit zugehörigem Sound (Zeile 107-144). 

Eigentlich sollte das turnOnDelay (Zeile 105) dazu dienen, genug Zeit zu haben bis der Tastersound abgespielt wurde, damit danach der Lichteffekt mit Sound abspielt.

Jetzt ist es so, dass ich den Taster genau diese Zeit lang gedrückt halten und dann loslassen muss, damit das klappt.

Hier ist nochmal der Code:

Code: [Select]
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);


// ===================== Variables =============================================================//
// -------  Declaring Pins ----------------------------------------------//
static byte disruptorPin = 9;
static byte enginePin = 6;
static byte pushButtonPin = 12;
static byte torpPin[] = { 2, 3 };

// -------  User Inputs ------------------------------------------------//
static unsigned long torpUpTime = 1680;
static unsigned long torpFlashTime = 200;
static unsigned long torpDownTime = 500;
static long double torpIdleBrightness = 20;
static long double torpMaxBrightness = 255;
static unsigned long engineFadePeriod = 3000;
static unsigned long disruptorFiringTime = 2400;

// -------  For the Button Pushing -------------------------------------//
unsigned long debounce = 50;
unsigned long holdTime = 1000;

// -------  Bookeeping ------------------------------------------------//
unsigned long currentMillis;
boolean buttonValue = false;
boolean buttonLast = true;
boolean ignoreUp = false;
unsigned long buttonUpTime;
unsigned long buttonDownTime;
unsigned int torpedoPushes = 0;
unsigned int disruptorPushes = 0;
unsigned long torpedoTime;
unsigned long disruptorTime;
unsigned long torpedoMillis;
unsigned long disruptorMillis;
unsigned long disruptorFlashTime;
boolean disruptorState = 0;

unsigned long turnOnDelay = 2500;
// ==================== End Variables ========================================================= //


// ===================== Setup ================================================================ //
void setup(){
  pinMode(disruptorPin,OUTPUT);
  pinMode(enginePin,OUTPUT);
  pinMode(pushButtonPin,INPUT_PULLUP);     // Enables internal pull-up resistor
  pinMode(torpPin[0],OUTPUT);
  pinMode(torpPin[1],OUTPUT);
 
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    while(true);
  }
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms
  myDFPlayer.volume(5);  //Set volume value (0~30).
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
 
}


// ===================== End Setup ============================================================ //



// ===================== Main Loop ============================================================ //
void loop() {
 unsigned long currentMillis = millis();         // get current time
 
 // ---------- Push Buttoon Code --------------------------------------------------------//

  buttonValue = digitalRead(pushButtonPin);
 
    // Record Time of Push
  if (buttonValue == false && buttonLast == true && (millis() - buttonUpTime) > debounce){
    buttonDownTime = millis();
    }
 
  // Record Time of Release
  if (buttonValue == true && buttonLast == false && (millis() - buttonDownTime) > debounce){
        buttonUpTime = millis();
        if (ignoreUp == false){
      disruptorTime = millis(); // If released early, fire disruptor!
      disruptorPushes++;
      myDFPlayer.playMp3Folder(2);
      }
      else{
       ignoreUp = false;
      }
   }

  // If push time is longer than threshold, fire torpedo!
  if (buttonValue == false && (millis() - buttonDownTime) > long(holdTime)){
    myDFPlayer.playMp3Folder(5);
   
    if ((millis() - buttonDownTime) >= turnOnDelay) {
             
    buttonDownTime = millis();
    torpedoTime = millis();
    torpedoPushes++;
    ignoreUp = true;
    myDFPlayer.playMp3Folder(1);

     }
   }
 
  // Record the button state for comparison in the next cycle
  buttonLast = buttonValue;   
 // -------------------------------------------------------------------------------------//
 
 
 
 // ---------- Torpedo Firing ----------------------------------------------------------//
 // Ramp Up Red LED, Flash White LED, then a Ramp Down of Red LED
  // Ramp Up

 
  if ((currentMillis-torpedoTime) < torpUpTime && torpedoPushes > 0){
    analogWrite(torpPin[1],torpIdleBrightness+(torpMaxBrightness-torpIdleBrightness)/torpUpTime*(currentMillis-torpedoTime));
    digitalWrite(torpPin[0], LOW);
   
   
  } 
  // Flash
  else if (((currentMillis-torpedoTime) > torpUpTime) && ((currentMillis-torpedoTime) < (torpUpTime+torpFlashTime)) && torpedoPushes > 0){
    analogWrite(torpPin[1], 0);
    digitalWrite(torpPin[0], HIGH);
   
  }
  // Ramp Down
  else if (((currentMillis-torpedoTime) > (torpUpTime+torpFlashTime)) && ((currentMillis-torpedoTime) < (torpUpTime+torpFlashTime+torpDownTime)) && torpedoPushes > 0){
    analogWrite(torpPin[1],torpMaxBrightness+(torpIdleBrightness-torpMaxBrightness)/torpDownTime*((currentMillis-torpedoTime)-(torpUpTime+torpFlashTime)));
    digitalWrite(torpPin[0], LOW);
   
  } 
  // Idle
  else{
    analogWrite(torpPin[1], torpIdleBrightness);
    digitalWrite(torpPin[0], LOW);
   
  }

 
 // ---------- Engine Fading ----------------------------------------------------------- //
  // Slow Up and Down Fade with Shorter Pusations
  int fadeValue = int(127.0+127.0/2.0*(1+(0.75*sin(2*PI*currentMillis/engineFadePeriod)+0.25*cos(14*PI*currentMillis/engineFadePeriod))));
  analogWrite(enginePin,fadeValue);

 
 // ---------- Disruptor Firing -------------------------------------------------------- //
  // Get Random On or Off Time Using getRandom() Function Below
  disruptorFlashTime = fmod(getRandom(), 4000UL) + 60UL;
  if (((currentMillis - disruptorTime) < disruptorFiringTime) && (disruptorPushes > 0)){
    if(currentMillis - disruptorMillis > disruptorFlashTime) {
      disruptorMillis = currentMillis; 
      digitalWrite(disruptorPin, disruptorState = !disruptorState);
      }
   }
   else{
     analogWrite(disruptorPin,5);
 
    }
 // ------------------------------------------------------------------------------------ //


}
// ===================== End Main Loop ======================================================== //




// ===================== Pseduo-Random Generator ============================================== //
// Found This Online. I Take No Credit for It.
unsigned long m_w = 1;
unsigned long m_z = 2;

unsigned long getRandom()
{
    m_z = 36969L * (m_z & 65535L) + (m_z >> 16);
    m_w = 18000L * (m_w & 65535L) + (m_w >> 16);
    return (m_z << 16) + m_w;  /* 32-bit result */
}
// ===================== End Pseduo-Random Generator ========================================== //
Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 16, 2019, 02:28 pm
Hallo,

ehrlich gesagt blicke ich nicht mehr durch. Ich dachte es ging um den Abschnitt "Torpedo Firing".

Wegen Zeile 102 usw.
Du musst dir merken das die Taste gedrückt wurde, wenn gedrückt wurde und Zeit vorbei, dann nächste Aktion starten. Ob du das mit if machst oder switch case ist am Ende ziemlich egal. Mit switch case sieht man besser das es eine Schrittkette ist die nacheinander bestimmte Aktionen startet und man kann mit lesebaren Namen arbeiten. enum und switch case gibt ein ziemlich gutes Paar ab.

Schaust du dir mein switch case Bsp. an, siehst du das ein "bin gedrückt Merker" hier nicht notwendig ist, weil direkt danach schon der nächste Zustand aktiv ist bzw. der Taster startet die Aktion überhaupt erst. Ich finde das ziemlich einfach und man kann es beliebig ausbauen. Eigentlich ideal für dein Vorhaben.

Wenn erst nach dem kompletten abspielen des Sounds die nächste Aktion starten soll, dann benötigst du wie schon gesagt einen Rückgabewert "bin fertig" oder wenn die Funktion keinen Rückgabewert hat, musste die Abspieldauer vom Sound abwarten.

Mein Tipp.
Mache mit dem Problemteil einen separaten Sketch, schreibe alles in Funktionen, dann kannste das leicht einbinden wenn es funktioniert. Nutze lokale Variablen. Desweiteren kannst du über Strukturen (struct) nachdenken um mehr Übersicht reinzubekommen. Variablen die zusammengehören zusammenfassen. Die ein oder andere globale Variable kannste bestimmt lokal machen. Hilft alles wirtschaften.
Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 16, 2019, 05:34 pm
Ja, um den Abschnitt "Torpedo Firing" ging es ja auch zuerst. Hatte ja dann geschrieben, dass ich erstmal etwas andere ausprobieren wollte, von dem ich dachte, es wäre einfacher.

Mein Problem ist einfach, dass andere Sketche meist anders aufgebaut sind, bestimmte millis Abfragen oder Zustandsänderungen sind anders und könne nicht einfach so übertragen werden.

Bei meinem letzten Code beispielsweise habe ich ein sehr einfachen Teil aus "Button-press with delayed action" genommen und wie du siehst, hat es nicht geklappt. Eizeln für sich, wie du vorgeschlagen hattest, kein Problem.....eingefügt in meinem Sketch...Problem.

Das liegt eben daran, dass bei dem Beispiele einfach nur eine LED blinken lassen. Bei mir hängt aber mehr dran als nur eine LED bzw. passieren beim Tastendruck mehr Dinge, die voneinander abhängig sind, als bei einem einfachen Blinkprogramm.

Es ist für mich äußerst Schwierig nachzuvollziehen, was sich alles ändern muss, bzw. welche Variablen wo zu deklarieren sind, damit der ursprüngliche Sketch normal weiterfunktioniert und der neue Teil diesen nur ergänzt.

Hast du dir meinen letzten Sketch mal angeguckt? Hatte ja geschrieben, dass ich der Lösung recht nahe bin und jetzt nur noch ein Zeitproblem zwischen dem Drücken der Taste, dem Abspielen des ersten Soundeffekts, des Zweiten und des Lichteffekts habe.

Es muss also auch auf diese einfache Art gehen, ohne jetzt die Funktionen durch Switch Case zu ersetzen. Auch ein "bin fertig" Rückgabewert war ja bisher nicht notwendig. Die Sounddatei ist ja auf die Dauer des LED-Effekts abgestimmt.

SwitchCase habe ich mir jetzt einiges durchgelesen und klingt einleuchtend aber dazu müsste ich ja den ganzen Sketch umschreiben, statt nur etwas zu ergänzen.

Bisher ist es ja so, dass nach dem Drücken des Tasters für x-Sekunden sofort der Sound startet und ohne Verzögerung der Lichteffekt. Das funktioniert ja auch prima.

Jetzt wollte ich "nur":  Taster für x-Sekunden gedrückt halten -> erster Sound, nach 2 Sekunden Verzögerung startet der zweite Sound und der Lichteffekt (Zeile 107-144).





Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 16, 2019, 06:34 pm
Hallo,

ich dachte Anfangs du möchtest programmieren lernen. Ich lese aber immer nur ich möchte Funktionalität x einbauen ohne y zu ändern. Wie soll das gehen? Der Thread ist voller Informationen und Lösungsansätze. Nichts davon interessiert dich. Schade.

Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 16, 2019, 06:42 pm
Hallo,

ich dachte Anfangs du möchtest programmieren lernen. Ich lese aber immer nur ich möchte Funktionalität x einbauen ohne y zu ändern. Wie soll das gehen? Der Thread ist voller Informationen und Lösungsansätze. Nichts davon interessiert dich. Schade.


Ich hab doch jetzt bereits einen veränderten Code gezeigt, den ich erstellt habe, nachdem ich mir diverse Vorschläge durchgelesen habe. Wie könnte ich das geschafft haben, wenn mich das alles nicht interessieren würde?

Wenn ich irgendwo Urlaub mache, möchte ich mich ein wenig verständigen können aber nicht gleich die ganze Sprache lernen.

Und ja, richtig, ich möchte y nicht ändern, denn y funktioniert doch einwandfrei. Also warum dort etwas ändern?

Leider bestehen die meisten Lösungsansätze daraus den Code neuzuschreiben oder anders zu gestalten. Auch hier sehe ich nicht den Sinn darin einen Code neuzugestalten, der doch an sich funktioniert. Oder übersehe ich da was?

Nochmal zum Verständnis. Der Anfangscode funktioniert reibungslos. Nur wollte ich diesen erweitern und stoße dabei auf Probleme.
Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 17, 2019, 02:52 pm
Hallo,

nochmal zum Verständnis. Du hast folgende Situation.

Du hast einen Sketch der "scheinbar" funktioniert. Er funktioniert jedoch noch nicht wie endgültig gewünscht. Demzufolge musst du am Sketch etwas ändern, was nicht nur eine neue Zeile einfügen bedeutet.

Wenn du wüßtest was ich schon alles umbauen mußte, teilweise widerwillig, aber ich mußte. Manchmal kommt man über Umwege wieder zu einfacheren Code, jedoch ist der neue einfachere Code immer noch anders wie der alte Code. Wenn der alte Code das machen würde was man sich wünscht, tja dann müßte man ihn nicht umbauen. Logisch oder?

Bei meiner aktuellen "Lib Codiererei" habe ich das Gefühl das ich ständig nur umbaue. Ich könnte mich auf meiner funktionierenden Version ausruhen. Tue ich aber nicht, weil es hier und da noch Optimierungspotential gibt. Mit Rückschlägen muss man dabei rechnen.

Mehr kann ich dir im Moment nicht sagen.
Title: Re: For Schleife geht nicht
Post by: Serenifly on Jun 17, 2019, 03:03 pm
Und ja, richtig, ich möchte y nicht ändern, denn y funktioniert doch einwandfrei. Also warum dort etwas ändern?

Leider bestehen die meisten Lösungsansätze daraus den Code neuzuschreiben oder anders zu gestalten. Auch hier sehe ich nicht den Sinn darin einen Code neuzugestalten, der doch an sich funktioniert. Oder übersehe ich da was?
Das ist beim Programmieren aber häufig so. Auch im professionellen Bereich. Selbst kleine Änderungen sind dann unter Umständen viel Arbeit. Manche Firmen verbringen Monate damit nur Code neuzuschreiben der schonmal funktioniert hat. Idealerweise schreibt man von Anfang an so das alles leicht änderbar und erweiterbar ist, aber das ist auch leichter gesagt als getan. Und irgendwann später merkt man dann doch vielleicht dass es nicht so gut geht wie gedacht.
Title: Re: For Schleife geht nicht
Post by: ElEspanol on Jun 17, 2019, 03:08 pm
und hier kommt noch dazu, dass der Code nicht von Dir ist, und somit keiner weiss, was sich der Programmierer seinerzeit gedacht hat, es gerade si und nicht anders zu machen.
Title: Re: For Schleife geht nicht
Post by: combie on Jun 17, 2019, 03:09 pm
Ich sehe das ein klein wenig anders!
Stimme aber grundsätzlich zu.


Bei größeren Projekten ist die erste Version sowieso für die Tonne bestimmt.
Sie dient nur als Prototype...
Die zweite Variante ist dann schon meist recht brauchbar.

Oft folgt daraufhin noch ein dritter kompletter Neubau, welcher dann sämtliche "dirty Hacks" eliminiert.

Ich sehe das als den einzigen wahren Weg, das neu gelernte und die beim Bau der Prototypen gemachten Erfahrungen einzuflechten.






Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 18, 2019, 11:00 am
Vielen Dank für die Erklärungen, mir ist jetzt etwas einleuchtender, warum man bereits funktionierende Bereiche neuschreiben muss.

Der Anfangscode funktioniert nicht nur scheinbar, sondern vollständig und auch zufriedenstellend. Was ich wollte, ist eine (oder 2) Funktionen hinzufügen. Eben statt den Effekt nur einmal ablaufen zu lassen, 3 mal und eine Sounddatei abspielen zu lassen, sobald ein Taster gedrückt wurde.

Vermutlich habe ich mir das einfacher vorgesellt als es tatsächlich ist. Denn beim Einfügen der Sounddateien musste ich tatsächlich nur per Copy/Paste ein paar Zeilen einfügen.

Ich sehe auch die Schwierigkeit darin, dass die Lichteffekte mit vielen Variablenvergleichen an die Tastenbestimmung gekoppelt ist, welche wiederum aus Variablenvergleichen besteht.

Diese ganzen Variablenvergleiche dann in andere Funktionen einzubauen ist für mich bisher geistig nicht machbar. Dafür reichen meine Grundkenntnisse nicht aus.

Beispiele mit swichtcase oder auch andere Beispiele beinhalten oft nur eine einfache Variable, welche dann als switch dient (Potiwert, einfacher Tastendruck usw.) oder mit einfachen Tasten. Das ist auch recht gut zu verstehen. Aber eben nur, so lange es sich um eine Variable handelt. Nicht um Abhängigkeiten. Oder es sind Beispiele, die schon wieder so komplex sind, dass man diese nicht so leicht aufs eigene Projekt ummünzen kann.

Der von mir gewünschte zusätzliche Effekt wäre mit Sicherheit einfacher umzusetzen, wenn der Anfangscode bereits anders geschrieben wäre. Da habt ihr alle natürlich recht.

Trotzdem finde ich es sehr ernüchternd, dass ich mich jetzt doch wesentlich intensiver mit Arduino auseinander setzen muss, wo ich doch "nur" einfach Blink- und Soundeffekte für den Modellbau haben wollte. Aber da muss ich dann jetzt wohl durch.
Title: Re: For Schleife geht nicht
Post by: ElEspanol on Jun 18, 2019, 11:03 am
Trotzdem finde ich es sehr ernüchternd, dass ich mich jetzt doch wesentlich intensiver mit Arduino auseinander setzen muss, wo ich doch "nur" einfach Blink- und Soundeffekte für den Modellbau haben wollte. Aber da muss ich dann jetzt wohl durch.
Gute Einsicht. Und das wird dir mit jedem Teilerfolg mehr Spaß machen.
Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 18, 2019, 12:09 pm
Gute Einsicht. Und das wird dir mit jedem Teilerfolg mehr Spaß machen.
Gute Einsicht. Und das wird dir mit jedem Teilerfolg mehr Spaß machen.
Stimmt. Denn egal wie klein, der erste Schritt ist immer der schwerste von allen.



Hab aber eben noch mal etwas ausprobiert und habe nun den gewünschen Effekt. Allerdings mit Delay, welches ich natürlich vermeiden möchte.

Aber ich weiß nicht genau, wie ich die millis schreiben muss, um kein Delay nutzen zu müssen,

Millis für den zeitlichen Ablauf einer blinkenden LED zu schreiben kann ich aber da hier eben so viele Variablen sind, die auch alle millis nutzen, komme ich nicht weiter.

Hier nochmal der Teilcode:

Code: [Select]
  if (buttonValue == false && (millis() - buttonDownTime) > long(holdTime)){
    myDFPlayer.playMp3Folder(5);
   
delay (1500);
             
    buttonDownTime = millis();
    torpedoTime = millis();
    torpedoPushes++;
    ignoreUp = true;
    myDFPlayer.playMp3Folder(1);

     }
   
 
 



Dadurch habe ich erreicht, dass beim Drücken des Tasters ein Sound abgespielt wird (MP3(5)), dann 1500millis gewartet wird und dann der Code weiterläuft, so dass der nächste Sound (MP3(1)) sowie der entsprechende Lichteffekt abspielt.

Wie gesagt, funktioniert. Aber ohne Delay, sondern mit millis wäre es ja korrekt. Und wenn schon, dann möchte ich es von Anfang an richtig machen.
Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 18, 2019, 12:40 pm
Hallo,

Zwischenfrage. Die Abspielfunktionen myDFPlayer.playMp3Folder(5) arbeiten blockierend?
Wenn ich dessen Code richtig verstehe?
Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 18, 2019, 01:25 pm
Hallo,

das abspielen kann nur blockierend arbeiten, sonst würde das mit dem delay nicht funktionieren. Wenn man das delay nicht blockierend umbaut, würde es den ersten Sound nochmals abspielen, die Funktion würde immer aufgerufen solange der Button gedrückt ist. Der Button muss bei dem hier aber gedrückt werden, sonst läuft das alles nicht durch. Katze beißt sich in den Schwanz. Deswegen mein Favorit switch case, weil damit kannste dir klare Zustände bauen ohne dich in einem wilden if elseif Wollknäul zuverfitzen.

fehlende Variablen und Lib ergänzen ...
Code: [Select]

const byte pin_Taster = 2;
const byte pin_LED13 = 13;

void setup() {
  pinMode(pin_Taster, INPUT_PULLUP);
  pinMode(pin_LED13, OUTPUT);
}

void loop() {

  steuerung();

}


void steuerung ()
{
  enum state {NICHTS, SOUND, WAIT_FIRE, FIRE, AUS};
  static state zustand = NICHTS;
  static unsigned long zeitmerker = 0;

  switch (zustand) {
    case NICHTS:
                if (update_Taster() ) {         // Tasterabfrage
                  zustand = SOUND;
                }
                break;

    case SOUND:
                digitalWrite(pin_LED13, HIGH);
                myDFPlayer.playMp3Folder(5);
                zeitmerker = millis();          // Zeit merken für nächsten Vergleich
                zustand = WAIT_FIRE;
                break;

    case WAIT_FIRE:  
                if ( millis() - zeitmerker > 1500) {
                  zustand = FIRE;
                }
                break;          

    case FIRE:
                buttonDownTime = millis();
                torpedoTime = millis();
                torpedoPushes++;
                ignoreUp = true;
                myDFPlayer.playMp3Folder(1);
                zustand = AUS;
                break;

    case AUS:
                digitalWrite(pin_LED13, LOW);
                zustand = NICHTS;
                break;

    default:    zustand = AUS;
                break;
  }

}


bool update_Taster()
{
  static unsigned long last_ms = 0;
  static bool state = false;

  if (millis() - last_ms > 30) {
    last_ms = millis();
    state = !(digitalRead(pin_Taster));
  }
  return state;
}
Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 18, 2019, 02:50 pm
Hallo,

das abspielen kann nur blockierend arbeiten, sonst würde das mit dem delay nicht funktionieren. Wenn man das delay nicht blockierend umbaut, würde es den ersten Sound nochmals abspielen, die Funktion würde immer aufgerufen solange der Button gedrückt ist. Der Button muss bei dem hier aber gedrückt werden, sonst läuft das alles nicht durch. Katze beißt sich in den Schwanz. Deswegen mein Favorit switch case, weil damit kannste dir klare Zustände bauen ohne dich in einem wilden if elseif Wollknäul zuverfitzen.

fehlende Variablen und Lib ergänzen ...
Code: [Select]

const byte pin_Taster = 2;
const byte pin_LED13 = 13;

void setup() {
  pinMode(pin_Taster, INPUT_PULLUP);
  pinMode(pin_LED13, OUTPUT);
}

void loop() {

  steuerung();

}


void steuerung ()
{
  enum state {NICHTS, SOUND, WAIT_FIRE, FIRE, AUS};
  static state zustand = NICHTS;
  static unsigned long zeitmerker = 0;

  switch (zustand) {
    case NICHTS:
                if (update_Taster() ) {         // Tasterabfrage
                  zustand = SOUND;
                }
                break;

    case SOUND:
                digitalWrite(pin_LED13, HIGH);
                myDFPlayer.playMp3Folder(5);
                zeitmerker = millis();          // Zeit merken für nächsten Vergleich
                zustand = WAIT_FIRE;
                break;

    case WAIT_FIRE:   
                if ( millis() - zeitmerker > 1500) {
                  zustand = FIRE;
                }
                break;         

    case FIRE:
                buttonDownTime = millis();
                torpedoTime = millis();
                torpedoPushes++;
                ignoreUp = true;
                myDFPlayer.playMp3Folder(1);
                zustand = AUS;
                break;

    case AUS:
                digitalWrite(pin_LED13, LOW);
                zustand = NICHTS;
                break;

    default:    zustand = AUS;
                break;
  }

}


bool update_Taster()
{
  static unsigned long last_ms = 0;
  static bool state = false;

  if (millis() - last_ms > 30) {
    last_ms = millis();
    state = !(digitalRead(pin_Taster));
  }
  return state;
}


Hallo,

danke für die Antwort.

Ich glaube nicht, dass die Abspielfunktion blockierend arbeitet. Wenn ich das Delay und den Sound für den Taster rausnehme, gibt es ja nur die Tasterabfrage für das gedrückt halten und den entsprechenden Variablen, die sich dabei ändern, woraus dann resultiert, dass der Lichteffekt läuft. Während der Lichteffekt läuft, wird die Sounddatei dafür abgespielt.

Nehme ich nur das Delay raus, wird der Sound (5) gar nicht erst abgespielt und das Programm läuft wie gewohnt weiter. Also Lichteffekt plus entsprechenden Sound.

Bei dem von dir vorgeschlagenen Code muss ich erstmal durchblicken und verstehen und dann noch gucken wo bei mir einbauen :D
Title: Re: For Schleife geht nicht
Post by: ElEspanol on Jun 18, 2019, 03:24 pm
Ich glaube, dass der player nur den Abspielbefehl bekommt und ansonsten nichts mit dem Arduino zu tun hat. Also blockierungsfrei.
Title: Re: For Schleife geht nicht
Post by: Nalp on Jun 18, 2019, 03:25 pm
Hi,

das Abspielen von zwei Tönen oder aber das dreifache "Feuern" ist im Prinzip die gleiche Problematik, deswegen hast du dort vermutlich auch wieder Probleme gehabt. Es geht schließlich jedes Mal darum, etwas zeitgesteuert zu starten.

Und noch eine kleine Ergänzung: delay() muss nicht falsch sein. Wenn es für deine Anforderungen ausreicht, dass während des Tons keine Eingabe und auch sonst nichts gemacht werden soll, dann kannst du das ruhig verwenden. Nur wenn du  achen parallel machen willst (z.B. während des Abspielens eine LED blinken etc.), oder "schöneren" Code haben willst, ist millis() nötig. Das kann man aber auch an kleineren Beispielen gut lernen ;)

Ich will auch nochmal wiederholen, dass es lohnenswert sein könnte, einfache Beispiele selbst zu schreiben und versuchen, diese komplett zu verstehen. Dann fällt es auch in größeren Anwendungen irgendwann leichter, durchzublicken.. Beispiele gibt es zuhauf im Internet, z.B. hier (https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing).

Beste Grüße
Jan
Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 18, 2019, 03:45 pm
Hallo,

okay, auch wenn play nicht blockiert, wird das erstmal laufen, wenn Prinzip verstanden ist bauste dir ein case ein der den Zählerstand von torpedoPushes abfragt. Wenn noch nicht erreicht wechselt du den Zustand wieder auf SOUND, wenn erreicht, Ende AUS. Eigentlich ganz einfach.  ;)   switch case sollte verstanden werden bevor du dran rumfummelst. Entscheidend ist ob du im aktuellen case wartest und dort immer alles wiederholst bis zum Wechsel oder ob du einen case nur einmal durchläufst, zum Nächsten wechselst und dort wartest und dann weitere Aktionen ausführen lässt. usw.


Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 18, 2019, 03:50 pm
Hallo,

okay, auch wenn play nicht blockiert, wird das erstmal laufen, wenn Prinzip verstanden ist bauste dir ein case ein der den Zählerstand von torpedoPushes abfragt. Wenn noch nicht erreicht wechselt du den Zustand wieder auf SOUND, wenn erreicht, Ende AUS. Eigentlich ganz einfach.  ;)   switch case sollte verstanden werden bevor du dran rumfummelst. Entscheidend ist ob du im aktuellen case wartest und dort immer alles wiederholst bis zum Wechsel oder ob du einen case nur einmal durchläufst, zum Nächsten wechselst und dort wartest und dann weitere Aktionen ausführen lässt. usw.


Ich habe das Gefühl, dass ich mir früher oder später den gesamten Code selbst schreiben werde. Da habe ich dann auch nicht das Problem etwas in einen bestehenden Code einbinden zu müssen, was so wie der Code jetzt geschrieben ist, vielleicht gar nicht "einfach so" geht.


Ich glaube, dass der player nur den Abspielbefehl bekommt und ansonsten nichts mit dem Arduino zu tun hat. Also blockierungsfrei.

So hatte ich die Einbindung des DFPlayers auch verstanden. Der bekommt ja über serial  nur den Befehl eine bestimmte Datei zu starten.


Und noch eine kleine Ergänzung: delay() muss nicht falsch sein. Wenn es für deine Anforderungen ausreicht, dass während des Tons keine Eingabe und auch sonst nichts gemacht werden soll, dann kannst du das ruhig verwenden. Nur wenn du  achen parallel machen willst (z.B. während des Abspielens eine LED blinken etc.), oder "schöneren" Code haben willst, ist millis() nötig. Das kann man aber auch an kleineren Beispielen gut lernen ;)


Ich glaube, mit dem Delay kann ich in diesem Fall leben. Schade ist nur, dass ich eine flackernde und zugleich fadende LED für das Antriebsleuchten habe. Dieses faden wird während dem Delay natürlich unterbrochen.

Naiv wie ich bin, dachte ich, dass es hier einen einfachen millis Ersatz für das Delay gibt :D
Title: Re: For Schleife geht nicht
Post by: ElEspanol on Jun 18, 2019, 05:57 pm
Ich glaube, mit dem Delay kann ich in diesem Fall leben. Schade ist nur, dass ich eine flackernde und zugleich fadende LED für das Antriebsleuchten habe. Dieses faden wird während dem Delay natürlich unterbrochen.
Schlechte Idee. Und die Begründung lieferst du ja gleich mit.
Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 18, 2019, 06:44 pm
Schlechte Idee. Und die Begründung lieferst du ja gleich mit.
Ja, das ist mir klar. Denn genau darum ging es in dem Thread ja bisher. Delay zu vermeiden. Aber um das zu vermeiden, habe ich ja einige Vorschläge bekommen. Diese machen aber ein neu-, bzw. umschreiben des Codes notwendig. Dazu bin ich noch nicht in der Lage.

Welche Idee (außer neu-/umschreiben) hast du denn um genau den Effekt zu erzielen, den ich jetzt mit Delay habe, nur eben ohne Delay, so dass meine Antriebs-LED nicht unterbrochen wird?
Title: Re: For Schleife geht nicht
Post by: ElEspanol on Jun 18, 2019, 07:04 pm
Poste mal deinen aktuellen Code, Schaltplan und das iso der sd-Karte. Vielleicht packt mich ja mal der Ehrgeiz und ich baue es nach und schaue es mir genauer an.
Und wenigstens eine Beschreibung, für was das ganze ist und ggf. der Link, wo es herkommt.
Title: Re: For Schleife geht nicht
Post by: combie on Jun 18, 2019, 07:07 pm
Quote
Welche Idee (außer neu-/umschreiben) hast du denn um genau den Effekt zu erzielen, den ich jetzt mit Delay habe, nur eben ohne Delay, so dass meine Antriebs-LED nicht unterbrochen wird?
Du könntest dein Dimmdingen in yield() verlagern, dann kannst du dein delay() beibehalten.


-----------
Quote
Dazu bin ich noch nicht in der Lage.
Dann versetze dich in die Lage!

Das Konzept "Zeitabhandlung mit millis()" und "Nebenläufigkeit" ist nur auf den ersten Blick kompliziert.
Das kann jeder verstehen und anwenden.
Es dauert allerdings manchmal etwas, bis der Groschen fällt.
Wichtig: Er muss bei dir fallen.

Das heißt, du solltest solange mit dem Konzept spielen, bis es richtig sitzt.
Und dann erst daran gehen, es bei dir einzubauen.

Tipp:
Der Kopf ist rund, damit das Denken die Richtung ändern kann.


---------

Ablaufsteuerung
Meine Standardantwort zu Ablaufsteuerungen:
Quote
Eine Stichworte Sammlung für Google Suchen:
Endlicher Automat,
State Machine,
Multitasking,
Coroutinen,
Ablaufsteuerung,
Schrittkette,
BlinkWithoutDelay, 
--
Blink Without Delay (https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay)
Der Wachmann (https://forum.arduino.cc/index.php?topic=423688.0)
--
Multitasking Macros  (https://forum.arduino.cc/index.php?topic=415229.msg2859554)
Intervall Macro (https://forum.arduino.cc/index.php?topic=413734.msg2848523)
Title: Re: For Schleife geht nicht
Post by: ElEspanol on Jun 18, 2019, 07:48 pm
Na ja, yield ist nun wirklich keine Lösung, um das Lernen der wichtigsten Basics zu umgehen.
Title: Re: For Schleife geht nicht
Post by: combie on Jun 18, 2019, 08:07 pm
Ja, mag sein...

Es ist allerdings eher die innere Ausrichtung unseres Trace841 welche modifiziert werden sollte.
Leider sind meine Ärmchen zu kurz.
Das muss er/sie/es selber machen.

Und wenn das verstehen von Nebenläufigkeit mit yield() dahin führt, soll es mir recht sein.
Wenn nicht, auch gut, dann nicht.


Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 18, 2019, 08:24 pm
Hallo,

naja, dass Thema hatten wir glaube ich schon einmal.   ;)  Wenn die Nutzung von yield() dazu führt das man das eigentliche Problem umgeht, dann führt das nicht zur Lösung des eigentlichen Problems. Mit der Anwendung millis kann man viele Nebenläufigkeiten bauen ohne diese kaschieren zu müssen. Damit wird yield() für den Anwender nicht mehr benötigt und bleibt den "Arduino Sketch Innereien" vorenthalten. Ansonsten kommt es wie es kommen muss, der Anwender kloppt sein delay auch in yield() rein und wundert sich das gar nichts mehr geht.

Ich vertrete die Linie man sollte dem unbedarften Neuling solche Dinge wie yield() erst gar nicht an die Hand geben. Das Problem wird nur verschleppt, es kann nur Mist bei rauskommen. millis muss als die Grundlage überhaupt verstanden werden, davor darf und soll sich niemand drücken. Das habe ich in Stein gemeißelt.  :)
Title: Re: For Schleife geht nicht
Post by: combie on Jun 18, 2019, 10:49 pm
Quote
Ich vertrete die Linie man sollte dem unbedarften Neuling solche Dinge wie yield() erst gar nicht an die Hand geben.
Was habe ich mit deinen Dogmen zu schaffen?


Title: Re: For Schleife geht nicht
Post by: Doc_Arduino on Jun 19, 2019, 12:08 am
Nichts direkt. Jemand verteilt Mantras und ein anderer Dogmen. Ist doch legitim.
Ich sehe es locker, solltest du auch.  :)
Ich belasse dabei versprochen, konnte es mir nur nicht verkneifen.



Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 19, 2019, 07:54 pm
Du könntest dein Dimmdingen in yield() verlagern, dann kannst du dein delay() beibehalten.


-----------Dann versetze dich in die Lage!

Das Konzept "Zeitabhandlung mit millis()" und "Nebenläufigkeit" ist nur auf den ersten Blick kompliziert.
Das kann jeder verstehen und anwenden.
Es dauert allerdings manchmal etwas, bis der Groschen fällt.
Wichtig: Er muss bei dir fallen.

Das heißt, du solltest solange mit dem Konzept spielen, bis es richtig sitzt.
Und dann erst daran gehen, es bei dir einzubauen.

Tipp:
Der Kopf ist rund, damit das Denken die Richtung ändern kann.


---------

Ablaufsteuerung
Meine Standardantwort zu Ablaufsteuerungen:


Ja, mag sein...

Es ist allerdings eher die innere Ausrichtung unseres Trace841 welche modifiziert werden sollte.
Leider sind meine Ärmchen zu kurz.
Das muss er/sie/es selber machen.

Und wenn das verstehen von Nebenläufigkeit mit yield() dahin führt, soll es mir recht sein.
Wenn nicht, auch gut, dann nicht.



Vielen Dank für das mehrfache darauf Hinweisen meiner Unzulänglichkeiten.......





Title: Re: For Schleife geht nicht
Post by: Trace841 on Jun 19, 2019, 08:00 pm
Poste mal deinen aktuellen Code, Schaltplan und das iso der sd-Karte. Vielleicht packt mich ja mal der Ehrgeiz und ich baue es nach und schaue es mir genauer an.
Und wenigstens eine Beschreibung, für was das ganze ist und ggf. der Link, wo es herkommt.
Danke für deine Mühe. Hier der Code:


Code: [Select]
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);


// ===================== Variables =============================================================//
// -------  Declaring Pins ----------------------------------------------//
static byte disruptorPin = 9;
static byte enginePin = 6;
static byte pushButtonPin = 12;
static byte torpPin[] = { 2, 3 };

// -------  User Inputs ------------------------------------------------//
static unsigned long torpUpTime = 1680;
static unsigned long torpFlashTime = 200;
static unsigned long torpDownTime = 500;
static long double torpIdleBrightness = 20;
static long double torpMaxBrightness = 255;
static unsigned long engineFadePeriod = 3000;
static unsigned long disruptorFiringTime = 2400;

// -------  For the Button Pushing -------------------------------------//
unsigned long debounce = 50;
unsigned long holdTime = 1000;

// -------  Bookeeping ------------------------------------------------//
unsigned long currentMillis;
boolean buttonValue = false;
boolean buttonLast = true;
boolean ignoreUp = false;
unsigned long buttonUpTime;
unsigned long buttonDownTime;
unsigned int torpedoPushes = 0;
unsigned int disruptorPushes = 0;
unsigned long torpedoTime;
unsigned long disruptorTime;
unsigned long torpedoMillis;
unsigned long disruptorMillis;
unsigned long disruptorFlashTime;
boolean disruptorState = 0;

// ==================== End Variables ========================================================= //


// ===================== Setup ================================================================ //
void setup(){
  pinMode(disruptorPin,OUTPUT);
  pinMode(enginePin,OUTPUT);
  pinMode(pushButtonPin,INPUT_PULLUP);     // Enables internal pull-up resistor
  pinMode(torpPin[0],OUTPUT);
  pinMode(torpPin[1],OUTPUT);
  
  mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    while(true);
  }
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms
  myDFPlayer.volume(5);  //Set volume value (0~30).
  myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
  
}


// ===================== End Setup ============================================================ //



// ===================== Main Loop ============================================================ //
void loop() {
 unsigned long currentMillis = millis();         // get current time
  
 // ---------- Push Buttoon Code --------------------------------------------------------//

  buttonValue = digitalRead(pushButtonPin);
  
    // Record Time of Push
  if (buttonValue == false && buttonLast == true && (millis() - buttonUpTime) > debounce){
    buttonDownTime = millis();
    }
  
  // Record Time of Release
  if (buttonValue == true && buttonLast == false && (millis() - buttonDownTime) > debounce){
        buttonUpTime = millis();
        if (ignoreUp == false){
      disruptorTime = millis(); // If released early, fire disruptor!
      disruptorPushes++;
      myDFPlayer.playMp3Folder(2);
      }
      else{
       ignoreUp = false;
      }
   }

  // If push time is longer than threshold, fire torpedo!
  if (buttonValue == false && (millis() - buttonDownTime) > long(holdTime)){
    myDFPlayer.playMp3Folder(6);
    
delay (2300);
            
    buttonDownTime = millis();
    torpedoTime = millis();
    torpedoPushes++;
    ignoreUp = true;
    myDFPlayer.playMp3Folder(1);

     }
  
  
  // Record the button state for comparison in the next cycle
  buttonLast = buttonValue;    
 // -------------------------------------------------------------------------------------//
  
  
  
 // ---------- Torpedo Firing ----------------------------------------------------------//
 // Ramp Up Red LED, Flash White LED, then a Ramp Down of Red LED
  // Ramp Up

  
  if ((currentMillis-torpedoTime) < torpUpTime && torpedoPushes > 0){
    analogWrite(torpPin[1],torpIdleBrightness+(torpMaxBrightness-torpIdleBrightness)/torpUpTime*(currentMillis-torpedoTime));
    digitalWrite(torpPin[0], LOW);
    
    
  }  
  // Flash
  else if (((currentMillis-torpedoTime) > torpUpTime) && ((currentMillis-torpedoTime) < (torpUpTime+torpFlashTime)) && torpedoPushes > 0){
    analogWrite(torpPin[1], 0);
    digitalWrite(torpPin[0], HIGH);
    
  }
  // Ramp Down
  else if (((currentMillis-torpedoTime) > (torpUpTime+torpFlashTime)) && ((currentMillis-torpedoTime) < (torpUpTime+torpFlashTime+torpDownTime)) && torpedoPushes > 0){
    analogWrite(torpPin[1],torpMaxBrightness+(torpIdleBrightness-torpMaxBrightness)/torpDownTime*((currentMillis-torpedoTime)-(torpUpTime+torpFlashTime)));
    digitalWrite(torpPin[0], LOW);
    
  }  
  // Idle
  else{
    analogWrite(torpPin[1], torpIdleBrightness);
    digitalWrite(torpPin[0], LOW);
    
  }

  
 // ---------- Engine Fading ----------------------------------------------------------- //
  // Slow Up and Down Fade with Shorter Pusations
  int fadeValue = int(127.0+127.0/2.0*(1+(0.75*sin(2*PI*currentMillis/engineFadePeriod)+0.25*cos(14*PI*currentMillis/engineFadePeriod))));
  analogWrite(enginePin,fadeValue);

 
 // ---------- Disruptor Firing -------------------------------------------------------- //
  // Get Random On or Off Time Using getRandom() Function Below
  disruptorFlashTime = fmod(getRandom(), 4000UL) + 60UL;
  if (((currentMillis - disruptorTime) < disruptorFiringTime) && (disruptorPushes > 0)){
    if(currentMillis - disruptorMillis > disruptorFlashTime) {
      disruptorMillis = currentMillis;  
      digitalWrite(disruptorPin, disruptorState = !disruptorState);
      }
   }
   else{
     analogWrite(disruptorPin,5);
 
    }
 // ------------------------------------------------------------------------------------ //


}
// ===================== End Main Loop ======================================================== //




// ===================== Pseduo-Random Generator ============================================== //
// Found This Online. I Take No Credit for It.
unsigned long m_w = 1;
unsigned long m_z = 2;

unsigned long getRandom()
{
    m_z = 36969L * (m_z & 65535L) + (m_z >> 16);
    m_w = 18000L * (m_w & 65535L) + (m_w >> 16);
    return (m_z << 16) + m_w;  /* 32-bit result */
}
// ===================== End Pseduo-Random Generator ========================================== //



Du kannst x-beliebige kurze MP3´s nehmen. Ob der Sound zum Licht passt ist ja egal. Hab den Sound auch an die Dauer der Lichteffekte angepasst.

Einen Schaltplan gibts nicht. Ist aber auch nichts größeres. Wie vor den Variablen angegeben Pin 10 und 11 fürs Serial (an TX und RX vom DFPlayer). Der DFPLayer bekommt normal Spannung und einen kleinen <3W 8Ohm Lautsprecher.

disruptorPin = 9 ist PWM
enginePin = 6 ist PWM
torpPin[] = { 2, 3 }   3 ist PWM

Hier das Originalvideo:

https://www.youtube.com/watch?v=Lgc1hYGJDoI (https://www.youtube.com/watch?v=Lgc1hYGJDoI)


Es geht um Effekte für ein Modell aus Star Trek. enginePin 6 ist ein Flackern mit auf und runterglühen für Triebwerke. Der Disruptor ist das Aufblitzen einer Waffe, wie eine Schuss-Salve beim kurzen Betätigen des Tasters. Und beim Torpedo glimmt die LED in "Idle" nur leicht. Nach längeren gedrückt halten wird diese LED bis zum Maximum heller, gefolgt von einem weißen Blitz, gefolgt vom dunkler werden der LED (Duo-LED).

Das funktionert bisher auch. Habe die Zeiten etwas angepasst und auch den Tasterbefehl getauscht. Ebenfalls das zeitgleiche Abspielen von einem Sound für die Disruptor und einem anderen Sound für die Torpedos hatte ich nachträglich eingefügt und funktioniert.

Nun wollte ich noch einen Sound für das Betätigen des Tasters haben. Als akustische Bestätigung beim Drücken. Danach sollte dann der jeweilige Lichteffekt mit Sound abgespielt werden.