-         

Ergebnis 1 bis 4 von 4

Thema: Hilfe!!! Asuro SnakeVision funktioniert nicht, wenn PollSwitch() ins Spiel kommt!

  1. #1

    Hilfe!!! Asuro SnakeVision funktioniert nicht, wenn PollSwitch() ins Spiel kommt!

    Anzeige

    Hallo liebe Community,

    ich bin neu hier und habe ein extrem dringendes Problem mit der SnakeVision von Asuro. Leider sind meine Programmier- geschweige denn Microcontrollerkenntnisse sehr beschränkt

    Folgendes Problem: Wenn die ganz normalen Taster von Asuro in der Schleife des SnakeVision Programmes abgefragt werden, um Asuro dazu zu bringen, dass er nach Kollision mit Wänden etwas anderes tut, dann funktioniert plötzlich der linke Wärmesensor nicht mehr richtig.

    Das Programm für die Verfolgung der Wärmequellen beruht auf dem Algorithmus aus dem Buch "Mehr Spaß mit Asuro Band2". Funktioniert soweit auch ziemlich gut. Sogar das Löschen von Teelichtern mit einem eingebauten Ventilator hat schon geklappt. Nur, wenn PollSwitch() ins Spiel kommt, geht halt der linke Sensor kaum noch Er erkennt bei Raumtemperatur meinen Finder dann nur noch auf wenige Millimeter Entfernung, während der rechte Sensor den Finger noch bei über 10cm Abstand erkennt (was der linke ja normalerweise auch tut)...

    Habe dazu auch nirgends was passendes gefunden im Internet, deshalb seid ihr meine letzte Rettung. Kann es sein, dass da irgendwas gleichzeitig an einem Prozessorpin hängt oder dergleichen? Oder übersehe ich etwas bei der Programmierung? Habe leider echt nich das nötige KnowHow, um das selbst herauszufinden.

    Hier mal der Code (ist jetzt erstmal einfach nur der Standard SnakeVision Code aus dem Buch, bloß mit Abbruch durch PollSwitch():
    Code:
    #include "asuro.h"
    //Schwellen für die intensitätsabhängige Geschwindigkeit
    #define THRESH1 20
    #define THRESH2 80
    #define THRESH3 200
    
    //Funktion, um Tasterwert abzufragen	
    char switchwert(void){
    	char taste=0;
    	unsigned char t1,t2,t3;
    	t1=PollSwitch();
    	t2=PollSwitch();
    	t3=PollSwitch();
    	
    	if((t1 == t2)&& (t2==t3))
    		{taste=t1;}
    	return taste;
    }
    
    //testet beim Fahren auf die Abbruchbedingungen
    int abbruchtest(void){
    	int abbruch=0;	
    	
    	char tasten=switchwert();	
    	
    	if(tasten>0){
    		abbruch=1;		
    		StatusLED(YELLOW);		
    	}
    	
    	return abbruch;
    }
    
    void ThermalData(unsigned int *data){
    
    	/* ThermalData() funktioniert genausi, wie LineData(), nur, dass dabei 
    	die interne Spannungsreferenz als AD-Wandlerdifferenz verwendet wird.*/
    	
    	//Prozessorinterne Referenz verwenden
    	//Multiplexer auf linken Sensor schalten
    	ADMUX = (1 << REFS0) | (1 << REFS1) | IR_LEFT;
    	
    	//Wandlung starten
    	ADCSRA |= (1 << ADSC);
    	
    	//Warten bis Wandlung beendet ist
    	while (!(ADCSRA & (1 << ADIF)));
    	
    	//ADCIF zurücksetzen
    	ADCSRA |= (1 << ADIF);
    	
    	//ADC-Wert auslesen
    	data[0] = ADCL + (ADCH << 8);
    	
    	// Multiplexer auf rechten Sensor schalten
    	ADMUX = (1 << REFS0) | (1 << REFS1) | IR_RIGHT;
    	
    	// Wandlung starten
    	ADCSRA |= (1 << ADSC);
    	
    	// Warten, bis Wandlung beendet		
    	while (!(ADCSRA & (1 << ADIF)));
    	
    	// ADCIF zurücksetzen
    	ADCSRA |= (1 << ADIF);
    	
    	// ADC-Wert auslesen
    	data[1] = ADCL + (ADCH << 8);
    
    }
    
    int main(void)
    {
    	// Speicher für die Messwerte bereitstellen
        unsigned int tdata[2],offset[2];
    	unsigned int speed;
    	signed int diff,sum;
        Init();
    	
    	//Port D, Pin 6 (die ehemalige FrontLED), auf Eingang schalten und den Pullup aktivieren.
    	DDRD&=~(1<<6);
    	PORTD|=(1<<6);	
    	
    	// Motoren immer auf vorwärts
    	MotorDir(FWD,FWD);
    	
    	//Offset mit 0 initialisieren
    	offset[0]=0;
    	offset[1]=0;
    	
    	int abbr=0;
    	
    	while(abbr==0)
        	{
    		//Messwerte einlesen
            ThermalData(tdata);
    		
    		//Wenn Knopf gedrückt, den aktuellen Wert als Offset speichern
    		if ((PIND&(1<<6))==0){
    			offset[0]=tdata[0];
    			offset[1]=tdata[1];
    		}
    		
    		//Offset abziehen, aber nur, wenn der Messwert groß genug ist, sonst gibt's nen Überlauf
    		if(tdata[0]>offset[0]) tdata[0]-=offset[0];
    		else tdata[0]=0;
    		
    		if(tdata[1]>offset[1]) tdata[1]-=offset[1];
    		else tdata[1]=0;
    		
    		/* Die Summe der Werte wird für die 
    		Berechnung derGeschwindigkeit genutzt*/
    		sum=tdata[0]+tdata[1];
    		
     		// Signal stark genug?
    		if (sum>THRESH1) {
    			StatusLED(GREEN);
    			speed=140;
    			
    			// Ziemlich stark?
    			if (sum>THRESH2) {
    				StatusLED(YELLOW); 
    				speed=200;
    			}
    			// Sehr stark?
    			if (sum>THRESH3) {
    				StatusLED(RED); 
    				speed=255;
    			}
    			// Richtung bestimmen
    			diff=((signed)tdata[0]-(signed)tdata[1])*32/sum;
    			if (diff>4) {
    				// Links deutlich wärmer? Nach links fahren!
    				 
    				MotorSpeed(0,speed);
    			}
    			else if (diff<-4) {
    				// Rechts deutlich wärmer? Nach rechts fahren!
    				 
    				MotorSpeed(speed, 0);
    			}
    			else {
    				// Sonst geradeaus!
    				 
    				MotorSpeed(speed, speed);
    			}
    		}
    		else {
    			// Keine Wärmequelle in Sicht? Stehen bleiben!
    			StatusLED(OFF);
    			
    			MotorSpeed(0,0);
    
    		}
    		abbr=abbruchtest();
        	}
    		MotorSpeed(0,0);
    	return 0;
    }
    Ich hoffe, dass mir jemand helfen kann, bin schon total verzweifelt

    Danke schonmal an alle!
    VG

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

    Da kann ich ja mal nur raten:

    Code:
    		//Messwerte einlesen
            ThermalData(tdata);
            ThermalData(tdata);
    Messwerte zweimal einlesen. Hintergrund: Beim Einlesen der Snake-Werte wird die interne Referenz verwendet, PollSwitch() verwendet aber die externe Referenz. Möglicherweise geschied das Umschalten auf die interne Referenz nicht schnell genug.

    Code:
    		abbr=abbruchtest();
        	}
    		MotorSpeed(0,0);
    	return 0;
    }
    Das sollte man nicht tun, besser ist:
    Code:
    		abbr=abbruchtest();
        	}
    		MotorSpeed(0,0);
    		while(1); // Programm sollte nie beendet werden!
    	return 0;
    }
    Gruß

    mic

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

  3. #3
    Hallo radbruch,

    vielen Dank für deine superschnelle Antwort

    Hat prima funktioniert. Witzigerweise hat es in dem geposteten Code mit zweimaligem Aufruf dazu geführt, dass dann der rechte Sensor plötzlich das Problem hatte. Bei 300maligem Aufruf hat es dann sehr gut funktioniert.

    Im kompletten Programm hat es dann allerdings mit zweimaligem Aufruf schon perfekt funktioniert Könnte das daran liegen, dass er da insgesamt mehr rechnen muss und somit mehr Zeit hat, um wieder auf interne Referenz zu schalten? Könnte man ihm das eigentlich auch aktiv sagen, dass er umschalten soll?

    Wie auch immer, auf jeden Fall funktioniert das nun soweit schonmal und es kann weitergehen

    Vielen lieben Dank für die schnelle Hilfe!

    Viele Grüße

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

    Schön, dass es funktioniert. Der Grundgedanke war, dass nach dem ersten Umschalten vor der ADC0-Lesung die Referenz noch nicht komplett umgeschaltet ist, bei der ADC1-Lesung dies dann aber abgeschlossen ist.

    Ja, man könnte die Referenz auch selbst aktiv umschalten. Die Referenz wird mit REFS0 und REFS1 im ADMUX-Register festgelegt. Nur REFS0 gesetzt bedeutet externe Referenz, beide gesetzt bedeutet interene Referenz. Spannenderweise wird in PollSwitch() nach dem Setzen der Referenz kurz gewartet und erst dann die Wandlung gestartet:
    Code:
    /* function to read out switches */
    unsigned char PollSwitch (void)
    {
    ...	ADMUX = (1 << REFS0) | SWITCH;	// AVCC reference with external capacitor
    	Sleep(10);
    
    	ADCSRA |= (1 << ADSC);			// Start conversion
    ...
    }
    (Auschnitt aus asuro.c v3.2)

    Möglicherweise würde eine entsprechende Wartezeit in ThermalData() das Problem der Referenzumschaltung lösen.

    Warum werden bei den Funktionen unterschiedliche Referenzen verwendet? Bei PollSwitch() wird ein Spannungsteiler verwendet der mit der Batteriespannung gespeist wird. Auch wenn sich die Akkuspannung ändert bleiben die Verhältnisse zwischen den Tastenwiderständen gleich, die Messung wird nicht beeinflußt. Anders das Snake-Vision. Um mit den Wärmesensoren gute Ergebnisse zu erzielen wurde auf der Platine ein 5V-Spannungsregler (getrieben über die Ladungspumpe um OCR2) zur Versorgung eingebaut. Deshalb schwanken die Ausgangsspannungen des Moduls nicht mit der Akkusspannung und deshalb muss man diese Spannungen mit der internen 2,56V-Referenz des ADC messen.

    Über die Umschaltprobleme der Referenz bin ich kürzlich schon mal gestolpert, dabei ging es um die Akkuspannungsmessung bei der bee:
    http://www.roboter.cc/index.php?opti...Itemid=20#1784

    Gruß

    mic

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

Ähnliche Themen

  1. Tiny85 kommt nicht aus Powerdown zurück Bitte Hilfe!
    Von dl1akp im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 28.03.2012, 12:29
  2. HILFE Schrittmotor funktioniert nicht
    Von DarkSoldier im Forum Motoren
    Antworten: 3
    Letzter Beitrag: 13.08.2011, 20:47
  3. Antworten: 3
    Letzter Beitrag: 02.06.2008, 12:44
  4. I2C funzt nicht, wenn über rs232 empfangen wurde...Hilfe!
    Von Charly_cs im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 20.04.2006, 11:04
  5. Programm funktioniert nicht --> Hilfe
    Von strunz im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 30.05.2005, 22:54

Stichworte

Berechtigungen

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