Arduino Forum

International => Deutsch => Topic started by: skyfox60 on Feb 15, 2020, 03:10 pm

Title: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 15, 2020, 03:10 pm
Hallo,

als blutiger Anfänger habe ich bezüglich LCD Display eine Frage.

Ich habe einen Sketch, der läuft soweit auch bestens. Nun möchte ich ein paar Werte in ein LCD Display schreiben., Ich weiß nur nicht, wie ich das ansteuern soll.

Der geamte Sketch läuft je Sekunde etwa 3 mal durch. Er ist also recht langsam.

Wenn ich nun die Werte nur 3 mal je Sekunde in das Display schreibe, dann wird das arg flackern.

Aus dem Grund habe ich bisher nie Displays verbaut. Schneller bekomme ich den Sketch auch nicht mehr, das ist schon ziemlich ausgereizt.

Eine Überlegung war, einfach zwischen jeder Zeile und der jeweils nächsten, immer wieder dasDisplay neu zu beschreiben, damit am Ende min so 25 Hz rauskommen, damit das Auge das als Schrift, und nicht als Geflacker wahrnimmt.

Bedenken machen mir da aber z.B. Befehle, wie Sensorabfragen, wo Daten hin und her fliessen, und allein dieser Schritt ja ein wenig dauern. Da kann man ja auch nicht zwischenfunken.
Waitstates wie z.B. 20000µs beim Einlesen eines Impulses von RC-Kanälen machen auch Todzeit, hat man meghrere davon, sammelt sich das.
Manchmal dauern berechnungen ja auch unterschiedlich lang, so das nie eine stabile Frequenz zu Stande kommt beim beschreiben des Displays.

Daher die Frage, wie bekommt ihr eure Programme so schnell, das die Displays genügent oft gefüttert werden, ohne das es ein Geflacker gibt. 25Hz ist ja so die untere Grenze, die das Auge noch als Dauernd an erkennt. Mehr wäre besser.
Laufen alle eure Programme in der praxis mehr als 25 mal die Sekunde komplett durch?

Bevor ich nun in ein Display investere, hätte ich gern gewussst, ob sich das lohnt.
Bisher reichen meine Programmierkenntnisse nicht recht weit.
Es ist halt nur blöd, sich durch Zählen von Tastendrücken, die aktuell eingegebenen Werte zu merken, die hätte ich gern auf dem Diplay.
Im konkreten Fall geht es um ein Thermostat, wo ich den Sollwert in °C ablesen können möchte.
Der soll dort angezeigt werden, auf ein Grad genau würde reichen, also eigentlich nur zwei Stellen.
Das °C braucht nicht, ich weiß ja das es eine Temperatur ist.
Vielleicht ist das auch einfacher mit einem simplen zweistelligen Sieben-Segment Baustein, aber ... keine Ahnung.
Vielleicht weiß jemand, wie ich das am besten löse.


Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 15, 2020, 03:18 pm
Du hast eine falsche Vorstellung davon, wie diese 16x2 LCD's funktiomieren.

Wenn Du da was drauf schreibst, zeigen die das selbständig dauerhaft an. Dass musst Du nicht dauernd refreshen. Es ist im Gegenteil eher nachteilig, wenn man da zu oft drauf schreibt. Das sollte man nur machen, wenn sich an dem angezeigten Text wirklich was ändert.

Ich wüsste kein LCD - weder rein Text noch Grafik - dass Du über den Ardino 'refreshen' müsstest.

Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: gregorss on Feb 15, 2020, 03:22 pm
[Geflacker]
Seit meinem ersten LC-Display in den 90ern habe ich nie eins gesehen, das geflackert hätte. Du Siehst einen Wechsel des Inhalts normalerweise nur, wenn es von Dir gewollt ist, ganz ohne Geflacker. Du aktualisierst den Inhalt und fertig.

Gruß

Gregor
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: HotSystems on Feb 15, 2020, 03:33 pm
Aus dem Grund habe ich bisher nie Displays verbaut. Schneller bekomme ich den Sketch auch nicht mehr, das ist schon ziemlich ausgereizt.
.....
Bevor ich nun in ein Display investere, hätte ich gern gewussst, ob sich das lohnt.
.....
Diese Invesatition lohnt sich bestimmt.

Wenn du mit den Beispielen der zugehörigne Library das dann aufbaust, wirst du sehen, da flackert nix.

Wernn doch, hast du etwas falsch programmiert und da können wir sicher helfen.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Whandall on Feb 15, 2020, 03:49 pm
Bedenken machen mir da aber z.B. Befehle, wie Sensorabfragen, wo Daten hin und her fliessen, und allein dieser Schritt ja ein wenig dauern. Da kann man ja auch nicht zwischenfunken.
Waitstates wie z.B. 20000µs beim Einlesen eines Impulses von RC-Kanälen machen auch Todzeit, hat man meghrere davon, sammelt sich das.
Man kann das (fast immer) auch so programmieren, dass loop dennoch sehr schnell wiederholt wird.
Würdest du deinen Kode posten, könnte man mehr dazu sagen.

Bevor ich nun in ein Display investere, hätte ich gern gewussst, ob sich das lohnt.
Ich schenk dir mal ein 'i', das hast du wohl verloren.  ;)

(https://forum.arduino.cc/index.php?action=dlattach;topic=664882.0;attach=346746)

2,81 € (freier Versand) für ein 16x2 LCD mit I2C Interface (https://www.aliexpress.com/item/32707720115.html) empfindest du als Investition?
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 15, 2020, 03:57 pm
Hallo zusammen,

erst einmal vielen Dank für die schnelle Hilfe.

Das heißt also, die Dinger haben einen Zwischenspeicher, der diese Aufgabe erledigt.

Das läßt vieles für mich jetzt in einem ganz anderen Licht erscheinen.

Ich beschäftige mich erst seit einem Monat mit dem Arduino überhaupt.
Bis dahin waren alle Dinge rund um ihn für mich Neuland.

Und vieles verstehe ich immer noch nicht.

Als Modellflieger dreht sich meine Programmiererei hauptsächlich um alles, was in, am, um um das Flugzeug passiert.

Das Thermostat soll einen Heizkoffer beflügeln. Die kann  man zwar auch fertig für 1,99 in China kaufen, aber das ist ja langweilig.  :)

Momentan versuche ich, die Sache mit den Timern zu verstehen, aber da tue ich mich echt schwer.
Werd mal einfach was damit programmieren, und experimentieren.

Ich brauche da was Ineinandergeschachteltes, was quasi im Hintergrund läuft.
Einfacher Timer, ok, das hab ich soweit gerafft.
ich möchte aber:

1 - 1,5 Sek. Aus
50µS an
50µS aus
50µS an
50µS aus
50µS an
50µ aus
50µS an
50µS aus
dann von Vorne, also wieder 1,5S Pause, und 4 mal 50µS an-aus usw.

Dazwischen kommen Dinge, wie Servopuls abfragen und andere Aus und Eingänge schalte.
Und ein Loop, der ca. 1,5 Sek. eh schon dauert für ein schwellendes Licht ( PWM steigt, fällt kontinuierlich. ) Möglicherweise kann man das sogar ebenfalls über einen zweiten Timer laufen lassen.
Ich weiß nicht.

Konventionell habe ich das gelößt, und es läuft auch Prima,
aber der Sketch ist dadurch sehr lang und unübersichtlich.
Geht, aber ist weit entfernt von auch nur annähernd professionell.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 15, 2020, 04:04 pm
Hallo Whandall,

danke für das "I", hatte ich übersehen beim Korrekturlesen.

Nun ja, es geht nicht um die ~3€.
Ich empfinde eine Investition dann als schlecht, wenn ich anschliessend nichts damit machen kann.

Da geht es weniger um die Höhe des Betrages, als um den zu erwartenden Erfolg der Aktion.
Die Erwartungshaltung hat sich ja durch die schnellen Antworten gerade deutlich nach oben bewegt.

Sogar so weit, das ich mehr ausgegeben habe, und eines gekauft hab, das von Deutschland versandt wird, um es schneller zu haben, und das hiesige Bruttosozialprodukt zu unterstützen. :)
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Serenifly on Feb 15, 2020, 04:18 pm
Der geamte Sketch läuft je Sekunde etwa 3 mal durch. Er ist also recht langsam.

Wenn ich nun die Werte nur 3 mal je Sekunde in das Display schreibe, dann wird das arg flackern.
Sooo extrem langsam sind die Displays auch nicht. Außerdem soll man das ja auch noch als Mensch lesen können.

Wodurch viele Anfänger Flackern produzieren ist indem sie das Display immer komplett löschen und dann neu beschreiben. Oder indem sie einzelne Zeilen komplett mit Leerzeichen überschreiben und dann den neuen Inhalt.
Richt macht man es wenn man seinen Text auf eine konstante Breite formatiert, alten Text direkt überschreibt und nur den Rest mit Leerzeichen auffüllt
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: gregorss on Feb 15, 2020, 04:22 pm
Ich beschäftige mich erst seit einem Monat mit dem Arduino überhaupt.
Bis dahin waren alle Dinge rund um ihn für mich Neuland.
Wenn Du auch Programmierneuling bist, solltest Du Dich vom Start weg darum kümmern, dass Dein Code gut aussieht (http://html.szaktilla.de/weekender/7.html). Wie sehr sowas bei der Fehlersuche hilft, lernst Du noch :-)))

Gruß

Gregor
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 15, 2020, 04:47 pm
Hallo Gregor,

ich geb mir ja schon Mühe. Hier mal mein Sketch für die Originalgetreue Beleuchtung eines Flugzeuges.

Code: [Select]
/*
  Scale like anticollision-light, strobe-light, NAV-lights and landing-light for RC-Aircraft

  Digital Channels Output
  NAV_light    = D5  ( Left = red, Right = green, Back = white ) digital out
  ACL          = D6  PWM _ Channel for intensity regulation ( ACL = Anticollision Light )
  Landinglight = D7  digital out
  Strobe       = D8  digital out
 
  Receiverchannel Inputs:
  Input a Servochannel from Receiver to D10, Try-State Switch is recommended ( 1000µs, >1500µs, 2000µs )
 
  In normal ( out ) condition ( a > 1400 a <2100 ) only the mainloop and ACL_only-routine is ruinning.
  This makes the ACL ( anticollision-light ) running as soon as the battery is plugged on and the lamp-test ist finished.
  I made this because in real aircraft the first action after switching the main switch on, is to activate the ACL, there should be no need to activate a switch at the transmitter for that.
  Also, the ACL remains Fading up and down, until battery is unplugged and aircraft save.
  If you have a transmitter that allowes the switch-position-test at the beginning, set it so that the light switch has to be in 2000µs position before transmitter starts.
  When switch in appx mid position ( a <1400 ) the ACL_NAV_Strobe-Loop runs. You find at first a similar routine like in ACL_only.
  This was required due to the need of some other values to have the same visiual appearence of ACL the and nearly continuing as it was.
  there is a Lamptest to check all lamps. 10 flashes wake up for you, followed by single test and finally 10 flashes to finish and exit to Mainloop.
 
*/

  int NAV_light = 5;
  int ACL = 6;                     // the PWM pin the LED is attached to
  int Landinglight = 7;
  int Strobelight = 8;
  int brightness = 7;              // how bright the LED is, 0 at startup
  int brightness_increment = 7;    // How many points increment or decrement per step to fade the LED, if you change this value ( default is 7 ), you have also to change the counter1 steps ( default is 68 ), just for the case you changed it and do not remember
                                   // Also max Brightness has to be altered, if you cange any of the values. ( default is 231 )

                                 
  int counter1 = 1;
  int counter2 = 0;


void setup()
{

  pinMode(5, OUTPUT);              // NAV_light
  pinMode(6, OUTPUT);              // output ACL
  pinMode(7, OUTPUT);              // output Landinglight
  pinMode(8, OUTPUT);              // putput Strobelight
  pinMode(10, INPUT);              // reads a and cycles ACL and Strobelight
}


// the loop routine runs over and over again forever:
void  loop() {
Serial.begin(9600);
goto Mainloop;
// Lamptest to check all lamps. 10 flashes wake up for you, then single test and then 10 flashes finish and exit to Mainloop

  for ( int L1 = 0; L1 <= 10; L1++ )
{
  digitalWrite (Strobelight,HIGH); ; digitalWrite(NAV_light, HIGH);  digitalWrite(ACL, HIGH);  digitalWrite(Landinglight, HIGH); delay(50);
  digitalWrite (Strobelight,LOW); digitalWrite(NAV_light, LOW);  digitalWrite(ACL, LOW);  digitalWrite(Landinglight, LOW);delay(50);
}
  for ( int L = 0; L <= 1; L++) { digitalWrite (NAV_light, HIGH); delay(300);  digitalWrite (NAV_light, LOW);delay(300); digitalWrite ( ACL, HIGH ); delay(300); digitalWrite ( ACL, LOW );delay(300); digitalWrite (Landinglight,HIGH);
  delay(300); digitalWrite (Landinglight,LOW);delay(300);  digitalWrite (Strobelight,HIGH);delay(300);digitalWrite (Strobelight,LOW);delay(300);
}
  for ( int L1 = 0; L1 <= 10; L1++ )
{
  digitalWrite (Strobelight,HIGH); ; digitalWrite(NAV_light, HIGH);  digitalWrite(ACL, HIGH);  digitalWrite(Landinglight, HIGH); delay(50);
  digitalWrite (Strobelight,LOW); digitalWrite(NAV_light, LOW);  digitalWrite(ACL, LOW);  digitalWrite(Landinglight, LOW);delay(50);
 
}


  Mainloop:;   
 
 // digitalWrite(ACL,brightness);
  counter1 = 1;
  counter2 = 0;
 
  int    a = pulseIn(10,HIGH,25000);        // Read in pulse lenght, 3rd parameter has to be finetuned with receiver behavior
 
  if ( a >=1600 & a <=2100 ) { digitalWrite (NAV_light, LOW);  digitalWrite (Landinglight, LOW); goto ACL_only; }
  if ( a >950 & a <1200 ) { digitalWrite (Landinglight, HIGH); }
  if ( a >1200 ) { digitalWrite (Landinglight, LOW);  }
  if ( a >=950 & a <=1600) { digitalWrite (NAV_light, HIGH); goto ACL_NAV_Strobe; }
 
 
       
  ACL_only:; 
 
   analogWrite(brightness, 7);
   for (brightness <=7; brightness <252; brightness = brightness + brightness_increment){ analogWrite(ACL, brightness); delay(20); Serial.println(brightness); }   
   for (brightness <=253; brightness >=7; brightness = brightness - brightness_increment){ analogWrite(ACL, brightness); delay(30); Serial.println(brightness); }
     
   delay(400); // this delay is importand to have not jump in the brightness of ACL when switching NAV-lights and strobe on and of. do not change this value.
 
  goto Mainloop;
 

 
  ACL_NAV_Strobe:;
 
  counter1 = counter1+1;
 
  analogWrite(brightness, 7); // brightness = 7; // for synchronisation, to have small remaining brightness at the lower end, like a downgoing bulb at the ACL
   for (brightness <=7; brightness <252; brightness = brightness + brightness_increment){ analogWrite(ACL, brightness); delay(20); Serial.println(brightness); }   
   for (brightness <=253; brightness >=7; brightness = brightness - brightness_increment){ analogWrite(ACL, brightness); delay(30); Serial.println(brightness); }
    // this two lines became necessary to synchronize the status of the ACL brightness when switching NAV lights and strobe on and off.
    //without the repeat of that two lines, a small jump occures, that is visible. Took me time to find out:) 
 
 
 
// the loop function Strobe runs 4 times ( 4 flashes ) and returns to Mainloop to check again the switch ( pulse ) status.

  Strobe:;
 
  counter2 = counter2+1; 
  digitalWrite(Strobelight, HIGH);         // turn the LED on by making voltge HIG
  delay(40);                               // wait for 50ms on time
  digitalWrite(Strobelight, LOW);          // turn the LED off by making the voltage LOW
  delay(60);   // wait for a second        // Wait for 50ms off time
  if ( counter2 == 4 ) { goto Mainloop; }  // the 4 is the number of flashes in each cycle
  { goto Strobe; } 

}
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Serenifly on Feb 15, 2020, 05:02 pm
Goto solltest du dir sofort abgewöhnen. Es gibt ein paar Nischen-Anwendung dafür, aber nicht hier

Und so viele Anweisungen in einer Zeile ist auch nicht gut. Eine oder zwei kurze danach sind ok, aber so ist das unübersichtlich. Und eine Anweisung direkt dahinter macht man eigentlich um sich die Klammern zu sparen:
Code: [Select]

if ( a >950 & a <1200 ) { digitalWrite (Landinglight, HIGH); }

Wenn dann so:
Code: [Select]
if ( a >950 & a <1200 ) digitalWrite (Landinglight, HIGH);
Oder:
Code: [Select]

if ( a >950 & a <1200 )
  digitalWrite (Landinglight, HIGH);
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: noiasca on Feb 15, 2020, 05:03 pm
vereinfacht gesagt:

STRG-T drücken in der IDE, damit man die Einrückungen besser sieht.
kein Delay verwenden.
kein Goto verwenden.

alle int überprüfen ob sie int sein müssen.

Sonst noch Fragen?

Lege deinen Sketch zur Seite, mach eine klare Aufstellung, welche Lampe in welchem Rhytmus blinken soll und wie die Lampen zueinander in Beziehung stehen. Mit Delay und Goto wird das nix.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 15, 2020, 05:37 pm
Hallo Fuchs des Himmels ;)

