Aus RN-Wissen.de
Wechseln zu: Navigation, Suche


Grundsätzliches

Computermäuse bieten sich als Entfernungs- und Geschwindigkeitsmesser in autonomen Robotern geradezu an. Die Entwicklung weg von den "Kugelmäusen" hin zu optischen Sensoren hat viele Probleme beseitigt, welche diese Bausteine jetzt hochinteressant erscheinen lassen:

  • berührungslos
  • billig
  • hochintegriert und einfach zu beschalten

Die optischen Mäuse verfügen über eine kleine CCD-"Kamera" von 16x16 bis 30x30 Pixeln. Damit wird ein mikroskopisches Bild des Untergrundes aufgenommen. Über den Vergleich zweier aufeinander folgender Bilder mittels eines integrierten DSPs wird eine Bewegungsinformation errechnet, welche die Bewegungsrichtung (2 Achsen) und Entfernung beinhaltet. Viele dieser Sensorchips haben noch einen "Kompatibilitätsmodus", welcher Quadratur-Signale wie eine Kugelmaus zur Verfügung stellt. Die neueren Chips verzichten darauf immer häufiger.

In einer Maus findet man in aller Regel den Sensorchip selber und einen Controller, der das Sensorsignal auswertet und in ein PS/2- oder USB-Signal umwandelt.

Sehr verbreitet in der Anfangszeit der optischen Mäuse waren die Sensoren von Agilent ADNS2051. Die Chips in vielen Billigmäusen sind dazu kompatibel, auch wenn die Bezeichnungen abweichen. In den meisten Billigmäusen (< 7 €) finden sich der PAN101 oder der kleine Bruder PAN3101 von Pixart.

Häufig kann über den SDIO-Anschluss auch das Sensorbild ausgelesen werden, was praktisch zur Anpassung einer geänderten Optik ist.

Datenblätter

Hilfreich und informativ ist auf jeden Fall das Studium von entsprechenden Datenblättern. Es finden sich sowohl Beispiele für die elektrische Beschaltung (die häufig sogar 1:1 von den Mausherstellern übernommen wurden) als auch eine exakte Beschreibung der Protokolle. Dabei ist häufig die genaue Taktung wichtig. Auch wenn man "seinen" Maussensor nicht findet, kann einem das Studium vergleichbarer Typen wichtige Hinweise geben, taiwanesische und chinesische Chips sind häufig kompatibel zu den "großen" Markenherstellern.

Anschluss (elektrisch)

Der Anschluss über SDIO ist relativ simpel. Man muss zwei Pins dazu identifizieren, Clock und SDIO. Der Takt wird vom Controller vorgegeben, damit kann dann bitweise gelesen oder geschrieben werden. Die Sensorchips haben in aller Regel auch ein paar Konfigurationsregister, in denen Betriebsmodus und Auflösung eingestellt werden können.

Für die Quadratur-Ausgänge muss man 4 Leitungen am Chip identifizieren.

seriell über SDIO

Um einen Maussensor an einen Mikrocontroller anzuschließen braucht man eigentlich nur 2 Leitungen.

  • Der SCLK Eingang vom Maussensor wird an einen Output-Pin des Controllers angeschlossen.
  • Der SDIO oder SDA Aus/Eingang des Maussensors wird an an einen IO-Pin des Controllers angeschlossen.

Falls man den Chip aus einer optischen Maus verwenden möchte und sich keinen neuen Chip gekauft hat, muss man die Verbindung der zwei Pins SCLK und SDIO/SDA am Maussensor-Chip noch mit einem Teppichmesser oder einer Trennscheibe abtrennen von den Pins des anderen ICs, der die Daten eigentlich an den PC schicken sollte, nun aber überflüssig ist.

