PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Maussensor an RP6



Panzerfan
20.01.2009, 19:33
Hi @ all

Weiß jemand zufällig wie man an den RP6 einen Maussensor anbaut? Hab schon im Netz geschaut aber nichts nennenswertes gefunden. Es wäre auch recht gut wenn mir jemand erklärt wie so ein Maussensor funzt und was für daten er ausgibt.


mfg Panzerfan :-k

the_Ghost666
20.01.2009, 21:51
Moin,
Grundsätzlich sind die meisten Sensoren von optischen Mäusen noch mit einer PS/2 Schnittstelle ausgerüstet, wenn auch nicht am Kabel, aber noch irgendwo am Chip. Such einfach mal das Datenblatt des Sensors (Bezeichnung steht auf dem Chip) und die Spezifikationen von PS/2. Ist im Grunde ein 3-Draht Bus, mit nem speziellen Code kannst du dann die verarbeiteten Mausdaten auslesen, die sollten aussehen, wie n Integer-Wert für die X und für die Y Richtung, welche die aktuell zurückgelegte Pixelzahl beschreibt. Google hilft sicher.

Panzerfan
21.01.2009, 15:21
Hi,
danke erstmal werd das alles mal ausprobieren. PS/2 Maus ist es nicht es ist eine alte USB Laserfunkmaus. Ich bau die Muas jetzt mal ausseinander und guck mal was das fürn Chip is.

VD Panzerfan

Panzerfan
21.01.2009, 15:49
Hi,
\:D/ ich hab den Sensor rausgefunden und das Datenblatt hab ich auch noch!!! Es ist ein ADNS2620. Jetzt schau ich mal wie man den anschließen könnte.

mfg Panzerfan

Edit: Weiss jemand wie man SDIO und SCK ausliest. Wie ich gesehen hab ist das so was ähnliches wie I²C, könnte man damit das Teil auch auslesen?

m.a.r.v.i.n
21.01.2009, 16:34
Hallo Panzerfan,

so ein Maussensor hat eine SPI Schnittstelle, über die man das Teil auslesen kann. Im CC2 Forum gibt es dazu ein Projekt, bei dem ein ADNS5020 an einen ATmega88 angeschlossen wird und über die SPI Hardware des AVRs ausgelesen wird.
http://www.cc-zwei.de/wiki/index.php/ATM18::Projekt::OMS_ADNS-5020

Auch der c't-Bot hat einen Mausensor ADNS2610, der an einem ATmega32 angeschlossen wird, dort wird die SPI Schnittstelle per Software Bitbanging emuliert.
http://wiki.ctbot.de/index.php/Maussensor

Panzerfan
21.01.2009, 19:09
Hi,

Könnte man sowas auch einfacher beim RP6 machen? Bin noch ziemlich neu in der Robotik(bin erst 13 :oops: ). Ausserdem wollte ich noch nich so ans ISP ranmachen.

mfg Panzerfan


Edit: Also ich hab jetzt mal auf den Schaltplan gesehen und gesehen das man dann SDIO an MOSI an den 1. Pin und SCK auf SL4/SCK an PIN 7. Stimmt das? Und ausserdem wenn an SCK auch SL4 hängt ist es dann nicht so das Status LED 4 blinkt wenn man was mit SCK macht? Oder sehe ich da was falsch?

radbruch
21.01.2009, 20:19
Hallo

Ein spannendes Thema. Ich habe in meiner Bastelkiste zwar nur eine Maus mit einem ADNS-2051 gefunden aber die SPI-Kommunikation (nicht mit ISP verwechseln!) dürfte ähnlich bis gleich sein. Da die gemeinsame Datenleitung von jedem Partner (Mega32 und Maussensor) in einen z-state (hochohmig) geschaltet werden sollte, würde ich, zumindest für erste Tests, den ADC0 als Datenleitung verwenden. Takt wäre dann auf ADC1. Vermutlich würde es auch mit SCL und SDA am XBUS funktionieren. Die sind zwar auch zusätzlich beschaltet, aber was dem I2C nutzt kann dem SPI vermutlich nicht wirklich schaden. Obwohl der RP6 auch SPI beherrscht werde ich zum Einstieg die Signale "von Hand" erzeugen, dann weiß ich wenigstens, was ich mache ;) Ich muss mich allerdings noch etwas mehr ins Thema einlesen, vielleicht ist Hardware-SPI doch die bessere Lösung.

Gruß

mic

