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?
Liste der Anhänge anzeigen (Anzahl: 1)
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:
Anhang 31315
Hier der Code :
share and enjoy! :cool:
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, ¶m);
pthread_create(&thread1, NULL, thread1Go, NULL);
param.sched_priority = 25;
pthread_setschedparam(thread1, SCHED_RR, ¶m);
pthread_create(&thread2, NULL, thread2Go, NULL);
param.sched_priority = 50;
pthread_setschedparam(thread2, SCHED_RR, ¶m);
pthread_create(&thread3, NULL, thread3Go, NULL);
param.sched_priority = 90;
pthread_setschedparam(thread3, SCHED_RR, ¶m);
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