Zitat von
jackalice
Hi Max,
Kompliment zu der Arbeit!! Ich beschäftige mich auch grade mit dem ADNS-2610 und möchte diesen zur Positionsbestimmung einsetzen... könntest du den C-Code zur Verfügung stellen? Dann müsste ich nicht von ganz vorne anfangen
Hi!
Klar, kein Problem!
Aber mein Code ist auch so ziemlich der gleiche wie der vom c't-Bot, wie steve schon richtig gesagt hat!
Code:
//ADNS Funktionen!!
void adns_writebyte(uint8_t bdata) {
//PD7 als Ausgang definieren
DDRB |= (1<<SDIO);
for(int8_t i = 7; i >= 0; i--) {
PORTB &= ~(1<<SCK);
/*
PORTB = (PORTB & (~PINB)) | ((bdata >> (7 - SDIO)) & (1<<SDIO));
bdata = bdata <<1;
*/
PORTB &= ~(1<<SDIO);
if(bdata&(1<<i)) PORTB |= (1<<SDIO);
asm volatile("nop");
PORTB |= (1<<SCK);
}
}
uint8_t adns_readbyte(void) {
uint8_t Bdata = 0;
PINB &= ~(1<<SDIO);
DDRB &= ~(1<<SDIO);
//Bdata = 0;
for(int8_t i = 7; i >= 0; i--) {
//Sck = 0
PORTB &= ~(1<<SCK);
Bdata = Bdata <<1;
PORTB |= (1<<SCK);
asm("nop");
Bdata |= (PINB >> SDIO) & 0x01;
}
return Bdata;
}
void adns_write(uint8_t adr, uint8_t Bdata) {
//erstes Byte auf eins, da schreibvorgang!
adr |= (1<<7);
adns_writebyte(adr);
adns_writebyte(Bdata);
_delay_us(200);
}
uint8_t adns_read(uint8_t adr) {
adr &= ~(1<<7);
//Adresse schreiben
adns_writebyte(adr);
_delay_us(200);
//antwort-byte ausgeben
return adns_readbyte();
}
void adns_init(void) {
DDRB |= (1<<SCK);
PORTB &= ~(1<<SCK);
//reset
adns_write(0x00, 0x80);
//forced awake mode
adns_write(0x00, 0x01);
}
@unapiedra:
Den Wert habe ich aus dem Datenblatt und nicht selbst getestet.
Aber ich kann es testen, da ich der Roboter mittlerweile wieder bei mir zuhause steht. Nur musst du dich noch etwas gedulden, denn ich stecke momentan voll im Abi-Stress.
Allerdings ist der ADNS-2610 mittlerweile eigentlich total veraltet. Es gibt, so weit ich weiß, Sensoren, die locker 100cm/s schaffen dürften. Einfach mal eine aktuelle Gamer-Maus zerlegen
Bei einem omnidrive-Roboter müsste das rein theoretisch schon mit einem Maussensor zu realisieren sein, ABER: nur bei dem Spezialfall, dass der Roboter nie um die eigene Achse rotiert. Soll heißen, dass der Roboter von Start bis Ende immer in die gleiche Richtung schaut. Die Richtungsänderungen erfolgen nur über die Geschwindigkeit der verschiedenen Omnidrive-Räder.
Dann müsste ein im Mittelpunkt des Roboters montierter Maussensor genügen, um den Winkel der aktuellen Fortbewegungsrichtung festzustellen. Formel wäre dann tan alpha = dY / dX (achtung: wenn dX=0 dann muss alpha = 90/180° gesetzt werden, da durch null geteilt wird). Den Weg kann man entweder über "sin alpha = dY / Weg" oder über "cos alpha dx / Weg" bestimmen.
Da der Sensor zentral sitzt erkennt er also keine Drehung um die eigene Achse.
Um den Roboter ganz normal benützen zu können, müsste man also einen zweiten Sensor einbauen, der exzentrisch sitzt und die Rotierung um die eigene Achse registriert und jeweils von dem anderen alpha abzieht/hinzuzählt. Allerdings dürfte dieser Sensor nur dann aktiviert werden, wenn sich der Roboter auch wirklich um die eigene Achse dreht. Der zurückgelegte Weg wird nach wie vor über den zentralen Sensor bestimmt.
Hoffe ich habe das einigermaßen verständlich (und richtig) erklärt, wenn nicht, dann mach noch ne Zeichnung!
Es gibt sicher noch besserere Möglichkeiten, rein theoretisch müsste es auch mit nur einem Sensoren, der sich außerhalb des Mittelpunkts befindet, funktionieren.... hm... ein sehr interessantes Problem!
Danke nochmal an alle für das positive Feedback =D>
mfg max
PS.: Hab 15pkt bekommen
Lesezeichen