- Labornetzteil AliExpress         
Seite 2 von 5 ErsteErste 1234 ... LetzteLetzte
Ergebnis 11 bis 20 von 50

Thema: GeneralKeys Lasermaus als Sensor für die Odometrie

  1. #11
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.02.2005
    Beiträge
    115
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hi,
    mich würde interessieren, was ihr für Teppich erfahrungen gemacht habt. Bei mir hier liegt fast überall Teppich und darauf sollte der Sensor natürlich auch Funktionieren.

    Gruß Starkeeper

  2. #12
    Benutzer Stammmitglied
    Registriert seit
    13.02.2005
    Ort
    Hannover
    Beiträge
    55
    @starkeeper: Das mit dem Teppich kannst du dir sehr schnell selbst beantworten: Einfach deine optische PC-Maus auf einem Stück Teppich plazieren und überprüfen, wie sich der "Mauszeiger" auf dem Bildschirm bei Bewegung verhält. Ich würde aber insbesondere keine hohen Erwartungen an die Reproduzierbarkeit einer derartigen "Messung" stellen.
    @despin: Zur Optik kann ich dir nur wenig sagen, ich denke aber hier im Forum gibts schon mehrere threads, die und in denen das Thema diskutiert wird.
    zu 3.: Ja, müsste aber auch im Datenblatt stehen, zumindest habe ich es dem Datenblatt des ADNS2620 entnommen, den ich seinerzeit dafür verwendet habe.
    zu 4.: über SPI (also i2c-ähnlich), siehe Datenblatt ADNS2620 von Agilent. zu 5.: zu stark für was ? Wenn du den sensor via SPI ausliest ("digital") ist das sicherlich vorteilhafter in Bezug auf die benötigten Resourcen, als diesen im Polling-Betrieb ("analog") abzufragen

    Datenblatt habe ich auf die schnelle nicht gefunden, einfach mal selbst bei www.agilent.com schauen. Bei Fragen kann ich gern versuchen, dir ein wenig auf die Sprünge zu helfen. Ist aber auch nicht so schwierig wie es aussehen mag.

    Gruß,
    S.

  3. #13
    Hallo avr_mcu,

    auch ich habe die Laser-Maus von General Keys mit 1200 dpi gekauft und
    möchte sie bei meiner Diplomarbeit verwenden. Thema meiner Diplomarbeit ist der Aufbau eines Autonomen Mobilen Roboters. Die Navigation würde ich gerne mit dieser Lasermaus realisieren. Ich verwende einen 16 Bit Mikrocontroller von Freescale der 56F8347. Die Mikrocontrollerplatine ist auch bereits aufgebaut. Eine SPI Schnittstelle habe ich nach Aussen geführt. Jetzt höre ich hier, dass ich die Maus mit der SPI Schnittstelle auslesen kann. Kann mir einer vielleicht noch nähere Details geben, welche Leitungen an welche Signale verbunden werden müssen. Vielleicht auch noch eine Funktion in C, wie die Maus genau ausgelesen werden kann. Das wäre Super.

  4. #14
    Benutzer Stammmitglied
    Registriert seit
    13.02.2005
    Ort
    Hannover
    Beiträge
    55
    Hallo Correia,
    So schwierig sollte es nicht werden. Prinzipiell benötigst du ja nur zwei
    Leitungen für SPI (SCK=also Taktleitung und SDA=Datenleitung).
    Am besten du besorgst dir, falls noch nicht geschehen, zunächst das Datenblatt des verwendeten Chips deiner Maus ...
    Gruß,
    S.

  5. #15
    Ich bin jetzt auch Besitzer dieser Maus, allerdings habe ich es noch nicht geschafft sie ueber SPI anzusteuern. Aus dem Datenblatt bin ich auch nicht schlauer geworden....
    Wenn jemand ein Beispiel hat, nur her damit

    Danke

  6. #16
    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.
    **
    ** ###################################################################
    */

  7. #17
    Benutzer Stammmitglied
    Registriert seit
    21.06.2005
    Beiträge
    41
    Hallo Correia,
    macht es denn bei der Genauigkeit einen Unterschied mit welchem Abstand die Maus über das Papier geführt? Welchen Abstand vom Papier kann die Maus denn überhaupt haben, sodass noch eine Richtung ausgegeben wird?

    grüße

  8. #18
    Hallo rscheubr,

    die Maus kann wie auch hier schon beschrieben bis ca. 25 mm über das Papier geführt werden. In der Genauigkeit habe ich keine Unterschiede feststellen können.

  9. #19
    Benutzer Stammmitglied
    Registriert seit
    21.06.2005
    Beiträge
    41
    Die Abtastgenauigkeit erscheint ja dann leider anscheinend nicht so berauschend zu sein - vielleicht könnte man die Daten von der Maus mit einem Radencoder "verrechnen", um eine höhere Genauigkeit zu erzielen...
    Grüße

  10. #20
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.12.2005
    Beiträge
    535
    Correia,

    ich finde die Frage nach der Abhängigkeit der Genauigkeit von dem Abstand zwischen Sensor und der Unterlage aus folgendem Grund interessant: Vor dem Bildaufnehmer des Sensors sitzt eine einfache Sammellinse, die den Leuchtpunkt des Lasers auf der Unterlage möglichst scharf auf dem Bildaufnehmer abbilden soll.

    Wenn Du den Abstand zwischen Linse und Unterlage änderst, dann wird das Bild auf dem Bildaufnehmer unscharf. Das könnte ein Grund sein, warum die Genauigkeit so enttäuschend ist. Mit einer Linse anderer Brennweite liesse sich das aber wieder einrenken.

    mare_crisium

Seite 2 von 5 ErsteErste 1234 ... LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress