-         
Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 28 von 28

Thema: Tastenentprellung +++ Fehlerhaft

  1. #21
    Erfahrener Benutzer Robotik Einstein Avatar von Moppi
    Registriert seit
    18.03.2018
    Beiträge
    1.974
    Blog-Einträge
    15
    Anzeige

    Praxistest und DIY Projekte
    Ich denke mal, wissen tu ich es ja nicht, dass Du diese Geschichte später woanders einsetzen willst, sprich, das muss alles ausgelagert werden, dass es später eingebunden werden kann. Da fängt man wohl mit einem Programmgerüst dafür an, würde ich jetzt so machen. Ich mache ein Beispiel. Dauert etwas ...

    Programmierst Du auch mit Arduino IDE ?

    MfG

    - - - Aktualisiert - - -

    Es gibt bei Klassen Methoden und Varibalen, die nach außen nutzbar sein sollen und damit "sichtbar" sind, also aufgerufen werden können und es gibt das Gegenteil, Methoden und Variablen, die nur innerhalb der Klasse verwendet werden und damit "privat" sind, also nicht nach außen sichtbar.

    Folgende Dateien könnten im Verzeichnis "libraries" im Arduino-Ordner gespeichert werden (dann dort Verzeichnis "MeinCode" und darin beide Dateien, *.h und *.cpp), damit sie in anderem Arduino-Code eingebunden werden können.


    Beispiel für "MeinCode.h"

    Code:
    #ifndef MeinCode_h
    
    
    #define MeinCode_h
    #include <Arduino.h>
    
    
    class MeinCode    //Klasse "MeinCode"
    {
      //Alle öffentlichen Variablen und Methoden hier bekanntgeben
      public:
        byte val1, val2;                     //Variablen
        MeinCode(unsigned long bps);  //Methode "MeinCode" - Hauptkonstruktor ... wird beim Instanziieren automatisch mit der Klasse aufgerufen
        boolean SendRequest(void);    //Methode von "MeinCode"
        
      //alle nicht öffentlichen Variablen und Methoden hier bekanntgeben
      private:
        void    ClearRBuffer(void);     //Methode
        boolean get2Chars(void);       //Methode
        int a;                                 //Variable
        unsigned long lastMillis;        //Variable
        byte tv1, tv2;                      //Variablen
    };
    
    
    #endif

    Beispiel für "MeinCode.cpp"

    Code:
    #include <Arduino.h>
    #include <MeinCode.h>
    
    //-----------------------------------------------------
    //Hauptkonstruktor
    //-----------------------------------------------------
    MeinCode::MeinCode(unsigned long bps)
    
    {
       .....
    }
    //-----------------------------------------------------
    boolean MeinCode::SendRequest(void)
    {
      ClearRBuffer();
      ....
      return ...;
    }
    //-----------------------------------------------------
    void MeinCode::ClearRBuffer(void)
    {
      ....
    }
    //-----------------------------------------------------
    boolean MeinCode::get2Chars(void)
    {
       ....
       return ....;
    }
    Eingebunden und verwendet wird das später, dann z.B. so.

    Code:
    #include <MeinCode.h>
    
    
    MeinCode meineInstanz();   //Hauptkonstruktor aufrufen, Instanz erzeugen (initialisieren von irgendwas im Code der Klasse "MeinCode")
    
    
    void setup() {
    
    
    }
    
    
    void loop() { 
    
    
        //Methoden (Funktionen) der Klasse "MeinCode" können über meine Instanz angesprochen werden
        if(meineInstanz.SendRequest()){
           . ...
        }
    
        //Variablen können wie Methoden meiner Instanz angesprochen werden
       Serial.print(meineInstanz.val1);
    
    
    }

    Für mehr Informationen siehe hier z.B. (da gibts noch zahlreiche andere Links im Netz) http://www.mintgruen.tu-berlin.de/ro...n:objektorient



    MfG
    Geändert von Moppi (18.04.2020 um 12:25 Uhr)

  2. #22
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.06.2019
    Beiträge
    124
    GM Moppi.
    Vielen Dank für deine Ausführungen!

    Tatsächlich beschäftige ich mir hier erst einmal mit Grundlagen, wie Kontaktentprellungen, Mittelwerte, Analogein-/ausgänge, etc.
    Diese werde ich dann in universelle und "griffige" Funktionen stecken, um sie dann später in diversen Programmen nach belieben zu verwenden.
    Hierbei hatte ich daran gedacht, die Funktionen irgend wie in eine Bibliothek zu fassen um via Copy/Paste die Funktionen einzubinden.
    Die von dir beschriebene Methode klingt da irgendwie "flexibler" und professioneller...
    Aber erst wenn die Funktionen super stabil laufen - dauert bei mir also noch etwas.

    Ja, ich programmiere den Teensy 3.2 über Arduino 1.8.5/Teensyduino 1.47.
    __________________________________________________ _
    | Sprache: C | Teensy 3.2 | Status: EwigerAnfaenger |

  3. #23
    Erfahrener Benutzer Robotik Einstein Avatar von Moppi
    Registriert seit
    18.03.2018
    Beiträge
    1.974
    Blog-Einträge
    15
    Ich verstehe Deine Einwände und kann das nachvollziehen. Kann Dir aber aus Erfahrung sagen, dass das nachträgliche Umstricken von Code, in eine andere Form u.U. nicht ganz trivial ist. Ich habe Deinen Code gesehen und Dir einen Vorschlag unterbreitet, der eigentlich eine super Sache ist. Weil Du brauchst irgendein Programmgerüst - setup() + loop() ist keines in dem Sinn. Du musst den Code in eine gescheite Form bringen, damit der gut wartbar ist und weiterzuverwenden. Und damit man gut durchblickt. War eigentlich nur als Abkürzung für Dich gedacht. Aber Du kannst das machen, wie Du möchtest. Erfahrung muss man selber sammeln. Kann Dir nur einen Rat noch mit auf den Weg geben: wenn Du den Code aufbaust, probiere ihn aus, immer und immer wieder, ob er funktioniert. So erkennst Du frühzeitig, wenn etwas nicht funktioniert und kannst stark einkreisen, in welchem Programmabschnitt sich ein Problem befindet. Übung macht hier den Meister, im wahrsten Sinn des Wortes. Zahlreiche Verstrickungen, um Ecken (Variablen in einer Funktion definieren, dann aber als statisch, um am Ende dann über Zeiger/Verweise die Variable an weitere Funktionen zu übergeben, usw.) macht es nicht gerade einfacher einen Fehler zu finden, auch wenn der Code nicht so groß ist. Deswegen bin ich auch kein großer Anhänger von Kompilerdirektiven.

    Freundlichen Gruß

  4. #24
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.06.2019
    Beiträge
    124
    ...Kompilerdirektiven
    Habe ich die benutzt?

    Du hast vollkommen Recht - werde ich auch machen, brauche aber noch allgemeingültige/universelle Vereinbarungen für mich selber.
    Z.B. bin ich mir nicht sicher, ob die Entprellzeit im den Globalvariablen-Bereich
    HTML-Code:
    const int EntprellZeit = 30;   // [ms], Entprellzeit (typ.Prellzeit 0,1-30ms)
    oder besser (kontrollierter, leserlicher) in der Funktion Entprell() aufgehoben ist
    HTML-Code:
    static int EntprellZeit = 30;   // [ms], Entprellzeit (typ.Prellzeit 0,1-30ms)
    Mit meinem derzeitigen code bin ich schon sehr zufrieden - gibt 3 Zustände zurück - 0..LOW, 1...HIGH, 2...in Entprellung
    HTML-Code:
    //==========MAIN==========//
    void loop() {
      static int AusgImpuls = 0;                // Ausg-AusgImpuls [ms]
      AusgTakt(AusgImpuls, 1000);               // Taktdauer [ms], Intervall [ms]
      
      static int TasteLiZustand = 0;            // akt. Zustand 0/1 der Taste
    
      if(Entprell(TasteLiPin) == 1) {           // sobald Taste HIGH und entprellt
        AusgImpuls = 900;                       // Ausg-AusgImpuls bei Taste HIGH
        TasteLiZustand = 1;                     // speichert das Taste "1" ist
      }
      else if(Entprell(TasteLiPin) == 0) {      // sobald Taste LOW und entprellt
        AusgImpuls = 10;                        // Ausg-AusgImpuls bei Taste LOW
        TasteLiZustand = 0;                     // speichert das Taste LOW ist
      }
      else
        TZ("Medlung: Kontakt derzeit in Entprellung");
    }
    
    //----------STANDARD-FUNKTIONEN----------//
    //Kontaktentprellung durchführen, Zustand zurück geben
    //Rückgabe 3 Zustände; "0"...LOW+Kontakt entprellt / "1"...HIGH+Kontakt entprellt / "2"...Zustand unbekannt, in Entprellung 
    int Entprell(int Pin) { 
      static int KontaktStatusNeu = 0;              // akt.Zustand
      static int KontaktStatusAlt = 0;              // vorheriger Zustand
      static unsigned long KontaktStartZeit = 0;    // Startzeit der ersten Kontaktzustandsänderung
    
      KontaktStatusNeu = digitalRead(Pin);          // speichert akt. Kontaktzustand
      if(KontaktStatusNeu != KontaktStatusAlt) {    // wenn sich Kontaktzustand ändert
        KontaktStartZeit = millis();                // speichert aktualisierte Startzeit
        KontaktStatusAlt = KontaktStatusNeu;        // geänderter Zustand gespeichert
      }
      if(KontaktStatusNeu == 0 && (millis() >= KontaktStartZeit + EntprellZeit)) // wenn Entprellzeit überschritten und Kontakt LOW
        return 0;                                   // "0" zuück, Kontakt LOW und entprellt
      else
        if(KontaktStatusNeu == 1 && (millis() >= KontaktStartZeit + EntprellZeit)) // wenn Entprellzeit überschritten und Kontakt HIGH
          return 1;                                 // "1" zurück, Kontakt HIGH und entprellt
      else
        return 2;                                   // "2" zurück, noch nicht entpellt, Kontaktzustand unbekannt
    }
    Fehlt nur noch, dass mehrer Taster/Kontakt gleichzeitig entprellt werden können.
    Danach werde ich die Zustands- und Entprellgeschichte in eine Bibliothek (*.h, *.cpp) einrichten.

    - - - Aktualisiert - - -

    ...ETWAS SPÄTER:

    Habe derzeit das Problem, dass innerhalb einer Entprellphase, keine andere Entprellung erfolge kann.
    Solang eine Entprellung läuft, werden alle anderen Kontakte/Tasten "verschluckt".
    Ursache ist, dass die Funktion Entprellung() eine Startzeit speichert und diese berechnet.

    Können diese 30ms-Überlappungen in der Praxis vernachlässigt werden?
    Oder sollte/muss ich für jede Taste/Kontakt eine eigene Funktion vorhalten, in der die Entprell-Startzeit gespeichert wird?
    __________________________________________________ _
    | Sprache: C | Teensy 3.2 | Status: EwigerAnfaenger |

  5. #25
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    09.10.2014
    Beiträge
    5.124
    du kannst, wie schon mal vorgeschlagen wurde, entweder einen C-Strukturtyp mit allen wesentlichen Variablen anlegen und dann für jeden Taster davon einen "Variablen-Ableger" erstellen oder eine C++ Klasse erstellen mit allen Variablen und Methoden, und davon für jeden Taster eine eigene Objekt-Instanz erstellen.
    Wenn du das selber schaffst, wirst du sicher viel lernen.
    Der einfachere Weg geht ntl über fertige Libs, denn du bist ntl nicht der erste, der sich darüber Gedanken macht - auch das wurde ja bereits vorgeschlagen.
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  6. #26
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.06.2019
    Beiträge
    124
    GM!
    Kontaktentprellung klappt, auch mit mehereren Kontakten unabhängig.
    Nun versuche ich universelle Blocks aufzubauen - Bibliothekaufbau kommt zum Schluss.

    Bei static Variablen bin ich mir der Namesgebung unschlüssig.
    Kann es ein Problem geben, wenn ich die gleichen Var.Namen in unterschiedlichen Funktionsblöcken vergebe?
    Bsp: (beide Var "KontakPin" haben nichts miteiander zu tun)
    HTML-Code:
    int Funktion1() {
      static int KontaktPin;
      ...sonst was...
    }
    
    int Funktion2() {
      static int KontaktPin;
      ...sonst was...
    }
    __________________________________________________ _
    | Sprache: C | Teensy 3.2 | Status: EwigerAnfaenger |

  7. #27
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    09.10.2014
    Beiträge
    5.124
    hallo,
    nein, in unterschiedlichen Funktionen dürfen die lokalen static Variablen heißen wie sie wollen, auch identisch, genauso als wären sie nicht static.
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  8. #28
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.06.2019
    Beiträge
    124
    Passt!
    Beliebig viele Tasten/Kontakte verwendbar, nacheiender oder ~gleichzeitig~.
    Pro Taste/Kontakt wird ledigtlich der "Zwischenspeicher" TasteMi, TasteLi kopiert und umbennat.
    Entpreller() setzt die Entprellzeit (Bsp.5ms) aus Sicherheitsgründen hinter die letzte Zustandsänderung.

    HTML-Code:
    void loop() {
      switch(TasteLi(TasteLiPin)) {
        case 0: Ausgang(LEDrtPin, 0); TZ("T/LINKS auf -0- entprellt!"); break;
        case 1: Ausgang(LEDrtPin, 1); TZ("T/LINKS auf -1- entprellt!"); break;
        case 2: TZ("Meldung: T/LINKS IN Entprellung"); break;   
      }
    
      switch (TasteMi(TasteMiPin))  {
        case 0: Ausgang(LEDgePin, 0); TZ("T/MITTE auf -0- entprellt!"); break; 
        case 1: Ausgang(LEDgePin, 1); TZ("T/MITTE auf -1- entprellt!"); break;
        case 2: TZ("Meldung: T/MITTE IN Entprellung"); break;
      }
    }
    
    //Kontakt Zustandsänderung, nur FunktionsName ändern, Rest ist Universell
    int TasteLi(int KontPin) {  //Prüfung; gibt 4 Zustand zurück; 0...Entprellt+LOW, 1...Entprellt+HIGH, 2...IN Entprellung, 3...keine Zustandsänderung
      static unsigned long StartZeit = 0; 
      static int KontZustAlt = digitalRead(KontPin);
      static int EntprellStatus = digitalRead(KontPin); 
     return Entpreller(KontPin, StartZeit, KontZustAlt, EntprellStatus); 
    }
    
    //Kontakt Zustandsänderung, nur FunktionsName ändern, Rest ist Universell
    int TasteMi(int KontPin) {  //Prüfung; gibt 4 Zustand zurück; 0...Entprellt+LOW, 1...Entprellt+HIGH, 2...IN Entprellung, 3...keine Zustandsänderung
      static unsigned long StartZeit = 0;   
      static int KontZustAlt = digitalRead(KontPin);  
      static int EntprellStatus = digitalRead(KontPin); 
      return Entpreller(KontPin, StartZeit, KontZustAlt, EntprellStatus); 
    }
    
    //Kontakt-Entprellung; gibt 4 Zustände zurück; 0...Entprellt+LOW, 1...Entprellt+HIGH, 2...derzeit in Entprellung, 3...keine Zustandsänderung
    int Entpreller(int KontPin, unsigned long &StartZeit, int &KontZustAlt, int &EntprellStatus) {
      int KontZustNeu = 0;
      if((KontZustNeu = digitalRead(KontPin)) == EntprellStatus) {
        return 3; 
      }
      if(KontZustNeu != KontZustAlt) { 
        StartZeit = millis(); 
        KontZustAlt = KontZustNeu;
      }
      if(KontZustAlt == 0 && (millis() >= StartZeit + EntprellZeit)) 
        EntprellStatus = 0; 
      else if(KontZustAlt == 1 && (millis() >= StartZeit + EntprellZeit)) 
        EntprellStatus = 1; 
      else
        EntprellStatus = 2; 
      
      return EntprellStatus;
    }
    PS:
    Was haltet ihr von dem code?
    Wie kann ich das ganze jetzt in eine Bib. packen?
    Vermutlich kann nur Entpreller() ausgelagert werden - oder?
    __________________________________________________ _
    | Sprache: C | Teensy 3.2 | Status: EwigerAnfaenger |

Seite 3 von 3 ErsteErste 123

Ähnliche Themen

  1. ISR Fehlerhaft
    Von Zille im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 20.01.2014, 18:11
  2. Tastenentprellung-Wiki
    Von Finn91 im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 03.03.2009, 20:37
  3. Schaltung fehlerhaft
    Von Atmelbeginne im Forum PIC Controller
    Antworten: 3
    Letzter Beitrag: 12.09.2008, 16:56
  4. Uartausgabe Fehlerhaft
    Von Picht im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 19.02.2007, 16:45
  5. Tastenentprellung mit Bascom
    Von milisan im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 23.11.2004, 06:06

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •