Hallo Zusammen,

ich bin jetzt mit der Laser-Maus von General Keys weitergekommen:

1) Ansteuerung habe ich seriell realisiert. Dafür werden 5 Leitungen benötigt:

a) SCLK - Clock Leitung
b) SDIO - Datenleitung, halb-duplex für Senden und Empfangen von Daten
c) PD - wird nicht unbedingt benötigt, kann aber für eine Re-Synchronisation zwischen Maus und µC hilfreich sein
d) 5V Leitung
e) GND Leitung

Im Datenblatt des Sensors PAN301A steht genau das Protokoll beschrieben, an dem man sich halten muss. Nachfolgend ist mein Quellcode in C für den µC 56F5847 von Freescale (16-Bit) angefügt.

Aber jetzt zum wichtigen Teil: Zu welchem Ergebnis bin ich gekommen?

Das Ergebnis ist kurz gesagt nicht zufriedenstellen, denn die Maus ist sehr ungenau in der Positionsermittlung. Ich habe dazu auf ein Milimeterpapierblatt ein Koordinatensystem aufgebaut. Beim Anfahren von z.B. von P(6cm;6cm), erst Fahren über x-Achse dann über y-Achse wird der Wert mal ziemlich genau erreicht, mal nur in etwa. Beim Anfahren des gleichen Punktes über die Y-Achse und dann über die X-Achse, bekomme ich dann wieder andere Werte. Ganz schlecht sieht es aus, wenn man den Punkt diagonal anfährt.
Darüber hinaus z.B. bei eine Strecke von 1m, gibt die Maus mal 84 cm oder auch mal 36 cm. Es scheint, dass sie zwischendurch keine Werte erfasst. Für einen Roboter, aus meiner Sicht, nicht zu gebrauchen.
Habt ihr andere Erfahrungen gemacht ? Gibt es vielleicht ein anderer Sensor der zuverlässiger arbeitet ? Sind die Werte beim Auswerten über Quadratur zuverlässiger ? Oder habt ihr noch eine andere Idee, warum ich zu einem solchen schlechten Ergebnis komme. Könnt ja mal mein Quellcode überprüfen. Bin gerne für Vorschläge, Anmerkungen offen.
Eine Sache noch. Was mich wundert ist auch die Aussage des Herstellers. Angeblich eine Auflösung von 800 cpi. Ich habe festgestellt, dass sie eine Auflösung von 1600 cpi hat. Aber jeder erzählt ja was anderes. Bei Pearl wird sie mit 1200 cpi verkauft und bei der "PCPraxis" war sie im Test mit 1600 cpi angegeben: Preis/ Leistungsverhältnis: gut war das Erbenis des Tests von "PCPraxis".
Bei Gamestar: http://www.gamestar.de/hardware/test...s_1600dpi.html

wurde sie für Spiele als "völlig ungeeignet" bewertet.


Quellcode:

Code:
/* Including used modules for compilling procedure */
#include "Cpu.h"
#include "Events.h"
#include "SCLK.h"
#include "SDIO.h"
#include "us1.h"
#include "us3.h"
#include "PD.h"
#include "ms2.h"
#include "FC1.h"
/* Include shared modules, which are used for whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"


volatile bool us1_flag=FALSE;		// Flag für 1us Timer
volatile bool us3_flag=FALSE;		// Flag für 3us Timer
volatile bool ms2_flag=FALSE;		// Flag für 2ms Timer

// Wartet bis der Timer 1us gelaufen ist

void wait_for_timer_1us (void);
void wait_for_timer_1us (void)
{
	while(us1_flag==FALSE)
	{
		;
	}
	us1_flag=FALSE;
}

// Wartet bis der Timer 3us gelaufen ist

void wait_for_timer_3us (void);
void wait_for_timer_3us (void)
{
	while(us1_flag==FALSE)
	{
		;
	}
	us3_flag=FALSE;
}


void wait_for_timer_2ms (void);
void wait_for_timer_2ms (void)
{
	while(ms2_flag==FALSE)
	{
		;
	}
	ms2_flag=FALSE;
}


/* Funktion zur Übertragung von einem Byte an den Sensor*/