Da hat man dir ja schon so allerhand von deinem Sketch zerrissen ;) . Aber es stimmt schon - so einige grundsätzliche Fehler sollte man von Anfang an vermeiden, damit man sie sich garnicht erst angewöhnt.

Vielleicht kannst Du auch meine MobaTools (https://github.com/MicroBahner/MobaTools) gebrauchen. Damit ist z.B. das Faden von Leds genauso einfach wie das harte Ein- und Ausschalten. Auch das Vermeiden von delay's geht damit ein wenig einfacher und übersichtlicher als die direkte und 'harte' Tour mit den millis().
Installieren kannst Du die direkt über den Bibliotheksverwalter in der IDE (Strg+Shift+I und dann im Suchfeld mobatools eingeben ).

Auch musst Du dir genauer überlegen, was inn setup(), und was in loop() gehört. Alles was nur zum Start des Sketches einmalig gemacht werden soll/muss gehört ins setup() - z.B. auch das Serial.begin(). Auch die Testroutine für deine Beleuchtung solltesr Du dahin verschieben. Das wird dann bei jedem Start des Sketches einmal gemacht, und dann geht's erst los mit der eigentlichen Funktionalität.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 15, 2020, 05:46 pm
Yep, da simmer schon beim Thema.

Hab mal was mit millis probiert.
Erwartungsgemäß funktioniert das nicht so, wie ich das gerne hätte.

Anbei das Beispiel:

Die intere LED flasht mit 50 mills, also ein Bltzlicht.

Code kopiert und hochgeladen, und läuft.

Sobald aber daneben andere Dinge laufen, passt das nicht mehr. Die Led geht jetzt ganz lansam, das "daneben" verzögert alles.
Frage??:
Wo ist da der Denkfehler?

Code: [Select]
unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 50;  //the value is a number of milliseconds

const byte ledPin = 13;    //using the built in LED

void setup()
{
 
  Serial.begin(9600);  //start Serial in case we need to print debugging info
  pinMode(ledPin, OUTPUT);
  startMillis = millis();  //initial start time
}

void loop()
{
  currentMillis = millis();  //get the current "time" (actually the number of milliseconds since the program started)
  if (currentMillis - startMillis >= period)  //test whether the period has elapsed
  {
    digitalWrite(ledPin, !digitalRead(ledPin));  //if so, change the state of the LED.  Uses a neat trick to change the state
    startMillis = currentMillis;  //IMPORTANT to save the start time of the current LED state.
  }

 // Bis hier funktionierte das. Unten stehendes soll einen längeren Programablauf simulieren
 // währed dessen aber das Blitzen oben munter weiter laufen sollte.
 
   for (int a=1; a<200; a++)
  {
    Serial.println ("waiting");
  }
 
}
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 15, 2020, 05:56 pm
Deine for-Schleife ist praktisch ein 'delay'. Wenn das mit den millis funktionieren soll, muss der gesamte Ablauf im loop so geschrieben werden, dass nichts blockiert bzw wartet.

Edit: hast Du früher auch mal 'Eisenbahn' gespielt und Züge im Kreis fahren lassen? Für das Vermeiden von delay habe ich mal ein Tutorial (https://www.stummiforum.de/viewtopic.php?f=21&t=163493) geschrieben, wo das mit einer im Kreis fahrenden Lok erklärt wird.
Ansonsten gibt's noch die 'Nachtwächtererklärung'.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: noiasca on Feb 15, 2020, 06:06 pm
ich hab da was in der Bastelkiste.
Verschiede Leuchten mit verschiedenen Blink-Mustern.

Jede einzelne Leute macht nach dem Muster "BlinkWithoutDelay" ihr Ding.

du legst nur neue Objekte an wo du den Pin bekannt gibst, und im Loop gibst du jeder Leuchte eine Zeitscheibe.

Code: [Select]

/* Blink a LED in a specific rhythm

  Turns on and off light emitting diodes (LED) connected to a digital pin,
  without using the delay() function. This means that other code can run at the
  same time without being interrupted by the LED code.

  noiasca
  2019-05-05

*/

class BlinkLed {
    byte state = 1;       // 1 blink, 0 off
    unsigned long previousMillis;
    uint16_t on = 180;
    uint16_t off = 320;   // 180/320 is according ECE
    const byte ledPin;

  public:
    BlinkLed(byte attachTo):
      ledPin(attachTo)
    {}

    void begin()
    {
      pinMode(ledPin, OUTPUT);
    }

    void set(uint16_t _on, uint16_t _off)  // modify on/off times during runtime
    {
      on = _on;
      off = _off;
    }

    void setState(byte _state)            // 1 Switch on blinking; 0 switch off blinking
    {
      state = _state;
    }

    void tick()
    {
      if (state)
      {
        uint32_t currentMillis = millis();
        if (digitalRead(ledPin) && currentMillis - previousMillis >= on) {
          // save the last time you blinked the LED
          previousMillis = currentMillis;
          digitalWrite(ledPin, LOW);
        }
        if (!digitalRead(ledPin) && currentMillis - previousMillis >= off) {
          // save the last time you blinked the LED
          previousMillis = currentMillis;
          digitalWrite(ledPin, HIGH);
        }
      }
    }
};

class RhythmLed {
    byte state = 1;
    unsigned long previousMillis;
    const byte ledPin;
    uint8_t lengthOfPattern;
    // the intervall pattern
    //                          ON    OFF  ON   OFF
    //                          1     2    3    4
    uint16_t intervall[5] = {0, 150,  60, 20, 270};                  // ECE 2
    //uint16_t intervall[3] = {0, 180, 320};                         // ECE 1
    //uint16_t intervall[7] = {0, 25, 25, 25, 25, 25, 375};          // HELLA 3
    //uint16_t intervall[9] = {0, 40, 40, 40, 40, 40, 40, 40, 220 }; // HELLA 4
    //uint16_t intervall[5] = {0, 150,  60, 20, 400};                // wie gewünscht vom TO

  public:
    RhythmLed(byte attachTo):
      ledPin(attachTo)
    {}

    void begin()
    {
      pinMode(ledPin, OUTPUT);
      lengthOfPattern = sizeof(intervall) / sizeof(intervall[0]);
    }

    void setState(byte _state)
    {
      state = _state;
    }

    void setIntervall(uint16_t _intervall1, uint16_t _intervall2, uint16_t _intervall3, uint16_t _intervall4)       // Modify the intervalls to your needs
    {
      intervall[1] = _intervall1;
      intervall[2] = _intervall2;
      intervall[3] = _intervall3;
      if (lengthOfPattern>3) intervall[4] = _intervall4;   // if someone declares a dual-intervall, this line would crash the sketch, therefore this if on the index length ;-)
    }

    void tick()
    {
      uint32_t currentMillis = millis();
      if (state > 0)                            // iterate through the states 1 to n, we don't use state 0 because state 0 is reserved to "switch off" the light
      {
        if (currentMillis - previousMillis > intervall[state])
        {
          if (state % 2 == 1)  // all uneven states are ON, at the end of an intervall we switch to the oposite pin state
          {
            digitalWrite(ledPin, LOW);
          }
          else
          {
            digitalWrite(ledPin, HIGH);
          }
          state++;
          if (state > lengthOfPattern - 1) state = 1;
          previousMillis = currentMillis;
        }
      }
    }
};

BlinkLed myBlinkLed(5);       // a simple blink led
RhythmLed topRKL(13);         // define an output PIN for your LED
RhythmLed outOffSyncRKL(6);  // eine Rundumkennleuchte die wegen eines "Massefehlers" am Originalfahrzeugs eine leicht verschobene Blinkfrequenz hat ;-)

void setup()
{
  myBlinkLed.begin();
  topRKL.begin();
  outOffSyncRKL.begin();
  outOffSyncRKL.setIntervall(250,  90, 30, 400);  // Modify the intervalls for this LED
}

void loop()
{
  myBlinkLed.tick();  // each object has to be called once in the loop
  topRKL.tick();
  outOffSyncRKL.tick();

  // put here other code which needs to run:

}


ausschalten einfach mit .setState(0) bzw. ein mit .setState(1)

Wenn dir das Konzept behagt, dann sag was du an Mustern brauchst, ich denke das geht ziemlich einfach. Die nächsten 45min bin ich noch online.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 15, 2020, 07:49 pm
Also es passiert folgendes:

Fall 1:
Nach dem einschalten geht zwangsweise eine LED in den Lampenmodus. Anschwellen, Abschwellen.
Das soll auch so bleiben, bis zum Ausschalten.

Daneben wird ständig  ein Impuls abgefragt, der zwischen 1000 und 2000µS lang sein kann.
Default aus ist bei mir alles was >1800&<2100 z.B. ist ( man braucht da ein wenig Luft, weil es schon mal ein parr µS mehr oder weniger sein können, die übertragen werden. pulseIn(x, HIGH, 25000)
die 25000 müssen sein, weil der Impulse nicht öfter kommt.

Geht der Impuls etwa in die Mitte ( 1400µS - 1600µS ), dann passieren 2 Dinge.

Fall 2:
-1. Ein Ausgang wird auf Dauer EIN gesetzt ( NAV-Lichter ).
-2. Ein weiterer Ausgang geht jetzt auf Strobe.
Das heißt 4 mal hintereinander 50mS an, 50mS aus( 40 an, 60 aus ist auch ok ). Danach hat er eine Pause von 1 - 1,5 Sek.

Nun gibt es 3 Möglichkeiten

1. Der Puls bleibt so, es läuft also Fall 1 ( ist ja immer an, und Fall 2 )

2. Der Puls geht zurück auf 2000> es läuft wieder nur Fall 1

3. Der Puls geht auf 1000 ( also 950 bis 1050 )

Dann laufen Fall 1 ( immer an ), Fall 2 läuft weiter
Aber es kommt in weiterer statischer Ausgang hinzu, nämlich der Landescheinwerfer.

Dann ist also alles an.

Üblicherweise soll nach der Landung zunächst der Landescheinwerfer abgeschaltet werden,
also von etwa 1000µS zurück nach 1500µS. Danach erst NAV und Strobe, während das ACL ( Fall 1 ) weiterläuft bis zur Stromlosigkeit.

Dazu soll es aber auch möglich sein, von Fall 1 direkt zu Fall 3 zu springen.
Impulse von 2000 auf 1000µS ( Dann laufen wieder alle 3 Fälle )
Und natürlich von 1000µS zurück auf 2000µS so das dann Fall 3 und Fall 2 abgeschaltet werden und wiederum nur Fall 1 läuft.


Und btw. Das macht mein vorhin geposteter Spagetthi-Code vom allerfeinsten.

Das schwierigste daran war, das man im Auf- und Abschwellen keinen Sprung sehen kann, egal, ob gerade der Puls abgefragt und umgeschaltet wird oder nicht. Dafür sorgt z. B: das an der einen Stelle eingefügte delay von 400mS ist genau die Zeit, die ansonsten die Strobes brauchen, wenn sie zugeschaltet sind.

Sind die ausgeschaltet, gilt das delay, sind sie eingeschaltet, brauchen sie genau diese Zeit, daher blitzt es immer in der Pause, die sowieso da ist. Das hat Kaffee verbraucht, bis das so geschmeidig lief.

Ja, das mit dem Code sieht noch so aus, wie früher Basic auf dem C-64, ich weiß, da war ich aber auch noch jung aund aufnahmefähig, das hat sich so also eingebrannt. Alles Versuche, den Spagetthi-Code ohne Goto hinzukriegen schlugen fehl, und ich war happy, als das nachher alles lief.

Er sieht halt nur nicht schön aus :)  :)  :)
Das war für mich schon eine Leistung, nach einem halben Monat, so tolle Spagetthi zaubern zu können.

