Go Down

Topic: Frage eines Anfängers zu einem LCD Display 16x2 oder so (Read 1 time) previous topic - next topic

skyfox60

@ postmaster_ino,

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

Mir raucht hier der Schädel, das es nur so Nebelt. :)
Der leckerste Fisch ist immer noch der Rumpsteak.

postmaster-ino

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
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

skyfox60

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);
  }
 
}
Der leckerste Fisch ist immer noch der Rumpsteak.

skyfox60

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
  }
Der leckerste Fisch ist immer noch der Rumpsteak.

postmaster-ino

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
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

skyfox60

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.
Der leckerste Fisch ist immer noch der Rumpsteak.

postmaster-ino

#51
Feb 16, 2020, 05:22 pm Last Edit: Feb 16, 2020, 06:56 pm by 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.
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

MicroBahner

#52
Feb 16, 2020, 05:56 pm Last Edit: Feb 16, 2020, 05:59 pm by MicroBahner
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.
Gruß, Franz-Peter

skyfox60

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
Der leckerste Fisch ist immer noch der Rumpsteak.

postmaster-ino

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
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

MicroBahner

#55
Feb 16, 2020, 06:42 pm Last Edit: Feb 16, 2020, 06:42 pm by MicroBahner
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 ;)
Gruß, Franz-Peter

agmue

... 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.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Serenifly

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

Whandall

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
  }


Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

skyfox60

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.
Der leckerste Fisch ist immer noch der Rumpsteak.

Go Up