radbruch
22.01.2009, 00:47
Inzwischen habe ich einen Adapter zusammengebastelt und ein kleines Testprogramm geschrieben, allerdings funzt es noch nicht so richtig :(

Wenn es denn nun funktionieren sollte, was kann der RP6 damit anfangen? Wenn er die Maus über den Boden schieben würde, was könnte er dann mit den Daten anstellen? Oder sollte man daraus einen Trackball basteln? Oder einen Fingerscannern? Fragen über Fragen...

Mein Adapter verwendet SCL(PC0) für Clock- und SDA(PC1) als Datenpin. Mit sleep(10) als extrem langsames Takten sieht der Code so aus:

/*Standardstecker
Pin Name Farbe Beschreibung
1 VCC Rot +5 V
2 D- Weiß Data - (Clock)
3 D+ Grün Data + (Daten)
4 GND Schw Masse

von: http://de.wikipedia.org/wiki/Universal_Serial_Bus#USB-Stecker
*/

#include "RP6RobotBaseLib.h"

#define clk_port PORTC
#define clk_ddr DDRC
#define clk_h clk_ddr |= 1; clk_port |= 1
#define clk_l clk_ddr |= 1; clk_port &= ~1
#define data_port PORTC
#define data_ddr DDRC
#define data_h data_ddr |= 2; data_port |= 2
#define data_l data_ddr |= 2; data_port &= ~2
#define data_z data_ddr &= ~2; data_port &= ~2
#define data_in (PINC & 2)

void init( void)
{
clk_h;
data_z;
}

void write_data(uint16_t data)
{
uint8_t bit=16;
while(bit--)
{
clk_l;
sleep(10);
if(data & (1<<bit)) {data_h;} else data_l;
sleep(10);
clk_h;
sleep(10);
}
}

uint16_t read_data(uint8_t adr)
{
uint8_t bit, data;

bit=8;
while(bit--)
{
clk_l;
sleep(10);
if(adr & (1<<bit)) {data_h;} else data_l;
sleep(10);
clk_h;
sleep(10);
}

data_z;
sleep(255);
bit=8;
data=0;
while(bit--)
{
clk_l;
sleep(10);
clk_h;
if(data_in) data |= (1<<bit);
sleep(10);
}
return(data);
}

int main(void)
{
initRobotBase();
init();
read_data(0);
mSleep(1000);
while(1)
{
writeInteger(read_data(0), 2);
writeString_P(" - ");
mSleep(1000);
writeInteger(read_data(2), 2);
writeString_P("\n\r");
//write_data(0x0a01 | (1<<15));
mSleep(1000);
}
return(0);
}

.. aber eben, es funktioniert nicht :(

m.a.r.v.i.n
22.01.2009, 12:10
Hallo mic,

ganz so einfach funktioniert es nicht mit den Maussensor. Dazu muß man sich schon durch das Datenblatt des Maussensors quälen. Das ist ja ein komplettes Protokoll mit Befehlen zum Abfragen und Schreiben von Config Registern zur Initialisierung. Die Befehle sind zudem noch von Sensor zu Sensor verschieden.

Zudem wird der SDA Pin als Eingang zum Lesen und als Ausgang zum Schreiben benutzt. Mit einem kleinen Fehler im Programm killt man sich schnell den Maussensor (ist mir auch einmal passiert), wenn der Maussensor und der Controller beide den SDA Pin als Ausgang betreiben. Für erste Versuche sollte man hier einen Reihenwiderstand in die Leitung hängen.

Für den ADNS2610 findet man hier ein komplettes Datenblatt:
http://www.avagotech.com/docs/AV02-1184EN
Für den ADNS2620:
http://www.avagotech.com/docs/AV02-1115EN
Für den ADNS2051:
http://bdml.stanford.edu/twiki/pub/Main/OpticalDisplacementSensor/ADNS2051.pdf

Man kann mit dem Maussensor über kleine Strecken recht genaue Informationen über die zurückgelegte Wegstrecke erhalten. Auf langen Strecken summieren sich die Fehler allerdings zu recht deutlichen Fehlern.
Als kleines Schmankerl ohne größeren Nutzwert: es lässt sich auch das gerade aufgenommene Bild der Kamera auslesen.
Das sieht dann z.B. so aus:

andieh
22.01.2009, 13:08
Als kleines Schmankerl ohne größeren Nutzwert: es lässt sich auch das gerade aufgenommene Bild der Kamera auslesen.
Das sieht dann z.B. so aus:

das bild hätte mich jetzt auch interessiert :D

öhm, wo kriegt man so nen sensor her, wenn man gerade nicht zufällig ne alte maus da hat (die hab ich gerade wirklich zufällig hier, aber der chip ist nicht identifizierbar!)

gruß
andieh

benx
22.01.2009, 13:26
Hi,

das Thema Maussensor und RP6 intressiert mich auch. Bin da auch gerade dran... mal schauen obs was wird.

mfg
benx

m.a.r.v.i.n
22.01.2009, 13:47
Hi andieh,


das bild hätte mich jetzt auch interessiert
Das Bild sieht man nur, wenn man eingeloggt ist, oder was meintest du?


öhm, wo kriegt man so nen sensor her, wenn man gerade nicht zufällig ne alte maus da hat
Den ADNS-2610 gibt es z.B. bei Segor (http://segor.de) für €3,20. Allerdings nutzt einem der Sensor alleine nicht viel, man braucht auf jeden Fall auch noch die Optiklinse und die zugehörige LED. Damit kommt man dann auf ca. 5€ bei Segor. Dafür kriegt man fast schon eine neue Maus, wo das auch schon alles drin ist. Im CC2 Forum (http://www.cczwei-forum.de/cc2/thread.php?threadid=1711) hat man sich für den ADNS5020 entschieden, weil dieser in der Logitech RX250 verbaut ist. Diese Maus bekommt man für €7,95 bei Reichelt (http://www.reichelt.de).

Panzerfan
22.01.2009, 15:24
hi,

Wow so viele Antworten in nur einem Tag!!! Ich hätte nicht gedacht das ich mal so ein bedeutendes Thema eröffne. hi m.a.r.v.i.n braucht man nicht für den Maussensor ADNS1620 auch einen Oszillator oder so irgendwas? Das wäre dann nämlich auch in der Maus drin. Hey radbruch das mit dem I²C werde ich acuh mal ausprobieren vielleicht schaffen wir es ja ne Lösung zu finden. Könntest du mal den Schaltplan deines Adapters reinstellen? Und, der RP6 hat von dem Maussensor schon einigen Nutzen er könnte z.b. Die Geschwindigkeit einregeln, einregeln wie weit er noch drehen muss um die vorgegebene Drehung zu vollenden oder einfach die Daten auf einem Display anzeigen. Ausserdem geht es hier glaube ich eher um den Spaß beim Suchen einer Lösung als um den Nutzen. Übrigens andieh der Chip war bei mir auch nich identiefizierbar. Bei mir z.b stand A2620 drauf und ich hab im Internet gesucht und gesucht und dann hab ich durch zufall herausgekommen das es eigentlich ein ADNS2620 ist(Bei den Suchen kam immer nur was über Steckboards und Commodore Computer :D )

mfg Panzerfan

radbruch
22.01.2009, 15:35
Hallo

Ich habe mal grob die Timeings der 26xx mit meinem 2051 verglichen. Bis auf die unterschiedlichen Verzögerungen scheint das gleich. Vor allem das Zusammenspiel von Takt und Daten ist gleich. Hier nun mein erster funktionierender Versuch:

// RP6 liest optischen Maussensor aus (nur x/y)(Maussensor: ADNS-2051) 22.1.09 mic

#include "RP6RobotBaseLib.h"

#define clk_h DDRC |= 1; PORTC |= 1 // Für Anschluss an SDA/CLK am XBUS
#define clk_l DDRC |= 1; PORTC &= ~1 // clk - Pin 10
// data= Pin 12
#define data_h DDRC |= 2; PORTC |= 2 // Vcc - Pin 3
#define data_l DDRC |= 2; PORTC &= ~2 // GND - Pin 1
#define data_z DDRC &= ~2; PORTC &= ~2
#define data_in (PINC & 2)

/*
#define clk_h DDRA |= 1; PORTA |= 1 // Für Anschluss an ADC0/1
#define clk_l DDRA |= 1; PORTA &= ~1 // clk - ADC0
// data- ADC1
#define data_h DDRA |= 2; PORTA |= 2
#define data_l DDRA |= 2; PORTA &= ~2
#define data_z DDRA &= ~2; PORTA &= ~2
#define data_in (PINA & 2)
*/

void init( void)
{
data_z;
clk_h;
sleep(5);
clk_l;
mSleep(2000); //timeout adnr2051 erzwingen => reset
}

void write_data(uint16_t data)
{
uint8_t bit=16;
while(bit--)
{
if(data & (1<<bit)) {data_h;} else {data_l;} // Klammern sind hier muss!
sleep(5);
clk_h;
sleep(5);
clk_l;
sleep(5);
}
data_z;
sleep(20);
}

uint8_t read_data(uint8_t adr)
{
uint8_t bit, data;

bit=8;
while(bit--)
{
if(adr & (1<<bit)) {data_h;} else {data_l;}
sleep(5);
clk_h;
sleep(5);
clk_l;
sleep(5);
}
clk_l;
data_z;
sleep(20);
bit=8;
data=0;
while(bit--)
{
clk_h;
if(data_in) {data |= (1<<bit);}
sleep(5);
clk_l;
sleep(5);
}
sleep(20);
return(data);
}

int main(void)
{
uint8_t status;

initRobotBase();
init();

writeString_P("Produkt-ID: ");
writeInteger(read_data(0), 16);
writeString_P("\n\n\r");
while(1)
{
status=read_data(2);
if(status & 128) // Bewegung erkannt?
{
writeString_P("Status: "); // wenn Bit7 gesetzt ist
writeInteger(status, 16);
writeString_P(" x: ");
writeInteger(read_data(3), 10); // können die eingefrorenen Deltawerte
writeString_P(" y: "); // für x und y ausgelesen werden.
writeInteger(read_data(4), 10);
writeString_P("\n\r");
}
sleep(255);
}

while(0) // Testansteuerung
{
clk_h;
data_h;
mSleep(1000);
clk_l;
mSleep(1000);
clk_h;
data_l;
mSleep(1000);
clk_l;
mSleep(1000);
clk_h;
data_z;
mSleep(1000);
clk_l;
mSleep(1000);
}
return(0);
}


wenn man die Maus bewegt werden die Daten zum RP6Loader gesendet :)

Das Programm verwendet zwei Funktionen:

write_data() sendet 16 Bits zur Maus. Bit15-8 sind dabei die Adresse, Bit7-0 die Daten. Bit15 für Schreibzugriff muss man selbst setzen!

read_data(adresse) liest Daten von der angegebenen Adresse. Dazu wird zuerst die Adresse gesendet, kurz gewartet und dann werden die Daten eingelesen.

Das Timeing ist noch nicht optimiert, Wartezeiten von 5 sleep()s dürften aber reichlich zuviel sein.

Der Chip in meiner Maus wurde mit digitalen Ausgängen genutzt, die Takt- und Datenpins waren mit GND verbunden. Ich habe sie einfach abgezwickt und das Kabel direkt auf die Pins gelötet. Vcc und GND sind geblieben:

http://radbruch.roboterbastler.de/maussensor/maussensor1_klein.jpg (http://radbruch.roboterbastler.de/maussensor/maussensor1.jpg) http://radbruch.roboterbastler.de/maussensor/maussensor2_klein.jpg (http://radbruch.roboterbastler.de/maussensor/maussensor2.jpg)

Das USB-Kabel steckt dann direkt im XBUS.

Ich glaube nicht das man die Maus sinnvoll zur Wegmessung/-berechnung nutzen kann, lasse mich aber gerne vom Gegenteil überzeugen.

Viel Spaß beim Nachbau.

[Edit]Noch ein kleines Update:

Bevor man mit dem Maussensor ein Foto machen kann sollte man die LED einschalten:
http://i1.ytimg.com/vi/Lhg-QdRft-A/2.jpg (http://www.youtube.com/watch?v=Lhg-QdRft-A)
http://www.youtube.com/watch?v=Lhg-QdRft-A

Das funzt ja schon prima:

//RP6 schaltet die LED einer optischen Maus (Maussensor: ADNS-2051) 22.1.09 mic

#include "RP6RobotBaseLib.h"

#define clk_h DDRC |= 1; PORTC |= 1 // Für Anschluss an SDA/CLK am XBUS
#define clk_l DDRC |= 1; PORTC &= ~1 // clk - Pin 10
// data= Pin 12
#define data_h DDRC |= 2; PORTC |= 2 // Vcc - Pin 3
#define data_l DDRC |= 2; PORTC &= ~2 // GND - Pin 1
#define data_z DDRC &= ~2; PORTC &= ~2
#define data_in (PINC & 2)

/*
#define clk_h DDRA |= 1; PORTA |= 1 // Für Anschluss an ADC0/1
#define clk_l DDRA |= 1; PORTA &= ~1 // clk - ADC0
// data- ADC1
#define data_h DDRA |= 2; PORTA |= 2
#define data_l DDRA |= 2; PORTA &= ~2
#define data_z DDRA &= ~2; PORTA &= ~2
#define data_in (PINA & 2)
*/

void init( void)
{
data_z;
clk_h;
sleep(5);
clk_l;
mSleep(1500); // timeout adnr2051 erzwingen zur Syncronisation
// kein Takt seit mehr als 0,9sec => reset
}

void write_data(uint16_t data)
{
uint8_t bit=16;
while(bit--)
{
if(data & (1<<bit)) {data_h;} else {data_l;} // Klammern sind hier muss!
sleep(5);
clk_h;
sleep(5);
clk_l;
sleep(5);
}
data_z;
sleep(20);
}

uint8_t read_data(uint8_t adr)
{
uint8_t bit, data;

bit=8;
while(bit--)
{
if(adr & (1<<bit)) {data_h;} else {data_l;}
sleep(5);
clk_h;
sleep(5);
clk_l;
sleep(5);
}
clk_l;
data_z;
sleep(20);
bit=8;
data=0;
while(bit--)
{
clk_h;
if(data_in) {data |= (1<<bit);}
sleep(5);
clk_l;
sleep(5);
}
sleep(20);
return(data);
}

int main(void)
{
uint8_t adresse, daten;
initRobotBase();
init();

writeString_P("Produkt-ID: ");
writeInteger(read_data(0), 16);
writeString_P("\n\n\r");

adresse=0x8a; // Registernr. + Bit7 gesetzt weil Kommando!
daten=0b00000001; // Bit0 gesetzt ist Sleep-Mode aus
//76543210
while(1)
{
write_data(256*adresse+daten); // Lampe an
mSleep(500);
write_data(256*adresse); // Lampe aus
init(); // Timeout erzwingen um PowerDown-Zeit zu umgehen
}
return(0);
}


[NocheinEdit]
Ist doch nicht sooo schwierig:

[READY]
Produkt-ID: 2


Bilddaten des Maussensors:

0123456789abcdef
0 |#¤¤¤¤¤¤¤x××××××·|
1 |¤¤¤¤¤#¤¤¤x××××··|
2 |¤¤¤¤¤##¤¤xx×××··|
3 |¤¤¤¤¤##¤¤¤x×××··|
4 |x¤¤¤¤###¤¤¤x××··|
5 |x¤¤¤¤###¤¤¤x×××·|
6 |xx¤¤¤##¤#¤¤x××·×|
7 |xxx¤¤¤#¤¤¤¤x××·×|
8 |xxx¤¤#¤¤¤¤¤x××··|
9 |¤x×x¤¤¤¤¤¤¤x×···|
a |¤x×x¤¤¤¤¤xxx×···|
b |xx××x¤¤¤xxxx××··|
c |xx×××x¤xxxx××···|
d |×xx××xxxxx××····|
e |××××××xx××××····|
f |×××·×××××××·····|

[READY]
Produkt-ID: 2

Bilddaten des Maussensors:

0123456789abcdef
0 |#¤¤¤¤¤¤¤x××××××·|
1 |¤¤¤¤¤#¤¤¤x××××··|
2 |¤¤¤¤¤##¤¤x××××··|
3 |¤¤¤¤¤#¤¤¤¤x×××··|
4 |x¤¤¤¤###¤¤¤×××··|
5 |x¤¤¤¤¤##¤¤¤x×××·|
6 |xx¤¤¤##¤#¤¤x××·×|
7 |xxx¤¤¤#¤¤¤¤x××·×|
8 |¤xx¤¤¤¤¤¤¤xx××··|
9 |¤××x¤¤¤¤¤¤xx×···|
a |¤x×x¤¤¤¤¤xxx×···|
b |xx××x¤¤¤xxxx××··|
c |xxx××x¤xxxx××···|
d |××x××xxxxxx×····|
e |××××××xx××××····|
f |×××·×××××××·····|

[READY]
Produkt-ID: 2

Bilddaten des Maussensors:

0123456789abcdef
0 |×······×××······|
1 |×···············|
2 |x×··············|
3 |¤¤x·············|
4 |¤¤¤¤x×··········|
5 |¤¤¤#¤xx××·×·×××·|
6 |¤¤¤¤#¤¤¤xxx×××××|
7 |¤¤¤¤#¤¤¤¤xxx××××|
8 |¤¤¤¤¤¤¤¤xxx×××·×|
9 |¤¤###¤¤¤xxx×××××|
a |¤¤##¤¤¤¤xx×××××·|
b |¤¤¤¤¤¤xxxx××××··|
c |xxx¤¤¤xxxx×××···|
d |xxxx¤xxxxx×××···|
e |xxxxxxxxx×××××··|
f |xxxxxxxx×××××···|

Zweimal der Scan einer Steuermarke auf einer Zigarettenschachtel, Maus wurde nicht bewegt. Das Dritte ist ein Scan aus einer Zeitschrift(Text).


// RP6 liest ein 16x16 Pixelbild vom Maussensor ein (63 Helligkeitswerte) 22.1.09 mic

// Maussensor: ADNS-2051

#include "RP6RobotBaseLib.h"

#define clk_h DDRC |= 1; PORTC |= 1 // Für Anschluss an SDA/CLK am XBUS
#define clk_l DDRC |= 1; PORTC &= ~1 // clk - Pin 10
// data= Pin 12
#define data_h DDRC |= 2; PORTC |= 2 // Vcc - Pin 3
#define data_l DDRC |= 2; PORTC &= ~2 // GND - Pin 1
#define data_z DDRC &= ~2; PORTC &= ~2
#define data_in (PINC & 2)

/*
#define clk_h DDRA |= 1; PORTA |= 1 // Für Anschluss an ADC0/1
#define clk_l DDRA |= 1; PORTA &= ~1 // clk - ADC0
// data- ADC1
#define data_h DDRA |= 2; PORTA |= 2
#define data_l DDRA |= 2; PORTA &= ~2
#define data_z DDRA &= ~2; PORTA &= ~2
#define data_in (PINA & 2)
*/

void init( void)
{
data_z;
clk_h;
sleep(5);
clk_l;
mSleep(1500); // timeout adnr2051 erzwingen zur Syncronisation
// kein Takt seit mehr als 0,9sec => reset
}

void write_data(uint16_t data)
{
uint8_t bit=16;
while(bit--)
{
if(data & (1<<bit)) {data_h;} else {data_l;} // Klammern sind hier muss!
sleep(2);
clk_h;
sleep(2);
clk_l;
sleep(2);
}
data_z;
sleep(20);
}

uint8_t read_data(uint8_t adr)
{
uint8_t bit, data;

bit=8;
while(bit--)
{
if(adr & (1<<bit)) {data_h;} else {data_l;}
sleep(2);
clk_h;
sleep(2);
clk_l;
sleep(2);
}
clk_l;
data_z;
sleep(20);
bit=8;
data=0;
while(bit--)
{
clk_h;
if(data_in) {data |= (1<<bit);}
sleep(2);
clk_l;
sleep(2);
}
sleep(20);
return(data);
}

int main(void)
{
uint8_t adresse, daten, zeile, spalte;
uint8_t graustufen[6]={32, 184, 216, 120, 165, 35}; // " ·×x¤#"

initRobotBase();
init();

writeString_P("Produkt-ID: ");
writeInteger(read_data(0), 16);
writeString_P("\n\n\r");

adresse=0x8a; // Registernr. + Bit7 gesetzt weil Kommando!
daten=0b00000001; // Bit0 gesetzt ist Sleep-Mode aus
//76543210
write_data(256*adresse+daten); // Lampe an
mSleep(500);
daten=0b00001001; // Bit3 gesetzt startet PixelDump
//76543210
write_data(256*adresse+daten); // Pixeldump anfordern

writeString_P("Bilddaten des Maussensors:\n\r");
writeString_P(" 0123456789abcdef\n\r");
for(zeile=0; zeile<16; zeile++) // 16x16=256 Pixel lesen
{
writeInteger(zeile, 16);
writeString_P(" |");
for(spalte=0; spalte<16; spalte++)
{
read_data(0x0d);
//do daten=read_data(0x0c); while(!(daten & 128);
daten=read_data(0x0c);
writeChar(graustufen[daten/10]); // 63 ist maxwert, 6 graustufen
}
writeString_P("|\n\r");
}
adresse=0x8a; // Lampe aus, PixelDump fertig
write_data(256*adresse);
while(1); // Kunstwerk betrachten
return(0);
}

Panzerfan
23.01.2009, 17:35
hi,
Wow radbruch das ist ja schon ziemlich gut. Bei mir funztz noch nich so denn ich hab den chip ausgelötet den Quarz wieder angelötet und noch ein paar Kabel dran, wenn ich aber anschließe geht der RP6 gar nicht an oder er stürzt ab. Jetzt hol ich mir ne billige Lasermaus von Logitech.

mfg Panzerfan

PS: Dass ich den Maussensor rausgelötet hab hat einen Grund. Grund:
Die Maus war eine Funkmaus deshalb konnte man nicht so einfach wie bei radbruch die Kabel anlöten und ausserdem war die Maus komplett in SMD und die Bauteile waren ziemlich aneinander.


Edit:


Noch ne Idee für radbruch:
man könnte doch mehrere aufnahmen von deinem Sensor aneinander reihen und dann hätte man villeicht ein ganzes Bild(Sensor halt immer ein bisschen verschieben) :-k

radbruch
25.01.2009, 00:17
Hallo Maussensorfans :)

Obwohl ich schon immer mal mit einer optischen Maus spielen wollte kommt so langsam die Ernüchterung. Zur Wegmessung nicht geeignet würde ich sagen. Der Hauptgrund: Bei jedem Auslesen der Deltadaten (Wegänderung seit der letzten Abfrage) gibt es einen Rundungsfehler der sich enorm addiert. Das alleine wäre schon übel, richtig schlimm ist die verlorene Orientierung schon nach kurzer Wegstrecke. Am PC korrigiert der Bediener die Ausrichtung der Maus, deshalb bewegt "Maus Richtung Kabel schieben" (weg vom Körper für Funkmäuse) den Mauszeiger am Bildschirm nach oben. Wenn man aber wärendessen die Maus zusätzlich noch auf dem Tisch dreht (so das ihr Kabel seitlich rauskommt) sieht man schön was ich meine. Vorwärts kann alle Richtungen sein.

An diese Deltadaten kommt man übrigends auch ohne die Maus zu öffnen über eine PS2-Schnittstelle.

Alternativ dazu könnte man natürlich auch die Bilddaten direkt verarbeiten. Aber das kann man meiner Meinung nach auch komplett vergessen. Mein ADNS-2051 kann bei 400 Dot/Inch 14 Inches/Sekunde, das sind knapp 40cm/Sekunde. Sein Bild hat 256 Bildpunkte, also 16x16 Pixel zu je 63 Graustufen. Bei ein Inch/400 Pixelgröße ist das "fotografierte" 16x16-Bild 25,4mm/400*16=1,016mm breit! Bei einer Brennweite von 2,4mm ist das unbrauchbar. Um mehrere Bilder zusammensetzen zu können muss man sie überlappend abspeichern (, drehen?) und dann zusammensetzen. Macht 256*6 Bit pro Bild + Ergebnissbild aus dem wir dann die absolut zurückgelegten Wege errechnen. Viel Spaß dabei mit dem AVR.

Damit wäre die Wegmessung für mich abgehakt. Eine alternative Anwendung wäre vielleicht eine Art Trackball zur Menusteuerung. Oder irgendwas in Richtung Linienerkennung/Barcodes... Dazu würde es reichen wenn man ein 16x16-Bild als ein einziges Pixel interpretiert und speichert. Aber wie erhält man einen representanten Wert für ein komplettes Bild? Das folgende gilt vielleicht nur für meinen ADNS-2051. Dieser liefert zu jedem Bild zusätzlich noch folgende Bilddaten: hellste Helligkeit, durchschnittliche Helligkeit, Anzahl unterschiedene Bildelemente(Güte), die Verschlußzeit (shutter) und schließlich die Framerate (Bilder/Sek). das sieht auf den erste Blick prima aus, die Tücke liegt in der automatischen Bildoptimierung des ADNS-2051: Er stellt die Verschlußzeit so ein das die max-Werte für die Helligkeit "in den 50ern" liegen:

Pixel Dump Pictures
The following images (Figure 40) are the output of the pixel dump command. The data ranges from zero for complete
black, to 63 for complete white. An internal AGC circuit adjusts the shutter value to keep the brightest feature (max.
pixel) in the mid 50s.(Aus dem Datenblatt im Kapitel über die "Pixel Dump Pictures")

Das bedeutet letztlich, dass die gespeicherten Helligkeitswerte eines Pixels von den Werten der Nachbarpixel abhängt. Viel Spaß beim pixelweisen Zusammensetzen der Bildchen...

Ein Ausweg scheint hier der Shutterwert zu sein. Er ist direkt abhängig von der durchschnittlichen Helligkeit des Bildes und eignet sich hervorragend zum Linienerkennen. Da es ein 16bit-Register ist wird aus einem 16x16-Bild ein 1mm-Pixel mit (fast) 64k-Graustufen. Ein Zahlenbeispiel: Shutterwert über hellen Bodenfiesen: 6tausendirgendwas, über dunklen Fugen: 380!. Wunderbar! Gleich mal testen :)

