WinFuture-Forum.de: [geloest] Pi - Phyton Code umschreiben - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

[geloest] Pi - Phyton Code umschreiben


#1 _nobido_

  • Gruppe: Gäste

geschrieben 01. Februar 2018 - 20:44

'nabend die Gemeinde.

Ich habe mir ja vor langer Zeit einen Pi3 geholt. Weil ich mich da bissl zu sehr drueber geaergert habe ueber die Handhabung per remote etc. lag das Teil nun ueber ein Jahr rum. Trotzdem hat es mich aber wieder gepackt und ich arbeite ein paar Tutorials durch - und schreibe, zum ueben, den original Code hier und dort mal ein wenig um.

Nun habe ich ein Problem bei dem ich nicht weiss ob es am Programmcode liegt (sprich: ich bin zu bloed), oder ob es vllt. eher an der Hardware liegt.

Der Originalcode ist hier im Netz hinterlegt: https://www.sunfound...aspberrypi.html

Im speziellen geht es um folgenden (original) Codeausschnitt:

def rotaryDeal():
	global flag
	global Last_RoB_Status
	global Current_RoB_Status
	global globalCounter
	Last_RoB_Status = GPIO.input(RoBPin)
	while(not GPIO.input(RoAPin)):
		Current_RoB_Status = GPIO.input(RoBPin)
		flag = 1
	if flag == 1:
		flag = 0
		if (Last_RoB_Status == 0) and (Current_RoB_Status == 1):
			globalCounter = globalCounter + 1
			print 'globalCounter = %d' % globalCounter
		if (Last_RoB_Status == 1) and (Current_RoB_Status == 0):
			globalCounter = globalCounter - 1
			print 'globalCounter = %d' % globalCounter



Den habe ich abgeaendert in:

def rotaryDeal():
        global flag
	global Last_RoB_Status
	global Current_RoB_Status
	global globalCounter

if GPIO.input(RoAPin) == True:
		Current_RoB_Status = GPIO.input(RoBPin)
		
		if Current_RoB_Status == True:
			globalCounter = globalCounter + 1
			print 'Rechts: globalCounter = %d' % globalCounter
		else:
			globalCounter = globalCounter - 1
			print 'Links: globalCounter = %d' % globalCounter



Meinem Verstaendins nach sagt die Beschreibung (siehe Link oben) doch folgendes aus:

Solange auf Pin 0 (RoAPin) kein True vorhanden ist muss ich mich um Pin 1 (RoBPin) nicht kuemmern, da keine Aktion im Sinne von links oder rechts drehen statt findet. Erst wenn auf Pin 0 ein True anliegt ist es notwendig Pin 1 auszuwerten um die Rotationsrichtung zu ermitteln (Pin 1 = True wenn im Uhrzeigersinn, ansonsten False).

Nun meine Frage: Macht der umgeschriebene Code irgendwas anders?
Ich meine, es ist doch egal wie der Status von irgendwas "vorher" war... bevor auf Pin 0 True anliegt?
Es ist doch eigentlich "nur" wichtig Pin 1 auszuwerten, wenn auf Pin 0 True anliegt...?

Oder irre ich?

Denn wenn ich das Programm starte und nichts am Drehregler mache bekomme ich halte die Ausgabe es wuerde rechts herum gedreht. Drehe ich dann links herum wird das nur alle ca. 6 - 10 Messungen registriert und entsprechend ausgegeben.


joar
greetz & netten Abend euch noch.

Dieser Beitrag wurde von nobido bearbeitet: 05. Februar 2018 - 19:45

0

Anzeige



#2 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 01. Februar 2018 - 22:31

Naja, Dein Code synchronisiert nicht mehr mit DT. Was zur Folge hat, daß -zumindest erwartungsgemäß- die Ausgabe nicht mehr auf "nur, wenn wirklich was passiert" beschränkt ist.

Jedenfalls dann, wenn die Doku so stimmt.

