- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 10 von 10

Thema: Raspi mit C/C++: Encoder per pigpio und callback auslesen?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    HaWe
    Gast

    Raspi mit C/C++: Encoder per pigpio und callback auslesen?

    hallo,
    ich komme nicht weiter:

    ich will 2 Rotationsencoder auslesen, dazu bräuchte ich eigentlich einen Timer-IRQ mit 100µs Frequenz.
    Das gibt es aber nicht auf dem Raspi.
    Andere Versuche sind gescheitert, da zu langsam:

    http://www.mindstormsforum.de/viewto...tart=15#p68001

    wie richte ich jetzt für meine 2 Encoder eine Callback-Funktion mit Pinchange-Interrupts ein, wie sie von "Joan" vorgeschlagen werden?
    Mir ist der Code ein einziges Rätsel:

    https://github.com/joan2937/pigpio/t...ROTARY_ENCODER
    bzw.
    https://github.com/joan2937/pigpio/t...ROTARY_ENCODER


    meine Pinbelegung ist diese:

    Code:
    // motor 0
    #define pigpio0A   23  // enc 0 A
    #define pigpio0B   24  // enc 0 B
    
    // motor 1
    #define pigpio1A   25  // enc 1 A
    #define pigpio1B   4   // enc 1 B
    und meine 2 Encoderwerte werden in diesem Array gespeichert:

    Code:
    volatile static long motenc[2];

    wer kann "Joan's" Code darauf anpassen helfen?

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Hallo,

    siehe Datei "test_rotary_encoder.cpp".

    Du brauchst wohl zwei Instanzen der Klasse und zwei Callbackfunktionen, etwa so
    Code:
    void callback1(int way)
    {
       static int pos = 0;
    
       pos += way;
    
       std::cout << "pos1=" << pos << std::endl;
    }
    
    void callback2(int way)
    {
       static int pos = 0;
    
       pos += way;
    
       std::cout << "pos2=" << pos << std::endl;
    }
    
    int main(int argc, char *argv[])
    {
       if (gpioInitialise() < 0) return 1;
    
       re_decoder dec1(23, 24, callback1);
       re_decoder dec2(25, 4, callback2);
    
      // ...

  3. #3
    HaWe
    Gast
    ach soooo - das mit den 2 Instanzen war mir bsolut nicht klar!

    Danke, das probiere ich sofort mal aus!

    was bedeutet dieser Teil...?
    Code:
    Pi_Renc_t * renc;
    
    
    sleep(3000);
    dec.re_cancel();
    in


    Code:
    int main(int argc, char *argv[])
    
       Pi_Renc_t * renc;
    
       if (gpioInitialise() < 0) return 1;
    
       renc = Pi_Renc(7, 8, callback);
    
       sleep(300);
    
       Pi_Renc_cancel(renc);
    
       gpioTerminate();
    
    }
    - - - Aktualisiert - - -

    und am Anfang was ist das: (ich nehme den C code, nicht cpp)

    Pi_Renc_t * renc;

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Eigentlich ist das schlechtes C++, guter Stil wäre es, das in einem Destruktor zu machen. (Google mal nach RAII)

    Im Konstruktor von re_decoder registriert er _pulseEx irgendwo in der Library
    Code:
    gpioSetAlertFuncEx(gpioA, _pulseEx, this);
    wobei in _pulseEx
    Code:
     mySelf->_pulse(gpio, level, tick);
    aufgerufen wird und dort der Callback auftaucht, z.B.
    Code:
    if (levB) (mycallback)(1);
    D.h innerhalb des Librarycodes wird irgendwo der Callback aufgerufen, wahrscheinlich bei jeder Änderung des Pins.

    Am Ende des Programms muss der Callback wieder abgeschaltet werden, das macht er in re_cancel()
    Code:
    gpioSetAlertFuncEx(mygpioA, 0, this);
    dort übergibt er einen Nullzeiger als neuen Callback.

  5. #5
    HaWe
    Gast
    ich kriegs nicht hin.

    gefühlte 50 Seiten Error Meldungen.


    Ich brauche echt jemanden, der mir den kompletten (!) C++ Code schreibt, für 2 unabhängige Rotationencoder.

    - - - Aktualisiert - - -

    Code:
    // encoder test
    // pigpio, pinchange IRQs
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <math.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/ioctl.h>
    #include <stdint.h>
    #include <errno.h>
    #include <pthread.h>
    #include <termios.h>
    #include <iostream>
    #include <pigpio.h>
    
    #include "VG/openvg.h"
    #include "VG/vgu.h"
    #include "fontinfo.h"
    #include "shapes.h"
    
    
    
    
    #define  byte  uint8_t;
    
    #define  MAXMOTORS           2 // max number of encoder motors at Arduino Uno=2 // Due=6 // Mega=8
    
    
    // motor 0
    
    
    #define pigpio0A   23
    #define pigpio0B   24
    
    #define pigpio0d1  11
    #define pigpio0d2  14
    #define pigpio0pwm 15
    
    
    // motor 1
    
    
    #define pigpio1A   25
    #define pigpio1B   4
    
    #define pigpio1d1  28
    #define pigpio1d2  29
    #define pigpio1pwm 30
    
    
    volatile long   motenc[MAXMOTORS],
                    oldenc[MAXMOTORS] ;
                   
    
    
                                   
    /*************************************************************
    * Interrupt Handler Routine
    *************************************************************/
    
    typedef void (*re_decoderCB_t)(int);
    class re_decoder
    {
       int mygpioA, mygpioB, levA, levB, lastGpio;
       re_decoderCB_t mycallback;
       void _pulse(int gpio, int level, uint32_t tick);
       /* Need a static callback to link with C. */
       static void _pulseEx(int gpio, int level, uint32_t tick, void *user);
       
       public:
       re_decoder(int gpioA, int gpioB, re_decoderCB_t callback);
       /*
       This function establishes a rotary encoder on gpioA and gpioB.
       When the encoder is turned the callback function is called.
       */
       void re_cancel(void);
       /*
       This function releases the resources used by the decoder.
       */
    };
    
    
    
    
    void re_decoder::_pulse(int gpio, int level, uint32_t tick)
    {
       if (gpio == mygpioA) levA = level; else levB = level;
    
       if (gpio != lastGpio) /* debounce */
       {
          lastGpio = gpio;
    
          if ((gpio == mygpioA) && (level == 1))
          {
             if (levB) (mycallback)(1);
          }
          else if ((gpio == mygpioB) && (level == 1))
          {
             if (levA) (mycallback)(-1);
          }
       }
    }
    
    void re_decoder::_pulseEx(int gpio, int level, uint32_t tick, void *user)
    {
       /*
          Need a static callback to link with C.
       */
    
       re_decoder *mySelf = (re_decoder *) user;
    
       mySelf->_pulse(gpio, level, tick); /* Call the instance callback. */
    }
    
    re_decoder::re_decoder(int gpioA, int gpioB, re_decoderCB_t callback)
    {
       mygpioA = gpioA;
       mygpioB = gpioB;
    
       mycallback = callback;
    
       levA=0;
       levB=0;
    
       lastGpio = -1;
    
       gpioSetMode(gpioA, PI_INPUT);
       gpioSetMode(gpioB, PI_INPUT);
    
       /* pull up is needed as encoder common is grounded */
    
       gpioSetPullUpDown(gpioA, PI_PUD_UP);
       gpioSetPullUpDown(gpioB, PI_PUD_UP);
    
       /* monitor encoder level changes */
    
       gpioSetAlertFuncEx(gpioA, _pulseEx, this);
       gpioSetAlertFuncEx(gpioB, _pulseEx, this);
    }
    
    
    
    void re_decoder::re_cancel(void)
    {
       gpioSetAlertFuncEx(mygpioA, 0, this);
       gpioSetAlertFuncEx(mygpioB, 0, this);
    }
    
    
    
    
    
    
    
    
    void setup() {
      int i;   
       
      // motor pin settings
      // setup for L293D motor driver
      // pullup resistors:
      // wiringPi: pullUpDnControl (butpin, PUD_UP);
      // pigpio:  gpioSetPullUpDown(butpin, PI_PUD_UP);
     
     
      // motor 0
         gpioSetMode(pigpio0A, PI_INPUT);                 // 4 enc0A    yellow
         gpioSetPullUpDown(pigpio0A, PI_PUD_UP);   
         gpioSetMode(pigpio0B, PI_INPUT);                 // 5 enc0B    blue
         gpioSetPullUpDown(pigpio0B, PI_PUD_UP);
         
         gpioSetMode(pigpio0d1, PI_OUTPUT);        // dir0-1   
         gpioSetMode(pigpio0d2, PI_OUTPUT);        // dir0-2   
         gpioSetMode(pigpio0pwm, PI_OUTPUT);       // enable0
           
      // motor 1
         gpioSetMode(pigpio1A, PI_INPUT);                 // 6 enc1A    yellow
         gpioSetPullUpDown(pigpio1A, PI_PUD_UP);   
         gpioSetMode(pigpio1B, PI_INPUT);                 // 7 enc1B    blue
         gpioSetPullUpDown(pigpio1B, PI_PUD_UP);
         
         gpioSetMode(pigpio1d1, PI_OUTPUT);        // dir1-1   
         gpioSetMode(pigpio1d2, PI_OUTPUT);        // dir1-2
         gpioSetMode(pigpio1pwm, PI_OUTPUT);       // enable1   
    
         for( i=0; i< MAXMOTORS; ++i) motenc[i] = 0;     
     
    }
    
    
    
     
       
       
       
    void callback0(int way){
       static int pos = 0;
       pos += way;
       std::cout << "pos=" << pos << std::endl;
    }
    
    
    void callback1(int way){
       static int pos = 0;
       pos += way;
       std::cout << "pos=" << pos << std::endl;
    }
    
    
    
    int main(int argc, char *argv[])
    {
       if (gpioInitialise() < 0) return 1;
    
       setup();
    
       re_decoder dec0(pigpio0A, pigpio0B, callback0);
       re_decoder dec1(pigpio1A, pigpio1B, callback1);
       
    
    
       sleep(3000);
    
       dec0.re_cancel();
       dec1.re_cancel();
    
       gpioTerminate();
       
       
    }

    g++ -Wall -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads -o "enc0005" "enc0005.c" -lshapes -L/opt/vc/lib -lOpenVG -lEGL -pthread -lrt -lwiringPi (im Verzeichnis: /home/pi/programs/test/encoder)
    Kompilierung fehlgeschlagen.
    /tmp/ccHKEpu6.o: In function `re_decoder::re_decoder(int, int, void (*)(int))':
    enc0005.c:(.text+0x1ac): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x1bc): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x1cc): undefined reference to `gpioSetPullUpDown'
    enc0005.c:(.text+0x1dc): undefined reference to `gpioSetPullUpDown'
    enc0005.c:(.text+0x1f0): undefined reference to `gpioSetAlertFuncEx'
    enc0005.c:(.text+0x204): undefined reference to `gpioSetAlertFuncEx'
    /tmp/ccHKEpu6.o: In function `re_decoder::re_cancel()':
    enc0005.c:(.text+0x240): undefined reference to `gpioSetAlertFuncEx'
    enc0005.c:(.text+0x258): undefined reference to `gpioSetAlertFuncEx'
    /tmp/ccHKEpu6.o: In function `setup()':
    enc0005.c:(.text+0x278): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x284): undefined reference to `gpioSetPullUpDown'
    enc0005.c:(.text+0x290): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x29c): undefined reference to `gpioSetPullUpDown'
    enc0005.c:(.text+0x2a8): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x2b4): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x2c0): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x2cc): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x2d8): undefined reference to `gpioSetPullUpDown'
    enc0005.c:(.text+0x2e4): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x2f0): undefined reference to `gpioSetPullUpDown'
    enc0005.c:(.text+0x2fc): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x308): undefined reference to `gpioSetMode'
    enc0005.c:(.text+0x314): undefined reference to `gpioSetMode'
    /tmp/ccHKEpu6.o: In function `main':
    enc0005.c:(.text+0x454): undefined reference to `gpioInitialise'
    enc0005.c:(.text+0x4c8): undefined reference to `gpioTerminate'
    collect2: error: ld returned 1 exit status

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Sieht so aus, als ob da ein include fehlt, wahrscheinlich
    Code:
    #include <pigpio.h>
    Außerdem sehe ich da ein
    Code:
    -lwiringPi
    wo sicher ein
    Code:
    -lpigpio
    hingehört.

    Ansonsten kenne ich mit pigpio nicht aus, Linux GPIOs stehen auf meiner Prioritätenliste weit unten.

Ähnliche Themen

  1. Raspi GPP C++ WiringPi: Rotationsencoder auslesen
    Von HaWe im Forum Raspberry Pi
    Antworten: 1
    Letzter Beitrag: 18.10.2015, 10:29
  2. [C, C++] GPIO lib: pigpio oder WiringPi?
    Von HaWe im Forum Raspberry Pi
    Antworten: 0
    Letzter Beitrag: 15.10.2015, 18:19
  3. [ERLEDIGT] Raspi Club?
    Von pofoklempner im Forum Raspberry Pi
    Antworten: 16
    Letzter Beitrag: 09.07.2015, 07:20
  4. wie funktioniert encoder(LEFT) und encoder(RIGHT)
    Von natalie im Forum Sonstige Roboter- und artverwandte Modelle
    Antworten: 2
    Letzter Beitrag: 22.11.2005, 22:45
  5. Encoder (IGR) auslesen??
    Von focobot im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 26.09.2004, 16:22

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen