- Labornetzteil AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: Erste Arrayversuche

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    39
    Beiträge
    199

    Erste Arrayversuche

    Anzeige

    Praxistest und DIY Projekte
    Moin!
    Ich habe folgendes problem:
    Ich habe einen Servo der immer hin und her dreht. Auf diesen servo ist ein GP2D12 montiert. Jetzt möchte ich, das für jede Position des Servos (das sind insgesamt 51), ein ADC-Wert gespeichert wird. Später soll mein Roboter jenachdem wo der kleinste Wert liegt, eine kette vor und eine zurück bewegen, um da hinzulenken, weil beim kleinsten Wert ja das weiteste Hinderniss liegt. Hier sind ein paar auszüge aus meinem Code, wo man sieht wie ich das versucht habe:

    Code:
    uint16_t IR_Wert[51]; //Array für Messwerte 0-50
    So habe ich das Array erstmal Global deklariert

    Code:
    ISR(ADC_vect)
    {
    if (changechannel<=0)
      {
      changechannel++;
      ADMUX |= (1<<MUX0); //Eingang ADC1 vorbereiten für den IR-Sensor
      LDR = ADC;
      }
    else
      {  
      changechannel=0;
      ADMUX &= ~(1<<MUX0); //Eingang ADC0 vorbereiten für LDR-Messung
      IR_Wert[posi]=ADC;
      }
    }
    Hier ist meine Interrupt routine in der unter anderem die GP2D12-Werte eingespeichert werden sollen. (posi ist meine Variable, die die position des Servos enthält also 0 bis 50)

    Code:
    void Motorsteuerung(int Hinderniss_info)
    {
    OCR0=60;
    OCR2=60;
    
    if(Hinderniss_info<=20)
      {
      PORTC |= (1<<Motor_Links_Rueck); //Roboter soll nach Links drehen
      }
    else
      {
      PORTC &= ~(1<<Motor_Links_Rueck); //Roboter soll aufhören nach links
                                                               //zu drehen
      }
    hier soll der Roboter anweisung bekommen sich nach lins zu drehen, wenn links frei ist.

    Code:
    int GP2D12(void)
    {
    uint8_t i, memoposi=0; 
    uint16_t memo=65535; //zum merken des kleinsten Wertes;  
                                       //65535=maxwert bei 16-Bit
    
    for (i=0; i<=50; i++)
      {
      if (IR_Wert[i]<memo)
    	{
    	memoposi = i; //Zum merken der Servoposition, bei der der kleinste 
                                  //wert liegt
    	}
      }
    return (memoposi);
    }
    hier soll die funktion GP2D12 die Position des kleinsten wertes zurückgeben

    Code:
    int main(void)
    {
    Initial_ADC();
    Initial_IR_Servo();
    Initial_Motoren();
    sei(); //Globales Interrupt gesetzt
    
    while(1)
      {
      ADCSRA |= (1<<ADSC); //ADC-Messung soll immer wenn möglich aktiv sein
      
      if (count)
        {
        count=0;
        IR_Servo = IR_Servoposition();
        Motorsteuerung(GP2D12());
        helligkeitsmessung();
        }
      }
    return 0;  //wird nie erreicht
    }
    Meine Main Function. Der GP2D12 wert soll der Funktion Motorsteuerung übergeben werden, wo dann ja geregelt wird wo der Roboter hinfährt.

    Hoffe ich hab nichts vergessen

    Ach ja! Das Problem was ich habe ist, das die linke Kette dauerhaft rückwärts dreht. Ich hab keine Ahnung was schiefgelaufen sein kann. Is auch das erste mal wo ich mit Arrays arbeite.
    Hoffe mir kann jemand helfen.

    MfG Jan
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von robocat
    Registriert seit
    18.07.2006
    Beiträge
    935
    in der for-schleife musst du memo einen neuen wert zuweisen:
    Code:
      if (IR_Wert[i]<memo) 
       { 
       memoposi = i; //Zum merken der Servoposition, bei der der kleinste 
                                  //wert liegt 
    
       memo=IR_Wert[i]; <------ fehlt
    
       }
    gruesse

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Wenn man den Fehler anhand der Code-Schnipsel erkennen könnte, hättest du ihn selbst wahrscheinlich als erster gefunden, da du den Zusammenhang kennst.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    39
    Beiträge
    199
    @robocat:
    Das stimmt natürlich. Hab das eben erstmal geändert.

    Das mit dem schalten, fürs rückwärtsdrehen klappt jetzt.
    Aber, wer hätte das gedacht, ich hab natürlich gleich noch ein Problem.
    Die Motoren brummen nur und quälen sich voll rum, seitdem ich das Array programmiert hab. Hab das setzen vom ADSC-Bit auch vorher nicht in der Main-Funktion gehabt. Selbst wenn ich OCR0 und OCR2 den wert 150 gebe ändert sich nichts.
    Ohne das Array laufen die Motoren ganz normal.
    Hier is mein ganzer Code:
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    
    #ifndef F_CPU
    #define F_CPU 16000000
    #endif
    
    #define Scheinwerfer PD0
    #define Rueckleuchten PD1
    #define PWM_ServoPort PD5
    #define IR_Servo OCR1A
    #define Motor_Links PB3
    #define Motor_Rechts PD7
    #define Motor_Links_Rueck PC0
    #define Motor_Rechts_Rueck PC1
    
    /*************************************Prototypes****************************************/
    void helligkeitsmessung(void);
    int IR_Servoposition(void);
    void Motorsteuerung(int);
    int GP2D12(void);
    /***************************************************************************************/
    
    /**********************************Globale Variablen************************************/
    uint8_t count=0, reward_time=0;
    int8_t posi=25, a=1, changechannel=0;
    uint16_t LDR;
    uint16_t IR_Wert[51]; //Array für Messwerte 0-50 
    /***************************************************************************************/
    
    /**********************************Interruptroutinen************************************/
    
    //--------------------------------------Timer1COMB--------------------------------------
    ISR(TIMER1_COMPB_vect)
    {
    count++;
    }
    
    //-----------------------------------------ADC------------------------------------------
    ISR(ADC_vect)
    {
    if (changechannel<=0)
      {
      changechannel++;
      ADMUX |= (1<<MUX0); //Eingang ADC1 vorbereiten für den IR-Sensor
      LDR = ADC;
      }
    else
      {  
      changechannel=0;
      ADMUX &= ~(1<<MUX0); //Eingang ADC0 vorbereiten für LDR-Messung
      IR_Wert[posi]=ADC;
      }
    }
    /****************************************************************************************/
    
    /***************************************Routinen*****************************************/
    
    //---------------------------------Helligkeitsmessung---------------------------------
    void helligkeitsmessung(void)
    { 
    if (LDR<=150)
      {
      PORTD |= (1<<Scheinwerfer);
      PORTD |= (1<<Rueckleuchten);
      }
    if (LDR>=190)
      {
      PORTD &= ~(1<<Scheinwerfer);
      PORTD &= ~(1<<Rueckleuchten);
      }
    }
    
    //-------------------------------------IR_Servosteuerung---------------------------------------
    int IR_Servoposition(void)
    {
    if (a>=1)
      {
      posi++;
      if (posi>=50)
        {
        a=0;
        } 
      }
    if (a<=0)
      {
      posi--;
      if (posi<=0)
        {
        a=1;
        }
      }
    return ((posi)+440);   //440=min, 490=max
    }
    
    //--------------------------------------Motorsteuerung-----------------------------------------
    void Motorsteuerung(int Hinderniss_info)
    {
    OCR0=100; //Maximal 255
    OCR2=100; //Maximal 255
    
    if(Hinderniss_info<=15)
      {
      PORTC |= (1<<Motor_Rechts_Rueck); //Roboter soll sich nach Rechts drehen
      }
    else
      {
      PORTC &= ~(1<<Motor_Rechts_Rueck); //Roboter soll aufhören nach Rechts zu drehen
      }
      
    if(Hinderniss_info>=35)
      {
      PORTC |= (1<<Motor_Links_Rueck); //Roboter soll sich nach Links drehen
      }
    else
      {
      PORTC &= ~(1<<Motor_Links_Rueck); //Roboter soll aufhören nach Lins zu drehen
      }
    }
    
    //------------------------------------------GP2D12---------------------------------------------
    int GP2D12(void)
    {
    uint8_t i, memoposi=0; 
    uint16_t memo=0xffff; //zum merken des kleinsten Wertes; 0xffff=maxwert bei 16-Bit
    
    for (i=0; i<=50; i++)
      {
      if (IR_Wert[i]<memo)
    	{
    	memo = IR_Wert[i];
    	memoposi = i; //Zum merken der Servoposition, bei der der kleinste wert liegt
    	}
      }
    return (memoposi);
    }
    /**********************************************************************************************/
    
    /**************************************initialisierungen***************************************/
    void Initial_ADC(void)
    {
    ADMUX |= 0x00;	//AREF, resultat rechtsbündig, ADC-Eingang ADC0
    ADCSRA |= ((1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0));  //ADC eingeschaltet, Teilungsfaktor..
    ADCSRA |= (1<<ADIE);
    DDRD |= ((1<<Scheinwerfer) | (1<<Rueckleuchten));
    }
    
    void Initial_IR_Servo(void)
    {
    TCCR1A |= ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode OC1A
    TCCR1A |= ((1<<COM1B1)|(1<<COM1B0)); //Inverted Mode OC1B
    TCCR1B |= (1<<CS12); 	//Prescaler 256
    TIMSK |= (1<<OCIE1B);
    DDRD |= (1<<PWM_ServoPort); 
    PORTD |= (1<<PWM_ServoPort);
    OCR1B=500; //beliebige zeit (irgendwas unter ner ms)
    }
    
    void Initial_Motoren(void)
    {
    //Ausgang Initialisieren (OC0)
    DDRB |= (1<<Motor_Links); //Setzen als Ausgang
    PORTB |= (1<<Motor_Links); //Pull-Up
    
    //Ausgang Initialisieren (OC2)
    DDRD |= (1<<Motor_Rechts); //Setzen als Ausgang
    PORTD |= (1<<Motor_Rechts); //Pull-Up
    
    //Initialisierung der Ausgänge für Rückwärtsfahren
    DDRC |= ((1<<Motor_Links_Rueck)|(1<<Motor_Rechts_Rueck));
    
    //Initialisierung PWM für OC0
    TCCR0 |= ((1<<WGM01)|(1<<WGM00)); //Fast PWM
    TCCR0 |= (1<<COM01); //Clear Output on Compare, Set on Top
    TCCR0 |= ((1<<CS02)|(1<<CS00)); //CLK/1024 (15,625kHz, 64µs/periode)
    //Compare Register ist OCR0
    
    //Initialisierung PWM für OC2
    TCCR2 |= ((1<<WGM21)|(1<<WGM20)); //Fast PWM
    TCCR2 |= (1<<COM21); //Clear Output on Compare, Set on Top
    TCCR2 |= ((1<<CS22)|(1<<CS21)|(1<<CS20)); //CLK/1024 (15,625kHz, 64µs/periode)
    //Compare Register ist OCR2
    }
    /**************************************************************************************/
    
    /**************************************Hauptprogramm***********************************/
    int main(void)
    {
    Initial_ADC();
    Initial_IR_Servo();
    Initial_Motoren();
    sei(); //Globales Interrupt gesetzt
    
    while(1)
      {
      ADCSRA |= (1<<ADSC); //ADC-Messung immer wieder gestartet werden, wenn möglich
      
      if (count)
        {
    	count=0;
    	IR_Servo = IR_Servoposition();
        Motorsteuerung(GP2D12());
        helligkeitsmessung();
        }
      }
    return 0;  //wird nie erreicht
    }
    /****************************************************************************************/
    Hoffe da findet jemand was. Ich finde die sache mit dem Array eigentlich echt gut und will das am liebsten beibehalten.
    Kann auch sein das ich mit den Zeiten wieder irgendwas falsch gemacht habe. Ich finde aber leider nichts.

    MfG Jan
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    55
    Beiträge
    524
    Hallo,

    schau dir mal diesen Thread an. könnte dir helfen.

    Gruß

    Jens

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    39
    Beiträge
    199
    Moin!

    Sorry das ich mich jetzt erst melde. Hab meine komplette Steuerplatine neu gebaut. Jetzt läuft alles wieder. Hab heut noch ein bisschen gerätselt, weil ich meine Quarz zwar angelötet, aber nicht mit dem uC verbunden hatte. Plötzlich ging gar nichts...Naja, bin ja froh das ich das selber gefunden hab. sonst hätt ich mich hier erstmal richtig zum Affen gemacht
    Ich hab den Tip von Jens jetzt mal mit "eingebaut" und vor alle Variablen die in Interrupts verändert werden "volatile" gesetzt. Leider macht der trotzdem nichts. Der reagirt überhaupt nicht auf Hindernisse. Ohne Array macht der das. Echt komisch. Naja, vielleicht hat noch jemand einen Tipp.
    Falls ich selbst was finde melde ich mich auch.

    MfG Jan
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von robocat
    Registriert seit
    18.07.2006
    Beiträge
    935
    bin noch etwas schläfrig...
    dass du hier in der 2ten zeile der funktion TCCR1B meinst, kann es nicht sein, oder?

    Code:
    void Initial_IR_Servo(void) 
    { 
    TCCR1A |= ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode OC1A 
    TCCR1A |= ((1<<COM1B1)|(1<<COM1B0)); //Inverted Mode OC1B  <-- HIER 
    TCCR1B |= (1<<CS12);    //Prescaler 256
    ansonsten finde ich grad nix -.-

    gruesse

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    39
    Beiträge
    199
    Ich komm einfach nicht weiter.
    Mein Prog sieht jetzt so aus:

    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    
    #ifndef F_CPU
    #define F_CPU 16000000
    #endif
    
    #define Scheinwerfer PD0
    #define Rueckleuchten PD1
    //#define Impulsgeber PD4
    #define PWM_ServoPort PD5
    #define IR_Servo OCR1A
    #define Motor_Links PB3
    #define Motor_Rechts PD7
    #define Motor_Links_Rueck PC0
    #define Motor_Rechts_Rueck PC1
    
    //---------------------------------Globale Variablen----------------------------------
    uint8_t count=0;
    int8_t posi=25, a=1, ADC_Switch=1;
    uint16_t LDR, memo=2000;
    uint16_t IR_Messung[51];
    
    //---------------------------------Interruptroutinen----------------------------------
    ISR(TIMER1_COMPB_vect)
    {
    count++;
    }
    
    ISR(ADC_vect)
    {
    if (ADC_Switch)
      {
      ADC_Switch=0;
      LDR = ADC;
      ADMUX = 0x01;    //Auf ADC1 umschalten
      ADCSRA |= (1<<ADSC);    //Nach aufzeichnen Ergebniss in LDR, neue Messung starten
      }
    else
      {
      ADC_Switch=1;
      IR_Messung[posi] = ADC;
      ADMUX = 0x00;    //Auf ADC0 umschalten
      ADCSRA |= (1<<ADSC);    //Nach aufzeichnen Ergebniss in IR_Messung, neue Messung starten
      }
    }
    
    //---------------------------------Helligkeitsmessung---------------------------------
    void helligkeitsmessung(void)
    {
    if (LDR<=140)
      {
      PORTD |= (1<<Scheinwerfer);
      PORTD |= (1<<Rueckleuchten);
      }
    if (LDR>=190)
      {
      PORTD &= ~(1<<Scheinwerfer);
      PORTD &= ~(1<<Rueckleuchten);
      }
    }
    
    //-------------------------------------IR_Servosteuerung---------------------------------------
    int IR_Servoposition(void)
    {
    if (a>=1)
      {
      posi++;
      if (posi>=50)
        {
        a=0;
        }
      }
    else
      {
      posi--;
      if (posi<=0)
        {
        a=1;
        }
      }
    return ((posi)+440);   //440=min, 490=max
    } 
    
    //--------------------------------------Motorsteuerung-----------------------------------------
    void Motorsteuerung(void)
    {
    uint8_t i, farest=0;
    
    OCR0=100; //255=Max (Links)
    OCR2=100; //255=Max (Rechts)
    
    //if (IR_Messung > 150)
    if (posi<=0)
      {
      for (i=0; i<=51; i++)
        {
        if (IR_Messung[i] < memo)
    	  {
    	  memo=IR_Messung[i];
    	  farest=i;
    	  }
        }
      }
    if (farest<=15)
      {
      PORTC |= (1<<Motor_Rechts_Rueck);
      }
    else if (farest>=35)
      {
      PORTC |= (1<<Motor_Links_Rueck);
      }
    else
      {
      PORTC &= ~((1<<Motor_Links_Rueck)|(1<<Motor_Rechts_Rueck));
      }
    }
      
    //-------------------------------------initialisierungen---------------------------------------
    void Initial_ADC(void)
    {
    ADMUX |= 0x00;   //AREF, resultat rechtsbündig, ADC-Eingang ADC0
    ADCSRA |= ((1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0));  //ADC eingeschaltet, Teilungsfaktor..
    ADCSRA |= (1<<ADIE);
    DDRD |= ((1<<Scheinwerfer) | (1<<Rueckleuchten));
    }
    
    void Initial_IR_Servo(void)
    {
    TCCR1A |= ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode OC1A
    //TCCR1A |= ((1<<COM1B1)|(1<<COM1B0)); //Inverted Mode OC1B
    TCCR1B |= (1<<CS12);    //Prescaler 256
    TIMSK |= (1<<OCIE1B);
    DDRD |= (1<<PWM_ServoPort);
    PORTD |= (1<<PWM_ServoPort);
    //DDRD |= (1<<Impulsgeber);
    //PORTD |= (1<<Impulsgeber);
    //OCR1B=500; //beliebige zeit (irgendwas unter ner ms)
    }
    
    void Initial_Motoren(void)
    {
    //Ausgang Initialisieren (OC0)
    DDRB |= (1<<Motor_Links); //Setzen als Ausgang
    PORTB |= (1<<Motor_Links); //Pull-Up
    
    //Ausgang Initialisieren (OC2)
    DDRD |= (1<<Motor_Rechts); //Setzen als Ausgang
    PORTD |= (1<<Motor_Rechts); //Pull-Up
    
    //Initialisierung der Ausgänge für Rückwärtsfahren
    DDRC |= ((1<<Motor_Links_Rueck)|(1<<Motor_Rechts_Rueck));
    
    //Initialisierung PWM für OC0
    TCCR0 |= ((1<<WGM01)|(1<<WGM00)); //Fast PWM
    TCCR0 |= (1<<COM01); //Clear Output on Compare, Set on Top
    TCCR0 |= ((1<<CS02)|(1<<CS00)); //CLK/1024 (15,625kHz, 64µs/periode)
    //Compare Register ist OCR0
    
    //Initialisierung PWM für OC2
    TCCR2 |= ((1<<WGM21)|(1<<WGM20)); //Fast PWM
    TCCR2 |= (1<<COM21); //Clear Output on Compare, Set on Top
    TCCR2 |= ((1<<CS22)|(1<<CS21)|(1<<CS20)); //CLK/1024 (15,625kHz, 64µs/periode)
    //Compare Register ist OCR2
    }
    
    //---------------------------------------Hauptprogramm---------------------------------
    int main(void)
    {
    Initial_ADC();
    Initial_IR_Servo();
    Initial_Motoren();
    ADCSRA |= (1<<ADSC);    //Erste Messung starten
    
    sei(); //Globales Interrupt gesetzt
    
    while(1)
      {
      if (count)
        {
    	count=0;
        helligkeitsmessung();
        IR_Servo = IR_Servoposition();
        Motorsteuerung();
    	}
      }
    return 0;  //wird nie erreicht
    }
    Warum geht das bloß nicht???
    Eine Kette dreht vorwärts und die andere rückwärts.
    Es ändert sich auch nichts und der Sensor reagiert auch auf nichts.
    Hoffe das kuckt sich noch jemand an.

    @robocat:
    Das war schon richtig so. Hab im datenblatt noch mal nachgesehen.
    Aber jetzt benutz ich das ja gar nicht mehr.

    MfG Jan
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

  9. #9
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Wenn du in der Motorsteuerung farest=20; eingibst dann lauffen beide Motore in die selbe Richtung.
    Du bist mit der Doku etwas sparsam, so ist es etwas mühsam nachzuvollziehen was du dir gedacht hast.

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    55
    Beiträge
    524
    Hallo,

    probier den Fehler durch vorgabe von Daten einzukreisen. Wie Hubert schon schrieb farest fest vorgeben. Wenn das Ergebnis wie erwartet ist, geht es weiter mit dem Array. Füll es in der Motorsteuerung über eine Schleife mit Werten. Einen Wert überschreibst du mit einem Kleinsten Wert. Was passiert? Alles ok? Dann geht es weiter, das Array im ADC interrupt füllen wie in der Motorsteuerung. usw, usw. Irgendwann wird was unerwartetets passieren. Das gilt es dann zu ergründen.

    Gruß

    Jens

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

12V Akku bauen