Wobei ich mir noch nicht so recht schlüssig bin, was da überhaupt hinten bei rumkommt, und zumindest für mich ist die Pinbelegung auch irgendwie irreführend: denn DT ist wohl der Takt und CLK gibt Informationen über die Drehbewegung --- und beide liefern Puls.

Die Frage ist also: was ganz genau ist Last_RoB_Status? Die Information wird ja unabhängig von DT beschafft, also laut Doku sollte Last_RoB_Status UNDEFINED sein. Ist aber aber ganz offensichtlich nicht; zumindest rückableitend aus dem Quellcode würde ich davon ausgehen wollen, daß das Signal an RoBPin stabil bleibt, egal was RoAPin sagt, und dabei darüber informiert, was die letzte Drehrichtung war (sprich, einmal gedreht wird RoBPin 0 oder 1 liefern gemäß Richtung und dieses Signal halten).

Die Schleife synchronisiert dann RoBPin mit dem Taktsignal (aus DT) und terminiert mit gültigem RoBPin, was dann - entsprechend Doku -- sagt, okay der Knopf WURDE gedreht, UND wie rum. "flag"s Informationsgehalt beschränkt sich dann darauf, ob an RoAPin überhaupt ein Signal anlag (ie. der Knopf betätigt wurde) oder nicht; falls nicht, passiert auch nichts; falls doch, wird globalCounter entsprechend angepaßt.

Rein intuitiv würd ich sagen, das flag kann weg, denn die Schleife wird warten, bis das Rad gedreht wird. Damit wäre (Rad gedreht => flag) eine Tautologie.


WENN das mit RoBPin (last vs current) so läuft, wie ich mir das EINBILDE, daß es so läuft, dann bleibt die Ausgabe beim Radbetätigen darauf beschränkt, ob die Drehrichtung geändert wurde. Dreh ich links, gibt es ein Increment auf globalcounter. Dreh ich nochmal links, passiert...nichts? Dreh ich rechts, geht globalcounter wieder runter; dreh ich nochmal rechts, passiert... wieder nichts?

Das ergibt natürlich keinen Sinn. Also zumindest für mich nicht. Woraus ich lese, daß a) RoBPin noch was anderes tut b) ich irgendwas nicht kapiert hab c) noch was anderes nicht hinhaut.

Option (b) ist sicherlich die wahrscheinlichste. :wink:


Denke, da müßte man schauen, ob man seine Finger an eine komplette Doku bekommen kann. Wer tut was; welches Signal landet wo, mit welcher Frequenz laufen DT/CLK, was sagt mir der Zustand von CLK, wenn DT inaktiv ist. Und so weiter.

Denn eigentlich müßte man mit den Werten aus DT und CLK noch mehr anfangen können: immerhin gibt es ja den Takt; ergo sollte man dann auch herausbekommen können, wie schnell das Rad gedreht wurde (Zustandsänderungen/Takt). Aber dann muß man halt wissen, unter welchen Bedingungen man welchen Pin lesen darf (und wann nicht) und, soweit zutreffend, in welchem Kontext welcher Pin was liefert. "Normal" würd ich sonst sagen, Last_RoB_Status darf nicht beschafft und schon gar nicht verwendet werden.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#3 _nobido_

  • Gruppe: Gäste

geschrieben 03. Februar 2018 - 16:09

Option b) waere dann die Zutreffende :)

Das Laesst mich ja dann doch nicht schlafen...
Nun ja. Hab mir also gestern ein Labornetzteil, ein Multimeter und ein wenig sonstige Ausstattung zugelegt.
Danach, nachdem ich das (extrem miese?) Datenblatt dazu gefunden habe gefuehlt eine Ewigkeit ebenjenes studiert. Hier gemessen, da gemessen. Ruminterpretiert. Und am Ende eine "Kontrollschaltung" in Form von Dioden in die Schlatung eingebaut.

Ergebnis ist nun folgendes:
GND = Masse, + = Vcc 3.3 V, SW = Taster (wenn der Drehschalter gedrueckt wird) sowie CLK und DT analog Pin 0 und Pin 1 (wobei ich mir nicht sicher bin was was ist - lt. Code DT = Pin 0, CLK = Pin 1, meine Messungen haben allerdings CLK = Pin 0 sowie DT = Pin 1 ergeben).
Da wird nichts synchronisiert mit rigendwas.