Deinen Vorschlag habe ich mir gerade runtergeladen und probiere damit rum.
Richtig verstehen tu ich ihn aber keineswegs, nur Ansatzweise.

Und die Beschreibung vom MoBahner lese ich auch gerade mit Interesse.
Das ist schon verständlich, und die Library hab ich auch schon installiert.

Das mit den Gleisen ist bildlich nachvollziehbar. Und eine Idee, was ich genau daraus machen könnte hab ich auch schon, verbunden mit einer Passage aus dem Vorschlag von dir.
Den müsste ich nur noch passend separieren, und da tue ich mich halt schwer.

Wenn ich also nicht gleich wieder antworte, dann lese ich, mache Versteh-Versuche oder probiere gerade wieder rum.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 15, 2020, 09:28 pm
@ Microbahner:

jetzt hab ich den kompletten Thread mit dem Wechselblinker und der Kreuzung gelesen.
Und tatsächlich, ich konnte das nachvollziehen. Ich könnte ihn jetzt nicht selbst programmieren, aber ich hab einigermassen verstanden, worum es da geht.

Da läßt sich einiges draus anpassen für andere Dinge.

Einzige Bauchschmerzen, die ich da grad habe sind folgende:

Die BueBelegt Abfrage ist hier "nur" das Einlesen eines Kontaktes.

Wenn ich das mittels einer Fersteuerung machen will, dann wird ja per Schalter am Sender z.B. ein Impuls von 1000 auf 2000µS geschaltet. Der Impuls wird alle 20mS ( etwa ) wiederholt.

Dazu verwendet man etwa Wert = pulseIn(x, HIGH, 25000)

Die Todzeit von 25mS benötigt man, um Sicher einen Impulse-rise zu erwischen, wonach die Pulslänge dann gemessen wird.

Da bremse ich doch durch die Todzeit das System um 25mS aus, oder verstehe ich das falsch?
Da ich ja ständig darauf schauen muss, ob der Schalter umgelegt, sprich, der Puls sich verändert hat, muss das bei jedem Loop-Durchlauf einmal abgefragt werden. Das summiert sich.

Da es sich jedoch nicht um eine Ampel handelt, sondern lediglich um schnöde Licht an- Licht aus abfragen, die nicht eben Zeitkritisch sind, handelt, könnte man ja vielleicht ( ich nur mal wieder nicht wie ) die Pulseabfrage auch mit einem Timer steuern, und nur alle 1 - bis 2 Sekunden mal fragen, wie der Puls ausschaut. Wenn ich schalte, und der Landescheinwerfer geht erst nach ein bis zwei Sekunden an, ist das nicht schlimm. Wenn ich meinem Flugschüler sage, Landing light on, braucht der jedenfalls mindestens genauso lang.

Wie würdest du das Wert = pulsIn(x,y,z) da rein schleusen?
Also in den Wechselblinker, Ampeln gibt es ja in der Luft nicht.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 15, 2020, 09:36 pm
Hi

Lese Dir die Nachtwächtererklärung durch.

Hat dann doch länger gedauert, als ich vermutet habe ...
Der Sketch lässt die Strope-Blitz-Leuchten ... äh ... blitzen ;)
Der benutzte Pin, wie die Zeiten für an/aus/Pause lassen sich im Code ändern.
Code: [Select]
//Forensketch, Nachtwächer für Strope-Blitzleuchten an Flugzeug

bool stropeaktiv = true;     //Hierdurch lässt sich das Strope-Licht an/aus schalten
const byte _pinStrope = 13; //Pin der Strope-LED

//Das heißt 4 mal hintereinander 50mS an, 50mS aus( 40 an, 60 aus ist auch ok ). Danach hat er eine Pause von 1 - 1,5 Sek.
const uint32_t StropeAN = 50; //wie lange ist der Blitz an?
const uint32_t StropeAUS = 50; //wie lange ist der Blitz aus? (denke 10/90 sieht besser aus)
const uint32_t StropePause = 1500; //die Pause zwischen den Blitzfolgen
const byte StropeCount = 4;   //Anzahl der Blitzfolgen vor Pause

void setup() {
  Serial.begin(9600);
  pinMode(_pinStrope, OUTPUT);
  Serial.println("Start");
}

void loop() {
  checkStrope();  //Strope-Light aufblitzen lassen, wenn erwünscht

  //Folgende Zeilen schalten 'nur' Strope an und aus - alle 15 Sekunden
  static uint32_t lastmillis = 0;
  const uint32_t changestrope = 15000;
  if (millis() - lastmillis >= changestrope) {
    stropeaktiv = !stropeaktiv;
    Serial.print("Strope:");
    Serial.println(stropeaktiv);
    lastmillis = millis();
  }
}

void checkStrope() {
  boolean _set = false;   //Merker, daß Ausgangspin gesetzt werden soll
  static byte statusStrope = 0; //bei welchem Impuls sind wir gerade?
  static uint32_t laststrope = millis(); //mit aktueller Uhrzeit initialisieren

  if (stropeaktiv) {
    //soll geblitzt werden?
    //Außer beim ersten Aufruf (Null) die Wartezeit warten
    //AN, AUS, Pausenzeit kann separat angegeben werden
    uint32_t wartezeit = (statusStrope == StropeCount * 2) ? StropePause : (statusStrope % 2) ? StropeAN : StropeAUS;
    if (millis() - laststrope > wartezeit || !statusStrope) {
      statusStrope++; //nach Warten, Status erhöhen
      if (statusStrope > StropeCount * 2) statusStrope = 1; //und über Maximum umbrechen
      _set = true;  //wir haben die LED umzuschalten
      laststrope = millis();  //und merken uns, wann wir Das gemacht haben
    }
  } else if (statusStrope % 2) {
    //Strope ist AUS, deshalb hier ausschalten, wenn die LES gerade an ist.
    statusStrope = 0; //beim nächsten Aktivieren fangen wir wieder vorne an
    _set = true;      //wir haben den Pin umzuschalten
  }
  if (_set) {
    digitalWrite(_pinStrope, statusStrope % 2); //aus dem Status wird der Zustand der LED berechnet
    Serial.println(statusStrope);
    _set = false;   //LED ist umgeschaltet, also den Merker auf false zurück
  }
}

Das mit PulseIn ist schon etwas schwierig.
Man müsste 'schauen', ob die Zeit gekommen ist, daß man auf den Impuls wartet.
Da der Impuls alle ca. 25ms wiederholt wird, sollte sich Das auch per millis() erschlagen lassen, wann man auf den Impuls wartet.
Dann aber mit einem TimeOut von maximal 2000ns - der maximal zu erwartenden Länge.
Wir wollen einen Impuls einlesen, nicht den Rest des Winters hier festsitzen!

Der Sketch hier rast 1,7 Millionen Mal beim Blinken durch loop() und fast 2,7 Millionen Mal, wenn Das nicht gefragt ist.
Trotz der seriellen Ausgaben mit 9600 Baud !! (jedes Zeichen braucht eine ms Zeit)

Das sollte ausreichen, um sich auch auf das regelmäßig wiederkehrende Sender-Signal einzuschießen.

MfG
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 15, 2020, 09:50 pm
Da bremse ich doch durch die Todzeit das System um 25mS aus, oder verstehe ich das falsch?
Das verstehts Du schon richtig - pulseIn ist blockierend, eigentlich auch sowas wie ein delay().
Damit dreht die 'Lok' ;) ihre Kreise natürlich erheblich langsamer. Wenn Du mit den langsameren Reaktionszeiten auskommst, sollte das aber trotzdem funktionieren. Du kannst dann halt keinerlei Aktionen machen, die in einem schnelleren Takt als diese 25ms ablaufen.

Da es sich jedoch nicht um eine Ampel handelt, sondern lediglich um schnöde Licht an- Licht aus abfragen, die nicht eben Zeitkritisch sind, handelt, könnte man ja vielleicht ( ich nur mal wieder nicht wie ) die Pulseabfrage auch mit einem Timer steuern, und nur alle 1 - bis 2 Sekunden mal fragen, wie der Puls ausschaut.
Grundsätzlich kann man so eine pulsIn-Messung auch nicht blockierend machen. Wenn dein loop schnell genug ist, dann einfach durch Abfrage des PinStatus, und mit micros() die Zeit zwischen steigender und fallender Flanke messen ( wobei Du den loop zwischen den Flanken natürlich weiterlaufen lässt - sonst ist es ja wieder blockierend). Deine Pulsmessung ist dann eben auch wieder so ein Abschnitt im loop wie die anderen auch: Bei der steigenden Flanke merkst Du dir die micros(). Wenn sich am Pin nichts ändert, geht es einfach durchs 'leere Gleis'. Bei der fallenden Flanke liest Du wieder die micros() und bildest die Differenz.
Je nachdem, was Du noch im loop machst, könnte da die Auswertegenauigkeit aber schon knapp werden. Ansonsten über einen Interrupt-Eingang, der die Pulsflanken erkennt, und dann in der ISR mit micros() die Zeit dazwischen bestimmen.

Die Frage ist, ob das für dich notwendig ist, oder ob du mit deinem 25ms-Raster im loop auskommst. Wenn ja, bestimmst Du am Anfang des loop deine Pulslänge mit pulsIn, und setzt dem entsprechend eine Variable ( so wie im Tutorial das 'bueBelegt'), die Du dann an den jeweiligen Stellen im loop auswerten kannst.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 09:10 am
@ postmaster.ino

in deinem Sketch verstehe ich ein paar Dinge nicht.
Suchen hat da ebenflls nicht zum Erfolg geführt:

1. statusStrope == StropeCount * 2, da verstehe ich das *2 nicht

2. digitalWrite(_pinStrope, statusStrope % 2), da verstehe ich das %2 nicht

3. if (millis() - laststrope > wartezeit || !statusStrope),

das Unterstrichene, was genau ist das in dem Fall, wartezeit ODER !statusStrope, was wird hier in dem konkreten Fall verglichen?

4. Dann aber mit einem TimeOut von maximal 2000ns - der maximal zu erwartenden Länge.

Das verstehe ich nicht, wieso nur 2mS (2000nS).
Das ist zwar die max. Pulslänge, jedoch ist zwischen zwei Pulsen immer so um die 20 - 25,
manchmal sogar 30 mS Pause.

Der Sender sendet z. B. 8 Pulse hintereinander. Im Empfänger werden diese über ein Schieberegister an die einzelnen Steuerkanäle ausgegeben. Dann folgt eine längere Pause, das Schiebergister setzt zurück.

Es kommt also ein Puls aus meinem Steuerkanal raus, danach werden erst mal alle anderen Kanäle bedient, dann die Pause, und dann geht der Zirkus von vorne los.
Warte ich also nur 2000nS und frage dann ab, greif ich in Pausenloch.
Ich müsste innerhalb dieser kurzen Zeit zufällig auf eine aufstegende Flanke stoßen, dann würde es ausnahmsweise zu einem Ergebnis führen.

Beim Steuern eines Flugzeuges ist Zufall aber kein Freund:)
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 09:28 am
@MoBahner

Du hast geschrieben
Grundsätzlich kann man so eine pulsIn-Messung auch nicht blockierend machen. Wenn dein loop schnell genug ist, dann einfach durch Abfrage des PinStatus, und mit micros() die Zeit zwischen steigender und fallender Flanke messen ( wobei Du den loop zwischen den Flanken natürlich weiterlaufen lässt - sonst ist es ja wieder blockierend). Deine Pulsmessung ist dann eben auch wieder so ein Abschnitt im loop wie die anderen auch: Bei der steigenden Flanke merkst Du dir die micros(). Wenn sich am Pin nichts ändert, geht es einfach durchs 'leere Gleis'. Bei der fallenden Flanke liest Du wieder die micros() und bildest die Differenz.
Je nachdem, was Du noch im loop machst, könnte da die Auswertegenauigkeit aber schon knapp werden.

Zitat Ende

Das kling hoch interessant.
Ich krieg das nur noch nicht prakttisch umgesetzt.
Könntest du mir da ein wenig helfen?
mein pulseIn ist der Pin D10
Das scheint mir komplex, da es nicht um HIGH oder LOW allein geht, sondern beim Wechsel ja eine Zeitmessung gestartet wird, und wiederum beim Wechsel auf low gestoppt wird.
Da komm ich ehrlich gesagt noch nicht so recht mit wie das gehen soll.

Wenn der Puls dann erfasst ist, müsste ich die 3 Zeitspannen, die in Frage komme ja auch noch irgendwie routen

if x > y & < z, Fall  1

if x > a & < b, Fall  2

if X > d & < e, Fall  3

wobei

Y=1900µS(minus max. Messfehler)
z=2100µS ( plus max. Messfeheler)

a=1400µS
b=1600µS

d=900µS
e=1200µS

Grob müssten wir also den Bereich von 900 bis 2100µS erfassen können

Aber:
Bitte nur, wenn Zeit und Lust ist, keine Hetze und keine Notwendigkeit.
Bin eh schon allen Dankbar, die mir hier so toll auf die Sprünge helfen.

Bin selbst eher der analog-Techniker ( Radio-Fernseher( analoge)) das ist so meine Technik Welt.
Ich kann einen Röhrenfernseher noch reparieren. Digitaltechnik ist für mich neu.
Und Programmiersprache, wie man an meinen Fragen erkennt ist für mich, wie wenn ich chinesische Schriftzeichen lesen sollte.
Jedes Wort neu.
Selbst die neuen programmierbaren Fersteuerungen machen mir so manches mal auch Kopfzerbrechen.





Jetzt muss ich leider erst mal off.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: noiasca on Feb 16, 2020, 09:34 am
2.     %2 ist eine Modulo-Division. Alles durch 2 und du bekommst den Rest (bei Modulo 2 eben 0 oder 1)


3.  !  negiert den Ausdruck. Also in dem Fall "nicht StatusStrope"
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 16, 2020, 10:20 am
Hi
Quote
1. statusStrope == StropeCount * 2, da verstehe ich das *2 nicht
1. ist nur ein Vergleich.
Da ich für jedes Blitzen zwei Status 'verbrauche' (1x an, 1x aus), nutze ich StropeCount (Anzahl der Blitze) Mal 2 als das Maximum der Status, Die mit einem Blitz zu tun haben.
Da wir bei 0 mit Zählen beginnen, ist die 8 bereits außerhalb, wir warten das Ende der Pause ab.
Nach Deren Ende wird statusStrope bereits wieder um 1 erhöht, daher die Abfrage auf 9 und das Setzen dann auf 1.
Quote
2. digitalWrite(_pinStrope, statusStrope % 2), da verstehe ich das %2 nicht
2. da sich der LED-Zustand mit meiner Status-Variable immer ändert, kann ich prüfen, ob Diese ungerade oder gerade ist.
Ein gerader Status % 2 --> 0, was gleichbedeutend mit LOW (oder auch FALSE) ist.
Im Gegenschluss ist TRUE und HIGH identisch mit 1 (bzw. eher mit !0 ... Nicht Null).
Quote
3. if (millis() - laststrope > wartezeit || !statusStrope)
Wenn die Funktion das erste Mal aufgerufen wird, ist der Status 0.
Hier will ich ja nicht, daß erst gewartet wird, sondern die LED soll DIREKT den Zustand wechseln.
Dafür ist das "|| !statusStrope".
Wenn statusStrope ungleich Null ist, wäre Das 'true', durch das ! wird der Wahrheitswert umgedreht.
NOT statusStrope greift also, wenn der Status Null ist.
Davor habe ich die Abfrage, ob die Wartezeit bereits um ist.
Wenn nun Eine der beiden Bedingungen zutrifft (wegen dem || ODER), wird die IF ausgeführt.
Status wird erhöht und die LED (weiter unten, durch _set=true) auf den Zustand von statusStrope gesetzt.
Quote
4. Dann aber mit einem TimeOut von maximal 2000ns - der maximal zu erwartenden Länge.
Das verstehe ich nicht, wieso nur 2mS (2000nS).
Das ist zwar die max. Pulslänge, jedoch ist zwischen zwei Pulsen immer so um die 20 - 25,
manchmal sogar 30 mS Pause.
4. Jain.
Mein Sketch kommt momentan über 100000x die Sekunde durch loop() durch.
Somit komme ich alle 1/100stel Millisekunde vorbei und könnte nachschauen, ob's langsam Zeit ist, auf den Puls zu warten.
Ich muß ja nicht 30ms Warten, wenn der Puls gerade erst fertig geworden ist - MINDESTENS die nächsten 20ms kann ich machen, was ich will - es wird dort ganz sicher kein neuer Impuls kommen!
Aber Das könnte man per Interrupt angehen, dort müsste man sich ein Flag setze (bool oder byte) und die Impulslänge.
Da der Impuls nur 'alle Jubeljahr' Mal kommt, müssen wir die Impulslänge noch nicht Mal atomar auslesen (was man sonst mit Variablen, Die sowohl IN, wie auch AUSSERHALB einer ISR benutzt werden und größer als die Prozessorbreite sind(beim AVR Arduino 8 Bit, beim ESP wohl 32 - hier bitte Belehrung!) UNBEDINGT nötig ist, da sich die Variable BEIM BEARBEITEN durch ein reinspuckenden Interrupt teilweise verändern kann, man aber diesen Teil bereits gelesen hat und, wenn man wieder darf, den anderen Teil lesen wird, Der übergelaufen sein könnte)
Quote
Warte ich also nur 2000nS und frage dann ab, greif ich in Pausenloch.
Diese 2ms warten wir ja auch nur, wenn wir einen Impuls erwarten.
Oder, nehmen einen Interrupt - die AVR-Arduino können an jedem Pin einen PCINT (PinChangeINTerupt) auslösen.
Wenn wir us nur um einen Pin kümmern, müssen wir nicht prüfen, ob genau dieser Pin den Interrupt ausgelöst hat - alle Pins von einem Port lösen die selbe(!!) ISR aus, wo zu dem Zeitpunkt nicht klar ist, Wer's nun war.
Wenn Das aber nur einer der Pins machen KANN (mehr haben wir nicht eingestellt), können wir direkt losarbeiten.
Quote
Ich müsste innerhalb dieser kurzen Zeit zufällig auf eine aufstegende Flanke stoßen, dann würde es ausnahmsweise zu einem Ergebnis führen.
Für den Arduino sind 20ms eine seeeeehr lange Zeit - zu Seinem Glück wächst Dem kein Bart, sonst würde der Chip bei der ganzen Warterei platzen ;)
Wie ich schrieb - mein Sketch kommt akut über 100000x jede Sekunde durch loop() durch!
Klar wird Das weniger, wenn der µC mehr abarbeiten muß - aber z.B. das Fade - alle 10ms die LED 'nachstellen', behindert den Arduino auch nur alle 10ms für einen wesentlich kleineren Bruchteil an Zeit.
Die größte Zeit Seines Leben rennt der Arduino hier nur im Kreis, um im Kreis zu rennen - weil Er gerade Nichts zu tun hat!
Das sieht man Deinem Modell nicht an, dort blinkt und blitzt Es an jeder Ecke - aber für den Arduino ist Das Alles immer nur WARTEN auf die nächste Aktion.
Quote
Beim Steuern eines Flugzeuges ist Zufall aber kein Freund:)
Netter Spruch :)
Wenn man zufällig einem Springbaum begegnet, gebe ich Dir Recht ;)

Hoffe, ich konnte Dir etwas Klarheit verschaffen.

MfG
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 16, 2020, 11:52 am
Bin selbst eher der analog-Techniker ( Radio-Fernseher( analoge)) das ist so meine Technik Welt.
Ich kann einen Röhrenfernseher noch reparieren. Digitaltechnik ist für mich neu.
Gibt' so Fernseher noch? Und dann auch die Röhren dazu?
Mein erster selbstgebauter Gitarrenverstärker war auch noch in Röhrentechnik - man ist das lange her .

Bitte nur, wenn Zeit und Lust ist, keine Hetze und keine Notwendigkeit.
Da ich gerade Zeit und Lust hatte, hier mal ein Sketch nach dem beschriebenen Prinzip.
Du must bei den Impulsen die Flanken erkennen. Dazu musst Du dir immer merken, wie der Pulseingang beim letzten loop-Durchlauf war, und schauen, ob sich das geändert hat.

Code: [Select]
// Pulsein-Messung im loop () fuer skyfox
//
#include <MobaTools.h>

// Variable für die Zeitmessung
const byte    pulsePin = 10;  // Pin an dem der Puls anliegt
unsigned long startTime;      // Zeit an der positiven Impulsflanke
bool          lastPinState;   // letzter Zustand am Pulse-Pin
int           pulseLength;    // Länge des Pulses
const byte    pulseOut = 11;  // nur für genauigkeitstest mit LA
byte          pulseValue;     // Auswertezustand der Pulslänge

// Variable für Led's

// die Strobe-Led wird immer abwechselnd entsprechend der Tabellenzeiten ein- und ausgeschaltet
const int   strobeTime [] = { 50,50,50,50,50,50,50,1500 };
const byte  strobeStates = sizeof( strobeTime )/sizeof(strobeTime[0]); // Zahl der Tabellenelemente
const byte  strobeLed = 3;    // Anschlusspin der Strobe-Led
byte        strobeIx;         // aktueller Index in der Tabelle strobeTime
MoToTimer   strobeTimer;
//

const byte  fadeLedPin = 4;      // An/Abschwellende led
const int  fadeTime = 1000;  // An/Abschwellzeit
MoToSoftLed fadeLed;   
MoToTimer   fadeTimer;        // zum Umschalten EIN/AUS nach fadeTime

void setup() {
  //Serial.begin( 115200 );
  //Serial.println("Start Sketch");
  // Initiierungen für die Pulsmessung
  pinMode( pulsePin, INPUT );
  lastPinState = digitalRead( pulsePin );   // für Erstauswertung
  pinMode( pulseOut, OUTPUT );              // nur für Testmessungen

  // Initiierungen für die Strobe-Led
  pinMode( strobeLed, OUTPUT );

  // Initiierungen für fade-Led ( läuft ständig )
  fadeLed.attach( fadeLedPin );
  fadeLed.riseTime( fadeTime );
  fadeLed.write(ON, LINEAR);
  fadeTimer.setTime( fadeTime );

 
 

}

void loop() {
  // -------------Messung der Pulslänge--------------------------------
  bool actPinState = digitalRead( pulsePin );
  if ( actPinState != lastPinState ) {
    // Es hat ein Flankenwechsel stattgefunden
    if ( actPinState == HIGH ) {
      // Positive Flanke -> Zeitmessung starten
      startTime = micros();
      digitalWrite( pulseOut, HIGH );             // Um delay zum echten Puls messen zu können
    } else {
      // negative Flanke, Zeit auswerten
      pulseLength = micros()-startTime;
      digitalWrite( pulseOut, LOW );             // Um delay zum echten Puls messen zu können

      if( pulseLength > 1900 && pulseLength < 2100) pulseValue = 1;
      else if ( pulseLength > 1400 && pulseLength < 1600 ) pulseValue = 2;
      else if ( pulseLength > 900 && pulseLength < 1200) pulseValue = 3;

      //Test der Pulsmessung:
      //Serial.print("Pulse=");Serial.println(pulseValue);
    }
  }
  lastPinState = actPinState;   // für Vergleich im nächsten loop-Durchlauf
  //----------------- Ende Pulsemessung --------------------------------

  //--------------standig laufende fade-LED-------------------------------
  if ( !fadeTimer.running() ) {
    // Zeit abgelaufen, LED umschalten
    fadeLed.toggle();
    fadeTimer.setTime( fadeTime );
  }
  //----------------StrobeLed-------------------------------
  // Die Strobe LED blitzt nur, wenn der pulsValue = 3 ist
  if ( pulseValue == 3 ) {
    // Strobe Led blitzt
    if ( ! strobeTimer.running() ) {
      // Led ein/ausschlaten, und Timer setzen
      digitalWrite ( strobeLed, !(strobeIx&1) ); // bei geraden indizes ein, bei ungeraden ausschalten
      strobeTimer.setTime( strobeTime[strobeIx] );  // Zeitdauer für den aktuellen Zustand setzen
      // Index auf nächsten Status setzen, am Tabellenende wieder auf 0
      if ( ++strobeIx >= strobeStates ) strobeIx=0;
    }
  } else {
    // StrobeLed rücksetzen
    digitalWrite ( strobeLed, LOW );
    strobeIx = 0;
  }
 
}

Ich habe versucht es übersichtlich zu machen und entsprechend zu kommentieren. Wenn was unklar ist, einfach fragen.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Serenifly on Feb 16, 2020, 12:51 pm
Gibt' so Fernseher noch? Und dann auch die Röhren dazu?
Er meint Bildröhren. Nicht Verstärker-Röhren. Und Röhenfernseher waren am Ende auch sehr stark digitalisiert und computerisiert. Das hat nicht erst mit LCDs angefangen.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 01:05 pm
Nein, er meinte schon richtige Röhrenfernseher.

Der erste, den ich repariert habe, war ein Philips K6 ( das war 1977, die Kiste war Baujahr 69 oder 70 ), das war ein Röhrengrab.

Wenn der an war, brauchte man weder Heizung noch Licht.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 01:10 pm
@ Microbahner

Den Sketch bekomme ich nicht kompiliert.
Er meckert an

MoToTimer does not name a type; did you mean eggTimer

Wenn ich // setze, mahnt er fadeLed.attach an usw.

Die Mobatools.h hab ich aber.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 16, 2020, 01:32 pm
Die Mobatools.h hab ich aber.
Nur die MobaTools.h?
Du brauchst schon die komplette Library in der aktuellen Version (2.1.1). Installierbar über den Bibliotheksmanager.
Werkzeuge->Bibliotheken verwalten. Dann im Suchfeld oben rechts 'mobatools' eingeben ( Groß/Kleinschreibung ist nicht relevant) . Sagt er da, dass die installiert ist? Und in welcher Version?
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 01:50 pm
Die Pulseabfrage hab ich aus dem Sketch extrahiert.
im Serialprint hab ich dann neben pulse ( 1,2,oder 3) auch die gemessene PulseLength printen lassen.
Wie schon erwartet, dadurch das eben kein Waitstate da ist, gibt es extreme Abweichungen.

Siehe Bild im Anhang. Der Pulsegenerator ist verlässig genau!!

