Optische Mäuse haben kleine Kameras drin mit einer Bildverarbeitung in Hardware.
Das Licht einer LED oder eines Lasers wird flach auf die Oberfläche geschickt und die Kamera mit meist 16x16 Pixel nimmt ein Schwaz-Weiß Bild auf, das die Helligkeit des Untergrundes in 6 Bit wiedergibt. Durch das flache Anleuchten sind auch bei einfarbigem Untergrund Schatten sichtbar (wie auf dem Mond)
Das Bild wird etwa 1500 mal pro Sekunde abgetastet und die Bewegung in X- und Y- Richtung festgestellt und an Quadratur-Ausgängen ausgegeben.
Zusätzlich wird die Bewegung in Registern aufsummiert, so dass man sie auslesen kann.
Die Kommunikation ist recht einfach, der AVR generiert ein Clock-Signal und gibt Daten aus bzw. liest sie auf einem Datenpin des Sensors.
Über einen Power-Down Pin lässt sich der Chip wecken.
Das Programm konfiguriert den ADNS2051 auf 800 cpi und LED Shutter on (die LED leuchtet nur, wenn ein Bild gemacht wird)
Das Auslesen geschieht hier in Software, die Ausgabe erfolgt seriell.
Die Original-Maus war übrigens eine Logitech Cordless Mouse mit 2 AA Batterien, die ständig leer waren. Den Steuerchip habe ich einfach herausgeschnitten, der hätte meinen Arduino nur gestört
Auf dem Sensor-Chip steht S2090, das Pinout und der 18MHz Resonator lassen aber nur den ADNS-2051 oder den ADNS-2030 zu.
Ich habe 5V angelegt und der Chip lebt noch, da kann es nur der ADNS2051 sein, das würde evtl. auch den Batterieverbrauch erklären.
Arduinomaus.jpg
Arduinomaus_Chip.jpg
Arduinomaus_Ausgabe.png
Alles anzeigen
Das Licht einer LED oder eines Lasers wird flach auf die Oberfläche geschickt und die Kamera mit meist 16x16 Pixel nimmt ein Schwaz-Weiß Bild auf, das die Helligkeit des Untergrundes in 6 Bit wiedergibt. Durch das flache Anleuchten sind auch bei einfarbigem Untergrund Schatten sichtbar (wie auf dem Mond)
Das Bild wird etwa 1500 mal pro Sekunde abgetastet und die Bewegung in X- und Y- Richtung festgestellt und an Quadratur-Ausgängen ausgegeben.
Zusätzlich wird die Bewegung in Registern aufsummiert, so dass man sie auslesen kann.
Die Kommunikation ist recht einfach, der AVR generiert ein Clock-Signal und gibt Daten aus bzw. liest sie auf einem Datenpin des Sensors.
Über einen Power-Down Pin lässt sich der Chip wecken.
Das Programm konfiguriert den ADNS2051 auf 800 cpi und LED Shutter on (die LED leuchtet nur, wenn ein Bild gemacht wird)
Das Auslesen geschieht hier in Software, die Ausgabe erfolgt seriell.
Die Original-Maus war übrigens eine Logitech Cordless Mouse mit 2 AA Batterien, die ständig leer waren. Den Steuerchip habe ich einfach herausgeschnitten, der hätte meinen Arduino nur gestört
Auf dem Sensor-Chip steht S2090, das Pinout und der 18MHz Resonator lassen aber nur den ADNS-2051 oder den ADNS-2030 zu.
Ich habe 5V angelegt und der Chip lebt noch, da kann es nur der ADNS2051 sein, das würde evtl. auch den Batterieverbrauch erklären.
Arduinomaus.jpg
Arduinomaus_Chip.jpg
Arduinomaus_Ausgabe.png
BASCOM-Quellcode: ADNS-2051
- $regfile = "M328pdef.dat"
- $crystal = 16000000
- $hwstack = 40
- $swstack = 16
- $framesize = 64
- $baud = 38400
- Ddrb.0 = 1
- Ddrb.5 = 1
- Pd Alias Portb.0 'Low = Ein, High = Powerdown
- S_clk Alias Portb.5
- Daten Alias Pinb.4
- Daten_io Alias Portb.4
- Dim Data_out As Byte
- Dim Data_in As Byte
- Dim I As Byte
- Dim Tempb As Byte
- Dim Z As Byte
- Dim Ausgabe As Integer
- Dim L_byte As Byte At Ausgabe Overlay
- Dim H_byte As Byte At Ausgabe + 1 Overlay
- Declare Sub Schreiben(byval Adresse As Byte , Byval Register As Byte)
- Declare Function Lesen(byval Adresse As Byte) As Byte
- S_clk = 1
- Waitms 100
- Pd = 1
- Waitms 5
- Pd = 0
- Waitms 10
- Print "Los geht's"
- Call Schreiben(10 , 80) 'LED Shutter on, 800 cpi
- Waitms 10
- 'Register
- ' 0 Product ID
- ' 1 Revision ID
- ' 2 Motion Register
- ' 3 Delta_X
- ' 4 Delta_Y
- ' 5 Surface Quality
- ' 6 Average Pixel Value in Current Frame
- ' 7 Maximum Pixel Value in Current Frame
- '10 Configuration Register
- '##############################
- Do
- Incr Z
- If Z < 100 Then Print " ";
- If Z < 10 Then Print " ";
- Print Z ;
- ' Print " Prod_ID" ;
- ' Tempb = Lesen(0)
- ' If Tempb < 100 Then Print " ";
- ' If Tempb < 10 Then Print " ";
- ' Print Tempb ;
- ' Print " Rev_ID=" ;
- ' Tempb = Lesen(1)
- ' If Tempb < 100 Then Print " ";
- ' If Tempb < 10 Then Print " ";
- ' Print Tempb ;
- Print " Mot=" ; 'Bit7 = Bewegung erkannt
- Tempb = Lesen(2)
- Print Tempb.7 ;
- Print " D_X=" ; 'relativer X-Wert
- Tempb = Lesen(3)
- Gosub Int_ausgabe
- Print " D_Y= " ; 'relativer Y-Wert
- Tempb = Lesen(4)
- Gosub Int_ausgabe
- Print " SQ=" ;
- Tempb = Lesen(5)
- If Tempb < 100 Then Print " ";
- If Tempb < 10 Then Print " ";
- Print Tempb ;
- Print " AP=" ;
- Tempb = Lesen(6)
- If Tempb < 100 Then Print " ";
- If Tempb < 10 Then Print " ";
- Print Tempb ;
- Print " maxP=" ;
- Tempb = Lesen(7)
- If Tempb < 100 Then Print " ";
- If Tempb < 10 Then Print " ";
- Print Tempb ;
- Print " Conf=" ;
- Tempb = Lesen(10)
- Print Bin(tempb)
- Waitms 200
- Loop
- End
- '##############################
- Int_ausgabe:
- L_byte = Tempb
- If Tempb.7 = 0 Then
- H_byte = 0
- Else
- H_byte = 255
- End If
- If Ausgabe < 0 Then
- If Ausgabe > -10 Then Print " ";
- If Ausgabe > - 100 Then Print " ";
- Else
- Print " ";
- If Ausgabe < 10 Then Print " ";
- If Ausgabe < 100 Then Print " ";
- End If
- Print Ausgabe ;
- Return
- Sub Schreiben(byval Adresse As Byte , Byval Register As Byte)
- Ddrb.4 = 1 'I/O Pin auf Ausgang
- Adresse.7 = 1
- For I = 7 To 0 Step -1
- S_clk = 0
- Daten_io = Adresse.i
- S_clk = 1
- Next
- For I = 7 To 0 Step -1
- S_clk = 0
- Daten_io = Register.i
- S_clk = 1
- Next
- Waitus 100 'Pause ist wichtig!
- End Sub
- Function Lesen(byval Adresse As Byte) As Byte
- Local Temp As Byte
- Ddrb.4 = 1 'I/O Pin auf Ausgang
- For I = 7 To 0 Step -1
- S_clk = 0
- Daten_io = Adresse.i
- S_clk = 1
- Next
- Ddrb.4 = 0 'I/O Pin auf Eingang
- Waitus 100
- For I = 7 To 0 Step -1
- S_clk = 0
- Temp.i = Daten
- S_clk = 1
- Next
- Lesen = Temp
- End Function