PiFace Input Interrupt Driven

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo Leute,

    ich nutze mein RaspBi (000e: Model B, Revision 2.0, RAM: 512 MB, Maker: Sony) zusammen mit dem PiFace Digital Board.

    Die ausgänge kann ich wunderbar steuern- da hängt meine Heizung dran.

    zum Stromzählen (via S0) würde ich jetzt gerne einen der Inputs nutzen. Ich habe es mit Hilfe der WiringPi library auch schon hinbekommen, die Eingänge auszulesen- er gibt mir 1 oder 0 aus. Wunderbar! ;)

    Mein Problem ist aber, dass ich das Ganze irgendwie Interrupt- gesteuert machen muss- das Signal, das mit den Input betätigt ist ja nicht vorhersagbar. Und es kommt auch immer nur ganz kurz- wenn ich gerade da nicht abfrage, verpasse ich es ja!

    Also brauche ich eine Lösung, die solange schläft, bis der Kontakt geschlossen wird.

    Vermute ich richtig, dass ich das in C mit einem zusätzlichen Thread realisieren muß? Gut, pThread ist nicht das Problem- aber wie sage ich dem "digitalRead()", dass er warten soll, bis 1 da ist?

    /KNEBB

    Einmal editiert, zuletzt von knebb (24. März 2016 um 15:05)

  • Hallo.

    Ok, anbei ein Testprogramm in C, mit der pigpio.lib
    Das Ding macht nichts anderes als alle 2 sec nen triggerpuls ausgeben, dessen up/down flanken gezählt und angezeigt werden.


    gruß root

    //Edit ... hab die korr. Einrückungen noch gemacht

    Einmal editiert, zuletzt von root (24. März 2016 um 15:36)

  • Die Alternative mit wiringPI (weil der TE das ja schon hat) nennt sich

    Code
    int wiringPiISR (int pin, int edgeType,  void (*function)(void)) ;
  • Ok, ich habe mein Thread wohl falsch beschrieben. Natürlich habe ich schon entsprechend gesucht- aber es gibt nirgends brauchbare Beispiele bzw. eine ordentliche Doku.

    dreamshader: Das ist ein Beispiel, das ohne PiFace ist. Nicht brauchbar!
    @root: Das liest mir GPIOs aus. Solche Beispiele habe ich auch massenhaft gefunden. Nur nicht mit PiFace.
    @__deets__: Ja, diese Funktion hatte ich auch schon gesehen- aber mangels Beispiele finde ich keine Möglichkeit, die zu verwenden.

    In der Zwischenzeit habe ich mir mal den Sourcecode der WirinPi Library heruntergeladen (geht zum Glück auch ohne GIT), da sind eine ganze Menge Beispiele enthalten.

    Und eines funktioniert wohl auch. Zumindest mit den Tastern. Ob das auch bei Impulsen funktioniert, muss ich noch testen. Werde es erst einmal anpassen und dann mal sehen:

  • Na, wenn du selber schon schreibst du weisst, wie du mit pthreads umgehst - wo ist denn das Problem?

    Code
    void pin10Callback()
    {
       printf("pin 10 toggled\n");
    }
    
    
    ...
     wiringPiISR (10, INT_EDGE_BOTH, &pin10Callback);

    So funktioniert ja auch die Uebergabe an einen pthread_create.

    Bloed ist allerdings, dass es kein User-Data-Pointer gibt... sowas ist eigentlich Standard. Ich halte uA auch deswegen nur so beschraenkt viel von wiringPI.

    Last but not least verstehe ich nicht, was das alles mit PiFace zu tun hat. Das sind Erweiterungen, die du auf deine GPIO-Pins klemmst - aber die werden doch abgefragt wie auch mimer du das moechtest. Ob PiGPIO oder Python RPI.GPIO oder wiringPI macht da doch keinen Unterschied.


  • Na, wenn du selber schon schreibst du weisst, wie du mit pthreads umgehst - wo ist denn das Problem?


    Das Problem sind nicht die pthreads, sondern die Funktionen, die den Input auslesen.
    Im Normalfall lesen die den aktuellen Stand aus und gehen weiter- meist in ein delay(), das in einer for (;;) Schleife steckt. Das braucht aber entweder 100% CPU oder aber der Impuls kommt während der delay-Zeit und man verpasst ihn. Deshalb Interrupt-gesteuert!


    Code
    void pin10Callback()
    {
      printf("pin 10 toggled\n");
    }
    
    
    ...
    wiringPiISR (10, INT_EDGE_BOTH, &pin10Callback);


    Das wiringPiISR hatte ich mir angesehen, das funktionierte irgendwie nicht. Wie gesagt, mittels

    Code
    pullUpDnControl(PIFACE+i, PUD_UP) ;

    funktioniert das jetzt scheinbar.


    Zitat

    Bloed ist allerdings, dass es kein User-Data-Pointer gibt... sowas ist eigentlich Standard.


    Naja, brauche ich nicht, weil es gibt ja keine UserData. Bei jedem Aufruf erhöhe ich einen globalen Zähler und gut ist :D


    Zitat


    Last but not least verstehe ich nicht, was das alles mit PiFace zu tun hat. Das sind Erweiterungen, die du auf deine GPIO-Pins klemmst - aber die werden doch abgefragt wie auch mimer du das moechtest. Ob PiGPIO oder Python RPI.GPIO oder wiringPI macht da doch keinen Unterschied.


    Weil ich nicht herausfinden konnte, welcher Input welchen GPIO zugeordnet ist. Dann geht das wohl auch ohne die PiFace libs. So ist es für mich als Laienprogrammierer aber übersichtlicher :)


    /KNEBB


  • Das Problem sind nicht die pthreads, sondern die Funktionen, die den Input auslesen.
    Im Normalfall lesen die den aktuellen Stand aus und gehen weiter- meist in ein delay(), das in einer for (;;) Schleife steckt. Das braucht aber entweder 100% CPU oder aber der Impuls kommt während der delay-Zeit und man verpasst ihn. Deshalb Interrupt-gesteuert!


    Weil ich nicht herausfinden konnte, welcher Input welchen GPIO zugeordnet ist. Dann geht das wohl auch ohne die PiFace libs. So ist es für mich als Laienprogrammierer aber übersichtlicher :)

    ...also ehrlich gesagt, versteh ich dein Problem nicht.
    Den Pin defnierst du doch selbst, und da muss nichts ausgelesen werden.
    Du hast 3 Möglichkeiten, wobei es egal ist, ob Taster oder Puls.
    Int 1 bei steigender Flanke, int 2 bei fallender.Da muss nichts ausgelesen werden.Die aufgerufene ISR weiss doch ob es steigende oder fallende war.
    3: Int wenn "state changes".Hier musst du entscheiden.War es ne steigende oder fallende.


  • ...also ehrlich gesagt, versteh ich dein Problem nicht.
    Den Pin defnierst du doch selbst, und da muss nichts ausgelesen werden.


    Klar. Aber ich habe das Kabel doch an einen bestimmten Input des PiFace angeschlossen. An Input 7 in diesem Fall. Welchen GPIO muss ich abfragen, um meinen Impuls auszulesen?


  • Klar. Aber ich habe das Kabel doch an einen bestimmten Input des PiFace angeschlossen. An Input 7 in diesem Fall. Welchen GPIO muss ich abfragen, um meinen Impuls auszulesen?


    ...gar keinen.
    Du definerst deine ISR so ,dass sie ausgelöst wird, wenn am Pin 7 (keine Ahnung welcher GPIO Pin 7 vom PiFace ist) ein Ereignis auftritt... wie weiter oben beschrieben.

    Die ISR wird ausgelöst, egal was die main() grade macht.


  • Ja, aber genau das ist doch mein Problem! :wallbash:
    Pin (Input) 7 vom PiFace will ich abfragen. Ich weiß aber nicht, welcher GPIO das ist! :baeh2:

    ....äachz... :wallbash: .. dann guck halt in der Beschreibung des dämlichen PiFaces nach... :D:D:D

    ... da glühen bei 3-4 Usern jetzt noch neuronale Hirnverknüpfungen nach, bis er edlich rausrückt, was er eigentlich will... :D:D:D

    Einmal editiert, zuletzt von root (24. März 2016 um 18:21)

  • Puh, das sieht so aus als als ob der PiFace ueber I2C arbeitet. Da verstehe ich dann aber eh nicht, wie wiringPI da mitspielt.


  • Puh, das sieht so aus als als ob der PiFace ueber I2C arbeitet. Da verstehe ich dann aber eh nicht, wie wiringPI da mitspielt.

    ...also ich geh etzt in's Kloster... :D:D:D
    Ich hatte mal so'n Dingens vor 3 Jahren in der Hand...


    Das Ding wird doch direkt auf die GPIO-Leiste gesteckt.
    mag sein dass bei neueren ne I"C Möglichkeit zsätzlich da ist.
    aber angesteuert über I²C ?.... nööö

    Einmal editiert, zuletzt von root (24. März 2016 um 18:48)

  • Hallöle,
    da ist doch nur ein MCP23S17 drauf und der RPi redet da per SPI ...
    Der Stein selbst unterstützt z.B. pin-change Interrupts und da instantiiert wiringPi halt ein eigenes Objekt, das eben den Käfer handelt ...
    Alles kein Hexenwerk ;)

    Und nein - als "GPIO" sind die I/Os des Boards nicht ansprechbar ...

    ciao,
    -ds-

  • @root: i2c oder SPI - das macht ja keinen nenneswerten unterschied. Wie ds schon sagt - ist ein MCP23S17, ich hab' halt nur gelesen "I2C or SPI" im Datenblatt und mich dann fuer I2C entschieden.

    Und bloss, weil das Ding auf allen moeglichen GPIOs sitzt heisst das ja nicht, dass er die braucht ;)

  • /KNEBB


    Und nein - als "GPIO" sind die I/Os des Boards nicht ansprechbar ...


    Das wird der Grund sein, warum ich da keine Docs zu gefunden habe... :daumendreh2:

    Also kann ich die Input-PINs NICHT direkt via GPIO ansprechen und damit auch nicht die wiringPiISR() Funktion, richtig?

    Na, wie gesagt, es läuft jetzt über pullUpDnControl(PIFACE+i, PUD_UP) ;.

    Nochmal Danke :danke_ATDE: und denkt nicht so kompliziert :fies:


    /KNEBB

  • Ah. Das erklaerts - hat der TE aber tatsaechlich auch schon erwaehnt, dass er das benutzt. Das war mir nicht klar. Letztlich funktioniert damit natuerlich aber nichts, was sich auf die "klassischen" GPIO-Pins setzt, "Interrupt" hin oder her.

    Langsam verstehe ich auch, wie das funktioniert. wiringPI erfindet einfach virtuelle pins, und in die kann sich eine Erweiterung einklemmen. Dadurch werden dann generische Funktionen wie digitalWrite moeglich - die Pin-Nummer ist dann etwas absurd hohes wie 200, und relativ dazu liegen dann halt 8 Pins, und die werden auf die PiFace Ports gemappt.

    knebb: jetzt habe ich das besser verstanden, aber das Problem bleibt - der von dir gezeigte scanButton-Code ist am Ende ein test + kurzes Delay im engen loop. Da kommt es jetzt halt auf deine Impulse an, wie lang die sind...

Jetzt mitmachen!

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