Die Abweichungen sind so groß, das es zu wilden Umschaltungen des States ( puls 1,2, oder 3 ) kommt.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 01:55 pm
Ich habe die MOBA.Tools aus deiner gestrigen Verlinkung aus der ZIP installiert.
Die dürfte komplett drin sein
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 16, 2020, 01:58 pm
Wie schon erwartet, dadurch das eben kein Waitstate da ist, gibt es extreme Abweichungen.
Das ist so nicht richtig. Wenn der loop() ausreichend schnell ist, funktioniert das ( hab' meine Sketch bei mir auch mit einem Pulsgenerator getestet). Waretezeiten im loop würden die Messung ungenau machen.
Das Problem können aber die vielen seriellen Ausgaben sein. Die beeinflussen auch die loop-Durchlaufzeiten, und dann wird es ungenau.  Mit welcher Baudrate arbeitest Du? Die 'üblichen' 9600 Baud sind auf jeden Fall viel zu langsam. Und dann auch möglichst wenig Text ausgeben. Je mehr Du ausgibst, um so wahrscheinlicher ist es, dass der Sendepuffer voll läuft, und dann blockieren die print Aufrufe.

Zu den MobaTools: Das Tutorial gibt's ja schon recht lange. Da hast Du vermutlich eine ziermlich alte Version der MobaTools. Mach mal ein Update über den Bibliotheksmanager.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 02:09 pm
mea culpa,

die 9600 Baud waren es. Da schreibt der wie ein Erstklässler.

Mit 115200 kann ich längere Sätze dahin printen, ohne Abweichung.

Das hatte ich auch vermutet und geändert. Jetzt geht das recht zuverlässig.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 16, 2020, 02:14 pm
Noch eine Frage: welchen Arduino verwendest Du? Wenn es am Ende doch nicht reicht mit den Loop-Durchlaufzeiten, dann muss man doch auf die Variante mit Interrupts zurückgreifen. Dann ist man aber nicht mehr frei bei der Auswahl des Pins für den Impulseingang. Vielleicht ist es deshalb geschickt, gleich einen zu nehmen, wo man die Option noch hat.

Und was ist mit den MobaTools? hast Du da ein Update gemacht?
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 02:16 pm
Jetzt habe ich als Variable die 1, die 2 und die 3.

Hab mal was gesehen mit cases, macht das Sinn, jetzt unten ein void(Zustand 1), dann ein void(Zustand2) usw

aufzurufen? ( ob das die cases sind weiß ich jetzt nicht mehr genau ).

#Ist halt viel, was da gerade auf mich einströmt.

Juhu,

nächster Fehler gefunden. Hab jetzt die richtige Version der MobaTools und kriege den Schketsch kompiliert, freu

Der Arduino ist so ein Nano V3, 328P mit USB auf der Platine.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 16, 2020, 02:26 pm
Hi

Der Uno und Nano haben einen vollwertigen Interrupt an den Pins 2 und 3.
Daneben ist an ALLEN Pins ein PCINT möglich (außer ggf. an A6/A7 am Nano).
DAS hatte ich aber oben bereits Mal angerissen.

Selbst, wenn die Ausgaben stören können - wenn man erst NACH dem Impuls die Ausgaben raushaut, sind wir lange vor dem nächsten Impuls damit fertig.
Aber auch klar, daß Debug-Ausgaben eben Zeit benötigen.

MfG
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 16, 2020, 02:28 pm
Der Arduino ist so ein Nano V3, 328P mit USB auf der Platine.
Dann wäre es vielleicht sinnvoll, den Puls gleich auf Pin2 oder 3 zu legen. Da hat man die Option mit Interrupts noch offen, ohne später umverdrahten zu müssen. Wenn's ohne geht, umso besser. Aber wer weis, was am Ende noch so alles in den Sketch soll ;)

Hab mal was gesehen mit cases,
Du meinst die switch-Anweisung, die auch in meinem Tutorial eingesetzt wird. Ob die hier sinnvoll ist, muss man dann im Einzelfall prüfen, wenn klar ist, was bei den Variablenwerten alles gemacht werden soll. U.U. können da einfach if's besser sein.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 02:32 pm
So, erste Anpassung.

Habe im Code if pulseValue ==3, strobe an,

geändert in if PulsValue ==3 || pulseValue ==2, strobe an,
denn in beiden Fällen läuft das Strobe.

das kann man aber so nicht lassen, geht nur zum Test und weil der Landescheinwerfer und die NAV Lichter noch nit dran sind.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 02:40 pm
Ein wenig beschämt mich schon, das ich nicht kapiere, wie und warum deine Pulsabfrage da oben läuft.
Bin den Loop jetzt gedanklich x mal durchgegangen. Es kettet sich mir nicht zusammen.
Bei läuft da Pulse = High immer im Kreis und ich kriege nicht den Gedankensprung( und Programmsprung ) hin zu Pulse low, und schon gleich gar nicht, wie da die Zeit gemessen wird. Ich steh da irgendwie voll auf der Leitung.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 02:51 pm
Code: [Select]
void loop() {
 // -------------Messung der Pulslänge--------------------------------
 bool actPinState = digitalRead( pulsePin );
 if ( actPinState != lastPinState )     Das ist hier jetzt sagen wir mal nicht der Fall, es kam noch kein puls
                                                  dann springen wir zu else ( richtig? )
{
   // Es hat ein Flankenwechsel stattgefunden
   if ( actPinState == HIGH ) {

     // Positive Flanke -> Zeitmessung starten

     startTime = micros();
     digitalWrite( pulseOut, HIGH );
         
   } else {
     // negative Flanke, Zeit auswerten

     pulseLength = micros()-startTime;      Starttime wurde ja noch nicht gemessen/gesetzt
                                                         Pulselänge jetzt micros()? Das ist noch kurz, oder, sagen wir mal
                                                         200?(fiktive Annahme) Aber was passiert jetzt?
                                                         

     digitalWrite( pulseOut, LOW );            

     if( pulseLength > 1900 && pulseLength < 2100) pulseValue = 1;
     else if ( pulseLength > 1400 && pulseLength < 1600 ) pulseValue = 2;
     else if ( pulseLength > 900 && pulseLength < 1200) pulseValue = 3;

     //Test der Pulsmessung:
     //Serial.print("Pulse=");Serial.println(pulseValue);
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Tommy56 on Feb 16, 2020, 02:58 pm
Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [*code] davor und [*/code] dahinter ohne *).
So ist er auch auf portablen Geräten lesbar. Das kannst Du auch noch nachträglich ändern.

Gruß Tommy
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 03:00 pm
voila
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 16, 2020, 03:02 pm
das kann man aber so nicht lassen, geht nur zum Test und weil der Landescheinwerfer und die NAV Lichter noch nit dran sind.
Warum soll das nicht gehen?
Könnte lediglich ein Grund sein, weshalb die if's besser sind als die switch-Anweisung.
Wann sollen den die beiden anderen an sein?
Du machst letztendlich für jede der 3 Lichterarten einen if-Block. In dem if fragst Du dann ab unter welchen Bedingungen ( 1, 2, oder 3 ) das Licht an sein soll. Das können dann freilich auch Kombinationen sein, so wie Du das jetzt für den Strobe gemacht hast.

Brauchst Du eigentlich keinen Zustand wo alle aus sind?

Ich steh da irgendwie voll auf der Leitung.
Ich habe nochmal ein paar Kommentare reingeschrieben, vielleicht ist es jetzt klarer. Der wesentlich Punkt ist, dass die Flanken des Signals erkannt werden. Solange sich der Zustand am Pulsepin nicht ändert, passiert nichts - die 'Lok' ;) fährt einfach weiter.
Code: [Select]
bool actPinState = digitalRead( pulsePin );
  if ( actPinState != lastPinState ) { // Hier prüfen wir, ob gerade die positive oder die nagative Flanke aufgetreten ist.,
                                        // indem verglichen wird, ab der aktuelle Zustand anders ist, als beim letzten Durchlauf.
                                        // in allen anderen Fällen ( kein Flankenwechsel ) passiert nichts, und der loop läuft einfach weiter
    // Es hat ein Flankenwechsel stattgefunden
    if ( actPinState == HIGH ) {        // Wenn der Zustand am Pin jetzt HIGH ist, haben wir eine positive Flanke ( war ja dann vorher LOW )
      // Positive Flanke -> Zeitmessung starten
      startTime = micros();
    } else {                            // Wenn es keine positive Flanke war, muss es die negative sein.
      // negative Flanke, Zeit auswerten
      pulseLength = micros()-startTime;
      if( pulseLength > 1900 && pulseLength < 2100) pulseValue = 1;
      else if ( pulseLength > 1400 && pulseLength < 1600 ) pulseValue = 2;
      else if ( pulseLength > 900 && pulseLength < 1200) pulseValue = 3;

      //Test der Pulsmessung:
      //Serial.print("Pulse=");Serial.println(pulseValue);
    }
  } // Ende der Flankenerkennung. War der Zustand am Pineingang stabil ( keine Änderung am
    // Pulseingang, werden sämgliche obige Anweisungen übersprungen, D.h. solange keine
    // Änderung des Pulseinganges erkannt wird, passiert einfach garnichts.
    
  // Hier merken wir uns den jetzigen Zustand am Pin, um beim nächsten loop-Durchlauf
  // erkennen zu konnen, ob eine Änderung stattgefunen hat
  lastPinState = actPinState;   // für Vergleich im nächsten loop-Durchlauf
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 16, 2020, 03:04 pm
Hi

Der Pin wird IMMER ausgelesen.
Aber, die IF greift nur, wenn der ausgelesene Zustand nicht mit dem 'letzten bekannten Zustand' übereinstimmt.
In der IF wird geprüft, ob JETZT HIGH oder LOW anliegt - dem nach wird die START- oder die END-Zeit 'gemerkt'.
Wobei bei LOW direkt mit micros() die aktuelle Uhrzeit ausgelesen wird und bei HIGH der micros()-Wert in die Variable startzeit gespeichert wird.

Bei jeder Flanke wird also eines der beiden Bereiche ausgeführt.
In Deinem Schnipsel fehlt noch das
lastPinState = actPinState;
Denn hier merken wir uns, wie der aktuelle Pinstate 'jetzt' ist.

Somit reagieren wir immer nur auf die Änderung des Pegel, die Zwischenzeit ist uns dabei komplett egal - Da passiert ja eh Nichts, worauf wir achten müssten.

Angemerkt noch: micros() ändert den Wert in 4er Schritten (ist den Interna des µC geschuldet), nicht, daß Du Dich wunderst, daß Da nur durch 4 teilbare Zahlen rum kommen.

MfG
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 03:33 pm
ok, ich glaub ich habs kapiert. der geht das if, dann tue nicht ständig durch solange die Flanke positiv ist, sondern nur einmal beim Wechsel der Flanke.
Das ist ja mal clever.
Mir ging nämlich das starttime= micros nicht auf, weil das ja ständig aktualisiert würde und im else
dann
length = micros - starttime immer 0 ergeben würde.

Heiland, da mus mein hiern aber Treppen steigen.


Ja, noch mal zu den ifs und den Aggregatzuständen:

Ich habe 4 Lamengruppen.

1. die FadeLed
Ja die muss immer auf an, sobalt sich elektronen bewegen.
In so fern gibt es hier keinen Zustand "Alles aus", ausser der Akku ist leer:)
pin 5,7, und 8 werden LOW gesetzt, alles andere ist also aus



Zustand 2
Pin 5 und 8 ( NAV und STROBE )gehen auf High ( die beiden gehen immer gemeinsam an und aus )

Es müssen 2 sein, weil einer ja Dauerfeuer gibt und der andere das Strobe ist

Pin 7 ist auf LOW ( egal wie der aktuelle wert ist, also bleibt low oder geht low)
Wird von hier in Zustand 1 zurückgeschaltet, gehen 5,7, und 8 wieder low


Zustand 3
Pin 5 und 8 gehen auf HIGH( wie Zustand 2, aber es könnte ja direkt von 1 auf 3 geschaltet werden )
Zusätzlich geht 7 auch auf HIGH.
Jetzt ist der Landescheinwerfer auch noch an.

Wird von hier zurückgeschaltet in Zustand 2, geht ja pin 7 ( landescheinwerfer wieder auf low und damit aus.

wird von hier in Zustand 1 zurückgeschaltet, werden ja eh 5, 7, und 8 zurückgeschaltet auf low.



Ich versuch das mal.

Dazu vorab eine Frage:

Wenn z.B. für pin 7 eine Variable bolean benenne, die NAV heißt, dann wäre doch NAV = an und !NAV gleich aus, richtig?
Reicht dann in der if Abfrage das kürzel if (NAV; !NAV) un es auszumachen, wenn es an ist?

oder muss das heißen if (NAV = true oder 1 oder High) dann NAV = Low oder !NAV oder false
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 03:40 pm
@ postmaster_ino,

danke für die Erklärung.
Ihr seid echte Profis, Respekt.

Mir raucht hier der Schädel, das es nur so Nebelt. :)
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 16, 2020, 04:38 pm
Hi

if(nav){
wird ausgeführt, wenn 'nav' ungleich Null ist.
Einzig die Null ist false - wenn 'nav' negative Werte annehmen kann (warum auch immer), sind Diese ebenfalls true!

if (!nav) {
dreht die Logik um - das ! ist hier ein NOT/NICHT, richtig erkannt.

Auch solltest Du tunlichst auf == in der IF-Abfrage achten!!
if(x=1){ funktioniert nämlich auch, macht aber NICHT, was Du vermutest!
Das ist eine ZUWEISUNG, also X bekommt den Wert 1.
Alle Werte, außer der Null, sind true.
Wenn diese Zuweisung also geklappt hat (warum sollte Sie nicht klappen??), ist die IF gültig - nicht, was Du wolltest, aber genau, was Du geschrieben hast.

Dein NAV-Licht soll also durchgehend 50ms an, 50ms aus blitzen?
Das sollte sich mit wenigen Zeilen Code realisieren lassen, auch die Abschaltung, wenn NAV eben doch aus sein soll (die Voraussetzungen für Strope und NAV eben nicht mehr gegeben sind).

Das Faden würde ich in einer eigenen Funktion 'erschlagen' - Das hält Deine loop() sauber.
Dann steht in Deiner loop()
checkStrope();
checkFade();

Fertig.
Hier musst Du 'nur' bestimmen, in wie vielen Schritten die LEDs gedimmt werden sollen und wie lang das Dimmen dauern soll.
Gibt Es Dauer-AN und Dauer-AUS-Zeiten?
Wenn nicht, einen bool, für die Richtung (hoch/runter dimmen), die 'letzte Uhrzeit' uint32_t lastfade, die Schrittweite (sofern nicht 1) und die Wartezeit zwischen den Schritten.
IMMER wird geschaut, ob's an der Zeit ist, die Helligkeit der Fade-LED anzupassen.
Wenn nicht, dann machen wir Nichts!
Sonst, je nach 'Richtung' zählen wir die gewünschten Schritte dazu oder ziehen Diese ab - bei PWM mit den Grenzen 0 und 1023.
Wenn wir die Grenze erreicht (oder überschritten) haben, wird die Richtung umgekehrt.
Bei jeder Anpassung merken wir uns die aktuelle Zeit in 'lastFade' für die kommende Wartezeit.

Im Grunde nicht viel Anders, als die erste Funktion, ok, nicht ganz so kompliziert.

MfG
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 04:40 pm
DANKE MicroBahner!!! und postmaster_ino und allen die sich beteiligt haben.

Das mit den if´s läuft perfekt.
Nach einigem Hin und her habe ich es hinbekommen. Es ist auch deutlich schnell genug, selbst kurze debug prints führen nicht mehr zu Meßfehlern.

Da gibt es aber eine Sache, die Verstehe wer will.

const int Strobe ist pin 8
Der Pin wird an und ausgeschaltet, wenn das Strobe läuft.

ich habe const int NAV auf pin 5 gemacht, aber beim Versuch es anders zu schalten, meckert er an, es sei ja eine read-only Variable. Ging nicht.
Habe es dann einfach als int NAV=5 gemacht, danach lief es. Dto. für die Variable LL ( Landinglight )

Und nun der Code, wie er perfekt funktioniert. Danke Danke Danke allen , die hier geholfen haben.

Hab viel dabei gelernt, und kann sicher das ein oder andere für weitere Projekte nutzen.

Und in der tat, die Verzögerungen durch die delays und das nacheinader abarbeiten in meinem Spagetthi-Code anfangs führten ja dazu, dass das Ding wohl lief, aber beim Schalten z.B. des Landescheinwerfers, je nach dem , wo er gerade war, auch schon mal ne halbe Sekunde oder etwas mehr Verzögerung auftrat.

Jetzt schalte ich, egal was, und plups, reagiert der kleine Scheisser.

Ich bin echt begeistert. So viel gelernt in den etwa 24 Stunden.

anbei nun der Code, wie ich ihn gerade erfolgreich getestet habe. So läuft er exakt wie er soll.

Code: [Select]
// Pulsein-Messung im loop () fuer skyfox
//
#include <MobaTools.h>

// Variable für die Zeitmessung
const byte    pulsePin = 10;  // Pin an dem der Puls anliegt
unsigned long startTime;      // Zeit an der positiven Impulsflanke
bool          lastPinState;   // letzter Zustand am Pulse-Pin
int           pulseLength;    // Länge des Pulses
const byte    pulseOut = 11;  // nur für genauigkeitstest mit LA
byte          pulseValue;     // Auswertezustand der Pulslänge

// Variable für Led's

// die Strobe-Led wird immer abwechselnd entsprechend der Tabellenzeiten ein- und ausgeschaltet
const int   strobeTime [] = { 50,50,50,50,50,50,50,1500 };
const byte  strobeStates = sizeof( strobeTime )/sizeof(strobeTime[0]); // Zahl der Tabellenelemente
const byte  strobeLed = 8;    // Anschlusspin der Strobe-Led
byte        strobeIx;         // aktueller Index in der Tabelle strobeTime
int         NAV = 5;
const byte  LL = 7;
MoToTimer   strobeTimer;


const byte  fadeLedPin = 6;      // An/Abschwellende led
const int  fadeTime = 1500;  // An/Abschwellzeit
MoToSoftLed fadeLed;  
MoToTimer   fadeTimer;        // zum Umschalten EIN/AUS nach fadeTime

void setup() {
  //Serial.begin( 115200 );
  //Serial.println("Start Sketch");
  // Initiierungen für die Pulsmessung
  pinMode( pulsePin, INPUT );
  lastPinState = digitalRead( pulsePin );   // für Erstauswertung
  pinMode( NAV, OUTPUT );
  pinMode(LL, OUTPUT );
  pinMode( pulseOut, OUTPUT );              // nur für Testmessungen

  // Initiierungen für die Strobe-Led
  pinMode( strobeLed, OUTPUT );

  // Initiierungen für fade-Led ( läuft ständig )
 fadeLed.attach( fadeLedPin );
 fadeLed.riseTime( fadeTime );
 fadeLed.write(ON, LINEAR);
 fadeTimer.setTime( fadeTime );

 
 

}

void loop() {
  // -------------Messung der Pulslänge--------------------------------
  bool actPinState = digitalRead( pulsePin );
  if ( actPinState != lastPinState ) {
    // Es hat ein Flankenwechsel stattgefunden
    if ( actPinState == HIGH ) {
      // Positive Flanke -> Zeitmessung starten
      startTime = micros();
      digitalWrite( pulseOut, HIGH );             // Um delay zum echten Puls messen zu können
    } else {
      // negative Flanke, Zeit auswerten
      pulseLength = micros()-startTime;
      digitalWrite( pulseOut, LOW );             // Um delay zum echten Puls messen zu können

      if( pulseLength > 1900 && pulseLength < 2100) pulseValue = 1;      
      else if ( pulseLength > 1400 && pulseLength < 1600 ) pulseValue = 2;
      else if ( pulseLength > 900 && pulseLength < 1200) pulseValue = 3;

      //Test der Pulsmessung:
     // Serial.print("Pulse= ");Serial.println(pulseLength);
    }
 }
  lastPinState = actPinState;   // für Vergleich im nächsten loop-Durchlauf
  //----------------- Ende Pulsemessung --------------------------------

  //--------------standig laufende fade-LED-------------------------------
 if ( !fadeTimer.running() ) {
    // Zeit abgelaufen, LED umschalten
    fadeLed.toggle();
    fadeTimer.setTime( fadeTime );
 }
  //----------------StrobeLed-------------------------------
  // Die Strobe LED blitzt nur, wenn der pulsValue = 2 oder 3 ist
  if (pulseValue == 3) digitalWrite (LL, HIGH);
  if (pulseValue == 2) digitalWrite (LL, LOW);
  if ( pulseValue == 2 || pulseValue ==3) {
    digitalWrite (NAV, HIGH );
    // Strobe Led blitzt
    if ( ! strobeTimer.running() ) {
      // Led ein/ausschlaten, und Timer setzen
      digitalWrite ( strobeLed, !(strobeIx&1) ); // bei geraden indizes ein, bei ungeraden ausschalten
      strobeTimer.setTime( strobeTime[strobeIx] );  // Zeitdauer für den aktuellen Zustand setzen
      // Index auf nächsten Status setzen, am Tabellenende wieder auf 0
      if ( ++strobeIx >= strobeStates ) strobeIx=0;
    }
  } else {
    // StrobeLed rücksetzen
    digitalWrite ( strobeLed, LOW );
    strobeIx = 0;
    digitalWrite (NAV,LOW); digitalWrite( LL,LOW);
  }
 
}
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 04:51 pm
Noch ein Versuch.

Das  funktioniert nicht

Code: [Select]
} else {
    // StrobeLed rücksetzen
    digitalWrite ( strobeLed, LOW );
    strobeIx = 0;
    if(NAV) {!NAV;} //NEU
    if (LL) {!LL}      //NEU
    //digitalWrite (NAV,LOW); //ALT
    //digitalWrite( LL,LOW);   //ALT
  }
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 16, 2020, 05:10 pm
Hi

Wenn NAV und LL die Pin-Nummern sind (müssen Sie sein, da Du digitalWrite drauf ansetzt), ändern sich Diese NIE im Programmablauf.
Somit wäre ein const byte _pinLL=6;
der richtige Weg gewesen und der Kompiler meckert mit Recht, wenn Du daran rumstellen willst.
Wie bekommst Du NAV wieder zurück auf den Pin-Wert, Den Du außerhalb zugewiesen hast?

Denke, Das funktioniert noch nicht 100% so, wie Du Das wünscht.
Probiere aber gerne erst weiter herum, schreibe Dir auf, was wann nicht so läuft, wie geplant.

MfG
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 05:17 pm
Also warum weiß ich nicht,
aber jetzt habe ich:
const byte LL = 7
const byte NAV = 5

und ich kann sie mit digitalWrite an und ausschalten.

Hab gerade noch mal rumprobiert,

funktioniert perfekt.

Auch die Pin 8 für die Strobes, die werden ja im Programmablauf dauernd an und ausgeschaltet, sind vom MicroBahner oben auch als const byte ausgelegt worden und das ging ja schon von Anfang an bestens.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 16, 2020, 05:22 pm
Hi

Du hattest Deine Änderung unten vorgenommen.
Dort hast Du NAV=!NAV; geschrieben - DAS ändert aber nur den Wert der Variable NAV, wo ja eigentlich der Pin für die NAV-Beleuchtung gespeichert war.
Nach dem NAV=!NAV; sollte sich NAV nicht mehr einschalten lassen, auch bin ich mir nicht sicher, zu welchem Pin Das Dann wird - 1 oder 255 (0xFF, alle Bits gesetzt) würden Sinn machen.
1 wäre blöd, da Da der serielle Monitor/USB dran hängt
255 wird wohl von digitalWrite ignoriert, da der Arduino nicht so viele Beinchen hat

MfG

*Edit*
Danke dem Test in #56
Beim Negieren:
Jede Nummer, außer die Null, wird zu Null.
Die Null selber wird zu 1.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 16, 2020, 05:56 pm
Du musst bei der Steuerung der Pins ein wenig aufpassen und die PinNummer vom Zustand des Ausgangs trennen. Das sind 2 verschiedene Dinge. Vielleicht ist da auch zur Verdeutlichung gut, im Namen für die Pinnummer immer das Wort 'Pin' mit aufzunehmen ( Habe ich jetzt auch nicht gemacht, könnte aber sinnvoll sein ).

Den Zustand des Pins kannst Du dann nur mit digitalWrite ändern, nicht durch Ändern eines Variablenwertes.
Wenn du den derzeitigen Zustand am Pin umschalten willst ( ich denke, dein NAV=!NAV ist so gedacht ), geht das auch nur über die digitalWrite/digitalRead Funktionen.
Also z.B.
Code: [Select]
digitalWrite( NavPin, !digitalRead(NavPin) );

Das heist, Du liest erstmal den Wert, den der Pin gerade hat, negierst das und das schreibst Du dann wieder auf den Pin raus.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 16, 2020, 06:09 pm
Ah, ok, verstanden,
na dann kann ich besser so lassen wie ist und direkt
digitalWrite (NAV, LOW ) schreiben.
Erst read um dann write zu machen ist an der Stelle ein unnötiger Aufwand und ein Befehl mehr in der Kette der Zeiträuber. ( Stimmt das, was ich gerade geschrieben habe?)

Gruß

Ludger
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 16, 2020, 06:26 pm
Hi

Fast - hier gibt Es keine Befehle - Das sind Alles Funktionen (teilweise mit Rückgabewert, teilweise mit Übergabeparametern).

Aber Zeit fressen Sie schon.
Wenn'*s wirklich schnell werden muß und man nicht die Flexibilität braucht, den Sketch auf einen anderen Arduino ebenfalls lauffähig zu bekommen, kann man auch direkt die Ports der Pins manipulieren - denke, Das brauchen wir aber noch nicht.
Auch gibt Es eine FastWrite-Library, Die Das ,mit noch ein/zwei Prüfungen, schon recht hardwarenah macht.

MfG
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 16, 2020, 06:42 pm
Hallo Ludger,
digitalWrite (NAV, LOW ) schreiben.
Erst read um dann write zu machen ist an der Stelle ein unnötiger Aufwand
Dir muss aber klar sein, dass das 2 verschiedene Dinge sind.
Wahrscheinlich willst Du schon den Ausgang abschalten. Dann ist die Schreibweise mit dem LOW richtig.

Mit der Variante von mir oben, wird der Ausgang umgeschaltet. Das kann man sehr elegant einsetzen, wenn der Ausgang in einem gleichmäßigen Zeitraster blinken soll.
Immer wenn die entsprechende Zeit abgelaufen ist, führst Du diese Anweisung aus, und der Ausgang schaltet um. Da in dem Fall ja egal ist, wie er vorher war, Hauptsache er ist jetzt andersherum ist dass dafür die kürzeste Variante.

Wenn'*s wirklich schnell werden muß und man nicht die Flexibilität braucht, den Sketch auf einen anderen Arduino ebenfalls lauffähig zu bekommen, kann man auch direkt die Ports der Pins manipulieren - denke, Das brauchen wir aber noch nicht.
Auch gibt Es eine FastWrite-Library, Die Das ,mit noch ein/zwei Prüfungen, schon recht hardwarenah macht.
Ich glaub', da schießen wir hier aber noch ein wenig weit übers Ziel hinaus ;)
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: agmue on Feb 16, 2020, 06:51 pm
... auch bin ich mir nicht sicher, zu welchem Pin Das Dann wird ...
Test:

Code: [Select]
void setup() {
  Serial.begin(115200);
  Serial.println("Anfang");
  int t = 5;
  Serial.print(t);
  Serial.print('\t');
  t = !t;
  Serial.println(t);
  t = 0;
  Serial.print(t);
  Serial.print('\t');
  t = !t;
  Serial.println(t);
}

void loop() {}

Eine 0 wird zu 1, alle anderen Zahlen werden zu 0. Entsprechend Deiner Beschreibung ist das konsequent.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Serenifly on Feb 16, 2020, 07:35 pm
ein Befehl
Die richtige Terminologie ist in C++ wichtig. Ich habe bei sowas immer das Gefühl jemand hält z.B. "!=" für einen Befehl und digitalRead() ist auch ein Befehl.
Das erste ist aber ein Operator und das zweite ist eine Funktion

Das mag kleinlich wirken aber es für das Verständnis und Fehlerdiagnose wichtig:
1.) Für Operatoren, Funktionen, sonstige Answeisungen (while, if, etc.) und auch andere Sprachelemente gelten unterschiedliche Regeln
2.) Der Compiler verwendet diese Begriffe in Fehlermeldungen (Sachen wie "error with function xyz")
3.) Wenn du selbst Informationen mit Google suchst, hilft es ungemein wenn du die richtigen Suchbegriffe verwendest
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Whandall on Feb 17, 2020, 08:37 am
Dort hast Du NAV=!NAV; geschrieben - DAS ändert aber nur den Wert der Variable NAV, wo ja eigentlich der Pin für die NAV-Beleuchtung gespeichert war.
Wo willst du das den gelesen haben?

