Go Down

Topic: Zähler per Lichtschranke, Problem mit dem Statusspeichern der Lichtschranke (Read 474 times) previous topic - next topic

MicroBahner

Noch ein Tipp zu deinen Kommentaren. Am Anfang ist es zwar verständlich, dass Du die Syntax kommentierst. Aber das wirst Du schnell lernen, und es ist ja auch immer dasselbe. Dann ist der Kommentar wertlos.
Viel wichtiger ist, dass Du die Semantik kommentierst. Z.B. hier:
Code: [Select]
if (photoWert2 < 50) //Wenn der Sensorwert 2 kleiner 50 ist….
Der Kommentar ist eine Übersetzung des Codes ins deutsche. Viel wichtiger wäre aber zu kommentieren, was das bedeutet, und wann es eintreten soll:
Code: [Select]
if (photoWert2 < 50) //Wenn die Lichtschranke am Ende der Strecke belegt ( unterbrochen ) ist….
Gruß, Franz-Peter

combie

Quote
Viel wichtiger wäre aber zu kommentieren, was das bedeutet, und wann es eintreten soll:
Meine Oma sage schon:
> "Was" da passiert, sieht man auch so, muss man nur die Döppen für auf machen..
> "Warum" es passiert, das ist eine Erklärung wert.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Doc_Arduino

Hallo,

ich würde für das sichere zählen per Lichtschranke noch eine Schwellwerthysterese einbauen. Sonst zappelt das und zählt bestimmt falsch?
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

MicroBahner

Sicher eine gute Idee. Erhöht auf jeden Fall die Zuverlässigkeit.
Gruß, Franz-Peter

Nordlicht

Hallo Zusammen,

mit der Änderung von MircoBahner funktioniert die Lichtschranke genau so wie sie soll. Vielen dank für die Hilfe :)

Und vielen dank für die zahlreichen weiteren Post mit Hilfestellungen zum programmieren von allen anderen. Ich habe gerade erst angefangen eigene Scatche zu schreiben, da hilft mir das sehr weiter.

Schönen Sonntag allen

Nordlicht

combie

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

Quelle: Joseph Joubert

Doc_Arduino

Hallo,

habe mir einmal die Mühe gemacht zu bauen wie ich dachte, dabei habe ich unweigerlich eine Klasse gebaut.
Auch wenn vielleicht Klassen, Objekten, Instanzen, Methoden, Member noch Neuland für dich sind, müßtest du im Grunde nur die Parametrierung in Zeile 90, 91, 93 und 94 ändern. Vielleicht auch eine Grundlage für später.

Die Zählvariable count bzw. der Rückgabe wert des Funktionsaufrufes in Zeile 115 wäre das zum auswerten.

Getestet mit einem 2 Potis als Kreuzknüppel.

Code: [Select]
/*
  Doc_Arduino - german Arduino Forum
  IDE 1.8.10
  avr-gcc 9.2.0
  Arduino Mega2560
  08.12.2019

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


class Schranke
{
  private:
    const uint8_t  pin;
    const uint16_t minHys;
    const uint16_t maxHys;
    const uint16_t intervall;
    uint32_t       lastMillis {0};
    bool state {true};
    bool newRead {true};
    bool oldRead {true};


    // speichert die "Schalterstellung" der Lichtschranke in 'newRead' abhängig der Hysterese
    void readPhotocell ()
    {
      uint32_t ms {millis() };

      if (ms - lastMillis >= intervall)
      {
        lastMillis = ms;
        uint16_t licht = analogRead(pin);
        if (licht < minHys)  newRead = false;
        if (licht > maxHys)  newRead = true;
      }
    }


    // wandelt die Schalterstellung in ein nicht retriggerbares Signal zum späteren zählen um
    // erzeugt praktisch nur einen Impuls zum einmaligen zählen pro Lichtschrankensignalwechsel
    void updateNoRetrigger()
    {
      state = false;

      if (!newRead && (oldRead) )   // nur wenn das vorherige Signal HIGH und das neue Signal LOW ist,
      {
        state = true;               // gibt es ein zählenbares Triggersignal
      }
      oldRead = newRead;
    }


  public:
    // Konstruktor
    Schranke(const uint8_t p, const uint16_t min, const uint16_t max, const uint16_t intv) :
      // Initialisierungsliste
      pin{p},
      minHys{min},
      maxHys{max},
      intervall{intv}
    {}


    void updaten(void)
    {
      readPhotocell();
    }

   
    bool getTrigger(void)
    {
      updateNoRetrigger();
      return state;
    }


    bool getState(void)
    {
      return newRead;
    }
};


/*              Pin
                |    min.Hysteres
                |    |    max.Hysteres
                |    |    |    Abfrageintervall der Lichtschranke [ms]
                |    |    |    |                      */