So, Taster, denke ich, ist klar: Wird gerueckt ==> Stromkreis geschlossen ==> Signal auf SW.
Das mit dem Drehregler ist ein wenig tricky. Wenn man den um eine Position weiter dreht werden dabei vier Phasen durchlaufen, waehrend dieser die Pins unterschiedliche Werte einnehmen.

Bei der Drehung nach rechts waere das: A und (nicht B), A und B, (nicht A) und B, (nicht A) und (nicht B)
bei der Drehung nach links waere das: B und (nicht A), B und A, (nicht B) und A, (nicht B) und (nicht A)

(bzw. jeweils anders herum, da ein HIGH-Pegel (warum auch immer) ein logisches False; ein LOW-Pegel ein logisches True ergibt). Diese Zustaende werden "gepulst".

Das ist auch die Reihenfolge, in welcher die Pins sich in der jeweiligen Phase befinden.

Somit macht dann auch der origianl Code Sinn (einfach mal im Zustandsautomaten durchspielen).

Das entfernen der Abfrage auf Flag == 1 und die darauf folgenden IF-Abfragen anzupassen fuehrt zu massiv falschen werten - bin hier allerdings noch nicht ganz dahintergestiegen warum dies so ist.


Was mir am Regler selber nicht ganz klar ist: Wenn SW, DT & CLK letztendlich auch als Masse fungieren (Drehrichtung, Schalter gedrueckt ==> Stromkreis geschlossen), warum ist dann "nochmal" ein Massepin auf der Platine vorhanden?


joar...
...mal gucken ob sich weiteres findet.

nettes WE wuensch ich

Dieser Beitrag wurde von nobido bearbeitet: 03. Februar 2018 - 16:11

0

#4 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 03. Februar 2018 - 20:44

Klingt logischer. Stand da halt nur anders. :blush: Na, solange es tut.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#5 _nobido_

  • Gruppe: Gäste

geschrieben 05. Februar 2018 - 19:44

So, der Drops ist gelutscht!

Wenn man den Regler mit der Platine verkabelt, dann ist auf den Ausgaengen ein Signal > 1.7V - was folgerichtig ein True ergibt. Wenn ich den Regler nun drehe faellt das Signal auf den entsprechenden Pins weg (Stichwort: 2Bit Grey-Code). Der Code prueft ja auch entsprechend:

while (not GPIO.input(RoAPin))


Was mir halt nicht klar war (und so aus dem Datenblatt fuer micht auch nicht ersichtlich war/ist) bzw. was ich falsch verstanden habe ist dass eben im Ausgangszustand ein True auf den Pins anliegt - weswegen der Code fuer mich auch keinerlei sind machte. Der funktioniert naemlich nur in eine Drehrichtung, wenn man davon ausgeht dass im Ausganszustand ein False an den Pins anliegt.


Was nun die Thematik des umschreiben des Code angeht: Ich habe einige Codebeispiele im Netz gefunden, wo per Eventhandler eine Callback-Funktion aufgerufen wird (analog der Switch-Funktion des Drehreglers)
GPIO.add_event_detect(...)


und dann per IF-Abfrage der Wert von Pin B ausgewertet wird. Was soweit auch funktioniert.
Allerdings scheint das (seitens des Drehregler) so zeitkritisch (3ms <= t2-t1 <= 5ms beim Uebergang von einem Pin-Zustand in den Naechsten) zu sein dass in diesem Fall die eine oder andere Messung einfach "verschluckt" wird, sprich: die Drehung wird nicht registriert. Interessant hierbei: Dieses Phaenomen tritt bei mir nur auf, wenn ich den Regler nach links drehe.
Das while()-Konstruckt liefert da wesentlich genauere Werte.


joar...
...womit das Thema Phyton-Code umschreiben in Verbindung mit dem Drehregler soweit erledigt ist.
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0