Naja, und dieser Test ist einfach: Die Maus über eine Linie schieben und möglichst auf dem selben Weg über die Linie zurückschieben. Währenddessen laufend die addierten Deltawerte und die Shutterstellungen ans Terminal ausgeben. Nichts, keine Chance. Meine Werte für die Linie waren nicht mal ähnlich. Deshalb habe ich die Maus nun wieder eingemottet.

Sorry, der Beitrag wurde irgendwie immer länger..

Gruß

mic

Panzerfan
25.01.2009, 15:01
Hi,
Radbruch ich glaube du hast Recht. Das "Maus Richtung Kabel schieben" Beispiel zeigt das. Ich glaube ich lass jetzt das mit dem Maussensor und widme mich anderen Dingen.

mfg Panzerfan

benx
02.02.2009, 21:56
Hi,

könnte man denn mit einem Maussensor messen ob sich der RP6 genau um eine gewünschte Gradzahl gedreht hat? Mein Problem ist das ich den RP6 auf unterschiedlichen Oberflächen betreibe und für einige Fahrmanöver eine relativ exakte Drehung (z.B. 90 Grad) brauche. Das bekomm ich trotz Änderung der ENCODER_RESOLUTION nie vernünftig hin.

Oder lieber gleich mit einem elektrischen Kompass versuchen? :-)

