- LiFePO4 Speicher Test         
Seite 3 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 21 bis 30 von 40

Thema: nibobee IR-Abstandsmessung

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    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!

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    59
    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?

  3. #3
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    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.

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    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!

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

    ich habe nochmals deine Änderungen in meinen Code eingepflegt, die IR_LEDs leuchten aber immer noch nicht.

    Kannst du bitte nochmals drübersehen?

    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 150R
    #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
    
       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  += 99; // += bewirkt, dass schon erfolgte Zähltakte nicht ignoriert werden!
       PORTA &= ~acs_36kHz; // bei Nulldurchgang 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(!(PINA & acs_tsop)); // warten bis keine Echo mehr
    
       OCR2=253;
       PORTA|= acs_led_r; // ACS LED right on
       while((PINA & acs_tsop) && (OCR2 > 151))
       {
          acs=30;
          while(acs);
          OCR2--;
       }
       PORTA &= ~acs_led_r; // ACS LED right off
       data[1]=OCR2;
       while(!(PINA & acs_tsop));
    }

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    59
    Beiträge
    847
    Nochmals Hallo,

    ich habe den Fehler gefunden, die LEDs leuchten wieder. Ausserdem habe ich die Wertausgabe auf mein I2C LCD eingebaut:
    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 150R
    #define acs_tsop  (1<<PA2) // Ausgang IR-Empfänger
    
    #include <nibobee/iodefs.h>
    #include <nibobee/delay.h>
    #include <nibobee/led.h>
    #include <stdlib.h>
    #include <nibobee/i2cmaster.h>
    #include <nibobee/lcdi2c.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();
       i2c_init();
       lcd_init(0x27);
       lcd_setBacklight(0);
       printf("Pinsel's NIBObee");
    
       // 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(1000); // 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
    
       while(1)
       {
          ACSData(data);
    //      PORTB &= ~15; // alle Leds aus
    
          lcd_setCursor(0,1);
          printf("WERT LI:  %4d", data[0]);
          lcd_setCursor(0,2);
          printf("WERT RE:  %4d", data[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  += 99; // += bewirkt, dass schon erfolgte Zähltakte nicht ignoriert werden!
       PORTA &= ~acs_36kHz; // bei Nulldurchgang 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(!(PINA & acs_tsop)); // warten bis keine Echo mehr
    
       OCR2=253;
       PORTA|= acs_led_r; // ACS LED right on
       while((PINA & acs_tsop) && (OCR2 > 151))
       {
          acs=30;
          while(acs);
          OCR2--;
       }
       PORTA &= ~acs_led_r; // ACS LED right off
       data[1]=OCR2;
       while(!(PINA & acs_tsop));
    }
    Nun wird für Links und Rechts jeweils der Wert von 252 angezeigt. Sollte der Wert sich nicht ändern, wenn die Bee bewegt wird?

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

    Was war denn der Fehler? Ich habe nichts gefunden. Weil mein LCD deine ACS-Pins belegt, mußte ich mein ACS an X2/3 anschließen. Diese Variante funktioniert (mit meiner Pinbelegung) an meiner bee:
    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 ddr_acs_led_l  	DDRA 	// Anoden der IR-LEDs links
    #define port_acs_led_l 	PORTA
    #define pin_acs_led_l	(1<<PA1)
    
    #define ddr_acs_led_r  	DDRA    // rechts
    #define port_acs_led_r 	PORTA
    #define pin_acs_led_r 	(1<<PA0)
    
    #define ddr_acs_36kHz  	DDRA 	// Kathoden der IR-LEDS mit 36kHz getaktet
    #define port_acs_36kHz 	PORTA
    #define pin_acs_36kHz 	(1<<PA3)
    
    #define ddr_acs_tsop  	DDRA 	// Eingang IR-Empfänger
    #define port_acs_tsop 	PINA  // Achtung, das ist ein Eingang!
    #define pin_acs_tsop  	(1<<PA2)
    
    #include <nibobee/iodefs.h>
    #include <nibobee/led.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();
    
    	ddr_acs_led_l |= pin_acs_led_l;		// die Anoden der IR-LEDs
    	port_acs_led_l &= ~pin_acs_led_l;
    
    	ddr_acs_led_r |= pin_acs_led_r;
    	port_acs_led_r &= ~pin_acs_led_r;
    
    	ddr_acs_36kHz |= pin_acs_36kHz;		// die Kathoden der IR-LEDs
    
      	led_set(0,1);
    	Msleep(2000); // wait4programmer
      	led_set(0,0);
    
    	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)
    {
    	port_acs_36kHz ^= pin_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; // += bewirkt, dass schon erfolgte Zähltakte nicht ignoriert werden!
    	port_acs_36kHz &= ~pin_acs_36kHz; // bei Nulldurchgang soll die IR-LED aus sein!
    	//port_acs_36kHz |= pin_acs_36kHz; // seltamerweise funktioniert das auch?
    	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;
       port_acs_led_l |= pin_acs_led_l; // ACS LED left on
       while((port_acs_tsop & pin_acs_tsop) && (OCR2 > 151))
       {
          acs=8; // Impulse senden, acs wird in OVF-ISR runtergezählt
          while(acs);
          OCR2--;
       }
       port_acs_led_l &= ~pin_acs_led_l; // ACS LED left off
       data[0]=OCR2;
       while(!(port_acs_tsop & pin_acs_tsop)); // warten bis keine Echo mehr
    
       OCR2=253;
       port_acs_led_r |= pin_acs_led_r; // ACS LED right on
       while((port_acs_tsop & pin_acs_tsop) && (OCR2 > 151))
       {
          acs=8;
          while(acs);
          OCR2--;
       }
       port_acs_led_r &= ~pin_acs_led_r; // ACS LED right off
       data[1]=OCR2;
       while(!(port_acs_tsop & pin_acs_tsop));
    }
    Bild hier  
    http://www.youtube.com/watch?v=ivMShzrRRC8

    Das ACS ist superempfindlich, beachte meine Abschirmung über den LEDs. In ACSData() kann man die Anzahl der Impulse pro Burst einstellen. Im Video verwende ich nur 8 Impulse und der Empfänger reagiert immer noch enorm empfindlich. Vielleicht sollte man die Trägerfrequenz absichlich etwas "verbiegen" um weniger empfindlich zu sein.

    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. #8
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    59
    Beiträge
    847
    Hi,

    mit diesem Code habe ich bis jetzt das beste Ergebnis erzielen können:
    Code:
    // nibobee IR-LEDs an PA0 und PA1 im Wechsel mit 36kHz ansteuern
    
    // https://www.roboternetz.de/phpBB2/ze...=479870#479870
    
    // 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
    
    
    #include <nibobee/iodefs.h>
    #include <nibobee/led.h>
    #include <nibobee/sens.h>
    #include <nibobee/i2cmaster.h>
    #include <nibobee/lcdi2c.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=6; //6 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=6;
          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();
       i2c_init();
       lcd_init(0x27);
       lcd_setBacklight(0);
       printf("Pinsel's NIBObee");
    
       // 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] > 251) led_set(1,1);
             else if(data[0] > 230) led_set(0,1);
          lcd_setCursor(0,1);
          printf("Links:   %4d", data[0]);
    
          if(data[1] > 251) led_set(2,1);
             else if(data[1] > 230) led_set(3,1);
          lcd_setCursor(0,2);
          printf("Rechts:  %4d", data[1]);
          Msleep(500);
       }
       return(0);
    }
    ISR (TIMER2_COMP_vect)
    {
       PORTA ^= (1<<PA3); // IR-LEDs togglen
    }
    // 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);
    }
    Du hast recht, ich musste ebenfalls die Impulse auf 6 reduziert um den besten Kompromiss zu erhalten. Die Schrumpschläuche habe ich ebenfalls um 1 cm verlängert, um nicht zu viele Störungen zu empfangen. Weiters musste ich die Bee vorne höher legen um die Reflexionen des Fussbodens zu reduzieren. Die Empfindlichkeit ist immer noch sehr hoch, besonders die Differenz der Werte links und rechts beträgt bei mir etwa 20 Einheiten.

    Aber im Grossen und Ganzen bin ich sehr zufrieden mit dem Ergebnis, ich werde versuchen ein Programm zu schreiben bei dem sich die Bee autonom im Raum bewegt.

    Nochmals vielen Dank für deine Unterstützung, vielleicht hast du noch Lust die Geschichte in Bascom zu übersetzen?

    To be continued...

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

    Hier die Umsetzung der ACS-Funktion in Bascom:
    https://www.roboternetz.de/phpBB2/vi...=480966#480966

    Die IR-Trägerfrequenz habe ich allerdings noch nicht gemessen.

    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!

  10. #10
    Hey ich würde mir gerne die IR- Abstandsmessung nachbauen. Hab mir das alles auch schön durchgelesen. Nur verstehe ich nicht wieso ihr beiden noch zwei Kondensatoren auf der Platine verbaut habt. Ich vermute die sind zur Rauschunterdrückung. Könnt ihr mir mal den Schaltplan für die Patine geben oder sagen wie groß, für was, und wo die Kondensatoren angeschlossen werden?

    Ich hab mir die Arbeit und den Schaltplan von raid_ox am Asuro auch durchgelesen (https://www.roboternetz.de/phpBB2/ze...=252907#252907)
    nur er verwendet keine Kondensatoren.

    Danke schon ma im vorraus

Seite 3 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

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

12V Akku bauen