RPM PIGPIO falsche Werte "entprellen"


  • Wie schon in Beitrag#15 erwähnt: Für Python sind Einrückungen extrem wichtig. Du hast hier leider auch wieder eine falsche Einrückung verwendet.

    Dazu kommt, wenn du alle Werte über 120 auf 50 ändern lässt wird das doch genau so verfälscht wie zuvor!? Sowas löst kein Problem sondern ignoriert es nur... Finde ich einen ziemlich miesen weg


    ich finde den Weg ja auch mies, aber wenn ich es nicht besser hin bekomme habe ich ja keine Wahl.

    Ich setze mich seit 2 Wochen damit auseinander, ich will ja auch was ändern, leider führt jede Änderung ins leere. Irgendwann bin ich halt am Ende und weiss nicht weiter. :wallbash:

    Ich weiss ja auch nicht, ob ich den ganzen perioden Krams raus lassen kann!? Je weniger, desto einfacher für mich.
    Automatisch zusammengefügt:


    Servus,
    ich würde den Reed-Kontakt mal durch einen Hall-Sensor ersetzen. Ich kann mir gut vorstellen dass der Kontakt durch die Vibrationen beim Fahren Fehlimpulse liefert ...

    -ds-

    So stark vibriert das nicht. Reed und Magnet sind so von einander getrennt, das der Kontakt nicht springen kann. Hab ich bei einem Glasreed Kontakt auch noch nie gehabt:
    http://www.reichelt.de/?ARTICLE=6281

    Einmal editiert, zuletzt von Landixus (8. Mai 2017 um 11:04)

  • Um was für ein Fahrrad handelt es sich denn?

    dreamshader meinte damit glaub ich eher die Vibrationen die durchs fahren an sich entstehen, nicht um den Abstand der Kontakte. Ein Reedswitch-Sensor ist für Vibrationen weitaus anfälliger als ein HALL-Sensor.


  • Um was für ein Fahrrad handelt es sich denn?

    dreamshader meinte damit glaub ich eher die Vibrationen die durchs fahren an sich entstehen, nicht um den Abstand der Kontakte. Ein Reedswitch-Sensor ist für Vibrationen weitaus anfälliger als ein HALL-Sensor.

    Das kommt aus:
    Power aus Tabelle anhand der Umdrehungen an ANT+ senden.

    der reed ist am Gehäuse und der Magnet auf der drehenden Scheibe. Der GPIO werde ich gleich nochmal mit 470nF Hardware entprellen, aber deswegen ist mein code ja immer noch falsch.
    Jetzt noch einen HALL Sensot mit extra 5V halte ich für etwas überzogen. Eher was fürs ebike oder großen Geschwindigkeiten?

  • Wie gesagt, ich würde den Code erst mal überarbeiten und einheitlicher gestalten. Angefangen damit nur 'pigpio' zu verwenden und RPi.GPIO raus zu werfen. Weiter geht es mit den Einrückungen denn da sehe ich in Beitrag#9 noch ein riesen Chaos.

    Dann könnte man, um die Übersicht zu behalten, die einzelnen Sachen in unterschiedliche Dateien auslagern:
    - Das erfassen der RPM in eine eigene Datei: read_rpm.py
    - Die Behandlung deiner LEVEL_TO_POWER Geschichte: main.py

    In read_rpm.py stünde dann wirklich nur die reader Klasse, sonst nichts. In main.py importierst du dann read_rpm und fügst den restlichen Code ein der benötigt wird.
    Muss man so nicht machen, man könnte auch alles in einer Datei belassen, fördert aber wie ich finde die Übersicht.

    Und tu dir diesmal selbst ein Gefallen und nutze pro Einrückung 4 Leerzeichen, dann erkennst du nämlich selber wo die Einrückung richtig ist und wo nicht - das bricht dir derzeit in Beitrag#9 nämlich den Hals ;)


    Heute Abend kann ich dir da gerne bei helfen - muss jetzt aber erst mal arbeiten.

  • Hab ich das richtig verstanden, dass es um eine Messung der Drehgeschwindigkeit des Rades eines Hometrainers oder sowas ähnliches geht?
    Der Reed-Kontakt ist fest montiert und am Rad ist ein Magnet? Ich staune, dass so ein Fall solche großen Probleme macht und denke, da muss doch was grundsätzlich faul sein.

    Kann es sein, dass der (mechanisch arbeitende) Reed Kontakt einfach nicht schnell genug ist? Wenn sich das Rad mit üblichen Fahrgeschwindigkeiten von sagen wir mal 20 Km/h bewegt und der Magnet nah an der Lauffläche ist, sind das ca. 7 m/s - das entspricht bei einem 2,5 cm langen Magneten maximal 3 ms Kontaktzeit. Vielleicht ist das zu wenig, um den Kontakt sicher zu schalten (Obwohl laut Datenblatt 0,6 ms Schaltzeit). Bei nem Reifenumfang von 2 m und 40 RPM komm ich auf 18 ms. Naja, eigentlich sollte das reichen - vorausgesetzt, der Magnet ist groß genug und überstreicht den Kontakt mit einem hinreichend breiten Magnetfeld. Ist der Magnet stark genug bzw. nah genug am Kontakt und ist der Kontakt richtig ausgerichtet. Kriegst du denn einen sauberen, dauerhaften Kontakt, wenn du den Magneten langsam vor den Reed Kontakt drehst?
    Hast du mal einfach ne LED angeschlossen und geschaut, ob der Kontakt überhaupt tut, was er soll, bevor du dich in den Code vertiefst?
    Könntest du ggf. mal alternativ eine einfache hell-dunkel Erkennung ausprobieren - mit einer kleinen Reflexlichtschranke oder einem Photosensor?
    Was macht dein Programm, wenn du die Eingabe des Sensors mit einem Taster simulierst? Oder generiere per Timerinterrupt ein regelmäßiges Signal auf einem GPIO und gebe das auf deinen Eingang, um zu sehen, ob das Programm präzise Signale auch richtig erkennt und berechnet.

    Irgendwo muss der Haken doch zu finden sein!

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Der Kontakt schaltet, habe ich mit LED und Durchgangsprüfer mehrfach getestet.
    Der Kontakt wird mit einem neodym Magnet geschaltet, damit man ein wenig Spiel hat :)

    wie ich sowas simuliere weiß ich nicht. Ich hatte die Schaltung vorher auf dem Tisch mit Tastern um halt >RPM zu simulieren, da waren auch diese Abweichungen enthalten.

    Hardware Seite passt. meigrafd hat mir angeboten heute Abend zu helfen, solange versuche ich mal den code zu kürzen, da sind ja viele Sachen drinne die ich nicht brauche (periode etc...)

  • Willst du nicht mal den Code total entrümpeln oder vielmehr mal testweise ein kleines Programm ganz von vorne schreiben - ganz einfach mit einem Interrupt auf die Flanke des GPIO und einer Ausgabe der Timerdifferenz schauen, ob du vernünftige Zeitwerte bekommst? Da kommst du doch mit 20 Zeilen Code hin, das ist in ner Viertelstunde gemacht und dann weißt dann wenigstens, ob es prinzipiell geht.
    Den bestehenden Code kann ich beim ersten Überfliegen nicht annähernd durchblicken. Wenn da irgendwo der Teufel im Detail steckt, ist es schwer, was zu finden.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

    Einmal editiert, zuletzt von Gnom (8. Mai 2017 um 13:44)

  • Ich hab alles mal zurüch gemacht und nur das Orginal script genommen. der REED Kontakt bleibt tatsächlich nicht lange genug high um zu zählen.
    Ich muss erstmal eine verlässliche hardware bauen und das Orginal script muss erstmal richtig zählen.
    Mal gucken ob ich das bis nachher schaffe :(

  • Bring den Kontakt näher zur Nabe - dann wird die Schaltzeit länger. Vielleicht hilft das schon. Und probier mal die verschiedenen Anordnungen von Reedkontakt und Magnet aus - längs/quer...

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • reed Kontakt tut wieder, hör ihn ja auch schalten, also doch script.. Mannnnnnnnnnnnnn! *würg
    hab jetzt mal aus Verzweiflung ein script gesucht was läuft bei mir *warum auch immer....:

    anders positionieren is doof bei einem Würfel. Egal läuft erstmal ( = saubere Basis!) :)


    Muss ich jetzt noch kürzen, ist ja zuviel Information die da kommt. Ich brauch doch nur die RPM!

    Dann muss das mit meinem *Geschusterten zusammen (Tabelle etc.)
    Irgendwie bin ich nicht weiter. Bleib aber mal Ball
    Automatisch zusammengefügt:

    So hab was von mir was dazu eingebaut:

    Wobei mir auffällt das die RPM immer gleich bleiben wenn ich aufhöre zu treten :(
    Ich lass das jetzt sein mit der Fummelei

    Einmal editiert, zuletzt von Landixus (8. Mai 2017 um 16:05)

  • So habe eingekürzt und das Programm gibt jetzt sauber die RPM aus:

    Es wäre toll wenn wir da ansetzen können, bitte.

    Nochmal zusammen gefasst, da ich schon selber nicht mehr hier durchsteige :)

    Die rpm werden gezählt (klappt jetzt ja)
    Mit den rpm und der Tabelle wird die Leistung "berechnet" gestartet wird mit Level 5
    Mit den GPIO 20 schalte ich "hoch" (nächster Level) mit 21 "runter" (nächst kleinerer Level)
    Mein kaputtes Script lege ich mal hier bereit, damit ich das Forum nicht weiter voll spam.

    http://quakeit.de/python/raspiforum/

    dort sind 7powerx.py.txt ( das interpoliert leider nicht zwischen den Leistungswerten)
    9powerx.py interpoliert zwischen den Werten, ich bekomms aber nicht zusammen gebaut.

    ich würde also gerne das 9powerx.py (da es interpoliert) so zusammen bauen, das es nur 1 ist und dann auch noch funktioniert :)

    Wenn die Werte rpm, level, power passen, wird nachher nur noch der power Wert ausgegeben und diesen Wert lese ich dann ein (Ja das kann ich!) Das ist "alles" :)

    Einmal editiert, zuletzt von Landixus (8. Mai 2017 um 18:19)

  • So hab noch mal versucht:
    Weiss nicht ob es richtig ist, komme aber auch nicht weiter:

  • Falls Jemand noch Interesse hat das zu zusammen zu fügen kann sich bei mir per PN melden.
    Ich zahle 150 für das fertige Script.

    Ansonsten bin ich raus und lass das Projekt sterben, irgendwann muss man ja auch mal aufhören.

    Aber Danke schon mal für die Versuche mir zu helfen.

  • Naja es bringt nichts irgendwas zusammen zu klatschen ohne den Code zu verstehen. Dadurch verbrauchst du mehr Zeit als wenn du verstehst was da eigentlich passiert.
    Beispiel:
    In deinem Fall wird ein GPIO ziemlich schnell nacheinander ausgelöst, dh. eine "bouncetime" von 200ms ist für dich störend. Findet ein Flankenwechsel statt und innerhalb von 200ms noch einer wird der darauffolgende ignoriert - Softwareseitiges entprellen.
    Die Verschachtelung einer "for" gefolgt von einer "while True" die aber nie unterbrochen wird, ist ebenso seltsam wie auch 1 als "wheel radius" zu setzen.

    Ich würde erst mal beim 'pigpio' bleiben.

    Geschwindigkeit = Stecke / Zeit
    Bedeutet also:
    Ein Impuls wird ausgelöst, dann wird eine Zeitmessung bis zum nächsten Impuls gestartet - dann hat man die Zeit. Zusätzlich brauch man dann noch den Radumfang. Kennst du den Radumfang bzw die zurückgelegte Strecke bei einer Umdrehung?

  • Hallo.
    Mal meine Meinung.


    Ich würde erst mal beim 'pigpio' bleiben.


    ...würde ich auch.

    Ich denke hier kommen 3 Faktoren zusammen, die das Problem ergeben.

    1: Ein Reedkontakt ist ein Preller in Perfektion, auch durch Erschütterungen.(unnötige Auslöser)
    2: Raspi Interrupt's sind an den DMA Takt gekoppelt.(kostet Zeit)
    3: Python ist ein Interpreter.(kostet noch mehr Zeit)

    Am Arduino geht's ja offensichtlich.
    Also, mit nem Oszi untersuchen, und dann Entscheidungen treffen.

    gruß root

  • Das time.sleep(0.2) innerhalb der while ist nicht tragisch, eigentlich sogar gut da sonst die CPU zu 100% belastet wird und eine zu schnelle Ausgabe erfolgt. Das steuert also quasi nur den Zeitpunkt wann eine Ausgabe erfolgen soll. Die RPM Messung ist von der while unabhängig da sie ja in einem separaten Interrupt-Thread läuft.

    Also allgemein zu unterscheiden gilt es:
    1) Geschwindigkeitsmessung ala km/h.
    2) Umdrehungsgeschwindigkeit.
    3) Impulszähler.

    Für 1. benötigt man den Radumfang um die zurückgelegte Strecke innerhalb einer bestimmten Zeit zu kennen.
    Für 2. benötigt man keinen Radumfang, aber trotzdem eine Zeit.
    Für 3. ist alles von 1. und 2. unwichtig da man einfach nur die Impulse zählt. Es wird also eigentlich nicht wirklich etwas gemessen oder bemessen.

    Allgemein gilt:
    Jede volle Umdrehung liefert einen Impuls und jeder Impuls findet zu einer definierten Zeit statt.
    Um die Genauigkeit zu steigern wären mehrere Erfassungspunkte gut, also nicht nur ein Sensor sondern mehrere. Dann würde es nicht nur einen Impuls für eine volle Umdrehung benötigen, sondern zum Beispiel drei. Hat man mehrere Sensoren kann man auch Halbe Umdrehungen (oder weniger) verwerten/erfassen.

    Wichtig für die Erfassung der Impulse:
    Im Interrupt Callback sollte nur das absolut nötigste stehen, sonst wird die Callback Funktion derbe ausgebremst und das ganze Konstrukt wird ungenau. Die Interrupt Callback läuft (automatisch) abgekoppelt vom restlichen Script und kann daher äußerst schnell nacheinander ausgelöst / verarbeitet werden. Steht da aber sowas wie ein "print" drin wird die Funktion ausgebremst und verpasst möglicherweise ein Impulse, was wiederum zu Ungenauigkeit führt.
    Eine art "timeout" braucht man auch, sonst bleibst du mit dem Fahrrad stehen aber der Tacho zeigt weiterhin den letzten Wert als aktuellen Wert an.

    Bezüglich 1. und 2.:
    Es bringt nichts jeden einzelnen Impuls direkt auszugeben. Es bedarf mindestens 2 Impulse um zu wissen wie viel Zeit zwischen Impuls #1 und Impuls #2 vergangen ist um die Umdrehungsgeschwindigkeit zu ermitteln. Um so mehr Impulse um so besser.
    Man sollte also seine Ausgabe an die Anzahl der Impulse koppeln - dreht sich die Scheibe / das Rad langsamer erfolgt auch die Ausgabe langsamer.
    Beispielsweise bei einem Windmesser/Windrad errechnet man die verstrichene Zeit erst nach 10 Umdrehungen. Der Startzeitpunkt der Messung muss also gespeichert werden sowie die Endzeit nach erfolgten 10 Umdrehungen. Mit Python und dem Pi übrigens kein Problem, man muss deshalb nicht zum AVR greifen.


    Hab den Thread noch mal durchgelesen und glaube verstanden zu haben das du nicht 1. oder 2. sondern 3. haben/erreichen möchtest?
    Die Umsetzung deines LEVEL_TO_POWER ist dabei erst mal nebensächlich - das ursprüngliche Problem hat ja damit nichts zu tun. Eins nach dem anderen.

    ...bevor ich jetzt aber weiter texte und mir die Finger wund schreibe, wäre ein Feedback deinerseits ganz hilfreich, sonst kann man sich das hier auch alles schenken


    PS:
    Interessant ist das du dieses Anliegen auch schon im Python-Forum behandelt hast: https://www.python-forum.de/viewtopic.php?t=40384
    Auch da sieht man fehlerhafte Einrückungen ziemlich deutlich. Was ist mit dem Kollegen der dir das zurecht basteln wollte/sollte?
    Du machst zu viele Baustellen auf ein mal auf. Copy&Paste von verschiedenen Quellen bringt nichts wenn man nicht versteht was da eigentlich passiert, und verbraucht letztlich auch viel mehr Zeit.
    Sogar __deets__ hat versucht dir zu helfen - und dir auch gesagt das Verstehen weniger Zeit kosten würde als 100 Versuche.


  • Allgemein gilt:
    Jede volle Umdrehung liefert einen Impuls und ... jeder Impuls findet zu einer definierten Zeit statt.

    ...wow.. Teilchenverschränkung der Qantenmechanik in nem halben Satz erklärt...
    Den Typ möcht ich kennenlernen :D:D:D

  • @root: Hast du wirklich nichts besseres zu tun?
    Das zeigt leider wieder mal aus welchem Holz du geschnitzt bist.
    Wenn du es genau wissen willst schrieb _das_ Andreas hier - wieso aber stänkerst du nicht dort rum?
    Ich weiß, du kannst mich nicht leiden.

    Wenn ich jetzt Andrea's Manier folgen würde: Ich verabschiede mich aus diesem Thread, :danke_ATDE: root!

    ... kindergarten ...

    :wallbash:


  • @root: Hast du wirklich nichts besseres zu tun?
    Wenn du es genau wissen willst schrieb _das_ Andreas hier - wieso aber stänkerst du nicht dort rum?
    Das zeigt leider wieder mal aus welchem Holz du geschnitzt bist.

    Wenn ich jetzt Andrea's Manier folgen würde: Ich verabschiede mich aus diesem Thread, :danke_ATDE: root!


    ...grins
    Niemand hat gestänkert... Der Puls von einem rotierendem Rad tritt geau dann auf, wenn das Rad (abhängig von der Rotationsgeschwindigkeit) eine volle Umdrehung gemacht hat, nicht davor
    oder danach, und schon gar nicht zu einem definiertem Zeitpunkt.

    Was du im übrigen machst oder tust, geht mir eh wo vorbei.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!