- Labornetzteil AliExpress         
Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 30 von 30

Thema: Asuro mit Ultraschallsensor SRF04

  1. #21
    Erfahrener Benutzer Roboter Genie Avatar von m.a.r.v.i.n
    Registriert seit
    24.07.2005
    Ort
    Berlin
    Beiträge
    1.247
    Anzeige

    Praxistest und DIY Projekte
    Hi,

    ein paar Dinge sind mir aufgefallen, warum dein Programm wahrscheinlich nicht funktionieren kann:

    * Du schaltest in deinem Programm nicht den Triggerausgang PB.3 sondern PB.0. Zudem schreibst du den gesamten Port B und nicht nur den einzelnen Portausgang. Für den AVR in C funktioniert das so:
    Code:
      PORTB |= (1 << PB3);      /* setzt Port B.3 auf HIGH */
      PORTB &= (1 << PB3);     /* setzt Port B.3 auf LOW */

    * Wieso verwendest du überhaupt Port B.3? Dort wird nämlich beim Asuro die 36kHz Trägerfrequenz für die IR-LED ausgegeben. Besser wäre es, Port D.2 zu verwenden, dort hängt die rote Status LED dran.
    * Die wait Funktion kommt mir sehr seltsam vor, dort werden sowohl die Register von Timer0 sowie Timer1 verwendet. Warum nimmst du nicht einfach die _delay_us Funktion aus der avrlibc.
    Code:
    #ifndef F_CPU
    /* wenn F_CPU nicht bereits vorher definiert (z.B. durch
       Übergabe als Parameter zum Compiler innerhalb des Makefiles) */
    #define F_CPU 8000000UL     /* Quarz mit 8 Mhz */
    #endif
    #include <util/delay.h>     /* in älteren avr-libc Versionen <avr/delay.h> */ 
    
    ...
    
      _delay_us(10);      /* 10µs Delay */
    * Das Einlesen des Ports D.6 für den Echo Impuls ist auch nicht ganz i.O. PORTx bezeichnet das Schreibregister eines Ports, PINx hingegen das Leseregister.
    Code:
      while ((PIND & (1<<PD6) ) == 0);   /*  solange warten, wie Port D.6 low ist */
    Es geht auch mit den folgenden avrlibc Bibliotheksfunktion.

    Code:
      loop_until_bit_is_set (PIND,PD6);      /* wartet bis Pin D.6 HIGH ist */
      loop_until_bit_is_clear (PIND,PD6);   /* wartet bis Pin D.6 LOW ist */
    *Natürlich kannst du dir auch für deine Ports ein paar Defines überlegen, die aussagekräftiger sind.
    Code:
    #define TRIGGER_PORT  PORTD
    #define TRIGGER_PIN (1 << PD2)
    #define ECHO_PORT PIND
    #define ECHO_PIN PD6
    
    ...
    
      TRIGGER_PORT |= TRIGGER_PIN;                        /* Trigger Port HIGH */
      _delay_us(10);                                                    /* 10µs warten */
      TRIGGER_PORT &= ~TRIGGER_PIN;                     /* Trigger Port LOW */
    Viel Erfolg. Zum weiteren Studium empfehle ich dir das [url=http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial]AVR-GCC Tutorial[/ur]

  2. #22
    Benutzer Stammmitglied
    Registriert seit
    23.05.2006
    Beiträge
    62
    Hallo m.a.r.v.i.n,

    das funktioniert nicht:
    Code:
                    PORTB |= (1 << PB3);      /* setzt Port B.3 auf HIGH */ 
                    PORTB &= (1 << PB3);     /* setzt Port B.3 auf LOW */
    Das ist das Assemblerlisting dazu:
    Code:
    	PORTB |= (1 << PB3);      /* setzt Port B.3 auf HIGH */ 
      9a:	c3 9a       	sbi	0x18, 3	; 24
    
      	PORTB &= (1 << PB3);     /* setzt Port B.3 auf LOW */ 
      9c:	88 b3       	in	r24, 0x18	; 24
      9e:	88 70       	andi	r24, 0x08	; 8
      a0:	88 bb       	out	0x18, r24	; 24
    So ist es richtig:
    Code:
                 PORTB |= (1 << PB3);      /* setzt Port B.3 auf HIGH */ 
                 PORTB =  (PINB & (~(1 << PB3)));    /* setzt Port B.3 auf LOW */
    Das Assemblerlisting dazu:
    Code:
    	PORTB |= (1 << PB3);      /* setzt Port B.3 auf HIGH */ 
      9a:	c3 9a       	sbi	0x18, 3	; 24
    
      	PORTB =  (PINB & (~(1 << PB3)));    /* setzt Port B.3 auf LOW */ 
      9c:	86 b3       	in	r24, 0x16	; 22
      9e:	87 7f       	andi	r24, 0xF7	; 247
      a0:	88 bb       	out	0x18, r24	; 24
    Du musst das Pinregister lesen und den geänderten Wert zum Portregister schreiben!

    Oder du benutzt zum Setzen und Rücksetzen der Bits gleich die alten GCC-Macros:

    Code:
    #define sbi(p,b) p|=(1<<(b))
    #define cbi(p,b) p&=(~(1<<(b)))
    
          sbi( PORTB, PB3 );  // setze bit3 portb
          cbi( PORTB, PB3 );   // rücksetze bit3 portb
    Ronny10

  3. #23
    Erfahrener Benutzer Roboter Genie Avatar von m.a.r.v.i.n
    Registriert seit
    24.07.2005
    Ort
    Berlin
    Beiträge
    1.247
    Hy Ronny10,

    danke für den Hinweis. Stimmt natürlich, beim Löschen von Bits müssen die zu löshenden Bits noch invertiert werden.

    So sollte es auch gehen:
    Code:
      PORTB &= ~(1 << PB3);     /* setzt Port B.3 auf LOW */

  4. #24
    Neuer Benutzer Öfters hier
    Registriert seit
    12.03.2007
    Beiträge
    15
    MHM jetzt kapier ich gar nichts mehr.

    Könntet ihr vielleicht wenn ihr Antworten schreibt nicht irgendwelche vorgefertigten Funktionen nutzen, da wir unser komplettes Asuro Projekt mit eigens Entwickelten Funktionen realisieren. Wäre echt nett.

    Des weiteren muss ich jetzt nochmal was bezüglich des SRF04 Fragen.

    Code:
    Um eine Messung zu starten, wird ein Impuls (TTL-Pegel, mind. 10us) an den Triggereingang gelegt. Der Wandler wird von der Ablaufsteuerung (PIC) fuer 200us (8 Zyklen, 40kHz) getaktet und der Echo-Ausgang des Moduls auf High gelegt. Das erste hereinkommende Echo schaltet den Echo-Ausgang wieder auf Low, so dass ein direkt zur Entfernung des Objektes proportionaler Impuls entsteht. Die Entfernung ergibt sich rechnerisch als Produkt aus Schallgeschwindigkeit (344m/s) und der Laenge des Echo-Impulses. Da die Strecke vom Schall doppelt zurueckgelegt wird, ist das Ergebnis durch 2 zu dividieren:
    hab diesen Text gefunden und jetzt wollte ich wissen ob der Echo-Ausgang automatisch auf High gesetzt wird oder ob man das bevor man den Triggerimpuls gibt selber machen muss??? Und dann hab ich noch die Frage wie ich denn genau das Echo Signal auswerten soll. Genügt es wenn ich einfach eine Schleife nehme und die solange hochzähle bis das Echo Signal 0 ist.

    Des weitern wollte ich nochmal Fragen ob mir jemand ein Beispiel für einen Timer des ATMEGA8 hat. Das heißt den Befehl wie ich den Timer initialisieren muss, starte, Timer Flag abfrage usw.

    Vielan Dank !!!!!!!!

  5. #25
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.04.2007
    Ort
    Einhausen
    Alter
    68
    Beiträge
    699
    Meinst Du so etwas? outp ((1<<CS01) | (1<<CS00), TCCR0); (8-Bit Timer/Counter starten, zählt nun ständig mit 1/64 des CPU-Takts von 0 bis 255. Bei jedem Überlauf von 255 auf 0 wird das Timer Overflow Flag TOV0 im Timer Interrupt Flag TIFR Register gesetzt. Damit kann ein entsprechender Interrupt ausgelöst werden (Beispiel: AT90S2313).

    http://ulrichradig.de/site/infos/pdf...rogramming.pdf

    siehe Datenblatt ATmega8(L)_doc2486.pdf ab Seite 106.

    und vor allem hier: https://www.roboternetz.de/wissen/in...nter_%28Avr%29

  6. #26
    Neuer Benutzer Öfters hier
    Registriert seit
    12.03.2007
    Beiträge
    15
    Ja so etwas habe ich schon gemeint, nur wundert es mich dass ich den Timer allein durch den einen Befehl starte und sonst nichts einstellen muss.

    Dass heißt dann ich kann so eine Timerfunktion schreiben:

    Code:
    void timer(){
        TCCR0 = 0x05;
        TIFR = 0;
        while(TIFR == 0);
        TIFR = 0;
    }

    Ich bin es in der Schule gewöhnt wo wir ein Trainigsboard haben allerdings mit einem anderen µController dass man ebenfalls einen wert einstellen muss sodass der Timer z.b. anstatt von 0 bei 100 anfängt um so genau zu sagen wie lang der timer für einen durchlauf benötigt.

    In der Schule haben wir das immer so gemacht:

    Code:
    void wait(){
        TR0 = 0;                           // Timer wird gestoppt
        TL0 = (0xffff-16666)%256; // Einstellung für
        TH0 = (0xffff-16666)>>8;  // 10ms Timer
        TF0 = 0;                           // Timer Flag wird auf 0 gesetzt
        TR0 = 1;                          // Timer wird gestartet
        while(TF0 == 0);              // warten solange Timer läuft
        TF0 = 0;                          // Timer wird wieder gestoppt
    }
    Um den Wert der von 0xffff abgezogen wird zu berechen haben wir diese Formel verwendet:

    Anzahl der Takte = Zeit(z.B. 10ms) / 0,6µs = 16666

    Ist sowas hier bei dem Timer des ATMEGA8 nicht nötig oder möglich?????

    Danke

  7. #27
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Milda
    Alter
    38
    Beiträge
    4.064
    der echo eingang des prozessors ist normalerweise auf low. wenn der echo impuls ankommt, wird er high gemacht, und die zeit in der er high ist bevor er wieder low wird, die muss gemessen werden.
    Read... or die.
    ff.mud.de:7600
    Bild hier  

  8. #28
    Neuer Benutzer Öfters hier
    Registriert seit
    12.03.2007
    Beiträge
    15
    Ja das hab ich jetzt mittlerweile auch alles herausbekommen, danke aber trotzdem. Bei mir funktioniert jetzt glücklicherweise die Distanzmessung via Ultraschall und ich brauche daher keine Hilfe mehr von euch. Danke nochmal dass ihr alle geholfen habt.

  9. #29
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Milda
    Alter
    38
    Beiträge
    4.064
    zeig mal deinen programmcode!
    Read... or die.
    ff.mud.de:7600
    Bild hier  

  10. #30
    Neuer Benutzer Öfters hier
    Registriert seit
    12.03.2007
    Beiträge
    15
    Also hier man Quellcode:

    Die nötigen Konstanten:

    Code:
    // Konstanten
    #define TRIGGER_IMPULS PORTB.3
    #define ECHO_PIN PIND.6
    Diese Funktio ist zunächst mal für den Triggerimpuls:

    Code:
    // Funktion um Triggerimpuls zu erzeugen
    void trigger(){              
        unsigned int i;   
        TRIGGER_IMPULS = 1; 
        for(i = 0;i<1000;i++); 
        TRIGGER_IMPULS = 0;    
    }
    Diese Funktion dient dann zum eigentlich Messen des Abstandes:

    Code:
    // Funktion zum messen der Distanz zwischen Roboter und Gegenstand
    unsigned int distanzmessen(){
        unsigned int entfernung;
        entfernung = 0; 
        trigger();   
        while(ECHO_PIN == 0);    
        while(ECHO_PIN == 1){
            entfernung++; 
        }                                                                            
        return entfernung;
    }

    Und zum Schluss noch eine Funktion mit dem man dass ganze Auswertet und dementsprechende Dinge ausführt wie anhalten und fahren:

    Code:
    // Funktion zum anhalten wenn ein Gegenstand im Weg ist
    void vorgegenstandhalten(){
        unsigned int l, entfernung2;
        entfernung2 = distanzmessen(); 
        for(l = 0;l<0xffff;l++);
        if(entfernung2 <= 2000){
            Motorstop();
        }else if(entfernung2 > 2000){
            Motorvor();
        }  
    }
    Vielleicht hilf es ja noch jemandem weiter

    Danke nochmal an euch alle!!!!!

Seite 3 von 3 ErsteErste 123

Berechtigungen

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

LiFePO4 Speicher Test