-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: ADC Sharp Ir Problem

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    27.09.2009
    Alter
    22
    Beiträge
    661

    ADC Sharp Ir Problem

    Anzeige

    Hi,

    ich arbeite immer noch sehr fleisig an meinen Smartinius und versuche nun schon seit einiger
    Zeit an der Sensor auslesung via ADC aber das will nicht recht klappen.
    Ich glaube es liegt daran das ich mit Kommerzahlen rechen.
    Zur der Brechnung kurz
    Die Entfernung ist proprtional zur ausgegebenen Spannung =>

    D = A/(X-B)

    D ist die Entfernung X ist der Ausgabewert des Sensors A ist die Steigung der Kurve A/X B ist der Offset der Kurve
    Da ich bei beiden Sensoren leichte Unterschiede messe habe ich B auf links und rechts aufgeteilt.
    BL und BR.

    Für das ADC benutzte ich AVCC und einen Vorteiler von 64 ich hoffe
    der Rest ist aus dem leicht kommentierten Code zu erkennen

    Code:
    /*
     * SMARTINIUS.c
     *
     * Created: 26.07.2011 00:17:22
     *  Author: Martinius
     */ 
    #define F_CPU 16000000
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h> 
    
    const ON = 1; //andere Werte
    const OFF = 0;
    const Left = 2;
    const Right = 1;
    const Enable = 1;
    const Disable = 0;
    const Reset = 2;
    
    #define A 11.925
    #define BL 0.660
    #define BR 0.610
    #define ADCconst 00.04883
    
    void Setup(void){ // Stellt den Controller für das nachfolgende Programm ein
                        // muss immer als erstes aufgerufen werden.
    DDRC |= (1<<PC7); // Status LED
    DDRB |= (1<<PB0); // IR_Eable
    DDRA &= ~(1<<PA0); // IR_Left
    DDRA &= ~(1<<PA1); // IR_Right
    ADMUX |= (1<<REFS0);//Reverrenzspannungsquelle des ADC wird festgelegt
    ADCSRA = (1<<ADPS1) | (1<<ADPS2);     // Frequenzvorteiler
    ADCSRA |= (1<<ADEN);                  // ADC aktivieren
    ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung
    while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten 
    }
    
    void Status_LED(uint8_t Status){
    if(Status == 1){
    PORTC |= (1<<PC7);
    }
    if(Status == 0){
    PORTC &= ~(1<<PC7);
    }
    }
    uint16_t get_Ir_Distance (uint8_t Dir){ // Distance in mm
    if(Dir==1){//Right
      uint16_t x;
      ADMUX = (ADMUX & ~(0x1F)) | (1 & 0x1F);
      ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
      while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten
      x = ADCW;
      x = x*ADCconst;
      x = x-BL;
      x = A/x;
      x = x*10
      return x;                    // ADC auslesen und zurückgeben
    }
    
    if(Dir==2){//Left
      uint16_t x;
      ADMUX = (ADMUX & ~(0x1F)) | (0 & 0x1F);
      ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
      while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten
      x = ADCW;
      x = x*ADCconst;
      x = x-BL;
      x = A/x;
      x = x*10;
      return x;
      
    }
    }
    void Ir_Enable(uint8_t Status){
    if (Status == 1){
    PORTB |= (1<<PB0);
    }
    if(Status == 0){
    PORTB &= ~(1<<PB0);
    }
    }
    int main(void)
    {
    Setup();
    
    Ir_Enable(ON);
    
        while(1){
        drive_ahead();
        if(get_Ir_Distance(Right)<200){
        Status_LED(ON);
        }
        if(get_Ir_Distance(Left)< 200){
        Status_LED(ON);
        }
        }
    }
    mfG _Martinius_
    MfG Martinius

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    26
    Beiträge
    1.192
    Hallo,
    Also die Multiplikation von x mit einer (kleinen) Fließkommazahl wird sicher keine schönen Werte liefern.
    Die Variable x sollte dann schon vom Typ float sein.

    Code:
    const ON = 1; //andere Werte
    const OFF = 0;
    const Left = 2;
    const Right = 1;
    const Enable = 1;
    const Disable = 0;
    const Reset = 2;
    Da fehlt doch der Typ der Variablen, also z.B. int ???

    Und get_Ir_Distance kann im Moment auch mal keinen return-Wert haben, wenn Dir!=1 && Dir!!=2
    Liefert der Compiler da keine Warnung ?

    Bei ein paar Methoden kannst du die Parameter noch auf bool umstellen und ggf als inline-Methode
    deklarieren, das spart etwas Programmspeicher und Ausführungszeit (Status_Led, IR_Enable).

    Grüße,
    Bernhard

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    27.09.2009
    Alter
    22
    Beiträge
    661
    Zitat Zitat von BMS Beitrag anzeigen
    Code:
    const ON = 1; //andere Werte
    const OFF = 0;
    const Left = 2;
    const Right = 1;
    const Enable = 1;
    const Disable = 0;
    const Reset = 2;
    Da fehlt doch der Typ der Variablen, also z.B. int ???

    Und get_Ir_Distance kann im Moment auch mal keinen return-Wert haben, wenn Dir!=1 && Dir!!=2
    Liefert der Compiler da keine Warnung ?

    Bei ein paar Methoden kannst du die Parameter noch auf bool umstellen und ggf als inline-Methode
    deklarieren, das spart etwas Programmspeicher und Ausführungszeit (Status_Led, IR_Enable).

    Bernhard
    Also ich hab bis jetzt immer const so gesetzt hat auch bis jetzt immer funktioniert
    aber ich lasse mich gerne aufklären wie man es richtig macht

    Und zu get_Ir_Distance also der Complier liefert keine warnungen aber es ist auch nicht forgesehn etwas anderes zu übergeben auser 1 und 2 aber ich werde ein return ergänzen.
    MfG Martinius

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    27.09.2009
    Alter
    22
    Beiträge
    661
    Ich habe jetzt das Program editiert aber es will immer noch nicht klappen jetzt leuchtet die LED dauerhaft:
    Code:
     /*
      * SMARTINIUS.c
      *
      * Created: 26.07.2011 00:17:22
      *  Author: Martinius
      */ 
     #define F_CPU 16000000
     #include <avr/io.h>
     #include <util/delay.h>
     #include <avr/interrupt.h> 
     
     const int FWD = 1; // Definition der Richtungswerte
    const int STOP = 0;
    const int BWD = 2;
    const int ON = 1; //andere Werte
    const int OFF = 0;
    const int Left = 2;
    const int Right = 1;
    const int Enable = 1;
    const int Disable = 0;
    const int Reset = 2;
    const float A = 11.925;
    const float BL = 0.660;
    const float BR = 0.610;
    const float ADCconst = 00.04883;
     
     void Setup(void){ // Stellt den Controller für das nachfolgende Programm ein
                         // muss immer als erstes aufgerufen werden.
     DDRC |= (1<<PC7); // Status LED
     DDRB |= (1<<PB0); // IR_Eable
     DDRA &= ~(1<<PA0); // IR_Left
     DDRA &= ~(1<<PA1); // IR_Right
     ADMUX |= (1<<REFS0);//Reverrenzspannungsquelle des ADC wird festgelegt
     ADCSRA = (1<<ADPS1) | (1<<ADPS2);     // Frequenzvorteiler
     ADCSRA |= (1<<ADEN);                  // ADC aktivieren
     ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung
     while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten 
     }
     
     void Status_LED(uint8_t Status){
     if(Status == 1){
     PORTC |= (1<<PC7);
     }
     if(Status == 0){
     PORTC &= ~(1<<PC7);
     }
     }
     uint16_t get_Ir_Distance (uint8_t Dir){ // Distance in mm
     if(Dir==1){//Right
       float x;
       ADMUX = (ADMUX & ~(0x1F)) | (1 & 0x1F);
       ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
       while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten
       x = ADCW;
       x = x*ADCconst;
       x = x-BL;
       x = A/x;
       x = x*10
       return x;                    // ADC auslesen und zurückgeben
     }
     
     if(Dir==2){//Left
       float x;
       ADMUX = (ADMUX & ~(0x1F)) | (0 & 0x1F);
       ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
       while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten
       x = ADCW;
       x = x*ADCconst;
       x = x-BL;
       x = A/x;
       x = x*10;
       return x;
       
     }
    return 0;
     }
     void Ir_Enable(uint8_t Status){
     if (Status == 1){
     PORTB |= (1<<PB0);
     }
     if(Status == 0){
     PORTB &= ~(1<<PB0);
     }
     }
     int main(void)
     {
     Setup();
     
     Ir_Enable(ON);
     
         while(1){
         drive_ahead();
         if(get_Ir_Distance(Right)<2000){
         Status_LED(ON);
         }
         if(get_Ir_Distance(Left)< 2000){
         Status_LED(ON);
         }
         }
     }
    MfG Martinius

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    26
    Beiträge
    1.192
    Hallo,
    du schaltest die LED auch nirgends im Programm wieder aus, deswegen leuchtet sie dauerhaft
    Also irgendwo sollte da noch ein Status_LED(OFF); in die while-Schleife.
    So z.B.
    Code:
    while(1)
    {
        drive_ahead();
        if(get_Ir_Distance(Right)<2000)
        {
            Status_LED(ON);
        }
        else if(get_Ir_Distance(Left)< 2000)
        {
            Status_LED(ON);
        }
        else
        {
            Status_LED(OFF);
        }
    }
    Grüße,
    Bernhard

    EDIT:
    Und in uint16_t get_Ir_Distance solltest du die return-Werte noch in einen int umwandeln, d.h. return int(x);

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    27.09.2009
    Alter
    22
    Beiträge
    661
    ja das weis ich schon ich meinte ja selbst wenn ich den roboter von mir weg halte einen reset auslöse leuchtet die
    LED auch sofort obwohl kein hinderniss da ist und sogar wenn ich die Sensoren ausstecke
    MfG Martinius

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    26
    Beiträge
    1.192
    Kannst du die "Rohwerte" vom AD-Wandler irgendwie ausgeben?
    Also z.B. über Display anzeigen oder über serielle Schnittstelle an PC übertragen?
    Wenn du die Sensoren aussteckst, liegen die Analogeingänge in der Luft,
    der kann dann irgendwelche Werte ausgeben.
    Aber die LED an sich lässt sich ein- und ausschalten?
    Also z.B. per Programm blinken lassen geht?

    Ansonsten: Bist du dir sicher, dass deine Konstanten passen?
    Grüße, Bernhard

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    27.09.2009
    Alter
    22
    Beiträge
    661
    Also das UART hat schon ne schnittstelle aber die software ist noch nicht fertig
    die LED kann ich ein und ausschalten
    Und die Sensoren sind dann komplett abgetrennt
    Und die Konstanten stimmen ich habe mal via multimeter nach gerechnet und es würde stimmen.
    MfG Martinius

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    27.09.2009
    Alter
    22
    Beiträge
    661
    Hat den niemand eine idee was verkehrt sein könnt?
    MfG Martinius

  10. #10
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    26
    Beiträge
    1.192
    Wie gesagt, schau mal, dass du irgendwie die Werte angezeigt kriegst. UART geht relativ zügig.
    Auf dem PC braucht man dann nur ein Terminal und sieht alles was der AVR geschickt hat.
    Sonst ist das nicht nachvollziehbar was da genau läuft, da fischt man zu lange im Trüben.
    Notfalls die LED blinken lassen und die Blinkfrequenz abhängig vom gemessenen Abstand machen.
    Dann sieht man überhaupt mal, ob sich die Werte auch ändern.
    Die Analogeingänge an sich funktionieren, oder?
    Schon mal etwas anderes angeschlossen als einen Sharp-Sensor?
    Grüße, Bernhard

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Problem mit Sharp Sensor 2Y0A02
    Von juergen009 im Forum Sensoren / Sensorik
    Antworten: 5
    Letzter Beitrag: 01.10.2010, 14:26
  2. IR Sensor SHARP GP1U52 40KHz Problem!
    Von Oliver Preußger im Forum Sensoren / Sensorik
    Antworten: 2
    Letzter Beitrag: 27.02.2006, 23:40
  3. Unterschied SHARP GP2D12 zu SHARP GP2Y0A21YK
    Von java-robotik im Forum Sensoren / Sensorik
    Antworten: 2
    Letzter Beitrag: 25.02.2006, 10:30
  4. Problem mit Sharp Sensor GP2d120
    Von patti16 im Forum Elektronik
    Antworten: 5
    Letzter Beitrag: 12.02.2006, 18:51
  5. Unterschied zwischen SHARP GP2D12 und SHARP GP2Y0A21YK
    Von Foooob im Forum Sensoren / Sensorik
    Antworten: 11
    Letzter Beitrag: 15.05.2005, 21:43

Berechtigungen

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