- fchao-Sinus-Wechselrichter AliExpress         
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
    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);
    
      // ...

  2. #2
    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;

  3. #3
    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.

  4. #4
    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

  5. #5
    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.

  6. #6
    HaWe
    Gast
    ja, stimmt, aber ich glaube, das war jetzt der Tropfen, der das Fass zum Überlaufen gebracht hat.
    Ich hasse diese tonnenweisen -l und -I Parameter für compile, make und build,
    dann dieser unglaublich langsame Bildschirmaufbau beim Raspi-Onboard-Programmieren,
    dann dass es keine Windows-IDE mit Crosscompiler gibt wie bei der Arduino IDE,
    dann die unglaublich - viel zu - wenigen Pins für IO, ADC, DAC, UART, I2C,
    keine Interrupts auf Hardware-level,
    und zu allem Überfluss noch nicht mal 2 pins mit PWM vorhanden.

    Ich lass es bleiben mit dem Raspi, es bringt nichts außer Ärger und Frust.


    Da kann ja ein Uno schon mehr.

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    54
    Beiträge
    765
    Da gebe ich Dir Recht. C zu kompilieren ist nicht immer nur GCC aufzurufen. Ich mag das auch nicht sonderlich, klappt aber bei meinen kleinen Projekten. Wo es auf Echtzeit ankommt, nutze ich immer einen AVR als 'Co-Prozessor'. Der kann Drehencoder, WS2812B LEDs und Interrupts problemlos. Die Kommunikation ist dann per UART zum Raspi. Der Raspi selbst ist für das Netzwerk und die Anbindung an USB-Hardware zuständig. Dafür sind die AVRs einfach zu lahm / ressourcenarm. Der große Vorteil ist, dass man den AVR bequem übers Netzwerk per Raspi flashen kann.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

Ähnliche Themen

  1. Raspi GPP C++ WiringPi: Rotationsencoder auslesen
    Von HaWe im Forum Raspberry Pi
    Antworten: 1
    Letzter Beitrag: 18.10.2015, 09:29
  2. [C, C++] GPIO lib: pigpio oder WiringPi?
    Von HaWe im Forum Raspberry Pi
    Antworten: 0
    Letzter Beitrag: 15.10.2015, 17:19
  3. [ERLEDIGT] Raspi Club?
    Von pofoklempner im Forum Raspberry Pi
    Antworten: 16
    Letzter Beitrag: 09.07.2015, 06: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, 21:45
  5. Encoder (IGR) auslesen??
    Von focobot im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 26.09.2004, 15:22

Berechtigungen

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

LiFePO4 Speicher Test