Schranke lichtA(A3, 350, 700, 10);    // Anfang vom Streckenabschnitt
Schranke lichtB(A4, 350, 700, 10);    // Ende vom Streckenabschnitt

const byte pinLedA {28};
const byte pinLedB {29};

int count;                // Wagenzähler

void setup(void)
{
  Serial.begin(9600);
  pinMode(pinLedA, OUTPUT);
  pinMode(pinLedB, OUTPUT);
}


void loop(void)
{

  lichtA.updaten();                             // permanent aktualisieren
  lichtB.updaten();
 
  digitalWrite(pinLedA, lichtA.getState() );    // Abfrage des aktuellen Signals der Lichtschranke in Abhängigkeit der Hysterese
  digitalWrite(pinLedB, lichtB.getState() );

  count = wagenCounter();       // wertet beide Lichtschrankentrigger aus und gibt Zählerstand zurück

  seriellerMonitor(count);      // Zählerstandausgabe
}


// ****** Funktionen ******

int wagenCounter ()
{
  static int counter {0};

  if (lichtA.getTrigger() ) counter++;
  if (lichtB.getTrigger() ) counter--;

  return counter;
}


void seriellerMonitor (int data)
{
  static int oldData {0};

  if (data != oldData)
  {
    Serial.println(data);
    oldData = data;
  }
}


Edit: Feinschliff im Monitor und Methoden um eine weitere aufgesplittet
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Nordlicht

Hallo Doc_Arduino,

deine Variante weicht ja sehr von der bis jetzt von mir verwendeten ab. Vielen dank für die Mühe.
Der Vorteil ist eine zuverlässigere Arbeitsweise?
Von Klassen, Objekten usw. habe ich keine Ahnung. Da muss ich mich wohl mal rein lesen :)

Gruß
Nordlicht

MicroBahner

Von Klassen, Objekten usw. habe ich keine Ahnung. Da muss ich mich wohl mal rein lesen :)
Ich würde an deiner Stelle erst mal schauen, dass Du in den Grundlagen fit wirst. Man kann auch ohne ( eigene ) Klassen gut funktionierende Programme schreiben  ;) .
Gruß, Franz-Peter

Nordlicht

Hallo MicroBahner,

hast du zum fit werden einen Tipp? Ein besonderees Buch lesen? Mein Plan war es Projekte zu überlegen und bei dem Versuch der Umsetzung "zu wachsen". Die Übungsaufgaben habe ich gemacht.

combie

Quote
hast du zum fit werden einen Tipp?
Wenn du OOP lernen möchtest, dann habe ich einen Tipp:
Der C++ Programmierer
Die ersten 50% sind OOP und C++ Grundlagen
Die zweiten beschäftigen sich mit der STL und GUIs
(Arduino wird übrigens mit keinem Wort in dem Buch erwähnt)


Quote
Ich würde an deiner Stelle erst mal schauen, dass Du in den Grundlagen fit wirst. Man kann auch ohne ( eigene ) Klassen gut funktionierende Programme schreiben
Ich kann übrigens nur dazu raten, erst die OOP zu lernen.
Also nicht mit dem C Stil anzufangen. Den lernt man automatisch mit.

Denn:
Wer die prozedurale Programmierung begriffen hat, ist verdorben für die OOP.
OK, nicht völlig verdorben. Aber es erschwert das (um)lernen doch ungemein.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

MicroBahner

Gut, da könnte mann jetzt trefflich, lange und fruchtlos drüber diskutieren  ;) .
Aber nicht jeder, der sich etwas mit Arduino beschäftigt, will gleich Profi-Programmierer werden. Aus der Beschreibung zum Buch:
Quote
Es ist für Anfänger gedacht, die noch keine Programmiererfahrung haben, sich aber beruflich mit C++ beschäftigen wollen oder werden, zum Beispiel Studierende technischer Fächer.
Da muss dann jeder selbst entscheiden, ob er so tief einsteigen will.