mfg
benx

proevofreak
30.06.2009, 20:18
da ich seit heute eine neue computer- maus besitze und der maussensor meiner alten noch voll funktioniert, ist das thema maussensor für mich nun auch interessant.
nach durchforsten des forums bin bisher immer nur auf threads gestoßen wo mit hilfe des sensors eine wegstrecke gemessen wurde. kann mir jemand von den erfahrenen "maussensorverwendern" sagen, ob er sich auch für eine hindernisserkennung eignet?

gruß

radbruch
30.06.2009, 20:31
Hallo

Wenn die Maus keine Wegänderung mehr meldet ist sie blockiert weil der Roboter gegen ein Hinderniss gestoßen ist :) Den Maussensor als Kamera zu nutzen um damit Hindernisse zu erkennen kann man vergessen. Seine Brennweite beträgt nur ein paar Millimeter.

Schade eigentlich...

Gruß

mic

proevofreak
30.06.2009, 20:38
find ich eigentlich auch schade, weil eine wegmessung wird beim RP6 ja schon mit den encodern gemacht. da fällt mir dann keine sinnvolle anwendung für den maussensor mehr ein.

gruß

radbruch
30.06.2009, 20:51
Als "sinnvolle Anwendung" dachte ich z.B. an eine Art Touchpad mit dem man durch Auflegen eines Fingers durch ein LCD-Menu scrollen kann.

