- LiFePO4 Speicher Test         
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
    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.

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

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    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! \/

  4. #4
    HaWe
    Gast
    update:
    hatte es dann doch hingekriegt, dass es wenigstens läuft (B+).
    A-Bär: wenn man normal schnell dreht (3 U/s), dann werden pro 360° nur 300 encoder ticks gelesen, also werden jede Menge übersehen und daher verschluckt.
    Wenn man es nicht über Pinchange implementiert, sondern als Extra-pthread-Task im 100µs-Takt, klappt es noch schlechter (beim Arduino klappen sogar 8 Motoren im 200µs-Timer-IRQ-Takt!)

    wenn man sehr langsam dreht (1U pro 2 sec), dann liest er korrekt alle 360 ticks.
    Der Raspi ist also tatsächlich nicht in der Lage, schnelle Pin-Lese-Vorgänge durchzuführen.

    neu:

    Ich habe jetzt einen Raspi 2B Quadcore und werde es nochmals testen -
    diesmal aber nicht per pinchange-Interrupt, denn da ändert sich ja nichts, sondern wieder als pthread-Task im 100µs-Takt und mit pthread-priority von 90%.
    Ich habe nämlich festgestellt, dass das Betriebssystem und Posix die Tasks sehr geschickt auf die cpu-Kerne verteilen, daher habe ich die Hoffnung, dass einer der cores bevorzugt nur mit diesem 90% prio-Task beschäftigt sein wird, um wenigstens halbwegs ein taktgenaues Arbeiten zu ermöglichen (ohne wieder von user space tasks ausgebremst zu werden).

    Ich werde berichten!

  5. #5
    HaWe
    Gast
    update:

    mit Raspi 2B klappt es! Keine Zähl-Ausfälle mehr, selbst bei recht schnellen Umdrehungen, getestet mit Lego-Encodermotoren
    (Auflösung: 1/2, d.h. 360 ticks/360°. Drehgeschwindigkeit 5 U/sec.).


    Es wird über einen High Priority pthread Task ein Timer-Interrupt im 100µs Takt simuliert, und der Pi Quadcore hat jetzt die Performance, dies auch im Linux User Space sicher durchzuhalten - die Simulation verwendet dazu bisher insgesamt 4 Tasks mit unterschiedlicher Priorität:

    Klicke auf die Grafik für eine größere Ansicht

Name:	Raspi_Enc_C++_200453.jpg
Hits:	11
Größe:	99,7 KB
ID:	31315

    Hier der Code :

    share and enjoy!


    Code:
    // encoder test
    // wiringPi,   
    // Encoder Timer High Priority Thread
    // ver 0007
    
    // protected under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
    // http://creativecommons.org/licenses/by-nc-sa/3.0/
    
    #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 "VG/openvg.h"
    #include "VG/vgu.h"
    #include "fontinfo.h"
    #include "shapes.h"
    
    #include <wiringPi.h>
    #include <wiringSerial.h>
    
    
    #define  byte  uint8_t;
    
    #define  MAXMOTORS    2   // max number of encoder motors
    
    typedef struct {
          uint8_t    pd1, pd2, pwm;
          uint8_t    pqa, pqb;
          int32_t    motenc, oldenc;
    
    }  tpimotor ;
    
    tpimotor  motor[MAXMOTORS];
    
                                   
    /*************************************************************
    * Encoder Handler Routine
    *************************************************************/
    
    volatile int8_t ISRab[MAXMOTORS];
    
    // 1/2 resolution
    int8_t enctab[16] = {0, 0,0,0,1,0,0,-1, 0,0,0,1,0,0,-1,0};
    
    void updateEncoders() {   
      int i;    
      for( i=0; i<MAXMOTORS; ++i ) {   
        ISRab [ i] <<= 2;
        ISRab [ i] &=  0b00001100;
        ISRab [ i] |= (digitalRead( motor[ i].pqa ) << 1) | digitalRead(  motor[ i].pqb );
        motor[ i].motenc += enctab[ ISRab[ i] ];   
      }     
    
    }
    
    
                                 
    
    void* thread3Go(void *)   // encoder high priority thread
    {
       while(1) {
         updateEncoders();
         usleep(100);
       }         
       return NULL;
    }
    
    void* thread2Go(void *)
    {
       while(1) {
          delay(10);
       }         
       return NULL;
    }
    
    void* thread1Go(void *)   // low priority display thread
    {
       char  sbuf[128];
       while(1) {   
         delay(100);
       }         
       return NULL;
    }
    
    void* thread0Go(void *)
    {
       char  sbuf[128];
       while(1) {
        sprintf(sbuf, " 0=%6ld    1=%6ld \n ",  motor[0].motenc, motor[1].motenc );
         printf(sbuf);
         delay(100);
       }         
       return NULL;
    }
    
    
    
    
    void setup() {
      int i;   
       
      // motor pins, wiringPi numbering (in parenthesis: BCM numbering)
    
         motor[0].pinQa = 5;   // (BCM 24) change for rotation direction
         motor[0].pinQb = 4;   // (BCM 23) change for rotation direction
         motor[0].pind1 =24;   // (BCM 19)
         motor[0].pind2 =25;   // (BCM 26)
         motor[0].pinpwm= 1;   // (BCM 18) hardware pwm
         
         motor[1].pinQa = 0;   // (BCM 17) change for rotation direction
         motor[1].pinQb = 2;   // (BCM 27) change for rotation direction
         motor[1].pind1 =21;   // (BCM 5)
         motor[1].pind2 =22;   // (BCM 6)
         motor[1].pinpwm=23;   // (BCM 13) hardware pwm   
    
         
         for( i=0; i< MAXMOTORS; ++i)  {       
            pinMode(motor[i].pqa, INPUT);        // encA   
            pinMode(motor[i].pqb, INPUT);        // encB   
            pinMode(motor[i].pd1, OUTPUT);       // dir-1   
            pinMode(motor[i].pd2, OUTPUT);       // dir-2   
            pinMode(motor[i].pwm ,OUTPUT);       // pwm
           
            motor[i].motenc = 0;
            motor[i].oldenc = 0;
            ISRab[i] = 0;
       }
    }
    
    
    
    
    
    int main() {
        char  sbuf[128];
        pthread_t thread0, thread1, thread2, thread3;
       
        wiringPiSetup();   
        if(wiringPiSetup() == -1) return 1;   
       
        setup();
       
        struct sched_param param;
       
       
        pthread_create(&thread0, NULL, thread0Go, NULL);
        param.sched_priority = 10;
        pthread_setschedparam(thread0, SCHED_RR, &param);
       
        pthread_create(&thread1, NULL, thread1Go, NULL);
        param.sched_priority = 25;
        pthread_setschedparam(thread1, SCHED_RR, &param);
       
        pthread_create(&thread2, NULL, thread2Go, NULL);
        param.sched_priority = 50;
        pthread_setschedparam(thread2, SCHED_RR, &param);
       
        pthread_create(&thread3, NULL, thread3Go, NULL);
        param.sched_priority = 90;
        pthread_setschedparam(thread3, SCHED_RR, &param);
       
       
        pthread_join(thread0, NULL);
        pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);
        pthread_join(thread3, NULL);
       
        exit(0);
       
    }
    Code:
    # build:
     g++ -Wall -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads -o "%e" "%f" -pthread -lshapes -L/opt/vc/lib -lOpenVG -lEGL -lrt -lwiringPi -lpigpio
    Geändert von HaWe (20.02.2016 um 12:18 Uhr) Grund: code update

Ä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
  •  

Labornetzteil AliExpress