Noch ein Versuch.

Das  funktioniert nicht

Code: [Select]
} else {
    // StrobeLed rücksetzen
    digitalWrite ( strobeLed, LOW );
    strobeIx = 0;
    if(NAV) {!NAV;} //NEU
    if (LL) {!LL}      //NEU
    //digitalWrite (NAV,LOW); //ALT
    //digitalWrite( LL,LOW);   //ALT
  }


Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 17, 2020, 09:40 am
Dachte ich hätte sowas gesehen.
Mir war aber weder die korrekte Syntx noch im Kopf, noch hatte ich den Sinn richtig verstanden.
Es ging da wohl eher um toggeln, aals um Schalten.
War hal´n Versuch, der in die Hose ging, so what.

Bin halt blutiger Anfänger.
Da tut man sich hier und dort halt schon mal schwer, bis man was richtig versteht.
Jetzt steht da wieder digitalWrite low und funktioniert perfekt.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Whandall on Feb 17, 2020, 10:14 am
@skyfox60 ich habe nicht deinen untauglichen Versuch kommentiert, sondern die falsche Erklärung.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 17, 2020, 06:12 pm
Hi

Wo Du Das fragst - hatte den Sketch kopiert und in der heimischen IDE durchgeschaut - meine, Das dort gelesen zu haben (da nicht mein Projekt aber nicht gespeichert).
Da ich diese Passage jetzt nicht mehr finde, werde ich mir wohl mehr was zusammengereimt haben, weshalb das const byte NAV=4; (oder welcher Pin Das nun war) nun ein Problem darstellen kann.
Trotzdem sehe ich an meiner Erklärung nicht so viel Falsches - Pin-Nummern ändern sich während der Laufzeit wohl nicht mehr, damit const, was zusätzlich zum Optimierungspotential des Kompiler noch verhindert, daß man Das auch noch probiert.