OOP wurde als ein Lösungsansatz entwickelt, die Softwarekrise zu lösen. Die Zusammenarbeit in grossen Programmiererteams sollte verbessert ( Modularisierung ) und die Erstellung von wiederverwendbarer Software erleichtert werden. Inwieweit diese Argumente für den Arduino-Hobbyprogrammierer greifen sei dahingestellt. Bei der Erstellung von Lib's greift auf jeden Fall das Argument 'wiederverwendbare Software' weshalb ja praktisch auch alle Lib's in diesem Stil programmiert sind. Zur Nutzung solcher Lib's sind aber keine tiefgehenden OOP-Kenntnisse nötig.

Letztendlich muss jeder selbst entscheiden, wie tief er einsteigen will. Und wer die OOP-Techniken rein aus persönlichem Interesse erlernen will, dem steht ja auch nichts im Wege.

Ich behaupte nur: der Großteil der Arduino-Hobbyisten kommt auch gut ohne selbstgeschriebene Klassen aus  :smiley-grin:
Gruß, Franz-Peter

combie

Quote
Gut, da könnte mann jetzt trefflich, lange und fruchtlos drüber diskutieren  ;) .
Das könnte man.
Denn es gibt wirklich diese 2 Fraktionen.
Die einen sagen:  Lerne erst C und dann C++,
Und die andere sagt dazu: Was ein Blödsinn.

Zu welcher ich gehöre, darfst du drei mal raten :o
Natürlich habe ich gewichtige Gründe für meine Ansicht.


Als Begründung für die andere Ansicht möchte ich folgendes anführen:
Wer sich einmal richtig in den C Stil rein gequält hat, der tut sich mit der Umstellung auf OOP, Templates und Operatorenüberladung recht schwer.

Das wird dann plötzlich zu einem Apfel, welcher zu hoch hängt.
Am schönsten ist es dann, den Apfel für "Der ist sowieso sauer!" zu erklären.
Dann kann man ihn guten Herzens hängen lassen.


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

Quelle: Joseph Joubert

Tommy56

Ich komme ja aus der ANSI-C-Ecke. Ja, der Umstieg auf OOP (JAVA) war nicht ganz einfach, zumal ich parallel immer noch prozedural in PL/SQL gearbeitet habe.
Wenn man das Grundanliegen von OOP erst mal verinnerlicht hat, wird es leichter, es anzunehmen.

Ich sehe den OOP-Ansatz auch weniger vordergründig in der Wiederverwendbarkeit. Ich sehe ihn eigentlich in einer stärkeren Annäherung an die reale Welt, bei der auch eine enge Verflechtung der Daten mit dem Handling gegeben ist.

Ob es anders herum leichter gewesen wäre, kann ich nicht sagen.

Nur so ein paar Gedanken aus meiner Erfahrung.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

MicroBahner

Die einen sagen:  Lerne erst C und dann C++,
Nun ja, C++ ist ja nicht nur OOP und Klassen. Da gibt es eine ganz Menge Erweiterungen zu C, die auch ohne OOP gut und sinnvoll sind. Und ich behaupte ja auch nicht, dass OOP grundsätzlich nicht sinnvoll ist. Ich mach ja auch viel damit.
Aber wer rein OOP lernen und damit starten will, sollte am besten nicht mit Arduino anfangen. Hier wird oft gesagt: schau dir die Beispiele der IDE an. Aber da ist von OOP nichts zu sehen ( zumindest für den Einsteiger nicht ;) ). D.h. wer mit Arduino anfängt und die vielen Tutorials nutzt, ist nach deiner Argumentation schon auf dem falschen Weg.
Ich sage ja auch nicht 'Finger weg von OOP' - absolut nicht. Nur wenn ich mir hier die Fragesteller so anschaue - die Mehrzahl wird nie so tief einsteigen ....

Aber wie gesagt - wir wollen den Tread hier nicht kapern, und der TO muss letztendlich selbst entscheiden wo seine Zielmarke liegt. Vielleicht helfen ihm diese paar Posts ja schon dabei.
Gruß, Franz-Peter

Go Up