Ansonsten muss man halt noch für die 5V-Spannungsversorgung des Maussensors sorgen. Dazu kann man gleich die Anschlüsse (normalerweise Schwarz=GND Rot=+5V) für das Kabel zum PC verwenden. Allerdings muss man hier aufpassen, dass die Stromversorgung ununterbrochen an den Maussensor-Chip geht und nicht z.B. über den USB-Controller gesteuert wird. Und wenn man grad dabei ist, kann man auch noch die anderen zwei Leitungen(andersfarbig z.B. Grün und Weiß) die eigentlich mal die Daten zum Pc gebracht haben, rauslöten und an unsere zwei Pins (SCLK und SDIO/SDA) am Maussensorchip löten. So hat man gleich noch das Mauskabel wiederverwertet ;) und hat zum Testen erst mal eine schöne Reichweite mit der Maus. Manchmal ist es auch noch hilfreich, den PD-Pin (Power Down) herauszuführen, da man damit den seriellen Anschluss wieder zurücksetzen kann, wenn man mal aus dem Takt gekommen ist.

Über Quadratur-Ausgänge

Für die Quadratur-Ausgänge muss man 4 Pins (XA, XB, YA, YB) identifizieren. Wenn man kein Datenblatt des Sensorchips zur Verfügung hat, kann man sie meistens daran erkennen, dass 4 Leitungen direkt nebeneinander vom Sensorchip zum Controller-Chip laufen.

Auswertung (Software)

Hier bitte Codebeispiele einfügen, anhand derer man einen Einstieg finden kann.

seriell über SDIO

Der hier vorgestellte Code ist in C geschrieben. Er ermöglicht es einen PAN3101 oder, nach kleinen Änderungen bei den Registern, einen PAN101 (großer Bruder des PAN3101) zu beschreiben und auszulesen.

Das Main Programm liest immer wieder die DeltaX- und DeltaY-Register ein, wobei auch eventuelle Überläufe überprüft werden, und addiert diese zu den Positionsvariablen posx und posy. Diese können dann ausgegeben werden.



#define DDR_SCK 	DDRB			/*!< DDR fuer Maus-SCLK */
#define DDR_SDA 	DDRA			/*!< DDR fuer Maus-SDA  */

#define PORT_SCK	PORTB			/*!< PORT fuer Maus-SCK  */
#define PORT_SDA	PORTA			/*!< PORT fuer Maus-SDA  */
#define PIN_SDA		PINA			/*!< PIN fuer Maus-SDA  */

#define SCK_PIN		(1<<PB0)		/*!< PIN nummer fuer Maus-SCK  */
#define SDA_PIN		(1<<PA0)		/*!< PIN nummer fuer Maus-SDA  */


/*!
 * Uebertraegt ein Byte an den Sensor
 * @param data das Byte
 */
void pan_writeByte(unsigned char data){
	signed char i;
	
	DDR_SDA|= SDA_PIN; 		        // SDA auf Output
	
	for (i=7; i>=0; i--){
	
		PORT_SCK &= ~SCK_PIN;		//SCK auf Low, Daten vorbereiten
		
		if(data&(1<<i)){		//Bit rausschieben
			PORT_SDA|=SDA_PIN;
		}else{
			PORT_SDA&=~SDA_PIN;		
		}
		
		PORT_SCK |= SCK_PIN;		// SCK =1 Sensor uebernimmt auf steigender Flanke
		
		_delay_us(1);			//Sensor Zeit lassen um Bit zu holen
	}

	DDR_SDA &=~ SDA_PIN;			//HI-Z state
	PORT_SDA &=~ SDA_PIN;
		
}

/*!
 * Liest ein Byte vom Sensor
 * @return das Byte
 */
unsigned char pan_readByte(void){
signed char i;
unsigned char data=0;
	
	_delay_us(3);				//Sensor Zeit lassen um die Daten aus dem Register zu holen

	for (i=7; i>-1; i--){
		PORT_SCK &= ~SCK_PIN;		// SCK =0 Sensor bereitet Daten auf fallender Flanke vor !
			
		_delay_us(1);			//Sensor kurz Zeit lassen
		
		
		PORT_SCK |= SCK_PIN;		// SCK =1 Daten lesen  auf steigender Flanke		
		
		if(PIN_SDA&SDA_PIN){ 		//BIT einlesen
			data |= (1<<i);			
		}else{
			data &=~ (1<<i);			
		}			

	}
	return data;
}