void pan_writeByte(unsigned char);
void pan_writeByte(unsigned char data)
{
	signed char i;
	SDIO_SetDir(TRUE);			// SDIO auf Output setzen
	
	for (i=7; i>=0; i--)
	{
		SCLK_ClrVal();			//  SCLK auf Low setzen, Daten vorbereiten			
	
		if((data&(1<<i))!=0)			// Bits werden rausgeschoben
		{
			SDIO_SetVal();
			

		}
		
		else 
		{
			SDIO_ClrVal();
		
		}
		
		us1_Enable();
		wait_for_timer_1us();	// Sensor Zeit lassen um Bit abzuholen
		us1_Disable();
		SCLK_SetVal();			//SCLK auf High setzen; Sensor übernimmt auf steigende Flanke
		//us1_Enable();
		//wait_for_timer_1us();	// Sensor Zeit lassen um Bit abzuholen
		//us1_Disable();
		
	}
	


}


/* Funktion zum Lesen eines Bytes vom Sensor */


unsigned char pan_readByte(void);
unsigned char pan_readByte(void)
{
	signed char i;
	unsigned char data=0;
	volatile bool wert=FALSE;	// Status SDIO
	
	
	SDIO_SetDir(FALSE);			// HI-Z state wird gesetzt
	us3_Enable();
	wait_for_timer_3us();		// Sensor Zeit geben, um die Daten aus dem Register zu holen
	us3_Disable();

	
	for (i=7; i>-1;i--)
	{
		SCLK_ClrVal();			// fallende Flanke; Sensor bereitet Daten vor
		us1_Enable();
		wait_for_timer_1us();	// Sensor Zeit geben
		us1_Disable();
		
		SCLK_SetVal();			// steigende Flanke; Daten werden gelesen
		//us1_Enable();
		//wait_for_timer_1us();	// Etwas warten damit das Signal sicher anliegt
		//us1_Disable();
		
		wert=SDIO_GetVal();		// Bit einlesen
		//us1_Enable();
		//wait_for_timer_1us();	// Etwas warten damit die Variable sicher geschrieben wird
		//us1_Disable();
		
		if (wert!=0)
		{
			data|=(1<<i);
		}
		
		else 
		{
			; //data&= ~(1<<i);
		}
		
	}
	
	
	
	return data;
		
}


/* Funktion überträgt ein write-Kommando an den Sensor */
/* Eingabeparameter: Adresse u. zu schreibendes byte*/



void pan_write(unsigned char, unsigned char);
void pan_write(unsigned char adr, unsigned char data)
{
	adr|=(1<<7);				// MSB wird auf 1 gesetzt
	pan_writeByte(adr);			// MSB muss 1 sein für Write Operation
	pan_writeByte(data);
	
}


/* Funktion überträgt ein Lesekommando an den Sensor */
/* und liest ein Byte zurück */
/* Parameter: Adresse u. Rückgabe des Registerwertes*/



unsigned char pan_read(unsigned char);
unsigned char pan_read(unsigned char adr)
{
	pan_writeByte(adr);
	return pan_readByte();
}


/* Initialisierung des PAN301ASI-208

Diese Funktion muss unbedingt ganz am Anfang von main stehen.
Wenn  der Sensor sich initialisiert hat, bevor der Controller
SCLK und SDIO auf Output gesetzt hat gibt es Fehler.

*/

void pan_init(void);
void pan_init(void)
{
	
	
	us1_Disable();			// Timer zunächst deaktivieren
	us3_Disable();
	ms2_Disable();
	FC1_Disable();




	SDIO_SetDir(TRUE);		// SDIO auf Output setzen
	SCLK_SetDir(TRUE);		// SCLK auf Output setzen
	PD_SetDir(TRUE);		// PD auf Output setzen	
	
	
	SCLK_SetVal();			// SCLK auf High setzen
	SDIO_SetVal();			// SDIO auf High setzen
	PD_ClrVal();			// PD auf low setzen

	
	// Reset Sensor und kein sleep Modus
	
	pan_write(0x05,0x01);
	
	
	
}


// Funktion zum reseten der seriellen Schnittstelle zur Maus;
// Serielle Schnittstelle wird nur re-synchronisiert; Register werden
// nicht gelöscht

void reset (void);
void reset (void)
{
	int i=0;
	
    SCLK_SetVal();
	us1_Enable();
	wait_for_timer_1us();
	us1_Disable();
	SCLK_ClrVal();
	us1_Enable();
	wait_for_timer_1us();
	us1_Disable();
	SCLK_SetVal();
	
	us1_Enable();

	for (i=1;i<2000;i++)
	{
		wait_for_timer_1us();
	}
	
	us1_Disable();


	
}


