- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 6 von 6

Thema: ADXRS620 Genauigkeit verbessern.. erster Versuch mit RN Controllerboard

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Der Anti-aliasing filter ist analog vor dem AD-wandler. Herausgefiltert werden da die Frequenzen die zu hoch sind für die Rate mit der der AD abgefragt wird. Wesentlich langsamer wird eine digitale Regelung davon nicht - die Verzögerung liegt mehr so im Bereich der Zeit zwischen den AD Samples.

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Ach so,

    ich dachte da eher an einer softwaremäßigen Bearbeitung der Daten. Das würde Zeit kosten. Sorry, falsch verstanden.
    Gruss R.
    Kaum macht man es richtig, schon funktioniert's ...

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332
    Hallo Zusammen,

    hier jetzt das kleine Testprogram mit Winkelanzeige via LED Anzeige in der Version 1.

    Das Programm zeigt jetzt den Winkel in Grad an ( Nun ja, nur bis 255 Grad korrekt.)

    Ich muss noch sehen, wie stark der Schleppfehler wird.

    - Programm für RN Control mit 16Mhz

    Code:
    /*************************************************************************************************
     * INCLUDES                                                                                      *
     *************************************************************************************************/
    
    # define F_CPU 16000000UL
    
    #include <stdlib.h>
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <string.h>
    #include <math.h>
    
    #include "uart.h"
    
    /**************************************************************************************************
     *         Generel setting                                                               *
     **************************************************************************************************/
    
    #define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))             // Bit Set
    #define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))         // Bit reset
    #define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))             // Bit Check
    
    
    #define        ARRAYSIZEVALUES                40
    int            ValueArray[ARRAYSIZEVALUES];
    int            NextArrayIndex=0;
    int            ZeroValue=0;
    float        Angle=0;
    
    volatile    unsigned    int            m_Status;
    volatile                char        m_TimerCounter=0;        // Time value 0...100 * 10ms-> 1 sec.
    
    
    /***************************************************************************************************************
     *  Init of the array for the floating average calculation                                                    *
     ***************************************************************************************************************/
    void        initFilterArray(void)
    {
    int        i;
    
        NextArrayIndex=0;
        for(i=0;i< ARRAYSIZEVALUES;i++)
            {
            ValueArray[i]=ZeroValue;                        // set up 2.56 Volt
            }
    }
    
    /***************************************************************************************************************
     *            return the floating calculated average value                                                    *
     ***************************************************************************************************************/
    
    int            getAverageValue(void)
    {
    long        Value=0,i;
    
        for(i=0;i<ARRAYSIZEVALUES;i++)
            {
            Value += ValueArray[i];                    // Add the value for sum
            }
    
        Value /= 4; 
    
        return    (int) Value;
    }
    /***************************************************************************************************************
     *  Init of the Board                                                                             *
     ***************************************************************************************************************/
    void Board_init(void)
    {
            
     /* Ports initialisieren */
       DDRA = 0x00;                                                    // Port A: All as Analoh Input
       DDRC = 0xFF;                                                    // Port C: Bit 0... 5, 6 and 7 as Output
    
       PORTA = 0x0;                                                    // Port A: without Pull-Up
       PORTC = 0xFF;                                                // Port C: with Pull ups for the LED
    
                                                                    // set up the timer 0
        TCCR0 = (1<<CS02) | (1<<CS00);                                // Pre-saler of 1024    
                                                                    // Set up the interrupt for timer 0, overflow
        TIMSK |= (1<<TOIE0);                                        // Activate the Interrupt "overflow"
    }
    
    
    int main(void)
    {
    int                Value,LastDiff=0,Diff;
    float            AngleChangeInDegree,AngleChangeInRad;
    float            AngleChangeInMinutes;
    unsigned char    Buffer;
    
        cli ();                                                // Clear any interrupt
        Board_init();
        PORTC = 0xff;                                        // Clear the Port 
        sei();
        // Set up the pre Scaler for the Input values
        // Prescaler 128
        ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);     
        
        // We are starting with channel zero
        ADMUX = 0;
        ADMUX |= (1<<REFS0);                                // REFS1 = 0 / REFS0 = 1 -> AREF -> 5 Volt
        ADCSRA |= (1<<ADSC);                                // Start the measurement
    
        ZeroValue=5285;                                        // 2.56 using 4,96 Reference Voltage ( + 5 -> rounding)
        initFilterArray();
    
        while(1)
        {
        if (ADCSRA & (1<<ADIF))                                // Do we have a new finished measurement of values    
            {                                                // 
            ValueArray[NextArrayIndex]=  ADCW;                // Store value in the next Position
            NextArrayIndex = (NextArrayIndex + 1) % ARRAYSIZEVALUES;
            ADMUX = 0;                                        // Select the Channel
            ADCSRA |= (1<<ADIF);                            // Clear the IF Flag
            ADCSRA |= (1<<ADSC);                            // Start the measurement
            }
            
        if((m_Status & 1))                                    // Do we have to control the motor speed
            {
            m_Status=0;                                        // Clear the request of the calculation
            Value = getAverageValue();                        // get the difference value
            Diff = ZeroValue - Value;                        // get the difference of the change
            if( Diff > 20 || Diff < -20 )                    // do we have a real change 
                {                                            // ->  +-300° (5,23598775rad)  -> per second
                                                            // ->  +-30°  (0,523598775rad) per 100ms
                                                            // ->  +-180 angular minute  per 10ms
                AngleChangeInMinutes=((float)((Diff+LastDiff) / 20 ) * 0.3515625);
                AngleChangeInDegree    = AngleChangeInMinutes / 60.0;
                AngleChangeInRad    = (AngleChangeInDegree * M_PI) / 180.0;
                Angle += (AngleChangeInDegree);
    
                if( Angle < 0.0 )                            // Limit Range (only 8 bits)
                    Angle=360.0;
                if( Angle > 360.0 )
                    Angle=0.0;
                    
                LastDiff=Diff;
                }
            else
                LastDiff=0;                                    // No difference found
            
            Buffer = (unsigned char) Angle;                    // Convert Angle to the LED format
            PORTC = ~(Buffer);                                // Output inverted         
            }
        }
    }
    
    SIGNAL (SIG_OVERFLOW0)                                     // Interrupt Overflow Timer T0
    {
        m_TimerCounter++;
        SETBIT(m_Status,0);                                    // Calculate the angle speed            
        TCNT0 = 99;                                            // restart the time again
    }

    Hier sind mit Sicherheit noch Rundsfehler (Aufaddieren der Fehler) enthalten. Bin für Ideen offen.

    Gruss R.
    Kaum macht man es richtig, schon funktioniert's ...

Ähnliche Themen

  1. QlockTwo - Mein erster Versuch
    Von Icon2k im Forum Konstruktion/CAD/3D-Druck/Sketchup und Platinenlayout Eagle & Fritzing u.a.
    Antworten: 15
    Letzter Beitrag: 03.01.2011, 21:56
  2. Erster Versuch - Simulator funktioniert nicht ?
    Von nigzak im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 04.08.2009, 20:42
  3. LED's mit Impulsen Ansteuern... erster Versuch
    Von PhoenixTS82 im Forum Elektronik
    Antworten: 13
    Letzter Beitrag: 12.07.2008, 10:46
  4. Erster Versuch in Assembler zu programmieren
    Von Smokey im Forum PIC Controller
    Antworten: 18
    Letzter Beitrag: 26.03.2006, 10:20
  5. Asuro-erster versuch
    Von drejc-slo im Forum Asuro
    Antworten: 5
    Letzter Beitrag: 03.08.2005, 09:25

Berechtigungen

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

Solar Speicher und Akkus Tests