/*!
 * Uebertraegt ein write-Kommando an den Sensor
 * @param adr Adresse
 * @param data zu schreibendes byte
 */
void pan_write(unsigned char adr, unsigned char data){
	adr|=(1<<7);
	pan_writeByte(adr);  //rl MSB muss 1 sein für Write Operation
	pan_writeByte(data);
}



/*!
 * Schickt ein Lesekommando an den Sensor
 * und liest ein Byte zurueck
 * @param adr die Adresse
 * @return der registerwert
 */
unsigned char pan_read(unsigned char adr){

	pan_writeByte(adr);
	return pan_readByte();
}


/*! 
 * Initialisiere PAN3101
 
 !! Muss unbedingt ganz am ANFANG von main stehen, sonst gibts FEHLER !!
 (wenn der PAN3101 sich initialisiert hat, bevor der Controler SCK und 
 SDA auf Output gestellt hat)
 Deshalb kann es auch sinnvoll sein die Powerup Zeit in den Config Bits 
 auf 4ms zu stellen oder noch besser mit Boden zu arbeiten.
 
 */ 
void pan_init(void){

	DDR_SCK  |= SCK_PIN; 	// SCK auf Output
	DDR_SDA |= SDA_PIN;		//SDA auf Output

	PORT_SCK |= SCK_PIN;	// SCK auf high	
	PORT_SDA|= SDA_PIN;		//SDA auf high

// hier muessen bei Umstellung auf PAN101 die entsprechenden Register gesetzt werden
//Reset PAN3101
	pan_write(0x00,0x80);
// kein Sleep modus
	pan_write(0x00,0x01);	
}


int main(void){

unsigned char ino;
signed char x,y;
signed short posx=0,posy=0;

//ganz an den Anfang damit der Controller schneller asl der PAN ist um Fehler zu vermeiden
pan_init();
//Individuelle Port Configuration und Initialisierung
initialisierung();

lcd_init(LCD_DISP_ON);
lcd_clrscr();

while(1){

        //Endlosschleife

	ino=pan_read(0x16);

	//wenn 7tes bit vom Register 0x16 gesetzt ist wurde die Maus bewegt => Bewegungsdaten abfragen
	if(ino&(1<<7)){		
		//Deltax Register auslesen
		x=pan_read(0x17);
                //und zu der Positionvariable addieren
		posx=posx+x;
	        
                /* Nachschaun ob das Ueberlauf-Bit im Register 0x16 gesetzt ist 
                   wenn das der Fall ist muss je nach Vorzeichen der Deltax Variable x
                   noch 128 (Ueberlauf nach oben) dazugezaehlt oder eben 128 abgezogen werden
                */
		if(ino&(1<<3)){
			if(x<0){
				posx-=128;
			}else{
				posx+=128;
			}
		}
		
                //ab hier nochmal das Gleiche fuer die yRichtung

		y=pan_read(0x18);
		posy=posy+y;
		
		if(ino&(1<<4)){
			if(y<0){
				posy-=128;
			}else{
				posy+=128;
			}
		}
	
	}
	
                //hier kann jeder seine Ausgabevariante selber waehlen ;) 
                
		lcd_ausgabe_int(0,3,posx);
		lcd_ausgabe_int(7,3,posy);
	
}

return 0;
}


Das Programm wurde mit einem PAN3101 auf einem ATMega32 mit 14,7456 Mhz getestet und lief problemlos.

über Quadratur-Ausgänge

Autor/en

Siehe auch

Weblinks

  • Pixart Hersteller diverser Maussensoren hat u.a. Datenblätter zum PAN3101