Der Erklärung zu NAV=!NAV; kann ich nun auch keine größeren Fehl-Aussagen entnehmen - bitte konkreter kritisieren - Alles Scheiße ist ähnlich zielführend, wie 'geht nicht'.

MfG
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 17, 2020, 09:23 pm
ich hatte da in meiner Euphorie irgendwas reingeschrieben
If NAV,!NAV

Dachte, das gäbe dann eine wenn/dann funktion. Also
wenn NAV = true, dann jetzt false, oder Wenn 1, dann jetzt null.
Das IF könnte der Haken daran gewesen sein.
NAV= !NAV geht ja offensichtlch

Gewöhnlich steht ja bei eine Bedingung, z.B. IF (A==0) B=1.....

Irgendwo hatte ich mal gesehen, das etwas abgefragt wurde ohne expliziete Bedingung, etwa IF( Variable, tue was oder setze was.
Da dachte ich, dass das IF hier nur einen Zustand wie 1 oder Null abfragen kann.
Viellecht muss das dann aber auch ein bestimmter Datentyp sein ´, bopol z.B:
das weiß ich nicht.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Whandall on Feb 17, 2020, 09:55 pm
Der Erklärung zu NAV=!NAV; kann ich nun auch keine größeren Fehl-Aussagen entnehmen - bitte konkreter kritisieren
Gerne.

Das Statement
Code: [Select]
  NAV=!NAV;
kommt im Kode des OP nicht vor, sondern der enthält das Statement
Code: [Select]
  if (NAV) !NAV;
Dein ganzes Elaborat gehört also nicht zu diesem Sketch, ich betrachte das als Fehler.

Hi

Du hattest Deine Änderung unten vorgenommen.
Dort hast Du NAV=!NAV; geschrieben - DAS ändert aber nur den Wert der Variable NAV, wo ja eigentlich der Pin für die NAV-Beleuchtung gespeichert war.
Nach dem NAV=!NAV; sollte sich NAV nicht mehr einschalten lassen, auch bin ich mir nicht sicher, zu welchem Pin Das Dann wird - 1 oder 255 (0xFF, alle Bits gesetzt) würden Sinn machen.
1 wäre blöd, da Da der serielle Monitor/USB dran hängt
255 wird wohl von digitalWrite ignoriert, da der Arduino nicht so viele Beinchen hat

MfG

*Edit*
Danke dem Test in #56
Beim Negieren:
Jede Nummer, außer die Null, wird zu Null.
Die Null selber wird zu 1.
Dass beide Kode Varianten nicht sinnvoll sind, ist unbestritten.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 17, 2020, 10:40 pm
mag sein, weiß ich nicht, dafür stecke ich nicht tief genug im Thema.Kann mich also darüber auch nicht fachlich steiten, wegen keine Anhung.

Vielleicht wäre es hilfreich, wenn statt sinngemäß "das ist alles murks",
mal ein "ich würde es so vorschlagen" käme.

Das dann noch verständlich erklärt, hilft einem Anfänger weiter.

Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 17, 2020, 10:52 pm
So, dann stelle ich hier mal das Endergebnis vor.

MicroBahner hat mir dabei nicht nur geholfen, sondern ich konnte auch noch richtig was lernen.
Danke ihm für seine endlose Geduld am heiligen Wochenende.

Da meine Harware schon fertig war und noch Spaghetti im Magen ( Magen = Speicher:) ) hatte
habe ich den neuen schnelleren Code pinmäßig so angepasst, das er auf der fertig verlöteten Hardware läuft.

Das Blinken, Blitzen und leuchten ist zwar grundsätzlich das gleiche, aber man merkt spätestens beim Umschalten, z. B. Landelicht an, Landelich aus, das beim Spaghetticode deutlich sichtbare Verzögerungen sind, während jetzt beim neuen Code gefühlt das Umschalten mit dem RC-Sender-Schalterklick zusammen fällt. Der Unterschied ist mega deutlch.

Wer mag, und das so nachbaut, kann ja mal zum Test zunächst den alten, dann den neuen Code laden und probieren. Dann seht ihr praktisch sofort, wo sich ein umständlicher Programmierstil rächt.

Wäre das z. B. bei den Steuerfunktionen des Flugzeuges so, wie im alten Code, wäre das unfliegbar.
Dem neuen würde ich es  hingegen zutrauen.

Nun hier das Ergebnis:

Code: [Select]
// Pulsein-Messung im loop () fuer skyfox
//Erstellt von MicroBahner,
// Angepasst von Skyfox60
//
#include <MobaTools.h>

// Variable für die Zeitmessung
const byte    pulsePin = 10;  // Pin an dem der Puls anliegt
unsigned long startTime;      // Zeit an der positiven Impulsflanke
bool          lastPinState;   // letzter Zustand am Pulse-Pin
int           pulseLength;    // Länge des Pulses
const byte    pulseOut = 11;  // nur für genauigkeitstest mit LA
byte          pulseValue;     // Auswertezustand der Pulslänge

// Variable für Led's

// die Strobe-Led wird immer abwechselnd entsprechend der Tabellenzeiten ein- und ausgeschaltet
const int   strobeTime [] = { 50,50,50,50,50,50,50,1500 }; // 40 an/60 aus sieht ein wenig besser aus , 10 an, 90 aus sieht gut aus, blitzt aber dann deutlich weniger hell
const byte  strobeStates = sizeof( strobeTime )/sizeof(strobeTime[0]); // Zahl der Tabellenelemente
const byte  strobeLed = 8;    // Anschlusspin der Strobe-Led
byte        strobeIx;         // aktueller Index in der Tabelle strobeTime
int         NAV = 5;          // Navigationslichter ( links rot, rechts grün, hinten weiß )
const byte  LL = 7;           //Landelicht/Lansescheinwerfer
MoToTimer   strobeTimer;


const byte  fadeLedPin = 6;    // An/Abschwellende led
const int  fadeTime = 1500;    // An/Abschwellzeit
MoToSoftLed fadeLed;   
MoToTimer   fadeTimer;         // zum Umschalten EIN/AUS nach fadeTime

void setup() {
  //Serial.begin( 115200 );
  //Serial.println("Start Sketch");
  // Initiierungen für die Pulsmessung
  pinMode( pulsePin, INPUT );
  lastPinState = digitalRead( pulsePin );   // für Erstauswertung
  pinMode( NAV, OUTPUT );
  pinMode(LL, OUTPUT );
  pinMode( pulseOut, OUTPUT );              // nur für Testmessungen

  // Initiierungen für die Strobe-Led
  pinMode( strobeLed, OUTPUT );

  // Initiierungen für fade-Led ( läuft ständig )
 fadeLed.attach( fadeLedPin );
 fadeLed.riseTime( fadeTime );
 fadeLed.write(ON, LINEAR);
 fadeTimer.setTime( fadeTime );

 
 

}

void loop() {
  // -------------Messung der Pulslänge--------------------------------
  bool actPinState = digitalRead( pulsePin );
  if ( actPinState != lastPinState ) {
    // Es hat ein Flankenwechsel stattgefunden
    if ( actPinState == HIGH ) {
      // Positive Flanke -> Zeitmessung starten
      startTime = micros();
      digitalWrite( pulseOut, HIGH );             // Um delay zum echten Puls messen zu können
    } else {
      // negative Flanke, Zeit auswerten
      pulseLength = micros()-startTime;
      digitalWrite( pulseOut, LOW );             // Um delay zum echten Puls messen zu können

      if( pulseLength > 1900 && pulseLength < 2100) pulseValue = 1;     
      else if ( pulseLength > 1400 && pulseLength < 1600 ) pulseValue = 2;
      else if ( pulseLength > 900 && pulseLength < 1200) pulseValue = 3;

      //Test der Pulsmessung:
      // Serial.print("Pulse= ");
      //Serial.print ( " plusOut  " )
      //Serial.println(pulseLength);
    }
 }
  lastPinState = actPinState;   // für Vergleich im nächsten loop-Durchlauf
  //----------------- Ende Pulsemessung --------------------------------

  //--------------standig laufende fade-LED-------------------------------
 if ( !fadeTimer.running() ) {
    // Zeit abgelaufen, LED umschalten
    fadeLed.toggle();
    fadeTimer.setTime( fadeTime );
 }
  //----------------StrobeLed-------------------------------
  // Die Strobe LED blitzt nur, wenn der pulsValue = 2 oder 3 ist
  if (pulseValue == 3) digitalWrite (LL, HIGH);
  if (pulseValue == 2) digitalWrite (LL, LOW);
  if ( pulseValue == 2 || pulseValue ==3) {
    digitalWrite (NAV, HIGH );
    // Strobe Led blitzt
    if ( ! strobeTimer.running() ) {
      // Led ein/ausschlaten, und Timer setzen
      digitalWrite ( strobeLed, !(strobeIx&1) ); // bei geraden indizes ein, bei ungeraden ausschalten
      strobeTimer.setTime( strobeTime[strobeIx] );  // Zeitdauer für den aktuellen Zustand setzen
      // Index auf nächsten Status setzen, am Tabellenende wieder auf 0
      if ( ++strobeIx >= strobeStates ) strobeIx=0;
    }
  } else {
    // StrobeLed rücksetzen
    digitalWrite ( strobeLed, LOW );
    strobeIx = 0;
    digitalWrite (NAV,LOW); digitalWrite( LL,LOW);
  }
 
}


Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 17, 2020, 10:57 pm
Der Vollständigkeit halber hier auch noch der bereinigte Sketch ohne Kommentare und ohne prüfpins und Prüf-Prints.

Code: [Select]
// Flugzeug-Beleuchtung
// MicroBahner und skyfox60

#include <MobaTools.h>

// Variable für die Zeitmessung
const byte    pulsePin = 10; 
unsigned long startTime;     
bool          lastPinState;   
int           pulseLength;   
//const byte    pulseOut = 11; 
byte          pulseValue;     


const int   strobeTime [] = { 30,70,30,70,30,70,30,1500 };
const byte  strobeStates = sizeof( strobeTime )/sizeof(strobeTime[0]);
const byte  strobeLed = 8;   
byte        strobeIx;       
const byte  NAV = 5;
const byte  LL = 7;
MoToTimer   strobeTimer;


const byte  fadeLedPin = 6;     
const int  fadeTime =1000; 
MoToSoftLed fadeLed;   
MoToTimer   fadeTimer;       

void setup() {
 
  pinMode( pulsePin, INPUT );
  lastPinState = digitalRead( pulsePin );   
  pinMode( NAV, OUTPUT );
  pinMode(LL, OUTPUT );
  //pinMode( pulseOut, OUTPUT );             

 
  pinMode( strobeLed, OUTPUT );

 
 fadeLed.attach( fadeLedPin );
 fadeLed.riseTime( fadeTime );
 fadeLed.write(ON, LINEAR);
 fadeTimer.setTime( fadeTime );

 
 

}

void loop() {
 
  bool actPinState = digitalRead( pulsePin );
  if ( actPinState != lastPinState ) {
   
    if ( actPinState == HIGH ) {
     
      startTime = micros();
      //digitalWrite( pulseOut, HIGH );           
    } else {
     
      pulseLength = micros()-startTime;
      //digitalWrite( pulseOut, LOW );             

      if( pulseLength > 1900 && pulseLength < 2100) pulseValue = 1;     
      else if ( pulseLength > 1400 && pulseLength < 1600 ) pulseValue = 2;
      else if ( pulseLength > 900 && pulseLength < 1200) pulseValue = 3;

     
    }
 }
  lastPinState = actPinState;   
 
 if ( !fadeTimer.running() ) {
   
    fadeLed.toggle();
    fadeTimer.setTime( fadeTime );
 }
 
  if (pulseValue == 3) digitalWrite (LL, HIGH);
  if (pulseValue == 2) digitalWrite (LL, LOW);
  if (pulseValue == 2 || pulseValue ==3) {
    digitalWrite (NAV, HIGH );
   
    if ( ! strobeTimer.running() ) {
     
      digitalWrite ( strobeLed, !(strobeIx&1) );
      strobeTimer.setTime( strobeTime[strobeIx] ); 
     
      if ( ++strobeIx >= strobeStates ) strobeIx=0;
    }
  } else {
   
    digitalWrite ( strobeLed, LOW );
    strobeIx = 0;
    digitalWrite(NAV, LOW);
    digitalWrite(LL, LOW);
   
  }
 
}
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 17, 2020, 10:59 pm
Hi
Code: [Select]

