- Labornetzteil AliExpress         
Seite 2 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 11 bis 20 von 40

Thema: nibobee IR-Abstandsmessung

  1. #11
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    58
    Beiträge
    847
    Anzeige

    Praxistest und DIY Projekte
    Hi,

    funktioniert - ich habe die Sekunde herausgenommen und mit einer Fernbedienung den SFH angeblinkt. Die roten LEDs flackern dann.

    Kannst du die "pulsweitenmoduliertes 36kHz-IR-Signal - Geschichte" noch in das gestrige Programm einbauen, oder macht dies im Moment noch keinen Sinn?

  2. #12
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Naja, Sinn würde das schon machen:
    Code:
    // Nibobee ACS mit Pinselbee                                          12.1.2010 mic
    
    #include <nibobee/iodefs.h>
    #include <nibobee/led.h>
    #include <nibobee/sens.h>
    
    volatile uint8_t count36kHz;
    volatile uint8_t acs=0;
    
    void Sleep(uint8_t pause);
    void Msleep(uint16_t pause);
    
    void ACSData(uint16_t *data)
    {
       OCR2=253;
       PORTA |= (1<<PA1); // ACS LED left on
       while((PINA & (1<<PA2)) && (OCR2 > 151))
       {
          acs=15; //15 Impulse senden, acs wird in OVF-ISR runtergezählt
          while(acs);
          OCR2--;
       }
       PORTA &= ~(1<<PA1); // ACS LED left off
       data[0]=OCR2;
       while(!(PINA & (1<<PA2))); // warten bis keine Echo mehr
    
       OCR2=253;
       PORTA|= (1<<PA0); // ACS LED right on
       while((PINA & (1<<PA2)) && (OCR2 > 151))
       {
          acs=15;
          while(acs);
          OCR2--;
       }
       PORTA &= ~(1<<PA0); // ACS LED right off                            6
       data[1]=OCR2;
       while(!(PINA & (1<<PA2)));
    }
    
    int main(void)
    {
    	uint16_t data[2]; // Speicher für ACS-Werte
    
    	led_init();
      	sens_init();
    
    	// Setup Timer2
    	TCCR2 = (1 << WGM20)|(1 << CS20); // PhaseCorrect-PWM, no prescaling, no OC2-Pin!
    	TCNT2  = 96; // (512-416) 36kHz @15MHz
    	OCR2 = 151; // (255-(208/2)) 151 ist 50:50 Compare Match für symetrische Halbwellen
    	TIMSK |= (1 << OCIE2)|(1 << TOIE2); // Comp und OVF-ISR enable, Overflow bei Bottum!
    	enable_interrupts();
    
      	led_set(0,1);
    	Msleep(2000); // wait4programmer
    
    	DDRA |= (1<<PA3)|(1<<PA1)|(1<<PA0);
    	PORTA &= ~((1<<PA3)|(1<<PA1)|(1<<PA0));
    	//DDRB |= (1<<PB4); // Test mit LineLEDs
    	//PORTB &= ~(1<<PB4);
    	
    	while(!sens_getLeft() & !sens_getRight()) // solange keine Taste gedrückt wird
    		{Msleep(200); PORTB ^= (1<<PB0);} // hektisches Blinken mit LED0
    
    	while(1)
    	{
    	   ACSData(data);
    		PORTB &= ~15; // alle Leds aus
    		if(data[0] > 250) led_set(1,1);
    		   else if(data[0] > 230) led_set(0,1);
    		if(data[1] > 250) led_set(2,1);
    		   else if(data[1] > 230) led_set(3,1);
    	   Msleep(100);
    	}
    	return(0);
    }
    ISR (TIMER2_COMP_vect)
    {
    	PORTA ^= (1<<PA3); // IR-LEDs togglen
    	//PORTB ^= (1<<PB4); // Test mit LineLEDs
    }
    // Frequenzkorrektur 512-416 plus 3 Takte fürs Laden von TCNT2?
    ISR (TIMER2_OVF_vect)
    {
    	TCNT2  = 99;
    	if(count36kHz) count36kHz--;
       if(acs) acs--;
    }
    
    void Sleep(uint8_t pause) // 1/36000 Pause blockierend
    {
    	count36kHz=pause;
    	while(count36kHz);
    }
    void Msleep(uint16_t pause) // 1/1000 Pause blockierend
    {
    	while(pause--) Sleep(36);
    }
    Der ACS-Code stammt von hier:
    https://www.roboternetz.de/phpBB2/ze...=459661#459661

    ACSData() liefert Werte von 151(kein Echo) bis 253(vor der Nase) und funktioniert wie LineData() oder Odometriedata() beim asuro. Ich hab's mit einer Brücke zwischen X2:1 (PA2) und X2:3 (GND) getestet....

    Gruß

    mic

    [Edit]
    Tilde entfernt s.u.
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #13
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    58
    Beiträge
    847
    Hi mic,

    ich habe deinen Code getestet, mit dem Ergebnis dass die IR-LEDs auf der rechten Seite nicht leuchten. Links wird der Abstand mit der gelben und roten LED angezeigt.

    Übrigens, dieIR-LED-Widerstände haben 150 Ohm.

  4. #14
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Im Moment habe ich das auch bemerkt (weil ich grad deine Erweiterung nachbaue). Hier ist die Tilde zuviel:

    PORTA|= ~(1<<PA0); // ACS LED right on
    _______^__________________________

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #15
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    58
    Beiträge
    847
    Ist OK, habe ich auch gerade beim Vergleichen festgestellt.

    Kleine Verbesserungfür deinen Nachbau: Löte das SFH von unten ein - siehe Foto.

  6. #16
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Danke für den Tipp, er kommt leider zu spät ;)

    Bild hier   Bild hier   Bild hier   Bild hier  
    (Wegen der Qualität meiner Lötstellen sind die Pics mit Absicht unscharf ;)

    Ich verwende nur einen 120 Ohm Widerstand für beide LEDs an der Kathode, der erscheint mir allerdings zu groß. Links habe ich noch keinen Empfang mit der IR-LED, mit der Fernbedienung funzt es aber. Ich verwende einen IRM 2636A mit 3mm-IR-LEDS aus der Kruschtelkiste (von meiner Cam= 100%-Recycling;). Vielleicht passen die Wellenlängen nicht optimal. Mein Code mit LCD:
    Code:
    // Nibobee ACS mit radbruchbee                                          13.1.2010 mic
    
    #define acs_led_l (1<<PA2) // Anoden der IR-LEDs
    #define acs_led_r (1<<PA3)
    #define acs_36kHz (1<<PC2) // Kathoden der IR-LEDS mit 36kHz getaktet und 120R
    #define acs_tsop  (1<<PC3) // Ausgang IR-Empfänger
    
    #include <nibobee/iodefs.h>
    #include <nibobee/delay.h>
    #include <nibobee/led.h>
    #include <stdlib.h>
    #include "lcd_lib.c"
    
    volatile uint8_t count36kHz;
    volatile uint8_t acs=0;
    
    void Sleep(uint8_t pause);
    void Msleep(uint16_t pause);
    void ACSData(uint16_t *data);
    
    int main(void)
    {
    	uint16_t data[2]; // Speicher für ACS-Werte
    
    	led_init();
    	lcd_init();                   // lcd initialisieren
    
    	// Setup Timer2
    	TCCR2 = (1 << WGM20)|(1 << CS20); // PhaseCorrect-PWM, no prescaling, no OC2-Pin!
    	TCNT2  = 96; // (512-416) 36kHz @15MHz
    	OCR2 = 151; // (255-(208/2)) 151 ist 50:50 Compare Match für symetrische Halbwellen
    	TIMSK |= (1 << OCIE2)|(1 << TOIE2); // Comp und OVF-ISR enable, Overflow bei Bottum!
    	enable_interrupts();
    
      	led_set(0,1);
    	Msleep(2000); // wait4programmer
    
    	DDRA |= acs_led_l|acs_led_r;			// die Anoden der IR-LEDs
    	PORTA &= ~(acs_led_l|acs_led_r); 	// muss angepasst werden!!!
    	DDRC |= acs_36kHz;                  // die Kathoden der IR-LEDs
    	DDRC &= ~acs_36kHz;                 // muss angepasst werden!!!
    
       lcd_cls();                    // lcd Inhalt löschen
       lcd_locate(2,0);
       lcd_writeString("NIBOBee mit ACS");
       lcd_locate(8,2);
       lcd_writeString("13.1.10 mic");
       lcd_locate(0,3);
       lcd_writeString("Bitte Taste druecken");
       while(!lcd_getkeys())
    		{Msleep(100); PORTB ^= (1<<PB0);} // hektisches Blinken mit LED0
    
       lcd_cls();                    // lcd Inhalt löschen
       lcd_locate(2,0);
       lcd_writeString("NIBOBee mit ACS");
       lcd_locate(0,2);
       lcd_writeString("ACS links:");
       lcd_locate(0,3);
       lcd_writeString("ACS rechts:");
    
    	while(1)
    	{
    	   ACSData(data);
    		lcd_locate(13,2);
    		lcd_writeInteger(data[0], 10);
       	lcd_writeString("  ");
       	lcd_locate(13,3);
    		lcd_writeInteger(data[1], 10);
       	lcd_writeString("  ");
    	   Msleep(100);
    	}
    	return(0);
    }
    ISR (TIMER2_COMP_vect)
    {
    	PORTC ^= acs_36kHz; // IR-LEDs togglen
    }
    // Frequenzkorrektur für 36kHz (512-416 plus 3 Takte fürs Laden von TCNT2?)
    ISR (TIMER2_OVF_vect)
    {
    	TCNT2  = 99;
    	if(count36kHz) count36kHz--;
       if(acs) acs--;
    }
    
    void Sleep(uint8_t pause) // 1/36000 Pause blockierend
    {
    	count36kHz=pause;
    	while(count36kHz);
    }
    void Msleep(uint16_t pause) // 1/1000 Pause blockierend
    {
    	while(pause--) Sleep(36);
    }
    void ACSData(uint16_t *data)
    {
       OCR2=253;
       PORTA |= acs_led_l; // ACS LED left on
       while((PINC & acs_tsop) && (OCR2 > 151))
       {
          acs=30; //15 Impulse senden, acs wird in OVF-ISR runtergezählt
          while(acs);
          OCR2--;
       }
       PORTA &= ~acs_led_l; // ACS LED left off
       data[0]=OCR2;
       while(!(PINC & acs_tsop)); // warten bis keine Echo mehr
    
       OCR2=253;
       PORTA|= acs_led_r; // ACS LED right on
       while((PINC & acs_tsop) && (OCR2 > 151))
       {
          acs=30;
          while(acs);
          OCR2--;
       }
       PORTA &= ~acs_led_r; // ACS LED right off
       data[1]=OCR2;
       while(!(PINC & acs_tsop));
    }
    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  7. #17
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Noch ein kleines Update:
    Code:
    ISR (TIMER2_OVF_vect)
    {
    	TCNT2  = 114; // oje??? (mit 114 werden gemessene 36kHz erzeugt!
    	PORTC &= ~acs_36kHz; // bei Nulldurchgangg soll die IR-LED aus sein!
    	if(count36kHz) count36kHz--;
       if(acs) acs--;
    }
    Ich habe nun die Frequenz mit einem Multimeter gemessen und nachjustiert. Warum man 114 ins TCNT2 laden muss ist mir noch völlig schleierhaft. Mit 99 habe ich 34,7kHz gemessen.

    Die zweite Änderung hatte ich schon zu Beginn angedacht: Wie erkenne ich in welche Richtung der Timer zählt um sicherzustellen, dass beim höchsten Timerwert die IR-LEDs auch an sind? Mit dieser Änderung ist es klar: Beim Nulldurchgang sind sie aus und damit syncron zum Timer.

    Meine linke Led war noch verpolt.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #18
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    58
    Beiträge
    847
    Hi mic,

    ich habe dein Programm an meine Belegung angepasst, mit Ausgabe über die roten und gelben LEDs:
    Code:
    // Die Anoden der rechten IR-LEDs hängen mit Vorwiderstand an PA0 (X1-AN0)
    // Die Anoden der linken IR-LEDs hängen mit Vorwiderstand an PA1 (X1-AN1)
    // Die Kathoden beider IR-LEDs sind mit PA3 (X3-AN3) verbunden
    // Der Empfänger SFH5110 ist mit PA2 (X2-AN2) verbunden
    
    #define acs_led_l (1<<PA1) // Anoden der IR-LEDs
    #define acs_led_r (1<<PA0)
    #define acs_36kHz (1<<PA3) // Kathoden der IR-LEDS mit 36kHz getaktet und 120R
    #define acs_tsop  (1<<PA2) // Ausgang IR-Empfänger
    
    #include <nibobee/iodefs.h>
    #include <nibobee/delay.h>
    #include <nibobee/led.h>
    #include <stdlib.h>
    
    volatile uint8_t count36kHz;
    volatile uint8_t acs=0;
    
    void Sleep(uint8_t pause);
    void Msleep(uint16_t pause);
    void ACSData(uint16_t *data);
    
    int main(void)
    {
       uint16_t data[2]; // Speicher für ACS-Werte
    
       led_init();
    
       // Setup Timer2
       TCCR2 = (1 << WGM20)|(1 << CS20); // PhaseCorrect-PWM, no prescaling, no OC2-Pin!
       TCNT2  = 96; // (512-416) 36kHz @15MHz
       OCR2 = 151; // (255-(208/2)) 151 ist 50:50 Compare Match für symetrische Halbwellen
       TIMSK |= (1 << OCIE2)|(1 << TOIE2); // Comp und OVF-ISR enable, Overflow bei Bottum!
       enable_interrupts();
    
    //     led_set(0,1);
    //   Msleep(2000); // wait4programmer
    
       DDRA |= acs_led_l|acs_led_r;         // die Anoden der IR-LEDs
       PORTA &= ~(acs_led_l|acs_led_r);    // muss angepasst werden!!!
       DDRA |= acs_36kHz;                  // die Kathoden der IR-LEDs
       DDRA &= ~acs_36kHz;                 // muss angepasst werden!!!
    
       while(1)
       {
          ACSData(data);
          PORTB &= ~15; // alle Leds aus
          if(data[0] > 251) led_set(1,1);
             else if(data[0] > 230) led_set(0,1);
          if(data[1] > 251) led_set(2,1);
             else if(data[1] > 230) led_set(3,1);
          Msleep(100);
       }
       return(0);
    }
    ISR (TIMER2_COMP_vect)
    {
       PORTA ^= acs_36kHz; // IR-LEDs togglen
    }
    // Frequenzkorrektur für 36kHz (512-416 plus 3 Takte fürs Laden von TCNT2?)
     ISR (TIMER2_OVF_vect)
    {
       TCNT2  = 114; // oje??? (mit 114 werden gemessene 36kHz erzeugt!
       PORTA &= ~acs_36kHz; // bei Nulldurchgangg soll die IR-LED aus sein!
       if(count36kHz) count36kHz--;
       if(acs) acs--;
    }
    
    
    void Sleep(uint8_t pause) // 1/36000 Pause blockierend
    {
       count36kHz=pause;
       while(count36kHz);
    }
    void Msleep(uint16_t pause) // 1/1000 Pause blockierend
    {
       while(pause--) Sleep(36);
    }
    void ACSData(uint16_t *data)
    {
       OCR2=253;
       PORTA |= acs_led_l; // ACS LED left on
       while((PINA & acs_tsop) && (OCR2 > 151))
       {
          acs=30; //15 Impulse senden, acs wird in OVF-ISR runtergezählt
          while(acs);
          OCR2--;
       }
       PORTA &= ~acs_led_l; // ACS LED left off
       data[0]=OCR2;
       while(!(PINC & acs_tsop)); // warten bis keine Echo mehr
    
       OCR2=253;
       PORTA|= acs_led_r; // ACS LED right on
       while((PINC & acs_tsop) && (OCR2 > 151))
       {
          acs=30;
          while(acs);
          OCR2--;
       }
       PORTA &= ~acs_led_r; // ACS LED right off
       data[1]=OCR2;
       while(!(PINC & acs_tsop));
    }
    Damit leuchtet aber gar keine LED mehr. Kannst du dir bitte das mal ansehen?

  9. #19
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Da bin ich auch reingetappt:
    DDRA &= ~acs_36kHz; // muss angepasst werden!!!

    Es sollte eigentlich so aussehen:
    //PORTC &= ~acs_36kHz;

    ...und sollte dazu dienen, die IR-LEDs auf einen definierten Startzustand zu bringen. Es wird nun durch die Änderung in der ISR ersetzt und kann gelöscht werden.

  10. #20
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Ha, 99 passt doch, wenn man die Takte für den Aufruf der ISR beachtet:
    https://www.roboternetz.de/phpBB2/ze...=473142#473142

    Ein kleiner Nebensatz der viel bewirkt:
    Das += bewirkt, dass inzwischen schon erfolgte Zähltakte nicht ignoriert werden.

    Das Schicksal meint es mal wieder gut mit mir und winkt als Sir William, der mich dazu anregte, die alten Threads nochmals durchzulesen ;)

    Wie Waste das alles rausbekommen hat ist mir echt schleierhaft. Das ist meiner Meinung nach echt genial!

    Die Overflow-ISR sieht deshalb nun so aus:
    Code:
    ISR (TIMER2_OVF_vect)
    {
    	TCNT2  += 99; // += bewirkt, dass schon erfolgte Zähltakte nicht ignoriert werden!
    	PORTC &= ~acs_36kHz; // bei Nulldurchgang soll die IR-LED aus sein!
    	if(count36kHz) count36kHz--;
       if(acs) acs--;
    }
    Gemessene Frequenz an den IR-LEDs: 36,22kHz

    Gruß

    mic

    P.S. Ich habe die Abstandsmessung als eigenständigen Thread angelegt. Ich hoffe, das ist o.K. so
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Seite 2 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress