- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 10 von 20

Thema: 250µs-Timer für Arduino Due

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    HaWe
    Gast
    ach so, ganz neu schreiben - das hatte ich nicht verstanden, ich dachte bis jetzt, das wäre schon für Sketch.
    Das kann ich allerdings leider nicht, dazu verstehe ich zuwenig davon, und C++ kann ich überhaupt nicht - nur nacktes C (oder eben extrem abgespeckte Objekte wie z.B. Serial und entsprechend automatisch included und aufbereitet wie in Sketch).

  2. #2
    HaWe
    Gast
    heißt das etwa, es gibt keine fertigen Sketch-Beispielcodes für Due-Timer ???

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Was ist mit der Lib, die Google gleich als erstes findet ?
    https://github.com/ivanseidel/DueTimer

    Wenn man mal in die DueTimer.cpp schaut, sieht man, dass sich das ganze doch etwas vom AVR unterscheidet.
    Die Registerzugriffe scheinen aber auch beim Due schon durch Funktionen gekapselt zu sein. Was da an Libraries
    in Arduino 1.5.x alles steckt, scheint aber nirgends richtig dokumentiert zu sein.

  4. #4
    HaWe
    Gast
    ah - jetzt verstehe ich...
    es ist ganz anders als die AVR-Variante. ich hatte nicht an so eine komplette lib gedacht.
    Das Programm sieht ja ausgesprochen simpel aus, viel einfacher als das oben für den AVR:

    Code:
    #include <DueTimer.h>
    
    int myLed = 13;
    
    bool ledOn = false;
    
    void myHandler(){
    	ledOn = !ledOn;
    
    	digitalWrite(myLed, ledOn); // Led on, off, on, off...
    }
    
    void setup(){
    	pinMode(myLed, OUTPUT);
    
    	Timer3.attachInterrupt(myHandler);
    	Timer3.start(500000); // Calls every 500ms
    }
    
    void loop(){
    
    	while(1){
    		// I'm stuck in here! help me...
    	}
    	
    }
    Hier wird dann ja wohl Timer 3 verwendet, bei mir oben war es glaube ich Timer 1 und alle 250µs, dann also
    Timer1.attachInterrupt(myHandler);
    Timer1.start(250); // Calls every 250µs

    in myHandler dann meine ISR arrays
    Code:
    volatile long   motenc[MAXMOTORS]    = {0, 0, 0, 0, 0, 0},
                    oldenc[MAXMOTORS]    = {0, 0, 0, 0, 0, 0};
    int8_t schrittTab[16] = {0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1, 0};
    
    volatile int8_t ISRab[MAXMOTORS]     = {0, 0, 0, 0, 0, 0};
    
    void myHandler() {  // read encoder values
    
      ISRab [ 0] <<= 2;
      ISRab [ 0] &= B00001100;
      ISRab [ 0] |= (digitalRead(pinenc0A) << 1) | digitalRead(pinenc0B);
      motenc[ 0] += schrittTab[ISRab[0]];           //
    
      ISRab [ 1] <<= 2;
      ISRab [ 1] &= B00001100;
      ISRab [ 1] |= (digitalRead(pinenc1A) << 1) | digitalRead(pinenc1B);
      motenc[ 1] += schrittTab[ISRab[1]];           //
    
      ISRab [ 2] <<= 2;
      ISRab [ 2] &= B00001100;
      ISRab [ 2] |= (digitalRead(pinenc2A) << 1) | digitalRead(pinenc2B);
      motenc[ 2] += schrittTab[ISRab[2]];           //
    
      ISRab [ 3] <<= 2;
      ISRab [ 3] &= B00001100;
      ISRab [ 3] |= (digitalRead(pinenc3A) << 1) | digitalRead(pinenc3B);
      motenc[ 3] += schrittTab[ISRab[3]];           //
    
      ISRab [ 4] <<= 2;
      ISRab [ 4] &= B00001100;
      ISRab [ 4] |= (digitalRead(pinenc4A) << 1) | digitalRead(pinenc4B);
      motenc[ 4] += schrittTab[ISRab[4]];           //
    
      ISRab [ 5] <<= 2;
      ISRab [ 5] &= B00001100;
      ISRab [ 5] |= (digitalRead(pinenc5A) << 1) | digitalRead(pinenc5B);
      motenc[ 5] += schrittTab[ISRab[5]];           //
    
    }
    - müsste dann doch so funktionieren...? Werde ich gleich am Wochenende austesten!

    Ein ganz herzliches Dankeschön! 8-)
    Geändert von HaWe (21.11.2014 um 16:52 Uhr)

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Ein Problem bei deinem Code dürfte das digitalRead() sein. Das ist bei Arduinos als ziemlich langsam verrufen.

    Bei mbed gibt es da die Möglichkeit mit PortIn alle 32 Pins eines Ports auf einmal zu lesen, das wäre für die Abfrage mehrerer Encoder sicher viel besser.

    Eventuell gibt es in den Untiefen der Arduino Software dafür auch Funktionen ...

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    13.01.2014
    Beiträge
    454
    Blog-Einträge
    3
    Das SFR GPIOx_ODR (data output register) hat laut Manual 32Bit, von denen aber die oberen 16 unbenutzt sind. D.h. man kann (und sollte) ein 16Bit Port (z.B. PortA_L + PortA_H) direkt in einem Zug auslesen, statt mehrere einzelne nacheinander.

  7. #7
    HaWe
    Gast
    danke für die Tipps, falls mein Code nicht funktioniert, werde ich dran denken!
    digitalRead hat allerdings bisher beim Mega mit Sketch perfekt funktioniert, und selbst da war noch Luft drin (theoretisch reichen bei 100° pro 100ms sogar 500-1000µs IRQ Takt).

  8. #8
    HaWe
    Gast
    es scheint zu stimmen, ich habe es gegen den Mega getestet:
    Beim mega mit dem ursprünglichen Code immer alle Encoder ok in Echtzeit, volle Umdrehungen aller Motoren werden immer als 360° angezeigt,
    beim Due mit dem angepassten Code werden aber etliche Werte verschluckt, meist wird pro volle Umdrehung irgendwas zwischen 180 und 360° angezeigt.

    Relativ gut war immer der erste Motor, alle anderen deutlich schlechter.

    Selbst nach Timer-Intervall von 250 auf 100µs kaum eine Verbesserung.
    Umpolen und Vertauschen der Motoren brachte keine Änderung: der erste in der Reihe war immer der beste, der Rest sehr schlecht.


    Wie kann ich das jetzt mit den 32 bit probieren, um das zu verbessern? Wo muss da was geändert werden?

    Der Vollständigkeit halber: hier ist der komplette Code für 6 Motoren:

    Code:
    /************************************************************
    * Programm zur Auswertung eines händisch betriebenen
    * Drehencoders (Quadraturencoder) mit dem Arduino Due
    * per Due-Timer mit einer Abfragefrequenz von rd. 4-10kHz
    * Entlehnt an http ://www.meinDUINO.de  
    ************************************************************/
    #include <DueTimer.h>
    
    char sbuf[100];
    
    #define MAXMOTORS           6 // maximum number of encoder motors supported by Arduino Uno == 2 // Mega == 8
    
    
    
    // motor 0
    #define pinenc0A   22  // enc0A yellow
    #define pinenc0B   23  // enc0B blue
    #define pinmot0d1  24  // dir0-1   <<
    #define pinmot0d2  25  // dir0-2
    #define pinmot0pwm  8 // pwm enable0  <<  %timer  
    
    // motor 1
    #define pinenc1A   26  // enc1A yellow
    #define pinenc1B   27  // enc1B blue
    #define pinmot1d1  28  // dir1-1   <<
    #define pinmot1d2  29  // dir1-2
    #define pinmot1pwm  9 // pwm enable1  <<  %timer  
    
    
    // motor 2
    #define pinenc2A   30  // enc2A yellow
    #define pinenc2B   31  // enc2B blue
    #define pinmot2d1  32  // dir2-1   <<
    #define pinmot2d2  33  // dir2-2
    #define pinmot2pwm 10 // pwm enable2  <<  %timer  
    
    // motor 3
    #define pinenc3A   34  // enc3A yellow
    #define pinenc3B   35  // enc3B blue
    #define pinmot3d1  36  // dir3-1   <<
    #define pinmot3d2  37  // dir3-2
    #define pinmot3pwm 11 // pwm enable3  <<  %timer  
    
    // motor 4
    #define pinenc4A   38  // enc4A yellow
    #define pinenc4B   39  // enc4B blue
    #define pinmot4d1  40  // dir4-1   <<
    #define pinmot4d2  41  // dir4-2
    #define pinmot4pwm 12 // pwm enable4  <<  %timer  
    
    // motor 5
    #define pinenc5A   42  // enc5A yellow
    #define pinenc5B   43  // enc5B blue
    #define pinmot5d1  44  // dir5-1   <<
    #define pinmot5d2  45  // dir5-2
    #define pinmot5pwm 13 // pwm enable5  <<  %timer  
    
    
    
    volatile long   motenc[MAXMOTORS]    = {0, 0, 0, 0, 0, 0},
                    oldenc[MAXMOTORS]    = {0, 0, 0, 0, 0, 0};
                    
    byte pinmotdir[MAXMOTORS][ 2] = { 
      {pinmot0d1, pinmot0d2},   // motor direction pin array
      {pinmot1d1, pinmot1d2},
      {pinmot2d1, pinmot2d2},
      {pinmot3d1, pinmot3d2},
      {pinmot4d1, pinmot4d2},
      {pinmot5d1, pinmot5d2},
    };
    
    int  pinmotpwm[MAXMOTORS] =      {pinmot0pwm, pinmot1pwm, pinmot2pwm,  // motor pwm pin array
                                      pinmot3pwm, pinmot4pwm, pinmot5pwm,
                                     };
    
    volatile int8_t ISRab[MAXMOTORS]     = {0, 0, 0, 0, 0, 0};
    
    // 1/2 Auflösung
    int8_t schrittTab[16] = {0, 0,0,0,1,0,0,-1, 0,0,0,1,0,0,-1,0}; 
    
    
                                    
                                     
    /*************************************************************
    * Interrupt Handler Routine
    *************************************************************/
    
    void myHandler() {
      
      ISRab [ 0] <<= 2;
      ISRab [ 0] &= B00001100;
      ISRab [ 0] |= (digitalRead(pinenc0A) << 1) | digitalRead(pinenc0B);
      motenc[ 0] += schrittTab[ISRab[0]];           //
    
      ISRab [ 1] <<= 2;
      ISRab [ 1] &= B00001100;
      ISRab [ 1] |= (digitalRead(pinenc1A) << 1) | digitalRead(pinenc1B);
      motenc[ 1] += schrittTab[ISRab[1]];           //
    
      ISRab [ 2] <<= 2;
      ISRab [ 2] &= B00001100;
      ISRab [ 2] |= (digitalRead(pinenc2A) << 1) | digitalRead(pinenc2B);
      motenc[ 2] += schrittTab[ISRab[2]];           //
    
      ISRab [ 3] <<= 2;
      ISRab [ 3] &= B00001100;
      ISRab [ 3] |= (digitalRead(pinenc3A) << 1) | digitalRead(pinenc3B);
      motenc[ 3] += schrittTab[ISRab[3]];           //
    
      ISRab [ 4] <<= 2;
      ISRab [ 4] &= B00001100;
      ISRab [ 4] |= (digitalRead(pinenc4A) << 1) | digitalRead(pinenc4B);
      motenc[ 4] += schrittTab[ISRab[4]];           //
    
      ISRab [ 5] <<= 2;
      ISRab [ 5] &= B00001100;
      ISRab [ 5] |= (digitalRead(pinenc5A) << 1) | digitalRead(pinenc5B);
      motenc[ 5] += schrittTab[ISRab[5]];           //
    
      
    }
    
    
    void setup() {
      // motor pin settings
      // setup for L293D motor driver
    
      // motor 0
         pinMode(pinenc0A, INPUT_PULLUP);  // enc0A    yellow 
         pinMode(pinenc0B, INPUT_PULLUP);  // enc0B    blue
         pinMode(pinmot0d1, OUTPUT);        // dir0-1   
         pinMode(pinmot0d2, OUTPUT);        // dir0-2   
         pinMode(pinmot0pwm ,OUTPUT);       // enable0  
           
         // motor 1
         pinMode(pinenc1A, INPUT_PULLUP);  // enc1A    yellow
         pinMode(pinenc1B, INPUT_PULLUP);  // enc1B    blue
         pinMode(pinmot1d1, OUTPUT);        // dir1-1   
         pinMode(pinmot1d2, OUTPUT);        // dir1-2  
         pinMode(pinmot1pwm, OUTPUT);       // enable1 
           
         // motor 2
         pinMode(pinenc2A, INPUT_PULLUP);  // enc2A    yellow
         pinMode(pinenc2B, INPUT_PULLUP);  // enc2B    blue
         pinMode(pinmot2d1, OUTPUT);        // dir2-1  
         pinMode(pinmot2d2, OUTPUT);        // dir2-2   
         pinMode(pinmot2pwm, OUTPUT);       // enable2  
           
         // motor 3
         pinMode(pinenc3A, INPUT_PULLUP);  // enc3A     yellow
         pinMode(pinenc3B, INPUT_PULLUP);  // enc3B     blue
         pinMode(pinmot3d1, OUTPUT);        // dir3-1   
         pinMode(pinmot3d2, OUTPUT);        // dir3-2  
         pinMode(pinmot3pwm, OUTPUT);       // enable3  
           
         // motor 4
         pinMode(pinenc4A, INPUT_PULLUP);  // enc4A     yellow
         pinMode(pinenc4B, INPUT_PULLUP);  // enc4B     blue
         pinMode(pinmot4d1, OUTPUT);        // dir4-1   
         pinMode(pinmot4d2, OUTPUT);        // dir4-2  
         pinMode(pinmot4pwm, OUTPUT);       // enable4  
           
         // motor 5
         pinMode(pinenc5A, INPUT_PULLUP);  // encA5     yellow
         pinMode(pinenc5B, INPUT_PULLUP);  // encB5     blue
         pinMode(pinmot5d1, OUTPUT);        // dir5-1   
         pinMode(pinmot5d2, OUTPUT);        // dir5-2   
         pinMode(pinmot5pwm, OUTPUT);       // enable5 
           
    
      
      Timer1.attachInterrupt(myHandler);
      Timer1.start(100); // Calls every ...µs
    
      Serial.begin(9600);
    }
    
    
    void loop() {
     
      while(true) {
        sprintf(sbuf, " 0=%5d, 1=%5d, 2=%5d, 3=%5d, 4=%5d, 5=%5d",
                 motenc[ 0],motenc[ 1], motenc[ 2], motenc[ 3], motenc[ 4], motenc[ 5]);
        Serial.println(sbuf);
        delay(100);
      }
    }
    Geändert von HaWe (22.11.2014 um 15:29 Uhr)

Ähnliche Themen

  1. G-Code Interpreter Arduino Due, CNC-Fräse
    Von stevie3354 im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 9
    Letzter Beitrag: 26.12.2014, 15:36
  2. [ERLEDIGT] I2C Problem mit dem Arduino DUE
    Von jok3r im Forum ARM - 32-bit-Mikrocontroller-Architektur
    Antworten: 2
    Letzter Beitrag: 22.03.2014, 12:21
  3. Arduino Due + Treiber + Schrittmotor PROBLEM
    Von stevie3354 im Forum Elektronik
    Antworten: 5
    Letzter Beitrag: 30.01.2014, 23:11
  4. Arduino Due HSMCI - SD/SDIO/MMC
    Von Superhirn im Forum ARM - 32-bit-Mikrocontroller-Architektur
    Antworten: 0
    Letzter Beitrag: 25.01.2013, 10:57
  5. Arduino Due erschienen
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 24.10.2012, 22:20

Berechtigungen

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

LiFePO4 Speicher Test