if (pulseValue == 3) digitalWrite (LL, HIGH);
  if (pulseValue == 2) digitalWrite (LL, LOW);
  if ( pulseValue == 2 || pulseValue ==3) {
  ...
-->
if ( pulseValue == 2 || pulseValue ==3) {
   digitalWrite(LL,pulseValue & 0x01);//oder pulseValue==3, pulseValue>2
   ...

Da die Information der LL (LandeLeuchten) aus der Variable pulseValue ableitbar ist, sollte Das identisch sein und etwas Speicher sparen.

MfG

PS: Du willst (ganz wirklich!!) NICHT die Kommentare aus einem Sketch raus werfen.
Die helfen Dir in zwei Wochen nachzuvollziehen, was Da eigentlich ablaufen soll!!
Das ist nicht Bereinigen, das ist Kastrieren!
... besser wäre gewesen, Du hättest die unnötigen Leerzeilen raus genommen ...
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 17, 2020, 11:05 pm
Hmm - ohne Prüfpins und Prüfprints - ok ( obwohl ich die dann meist eher auskommentiere als sie ganz rauszulöschen - man weis ja nie... ).

Aber wozu die Kommentare entfernen? Was soll das bringen - mehr Geheimhaltung?

Die Kommentare waren nicht nur wegen Dir da drin. Ich kommentiere meine Programme IMMER ausführlich. Auch für mich selbst. Und wenn ich nach einem Jahr oder mehr da noch was dran ändern will, wünschte ich mir oft, dass ich noch mehr kommentiert hätte.
(Edit: ja manchmal reichen auch schon ein paar Wochen, um sich mehr Kommentare zu wünschen  ;D  )
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 17, 2020, 11:15 pm
Er steht ja nun mit und ohne drin.

Dachte mir, die ganzen Kommentare belasten doch nur unnötig den eh schon knappen Speicher.
Ebenso, wie die am Ende nicht mehr benötigten prints und pulsout.

Der erste Post war mit, der zweite der kastrierte:)
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 17, 2020, 11:20 pm
Dachte mir, die ganzen Kommentare belasten doch nur unnötig den eh schon knappen Speicher.
Das war wohl früher bei Basic-Interpretern so, dass mehr oder weniger der ganze Source Code im Speicher stand.

Von dem was Du in der IDE in deinem Sketch schreibst/siehst, steht hinterher absolut nichts im Speicher das Arduino. Das steht nur in der Datei auf dem PC. Der Compiler macht da reinen Maschinencode draus, der dann in den Speicher  des Arduino kommt. Du kannst ganze Romane als Kommentar schreiben - dadurch wird hinterher nicht ein Byte mehr im Flash Speicher gebraucht.

Edit: Die Debug-Ausgaben landen natürlich schon im Flash und belegen da Platz. Das macht dann evtl. schon Sinn, dass rauszunehmen. Aber wie gesagt - es reicht einen Kommentar da draus zu machen. Vielleicht braucht man sie ja wieder, wenn man später den Sketch ändert oder erweitert.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 17, 2020, 11:47 pm
Wie verarbeitet der Compiler denn die Kommentare, das sie nachher nicht ein Byte brauchen.

wenn man mal so ein Programm wieder aus dem Arduino auslesen möchte in die IDE, weil man was dran machen will und vielleicht den Sketch nicht hat.
Da braucht man die selbst ja auch irgendwie wieder.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Serenifly on Feb 17, 2020, 11:55 pm
Wie verarbeitet der Compiler denn die Kommentare, das sie nachher nicht ein Byte brauchen.
Einfach ignorieren

Quote
wenn man mal so ein Programm wieder aus dem Arduino auslesen möchte in die IDE, weil man was dran machen will und vielleicht den Sketch nicht hat.
Das geht sowieso nicht. Du kannst den Maschinen-Code einigermaßen in Assembler zurück übersetzen. Aber da wird kein C/C++ Code mehr draus. Das geht einfach nicht. Die ganzen Variablen-Namen z.B. gehen verloren. Außerdem optimiert der Compiler stark und macht da manchmal ganz andere Dinge als du denkst
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 18, 2020, 12:13 am
ok, das heißt ein Code wird dabei in einen anderen geändert und der wird dann in den Speicher geschrieben.
Wozu ist das nötig?,
Warum schreibt man dann nicht direkt diesen Maschienencode und lädt den rein.
Ich schreib ja hier auch nicht auf Chinesisch und die Forumssoftware übersetzt es erst in Deutsch und postet es dann.

Oh je, wie einfach war doch die analoge Elektronik.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Serenifly on Feb 18, 2020, 12:19 am
Warum schreibt man dann nicht direkt diesen Maschienencode
Weil das kaum jemand könnte:
https://de.wikipedia.org/wiki/Maschinensprache#Beispiel (https://de.wikipedia.org/wiki/Maschinensprache#Beispiel)

Um das unnötig zu machen hat man sehr früh Assembler (https://de.wikipedia.org/wiki/Assemblersprache) entwickelt. Und das ist auch schon schwierig genug. Außerdem ist es fast völlig Hardware-abhängig (von Cross-Compilern mal abgesehen).

Hochsprachen wie C/C++ sind dagegen für Menschen gut lesbar und du kannst Code schreiben der auch auf unterschiedlichen Prozessoren läuft. Mit Einschränkungen wenn sich auf Mikrocontrollern wieder nah an der Hardware bewegt
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: skyfox60 on Feb 18, 2020, 12:34 am
ui, ok, verstanden.

Das kann tatsächlich wohl kaum einer lesen.

Ganz zu Anfang haben sich aber scheinbar einige damit ausgekannt, und mussten das machen, weils noch nichts anderes gab.
Respekt. Das ist ne Lebensaufgabe.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: michael_x on Feb 18, 2020, 12:40 am
Kann sich keiner mehr vorstellen, dass der allererste C - Compiler nicht selbst in C geschrieben wurde.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: MicroBahner on Feb 18, 2020, 09:20 am
Ja, der Weg von deinem Sketch bis zum Code im Arduino ist weiter als Du denkst ;) . Dein PC erledigt das zwar im Handumdrehen - aber was der dazu alles macht kannst Du dir kaum vorstellen.
Letztendlich dient das alles dazu, Dir das Leben leichter zu machen.
Auch wenn dir C++ kompliziert erscheinen mag ( und es in der Tiefe sicher auch ist ). Es ist geradezu nichts im Vergleich dazu, wenn DU den Maschinencode selbst erstellen müsstest.

N.B. Bei meinen ersten Schritten auf einem 6502 habe ich auch mal den dort vorhanden einfachst-Compiler selbst erweitert. Das war auch noch kein Cross-Compiler. Der lief auf dem 6502 selbst.
Das ist wie man sich selbst aus dem Sumpf zieht. Man schreibt den Compiler in seiner eigenen Sprache, und mit jeder Version kann er dann ein bisschen mehr - was man dann bei der nächsten Version wieder nutzen kann 8) .
War aber meilenweit ( eher Lichtjahre ;) ) entfernt von dem was jetzt geht.

Edit: Und immer schön Buch führen und sichern welchen Sketch Du auf welchen Arduino geladen hast. Denn wie schon geschrieben: Aus dem Arduino bekommst Du den nicht mehr zurück.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: agmue on Feb 18, 2020, 11:07 am
Das kann tatsächlich wohl kaum einer lesen.
Doch kann man. In diesem Forum sind ein paar aktiv, die sich mit solchen Dingen beschäftigt haben.

Neben mir liegt das Zilog Data Book (https://www.apple.asimov.net/documentation/hardware/processors/Zilog%20Data%20Book.pdf) als wohl gehütetes Juwel, mit recht abgenutzten Seiten 6 und 7.

Nach Jahrzehnten ist mir "C9" noch als Return in Erinnerung. Ich habe es gerade mal im Anhang E von Programmierung des Z80 (http://www.mathematik.uni-ulm.de/users/ag/yaze-ag/devel/Programmierung_des_Z80.pdf) nachgeprüft.

In der IDE kannst Du in den Voreinstellungen die ausführliche Ausgabe während der Kompilierung einschalten, dann siehst Du, was Dein PC in Windeseile so tut. Aus dem kompfortablen C++ wird "Zahlensalat" für den µC, siehe  *.ino.hex

Einige schlaue Spezialisten beschäftigen sich gerade jetzt mit solchen Fragen, da sie einen neuen µC designen oder überarbeiten. Chapeau!

Mir war das zu hoch und zu mühselig. Für mich blieb es daher nur Hobby, schon ein paar blinkende LEDs machen mich glücklich!
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: postmaster-ino on Feb 18, 2020, 05:39 pm
Hi

Assembler hat durchaus Seinen Reiz - ist aber auf genau diesen µC / diese Familie zugeschnitten.
So kannst Du eine .hex von einem Uno nicht auf einem Mega benutzen - ist ein anderer µC, andere Register, andere Hardware (z.B. mehr Timer, mehr serielle Schnittstellen - hat der Uno Alles gar nicht).
Was geht Uno<->Nano (der 'normale' Nano) - Das aber auch nur, weil diese Beiden den gleichen µC benutzen, einzig das Aussehen (und beim Nano zusätzlich A6/A7) ist anders.

Am "Schneider CPC464" und an einem 80286er, wie dann kurz vor Arduino an ATtiny45 (25/45/85 haben den gleichen Befehlssatz, Register ect.pp. - nur der Speicher ist jeweils größer - 45 und 85 lassen sich auch mit der IDE programmieren - beim 25 ist einfach zu wenig Platz drin) habe ich mit Assembler 'gespielt'.
Am ATtiny45 habe ich händisch in Assembler DS18B20, also 1-wire Temperatur-Sensoren ausgelesen und auf eine 4x 8x8er Dot-Matrix (MAX7219, SPI) ausgegeben.
Das Ganze dauert aber Äonen länger, als in der IDE drei Zeilen Code hinzukritzeln, kompileren, hochschieben, glücklich sein.
Ok - man kennt jedes Bit in den Innereien mit Vornamen - bringt Einem aber recht wenig.

Beim Arduino, also hier den AVR-µC, ist der Befehlssatz übersichtlich klein - es gibt nur wenige Knöpfe, Die man drücken kann, um ALLES, was man mit dem Steinchen machen kann, zu machen. Das Datenblatt zum µC zeigt auch die (meine 131 - Alle machen immer nur eine Kleinigkeit) Assembler-Befehle, Die der µC kann - und damit kann man dann ALLES machen ... wenn man kann ... man muß halt nur den richtigen Knopf zur richtigen Zeit drücken ...

Hier schlägt dann die Stunde der Hochsprachen - jeder Deiner Sketche wird auf den von Dir angewählten µC hin übersetzt (Uno/Mega/ESP oder sonst was), dort kristallisiert sich auch heraus, wie viel Platz wohl benötigt wird.
Man kann zwar auch in Assembler richtig programmieren, also auch Sprungmarken und so Zeug, ist aber wenigstens auf die Familie (AVR oder PIC, 8088, die 286/386/486er Prozessoren - also Vor-Pentium Zeug) begrenzt.
Man lernt viel eher, wie sich die Datentypen zusammen setzen, man spart, wo man kann - man nimmt also keine 16bit-Variable, wenn man auch mit einer 8bit zurecht kommt - auch, weil der kleine AVR 8bit in einem Takt verarbeitet.
Man ist viel mehr am Bytes oder Timer-Ticks zählen, als in den Hochsprachen - ok, in Assembler wieß man, wie lange ein Befehl dauert - in der Arduino-IDE ist's nicht 100% sicher, was aus einem digitalWrite wirklich wird, weil Das im Kontext durchaus anderen Code ergeben kann - am Schluss bekommst Du Deinen Ausgang geschaltet, der Weg dahin bleibt aber dem Kompiler überlassen.
Ist aber interessant, was ein heutiger Kompiler an nahezu idealen Assembler/Maschinen-Code zusammen bekommt - wobei ich Das auch nur an Mini-Beispielen ansatzweise überschauen kann - aber immerhin da.

Doch, ich mag Assembler

MfG
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Serenifly on Feb 18, 2020, 07:39 pm
Assembler hat auch zur Detail Optimierung an extrem zeit-kritischen noch seine Berechtigung. Vor allem FastLED macht da interessante Sachen mit optimierten Funktionen um bestimmte Rechnungen zu beschleunigen.

Und man lernt generell sehr viel über Logik und wie µC arbeiten wenn man sich wirklich um alle Details kümmern muss. Recht einfache Elektronik-Anwendungen sind mit Assembler nicht soooo kompliziert. Ich habe da in der Vergangenheit viel mit dem 8052 gemacht.

in Assembler wieß man, wie lange ein Befehl dauert
Da gibt es schöne Übungen sich Verzögerungs-Unterprogramme auf den Takt genau zu bauen. Die Ausführungszeit zweier ineinander verschachtelten Schleifen zu zählen hat es durchaus in sich.
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: Tommy56 on Feb 18, 2020, 08:00 pm
Da gibt es schöne Übungen sich Verzögerungs-Unterprogramme auf den Takt genau zu bauen. Die Ausführungszeit zweier ineinander verschachtelten Schleifen zu zählen hat es durchaus in sich.
Damit haben wir früher (TM) unter DOS/Win 3 den PC ausgebremst, damit die alten Spiele auf schnelleren PC spielbar blieben.

Gruß Tommy
Title: Re: Frage eines Anfängers zu einem LCD Display 16x2 oder so
Post by: michael_x on Feb 18, 2020, 10:51 pm
Stimmt:

Die inline asssembler Anweisung
 __asm __volatile ("nop"); // 1 Takt mehr  (62.5 ns auf einem 16 MHz Arduino )
macht evtl. gelegentlich Sinn. Das compiliert auch für jedes avr-gcc Zielsystem (attiny .. atmega)  :)