void main(void)
{
  	
  unsigned char motion=0;			// Variable zur Angabe, ob eine Bewegung erfolgte
  signed int x=0;					// delta X
  signed int y=0;					// delta Y
  signed long posx=0, posy=0;		// Absolute Position in Counter
  double posxcm=0.0, posycm=0.0;
  int test=0;						// Überprüfung, ob die Kommunikation fehlerfrei ist	
  int ueberlaufx=0;				    // Überprüfung, ob Überlauf im x-Buffer
  int ueberlaufy=0;				    // Überprüfung, ob Überlauf im y-Buffer
  
  unsigned int m=0;					// Prüfung wie oft die Endlosschleife läuft
  unsigned int ueberlaufxbei=0;		// bei welchem Schleifengang ueberlauf x
  unsigned int ueberlaufybei=0;		// bei welchem Schleifengang ueberlauf y

  unsigned char reg1=0;	  		    // Variable zum Speichern des gelesenen Registerwertes
  unsigned char reg2=0;	  		    // Variable zum Speichern des gelesenen Registerwertes
  unsigned int fehler=0;
  unsigned int ende=0;
  
  word counter=0;
  word *pcounter=0;
  word maxwert=0;


 
  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  PE_low_level_init();
  /*** End of Processor Expert internal initialization.                    ***/

  /* Write your code here */
  
  
 // ganz an den Anfang wird initialisiert, damit der Controller
 // schneller als der Sensor reagiert, um Fehler zu vermeiden
 
 
  reset();  				// Reseten der seriellen Schnittstelle
  pan_init();				// Initialisierung der seriellen Schnittstelle
   
  //pan_write(0x07,0x08); 	// Möglichkeit zum Schreiben eines Registers
  reg1=pan_read(0x05);		// Direkte Überprüfung des geschriebenen Wertes	
  reg2=pan_read(0x00);		// Direkte Überprüfung des geschriebenen Wertes	
  
  
  
  for(;;) 
  {
    /*
    ms2_Enable();
	wait_for_timer_2ms();
    ms2_Disable(); 
	*/  
    FC1_Enable();
    FC1_Reset();


    m=m+1;
    
    if (pan_read(0x00)!=0x30) 
    {
    	test=1;		// Prüfung ob Kommunikation i.O.
    	fehler=m;
    }
    else
    {
    	;
    }
    
  	motion=pan_read(0x02);
  	
  	//Überprüfen, ob das Überlauf-Bit im Register 0x02 gesetzt ist. Wenn das der Fall
  	// ist, wird die Variabe ueberlaufx gesetzt.
  		
  		if ((motion&(1<<3))!=0)
  		{
  			ueberlaufx=1; 
  			ueberlaufxbei=m;
  			 		 			
  		}
  		else
  		{
  			;
  		}
  		
  	//Überprüfen, ob das Überlauf-Bit im Register 0x02 gesetzt ist. Wenn das der Fall
  	// ist, wird die Variabe ueberlaufy gesetzt.
  	
  		if((motion&(1<<4))!=0)
  		{ 			
  			ueberlaufy=1;
  			ueberlaufybei=m;  		  			
  		}
  		else
  		{
  			;
  		}
  	
  	// wenn 7tes bit vom Register 0x02 gesetzt ist wurde die Maus bewegt
  	// Bewegungsdaten dann abfragen
  	
  	
  	if((motion&(1<<7))!=0)
  	{
  		
  		
  		ende=m;
  		
  		// Delta x Register auslesen
  		x=(signed int)((signed char)pan_read(0x03));
  		
  		// Delta y Register auslesen
  		y=(signed int)((signed char)pan_read(0x04));
  		
  		
  		// und zu der Positionsvariable addieren
  		
  		posx=posx+((long)(x)); 	
  		posy=posy+((long)(y));
  		posxcm=((double)(2.54/1600))*((double)(posx));
  		posycm=((double)(2.54/1600))*((double)(posy));
  		
  		
  		
  	
  	 }
  	 
  	   pcounter=&counter;
  	   FC1_GetCounterValue(pcounter);
       FC1_Disable();
       if (maxwert<counter) 
       {
       	maxwert=counter;
       }
       else
       {
       	;
       }

   }
   
   
   
   

}

/* END Maus */
/*
** ###################################################################
**
**     This file was created by UNIS Processor Expert 2.95 [03.58]
**     for the Freescale 56800 series of microcontrollers.
**
** ###################################################################
*/