Posts by Singletrailer

    Um nochmal auf das ursprüngliche Problem zurückzukommen:


    Ausgabe des Scripts:

    Code
    ('one', 'two') <type 'tuple'>
    one - two
    <type 'str'> <type 'str'>
    one - two

    Wie man hier sieht, handelt es sich eigentlich um ein Missverständnis. Auch Python gibt nur einen einzigen Rückgabewert zurück, nämlich ein Tupel! Dieses Tupel enthält zwei Strings. Also ist es auch Unterschied zu C, wo ich ja auch einen struct von verschiedenen Werten zurückgeben kann.

    Die Verwirrung kommt nur daher, dass Python mehrere hinter einem return aufgelistete Werte automatisch in ein Tupel packt und bei Zuweisung an eine Auflistung von Variablen das Tupel auch wieder automatisch entpackt.

    Code
    def Funktion():
        return 1, 2, 3    # gibt eigentlich (1, 2, 3) zurück
    
    
    a = Funktion()        # a = (1, 2, 3), type(a) == 'tuple'
    
    
    a, b, c = Funktion()  # Tupel wird automatisch entpackt --> a = 1, type(a) == 'int'


    Auch wenn eine Funktion ja eigentlich immer nur genau eine wohldefinierte Aufgabe erledigen soll, gibt es für dieses Verhalten viele praktische Anwendungsfälle. Man sollte sich halt nicht unbedingt verschiedene Dinge zurückgeben lassen, die eigentlich nichts miteinander zu tun haben.

    Hallo,

    ich habe auf meinem Pi derzeit RetroPie installiert und denke darüber nach, ihn dauerhaft als Emu-Konsole zu nutzen. Leider habe ich bisher noch nicht herausgefunden, wie ich den Zustand eines Emulators speichern kann, also unabhängig von der Speicherfunktion des jeweiligen ROMs. Google sagte was von F2 zum emulatorübergreifenden Aufruf eines Speichermenus, aber das funktioniert bei mir nicht.

    Gibt es bei den in RetroPie enthaltenen Emulatoren überhaupt eine Möglichkeit, jederzeit zu speichern? Eigentlich kenne ich das von anderen Emus als Standardfunktion.

    Vielleicht solltest du einfach mal vollständige Fehlermeldungen posten. Keiner hat Lust, deinen Sourcecode bei sich zu übersetzen, was auch nichts bringen würde, wenn dein Problem fehlende Abhängigkeiten sind. Wenn es tonnenweise Fehler sind, reichen auch erstmal die ersten paar Fehler.

    Das gilt dann auch für deine Python - Experimente. Gerade Python liefert in der Regel sehr aussagekräftige Fehlermeldungen. Ich finde die Entscheidung, das mit Python zu lösen, sehr gut, da für solche Projekte C unnötige Hürden bereitstellt.

    Die Union löst aber die Probleme nicht:

    • Wenn sie in der Library angelegt wird, muss die Library jeden Treiber "kennen", damit dessen struct Teil der union werden kann.
    • Nicht alle Compiler unterstützen den anonymen "Durchgriff" in die einzelnen structs, da dies nicht C-Standard-konform ist. Also muss die Library die Elemente der structs mit vollem Namen ansprechen, wodurch sie wieder eine Fallunterscheidung für alle einzelnen Treiber machen muss.


    Für das ursprüngliche Problem (Code arbeitet mit einer Abstraktion von Daten, nicht mit deren konkreten Ausprägung) gibt es in objektorientierten Sprachen das Konzept der Vererbung: Die Treiber werden als Klassen implementiert, die alle von einer gemeinsamen Basisklasse abgeleitet werden. Die Library arbeitet ausschließlich mit den Methoden und Daten der Basisklasse, während die Treiber diese beliebig erweitern und an ihre konkrete Implementierung anpassen können.

    Dieses Konzept kannst du in C nachbilden. Dazu wurde im C-Standard extra die Eigenschaft definiert, dass Strukturen, die mit gleichen Elementen beginnen, vom Compiler immer gleich angelegt werden müssen. Damit werden sie kompatibel im Sinne einer Basisklasse:

    Die Library ist somit total unabhängig von den Treibern und kann auch mit noch gar nicht existierenden Treibern zusammenarbeiten, solange diese sich später an die vereinbarte Schnittstelle halten. Wie von dreamshader beschrieben, kann man sogar Funktionen im Treiber aufrufen, wenn man diese als Funktionspointer in der Struktur ablegt. Die Treiber können die Struktur darüber hinaus beliebig erweitern. Natürlich kann die Library mit diesen Erweiterungen nicht umgehen.

    Wenn du diesen Ansatz umsetzt, solltest du übrigens trotzdem darüber nachdenken, jeder Funktion den Treiber-Pointer zu übergeben. Dadurch könnte die Library später sogar gleichzeitig mit mehreren Treibern umgehen.

    Ein Pointer ist hier die Lösung. Er kann ja in deiner library global sein, wenn du ihn nicht übergeben willst.

    Ich vermute mal, dass die Struktur gemeinsame Teile beinhaltet (mit denen die library arbeitet) und spezifische Teile, die nur der jeweilige Treiber nutzt. Das geht, wenn du alle gemeinsamen struct - member am Anfang des structs definierst. Dahinter können dann spezifische member folgen. Du definierst dann in der Lib einen struct, der nur die allgemeinen member enthält. Von diesem Typ legst du dann einen Pointer an, den du mit einem (auf deinen Basis-struct gecasteten) Pointer auf den tatsächlichen struct des Treibers initialisiert.

    Und nochmal, weil man es nicht oft genug sagen kann: nicht in der Einstellung "Strommessung" von einem GPIO gegen Gnd messen, das belastet den Pin wie ein Kurzschluss und kann deinen Raspi schnell killen.

    Zu deiner Verteidigung: ich hatte tatsächlich von einer Spannungsmessung am Port gesprochen, während der Kollege oben von dir eine Durchgangsprüfung des Kabels wollte. Sorry für die Verwirrung. So wie deine Messergebnisse aussehen, müssen wir uns nun aber wohl wirklich mal mit deinem Kabel beschäftigen.

    Also: klingel das Kabel mal im Ohm-Modus und ohne angeschlossenen Raspi durch.

    Und bitte an den Ports nicht einfach in der Einstellung GleichSTROM des Multimeters messen. Das Messgerät stellt in diesem Modus einen Kurzschluss dar. Damit kann man auch wunderbar Ausgänge kaputt machen. Für deinen Zweck ist GleichSPANNUNG der richtige Modus.

    Um sicherzustellen, dass man das Messgerät richtig eingestellt hat und die Messstrippen in den richtigen Buchsen stecken, sollte man sich angewöhnen, erst mal eine bekannte Größe zu messen. Bei Widerstand oder Durchgangsprüfung hält man die Messspitzen aneinander und guckt, ob 0 Ohm angezeigt werden. Bei Spannungsmessung misst man z. B. die Versorgungsspannung der Schaltung. So stellt man schon mal sicher, dass man bei der Messung selbst keinen Fehler macht.

    Ohne solche Grundlagen wärst du aber auch beim Arduino nicht weiter gekommen... Und wenn du nicht einfach nur Schaltungen aus dem Internet nachbauen willst, wirst du dir nach und nach noch viel mehr Wissen draufschaffen müssen. Das ist aber nicht unmöglich, setzt aber voraus, dass du bereit bist, dich mit den Grundlagen auseinandersetzen, bis du sie wirklich verstanden hast.

    Modellbauservo geht aus dem einen YouTube - Link hervor. Andere Servo - Ansteuerungen sind im Hobby-Bereich auch eher selten zu finden, da reichlich komplex.

    Modellbauservos werden mit 5, 6 oder (selten) auch mit 7.4 Volt betrieben, und zwar unabhängig von der Spannung des Antriebsakkus. Die Speisung erfolgt aus dem separaten Empfängerakku mit 4 oder 5 NC-Zellen oder 2 Lipoly-Zellen, selten und grenzwertig auch mit 1 Lipoly bei 3.7 Volt. Oder per Spannungswandler aus dem Antriebsakku mit üblicherweise 5V.


    brauchen die keinen Strom ? (bei Servo denke ich an Servo Motore, mit nur Spannung kommt man da nicht weit und passen muss sie auch noch und der PI liefert nur 3,3V aus dem GPIO Port)

    Modellbauservo haben die Leistungselektronik schon integriert. Diese wird mit 5V versorgt. Der steuernde Controller muss dann am dritten Anschluss ein 50hz-Signal mit einer Pulsweite von 1-2ms anlegen, das dann die Position vorgibt.


    trotzdem solltest du lernen wie man LED anschliesst, was unterscheidet die von Servos ? beide wollen Spannung und Strom, besonders Servos, ohne Treiber wird das nix und man sollte schon wissen was man den Ports zumuten kann.

    Naja, vom physikalischen Anschluss her ist ein Modellbauservo eigentlich einfacher, weil es eigentlich nur eine Spannung sehen will. Allerdings 5V, was aber jetzt mal noch nicht das Thema ist. Man kann damit aber zumindest nicht so einfach den Raspi überlasten, da kein nennenswerter Strom fließt. Bei einer LED geht das Ruck-zuck, da sie auch mal kurzzeitig deutlich mehr Strom verkraftet, als der Port liefern kann, ohne dass sie sich gleich in eine DED (darkness emitting diode) verwandelt.

    Also mach mal die oben beschriebenen Schritte, damit wir hier weiterkommen. Auch wenn du eigentlich Servos steuern willst, hilft es doch sehr, das Problem in kleine Schritte zu zerlegen und diese dann nacheinander zu gehen. Sowohl Arduino als auch Raspi sind komplexe Systeme, die man nicht an einem Tag meistert.


    Achja und ich hab das LED an eine 9V Blockbatterie ohne Widerstand angeschlossen und sie hat geleuchtet(ohne danach kaputt zu gehen).

    Bei dieser Aktion können zwei Dinge kaputt gehen: entweder die Spannungsquelle (hier der GPIO), oder die LED. Dummerweise ist das teurere Bauteil (der GPIO des Raspi) auch das empfindlichere, weshalb du hier ohne gewisse Grundlagen gar nichts anschließen solltest. Die LED stirbt üblicherweise einen Hitzetod, wenn sie deutlich überlastet wird. Das kann abhängig von der LED und der Spannungsquelle schon eine gewisse Zeit dauern, sprich, du bekommst sie vielleicht mit einer Blockbatterie (deren Strom auch relativ schnell in die Knie geht) nicht kaputt. Die FET-Stufe am GPIO ist relativ schnell "durch", wenn ihr Maximalstrom überschritten wird. Daher machte ich mir in meinem vorherigen Posting auch weniger Sorgen um die LED, deren Beständigkeit du ja bereits nachgewiesen hast :thumbs1:

    Ich werde dir die Grundlagen der LED-Beschaltung jetzt nicht im Detail erklären. Dazu gibt es genug gute Quellen im Netz. Nur soviel: betreibe sie nie, und wirklich nie, ohne eine ordentlich dimensionierte Strombegrenzung. (Profis dürfen den Satz abändern in "ohne dir vorher über die Strombegrenzung Gedanken gemacht zu haben"). Das ist im einfachsten Fall ein einfacher Widerstand, in aufwändigeren Anwendungsfällen (z.B. schwankende Versorgungsspannung oder hohe Leistung) eine Konstantstromquelle.

    Der Zusammenhang zwischen der Betriebsspannung und dem Stromfluss ist bei einer LED nicht linear (wie beim Ohm'schen Gesetz), sondern basiert auf einer e-Funktion, was zur Folge hat, dass "ein klein wenig zuviel" Spannung in "sehr viel zuviel" Strom resultiert. Daher bitte immer einen entsprechend berechneten Widerstand vorschalten.

    O.k., deine LED ist schonmal keine RGB-LED, sondern eine einfarbige. Welche Farbe hat sie? Das hat einen Einfluss auf die Vorwärtsspannung, anhand derer man so grob den Widerstand dimensionieren kann.

    Wenn du meinst, dass du eine LED ohne Vorwiderstand betreiben kannst, weil ihre Vorwärtsspannung Uf bei etwa 3,3V liegt, würde ich schon mal einen neuen Raspi bestellen. Und mich derweil mal in die Grundlagen der LED-Ansteuerung einlesen. Stichwort "logarithmische Kennlinie".

    Hast du nicht vielleicht wenigstens ein einfaches Multimeter, um mal ohne angeschlossene Last den Port ausmessen zu können? Vielleicht hat der ja schon das zeitliche gesegnet..