GPIO zeitgleiche mehrfachverwendung

  • Hallo zusammen.

    Ich habe gerade ein Problem und brauche mal wieder Hilfe.

    Ich habe einen RPi2 als Heimautomationsserver. Da fand ich die Idee toll eine 433MHz Fernbedienung zu nutzen. Das ganze habe ich jetzt verdrahtet und läuft auch soweit. Ich nutze die Lib von Milaq (https://github.com/milaq/rpi-rf). Der RXB6 ist an GPIO 27.
    So, nun habe ich der Taste A gerade die Funktion zugewiesen das Licht anzuschalten. Dazu sendet der RPi mit einem NRF24L01 ein Signal zu einem Arduino. Der NRF wird jedoch auch über GPIO angesprochen. Diese Funktion macht natürlich, wie es sich gehört, einen GPIO.cleanup(). Damit scheint sie aber auch den GPIO Aufruf für den 433MHz Receiver zu 'cleanen'.

    Wie löst man das jetzt am elegantesten? Der Receiver für den RXB6 muss die ganze Zeit laufen... man weiß ja nie wann mal einer die Fernbedienung drückt.
    Kann man das cleanup generell weglassen? Nicht so toll, oder? Kann man nur eine Instanz cleanen?

  • Die Scripte... ok... mal gucken


    Hier das Script für den 433 Receiver:

    Da benutze ich, wie gesagt, die Lib von Milaq (https://github.com/milaq/rpi-rf).



    So, dann wird die Taste A gedrückt und die Funktion:

    Code
    bob.switch_small_relay(2, 0)

    aufgerufen. Die 2 ist einfach der Index des Relais und die 0 = Aus (1 = An).



    Und die Funktion CWA.communication_via_nrf24l01 sieht so aus:


    Diese macht, nach der Arbeit, ein GPIO.cleanup(). Dieses zerstört aber auch das GPIO Handling der rpi-rf... woraufhin diese keine Daten mehr Empfangen kann und einfach nichts mehr macht. Bei STRG+C kommt:


    Edit: Ok, das letzte hat "nichts" mit dem Problem zu tun. Das ist eine Cleanup Funktion von rpi-rf, die beim Beenden (auch STRG+C) ausgeführt wird.

  • Man kann mehrere Python Scripts bzgl. GPIO gleichzeitig nutzen / laufen haben.

    Durch GPIO.cleanup() werden nicht _alle_ GPIO's auf Werkseinstellungen zurückgesetzt, sondern nur die die vom jeweiligen Script tatsächlich verwendet wurden.

    Man kann GPIO.cleanup() aber auch den GPIO übergeben der zurückgesetzt werden soll: GPIO.cleanup(17)


    Wenn du GPIO.cleanup() in der RFDevice Klasse (Zeile 68) entsprechend anpasst sollte es eigentlich den gewünschten Effekt haben...

    Ggf. müsstest du dann noch ein GPIO.setwarnings(False) nach Zeile 58 einfügen. (Optional)

    Zeile 68 müsste wie folgt angepasst werden: GPIO.cleanup(self.gpio)


    In der cleanup() Methode der RFDevice Klasse wird halt noch mehr gemacht, deshalb solltest du die Methode schon weiterhin aufrufen.


    Ausprobiert hab ich das noch nicht, aber du ja gleich :angel:

  • Funktioniert leider nicht. Das Skript bleibt immer noch 'stecken' und es werden keine Signale der Fernbedienung mehr angezeigt.
    Wobei ich auch nicht ganz verstehe warum es in der RFDevice Klasse geändert werden soll. Müsste nicht die communication_via_nrf24l01 bearbeitet werden? Denn die RFDevice Klasse ist ja die, die dauerhaft läuft und die communication_via_nrf24l01 Funktion immer nur zwischendurch.
    Wie dem auch sei, ich habe es an beiden Stellen probiert... es gibt zwar keinen Fehler, aber funktionieren tut es auch nicht. Aus irgend einem Grund unterbricht die communication_via_nrf24l01 den Ablauf der RFDevice. :(

  • Habe jetzt versucht nach einem erkannten Code einen

    Code
    rfdevice.cleanup()

    zu machen, dann die Kommunikation mit dem nrf24l01, dort einen CleanUp und dann ein

    Code
    rfdevice.enable_rx()

    Bringt auch nichts. Dann bekomme ich einen 'Speicherzugriffsfehler'.

    Zum Mäusemelken.

  • Achso ich hab das anders herum verstanden, dass das RFDevice Script zwischendurch gestartet wird. Leider hast du nicht erwähnt welches nrf24l01 Module du da nutzt...


    Dann pass mal in der communication_via_nrf24l01() Funktion Zeile 44, 54 und 60 an bzw kommentier alle GPIO.cleanup() Zeilen aus und füge nach Zeile 3 GPIO.setwarnings(False) ein.


    Bei communication_via_nrf24l01() gibt es halt eine Besonderheit: NRF24() wird nur das Module zur Steuerung der GPIOs übergeben, das wiederum kümmert sich selber um die Initialisierung aber macht normalerweise kein cleanup.

    Somit müsste es also eigentlich reichen communication_via_nrf24l01() anzupassen.

  • Warum macht es normalerweise kein Cleanup? Sollte nicht immer ein Cleanup der GPIOs gemacht werden, da sie sonst - auch nach Programmende - weiterhin belegt sind und nicht neu genutzt werden können?

    Ich habe jetzt einen neuen Parameter in communication_via_nrf24l01() eingebaut; gpio_clean_up

    Damit übergebe ich der Funktion den Hinweis ob ein cleanup gemacht werden soll oder nicht. Die Funktion wird auch von anderen Programmfunktionen aufgerufen und da ist dann ein CleanUp notwendig. So ganz richtig fühlt sich das aber noch nicht an, da einen Parameter überall durchzuschleifen. Scheint wohl aber nicht anders zu gehen.