Frage eines Anfängers zu einem LCD Display 16x2 oder so

Hallo Ludger,

skyfox60:
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.

postmaster-ino:
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 :wink:

postmaster-ino:
... auch bin ich mir nicht sicher, zu welchem Pin Das Dann wird ...

Test:

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.

skyfox60:
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

postmaster-ino:
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?

skyfox60:
Noch ein Versuch.

Das funktioniert nicht

} 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
  }

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.

@skyfox60 ich habe nicht deinen untauglichen Versuch kommentiert, sondern die falsche Erklärung.

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

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.

postmaster-ino:
Der Erklärung zu NAV=!NAV; kann ich nun auch keine größeren Fehl-Aussagen entnehmen - bitte konkreter kritisieren

Gerne.

Das Statement

  NAV=!NAV;

kommt im Kode des OP nicht vor, sondern der enthält das Statement

  if (NAV) !NAV;

Dein ganzes Elaborat gehört also nicht zu diesem Sketch, ich betrachte das als Fehler.

postmaster-ino:
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.

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.

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:

// 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);
  }
 
}

Der Vollständigkeit halber hier auch noch der bereinigte Sketch ohne Kommentare und ohne prüfpins und Prüf-Prints.

// 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);
    
  }
 
}

Hi

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 ...

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 )

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:)

skyfox60:
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.

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.

skyfox60:
Wie verarbeitet der Compiler denn die Kommentare, das sie nachher nicht ein Byte brauchen.

Einfach ignorieren

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

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.

skyfox60:
Warum schreibt man dann nicht direkt diesen Maschienencode

Weil das kaum jemand könnte:

Um das unnötig zu machen hat man sehr früh Assembler 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