proevofreak
01.07.2009, 13:18
gute idee. doch leider stell ich mir diese anwendung für mich momentan noch viel zu kompliziert vor. ich muss mich jetzt einfach mal mit einer cmos kamera in dieses thema einsteigen.
vielleicht kannst du mir ja mal meine letztens gestellte frage in deinem thread Minimallösung: Kamera für den RP6
beantworten. du scheinst ja mit kameras schon sehr viele erfahrungen gemacht zu haben?

danke schon mal im voraus für deine hilfe

mare_crisium
03.08.2009, 19:18
radbruch,

tut mir leid, dass Dich die Mäuschen so enttäuscht haben ;-) ! Könnte aber sein, dass da vielleicht doch noch was geht. Wenn Du Lust hast, guck' doch mal in den Fred "Maus-Odometrie", den Robotino unter KI angefangen hat.

Ciao,

mare_crisium

radbruch
03.08.2009, 20:16
Den "Maus-Odometrie"-Fred (https://www.roboternetz.de/phpBB2/viewtopic.php?t=49398) habe ich natürlich auch schon entdeckt ;)

Es gibt wieder den Rundungsfehler beim Auslesen der Deltadaten und den Schlupf am Boden. Auch hier wird der Schwanz der Maus (https://www.roboternetz.de/phpBB2/viewtopic.php?p=421528#421528) (oder des Roboters) irgendwann mal zur Seite zeigen. Ohne externe Referenzen wie GPS, Baken, Kameras oder Markierungen wird sich der Bot verirren.

mare_crisium
03.08.2009, 22:06
radbruch,

tja, das mit dem Drehen ist so eine Sache. Du hast recht: Bei der Berechnung der Mausposition auf dem Bildschirm können Drehungen überhaupt nicht erfasst werden. Der Maussensor liefert zwei Zahlen, delta-x und delta-y, und die reichen bei einer frei beweglichen Maus nur aus, um x- und y-Koordinate der Bildschirmposition zu berechnen.

Bei einem Maussensor, der an ein Fahrzeug montiert ist, ist das anders: Nehmen wir mal an, der Maussensor ist an einem Asuro montiert und zwar so, dass die x-Achse des Maussensors genau senkrecht zu den Antriebsachsen, also in Vorwärtsrichtung zeigt. Der Asuro kann sich nur vorwärts/rückwärts bewegen und/oder drehen. Seitwärtsfahren kann er nicht. Diese Beschränkung der möglichen Bewegungen nutzt man aus, und kann - mit nur einem Maussensor - die Bewegungen des Asuro tatsächlich nachrechnen.

Die zwei Zahlen, die der Maussensor liefert, werden jetzt in Drehwinkel und Fahrstrecke umgesetzt: Jede Bewegung in x-Richtung, die der Maussensor anzeigt, bedeutet, dass der Asuro vorwärts/rückwärts gefahren ist. Jede Bewegung in y-Richtung besagt, dass er sich gedreht hat.

Der Drehwinkel lässt sich aus der Bewegung in y-Richtung und dem Abstand des Messflecks vom Bezugspunkt ausrechnen. Damit bekommt man die neue Vorwärtsrichtung (im ortsfesten Koordinatensystem). Mit der neuen Vorwärtsrichtung und den Bewegungsdaten in x-Richtung ist dann auch der neue Ort des Asuro auszurechnen.

Eine Drehung des Asuro allein macht die Genauigkeit der Ortsbestimmung noch nicht zunichte. Die Richtung und Länge der Bewegung wird dabei immer noch ziemlich genau berechnet. Erst über mehrere Drehungen und längere Wegstrecken wird die Messgenauigkeit allmählich und vor allem durch die Rundungsfehler beim Berechnen der neuen Vorwärtsrichtung immer schlechter.

Ich kann meinen Versuchsaufbau mit zwei Maussensoren jedenfalls in jeder Richtung umherschieben und ihn dabei auch um 180° drehen und habe am Ende einer Bewegung von ca. 50cm Länge einen Positionsfehler von weniger als 5cm. - Das ist immer noch unbefriedigend - aber: Wir arbeiten dran ;-) !

Ciao,

mare_crisium

radbruch
03.08.2009, 22:41
Hallo

Das Problem liegt nicht in der (umfangreichen und auch mit Rundungsfehlern behafteten) Berechnung der vorwärts/seitwärts-Bewegung. Es liegt hier:

Der Maussensor liefert zwei Zahlen, delta-x und delta-y... Und eben diese Zahlen enthalten ebenfalls einen Rundungsfehler und der addiert sich unter ungünstigen Umständen enorm. Die geringste Abweichung in der Ausrichtung führt unweigerlich in Chaos.

Ich habe meine Versuche mit dem Maussensor verschoben/eingestellt. Deshalb habe ich keine eigenen Erfahrungen damit, das oben geschriebene ist möglicherweise totaler Unsinn. Aber ich vermute, sobald irgendwo ein Schlupf oder Rundungsfehler auftritt kann man die Odometrie, ohne externe Referenzen als einziges Navigationssystem,vergessen. Ein Fehler von 10% ist übrigens vollkommen unakzeptabel!

Gruß

mic

oberallgeier
03.08.2009, 23:08
... kann man die Odometrie, ohne externe Referenzen ... vergessen ... Fehler von 10% ist übrigens vollkommen unakzeptabel ...Im Moment hänge ich an genau diesem Problem - nicht mit RP6 und Mäusen, sondern mit meinem MiniD0 bzw. Encodern an den Motorwellen. Immerhin bin ich nach einer Drehung um 990°, einer 180°Kurve, einer 90°Kurve, dazwischen immer Geradenstücke und zum Schluss eine Drehung um 540°, nach insgesamt mehr als 80 cm Fahrstrecke (http://www.youtube.com/watch?v=MjLqexH6fDQ) bei einer Abweichung von +- 1 mm, maximal +-25 mm. Maximal leider auch fast 10%. Aber ich arbeite dran . . . .

radbruch
03.08.2009, 23:15
Das liegt in erster Linie am Schlupf der Räder. Teste mal mit entfetteten Radoringen auf einer sauberen waagrechten Glas-/Spiegelfläche ;)

oberallgeier
03.08.2009, 23:23
Na ja, meine Räder

............http://oberallgeier.ob.funpic.de/Rad_Dottie.jpg

haben O-Ring-Slicks und der Schreibtisch ist relativ fettlos . . . .

horsty
24.10.2009, 19:55
jungs,

sorry, dass ich dieses thema hier nochmals ausgrabe. aber ich versuche im moment, mittelt eines adns2610 an einem atlem atmega32 den hub von hydraulikzylindern zu messen.

momentan alles noch fiktion, aber ich denke, dass ihr mir, weil ihr euch wie ich sehe, ausgiebig damit beschäftigt habt, sehr helfen könnt. auch in bezug zu alternativen sensortechnik für den job, wäre ich dankbar.

am liebsten hätte ich den nackten sensor am atmega32.

danke im vorraus!! horsty

s.frings
14.04.2010, 17:50
Danke für diesen Beitrag, ich wollte es nämlich auch schon mit einer Maus versuchen. Aber der Test mit der Drehung in der Bewegung zeigt auch bei meiner Logitech Maus völliges Versagen.

Am Computer funktioniert sie Top, aber für den Roboter ist sie wohl wirklich nicht zu gebrauchen.

mare_crisium
14.04.2010, 18:23
s.frings,

stimmt zwar, dass Du mit einer Maus keine Drehungen messen kannst. Das ist wegen des Messprinzips auch nicht anders zu erwarten. - Aber mit zwei Maussensoren geht's ;-).

mare_crisium