PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programmierung des ADNS 3060



VictimOfMyOwn
06.10.2005, 22:13
hi ho...

also...wir haben ein board gebastelt. darauf befinden sich der ADNS 3060, ein mikrocontroller 89c4051 und ein MAX 232 zur seriellen kommunikation mit dem PC.

wenn wir das board jetzt in betrieb nehmen, dann leuchtet die LED, welche an dem ADNS angeschlossen ist, nur recht schwach. bei einem test ohne den ADNS chip, leuchtete die LED mit voller intensität.

der ADNS "kontrolliert" ja diese LED. in seinen registern kann man dieses an und abstellen. laut datenblatt, ist der ADNS so voreingestellt, daß die LED dauerhaft leuchtet.

demnach müsste die LED nach "anschalten" des boards hell leuchten. evtl. muss man bei dem ADNS auch erst einen reset durchführen...wie mache ich das ? die LED wurde nach schaltplan im datenblatt von agilent angeschlossen.

vielleicht hat da ja schon jemand erfahrungen sammeln können.

schonmal danke im voraus !

mfg

Manf
07.10.2005, 07:49
bei einem test ohne den ADNS chip, leuchtete die LED mit voller intensität.
der ADNS "kontrolliert" ja diese LED :?:

http://cp.literature.agilent.com/litweb/pdf/5989-3421EN.pdf
Funktioniert das board denn sonst?

VictimOfMyOwn
07.10.2005, 12:05
Es handelt sich bei dem eigentlich um genau die Schaltung aus dem Datenblatt, nur eben mit einem 89c2051, der an 3,3V Betrieben wird und einem zusätzlichen max232.
Die LED wird ja über einen MosFET geschaltet. Bevohr ich den IC aufgelötet hatte habe ich das Bord mal an Spannung gelegt um zu prüfen ob auch alles richtig arbeitet, dabei hat die LED voll geleuchtet, weil der MosFET ja nicht auf Masse gezogen wurde.
Soweit funz alles, ich bekomme bloß kein Lebenszeichen vom ADNS.

Mus man erst irgendeinen Reset durchführen? Ich werd aus dem Datenblatt net so ganz schlau...

mfg

VictimOfMyOwn
11.10.2005, 20:18
hi ho...

wir haben immer noch probleme den ADNS 3060 anzusprechen.

bei einem versuch aus dem register 0x00 zu lesen (product-id) bekamen wir keine antwort bzw. nur nullen zurück.

hier erstmal unser quellcode:



#include<reg51.h>

// Port 1
sbit NPD = 0x92;
sbit Reset = 0x93;
sbit MOSI = 0x94;
sbit SCLK = 0x95;
sbit MISO = 0x96;
sbit NCS = 0x97;

// Port 3
sbit LED = 0xB5;

// Variablendekleration

unsigned char clock_count, enable;

char i;

int adresse[8], wert[8];

// Funktionsdeklaration

void senden(unsigned char var_adresse, var_wert);
void lesen(unsigned char var_adresse);
void pause(unsigned char time);

void main (void) {

//Initialisierung - Register und Timer einstellen

SCON = 0x50; //01010000
PCON = 0x80; //10000000 1000 0000
IE = 0x9A; //10011010 Timer0, Timer1, Serial Interrupt
TMOD = 0x21; //00100001 Timer1 für Baudrate, Timer0 16bit

TH0 = 0xB7; // Interrupt 20,000 ms
TL0 = 0xFF; // bzw. f=50 Hz

TH1 = 0xFA; // Timer1 HighByte
TL1 = 0xFA; // Timer1 LowByte

TR0 = 1; // Timer0 starten
TR1 = 1; // Timer1 starten

// Variablen setzen

i = 0;
clock_count = 0;

// PortPins setzen

LED = 1;
Reset = 1;
SCLK = 1;
MOSI = 1;
MISO = 1;
NCS = 1;
NPD = 1;

while (1)
{

}
}

void timer0(void) interrupt 1 {

//interrupt tritt 50x in der Sekunde auf

TH0 = 0xB7; // Interrupt 20,000 ms
TL0 = 0xFF; // bzw. f=50 Hz

if (i==25)
{
Reset = 0;
}

if (i == 50)
{
i = 0;
}

i = i + 1;
}

void serial(void) interrupt 4
{
if(RI == 1)
{
switch(SBUF)
{
case 1: LED = 0;
break;
case 2: LED = 1;
break;
case 3: Reset = 1;
Reset = 0;
break;
case 4: senden(138, 89);
break;
case 5: lesen(0);
break;
}
RI = 0;
}
}

void senden(unsigned char var_adresse, var_wert)
{
int rest;

// 8 Bit Adresse ins Array schreiben

adresse[0] = var_adresse%2; // adresse[0] ist Bit0 - LSB
rest = (int)var_adresse / 2;

adresse[1] = rest%2;
rest = (int)rest / 2;

adresse[2] = rest%2;
rest = (int)rest / 2;

adresse[3] = rest%2;
rest = (int)rest / 2;

adresse[4] = rest%2;
rest = (int)rest / 2;

adresse[5] = rest%2;
rest = (int)rest / 2;

adresse[6] = rest%2;
adresse[7] = (int)rest / 2;

// 8 Bit Wert ins Array schreiben

wert[0] = var_wert%2; // wert[0] ist Bit0 - LSB
rest = (int)var_wert / 2;

wert[1] = rest%2;
rest = (int)rest / 2;

wert[2] = rest%2;
rest = (int)rest / 2;

wert[3] = rest%2;
rest = (int)rest / 2;

wert[4] = rest%2;
rest = (int)rest / 2;

wert[5] = rest%2;
rest = (int)rest / 2;

wert[6] = rest%2;
wert[7] = (int)rest / 2;

// Adresse und Wert an den ADNS senden

NCS = 0;
SCLK = 0;

for(clock_count=8; clock_count>0; clock_count--) // 8 Bit Wert senden
{
MOSI = adresse[clock_count - 1];
SCLK = 1;
SCLK = 0;
}

for(clock_count=8; clock_count>0; clock_count--) // 8 Bit Wert senden
{
MOSI = wert[clock_count - 1];
SCLK = 1;
SCLK = 0;
}
}

void lesen(unsigned char var_adresse)
{
int rest;

// 8 Bit Adresse ins Array schreiben

adresse[0] = var_adresse%2; // adresse[0] ist Bit0 - LSB
rest = (int)var_adresse / 2;

adresse[1] = rest%2;
rest = (int)rest / 2;

adresse[2] = rest%2;
rest = (int)rest / 2;

adresse[3] = rest%2;
rest = (int)rest / 2;

adresse[4] = rest%2;
rest = (int)rest / 2;

adresse[5] = rest%2;
rest = (int)rest / 2;

adresse[6] = rest%2;
adresse[7] = (int)rest / 2;

// Adresse und Wert an den ADNS senden

NCS = 0;
pause(5);
SCLK = 0;


for(clock_count=8; clock_count>0; clock_count--) // 8 Bit Wert senden
{
MOSI = adresse[clock_count - 1];
pause(5);
SCLK = 1;
pause(5);
SCLK = 0;
}

pause(5);

// Wert an den PC senden

for(clock_count=8; clock_count>0; clock_count--) // 8 Bit Wert senden
{
SCLK = 0;
pause(5);
SCLK = 1;
pause(5);
SBUF = MISO;
while(TI == 0)
{

}
TI = 0;
}
}

void pause(unsigned char time) // Pausenfunktion; Auflösung von 1 us bei 12 Mhz
{
unsigned char time_count;
for (time_count=0;time_count<time;time_count++) // Aufruf bis hier 4 Takte
{

} // Bis hier dann 14 Takte; Dann Pro count 16 Takte
} // Verlassen der Funktion 2 Takte

end;



wir sind uns aber auch noch nicht im klaren darüber, ob der ADNS überhaupt einen richtigen reset bekommt, da die LED durchgehend nur schwach leuchtet.

tips, wie man einen "perfekten" reset durchführt oder wie man daten senden/empfangen kann wären ganz nützlich.

mfg

Ruppi
12.10.2005, 07:52
Moin,
wieso nutzt Du nicht einfach den normalen Hardware-Reset? Ich mein, dafür ist die Leitung ja da. Allerdings funktioniert das ganze auch ohne Reset, d.h. nach Anlegen der Betriebsspannung sollte alles klar sein.
Dass Dir beim Auslesen nicht mal die korrekte Produkt-ID angezeigt wird, klingt merkwürdig.
Bin Deinen Code nicht durchgegangen, weil ich mich nur sehr wenig mit C auskenne. Hast Du die kleinen Stolpersteine beachtet, wie z.B. die Kennzeichnung der Datenrichtung bei der Übergabe der Adresse? Ich bin anfangs ein paar mal daran hängen geblieben.

Gruß, Ruppi

VictimOfMyOwn
12.10.2005, 12:17
hi ho...

wir habens gestern doch noch zum laufen gebracht.

zuerst haben wir den MOSI pin welcher vom µC zum ADNS geht mit einem pull-up versehen. evtl. ist der jetzt im nachhinein garnicht mehr nötig...müssten wir dann nochmal testen.

nach tauschen des 24mhz quarzes vom ADNS gegen eines mit 12mhz, leuchtete auch aufmal die LED kurz nach dem einschalten mit voller intensität. entweder ist das andere quarz "inne dutten" oder wir haben es falsch angeschlossen...ist ein SMD quarz mit vier anschlüssen.

der reset wird übrigens softwaremäßig durchgeführt. wird dieser weggelassen bleibt die LED wieder dunkel. ohne geht es also nicht.

das lesen der produkt - id hat dann auch wunderbar funktioniert. bilddaten lassen sich nun auch in ein delphi programm einlesen. wobei der erste wert komischerweise immer ein minus davor hat. und etwas langsam ist es auch noch. könnte an dem 12mhz quarz liegen...oder aber einfach an der noch nicht ganz so sauberen programmierung in delphi. da muss also noch dran gefeilt werden.

das nächste problem ist jetzt, die bilddaten in ein image zu schreiben.

jetzt frage ich mich nur, wie ich die 8 bit bilddaten "entschlüsseln" muss. unser erster ansatz war, diese 8 bit irgendwie in eine sechsstellige hex zahl zu wandeln, womit man einem pixel eine farbe zuweisen könnte. 0x000000 bis 0xFFFFFF sind ja graustufen...solange die sprünge 0x111111 entsprechen.

also erstmal wäre es jetzt wie gesagt interessant, wie die empfangenen daten aufgebaut sind und wie man aus einem byte die farbe herausbekommt.

mfg

Ruppi
12.10.2005, 12:31
Steht alles im Datenblatt - das sind keine 8bit, sondern nur 6bit Grauwerte. Das erste Pixel im Bild hat eine Kennzeichnung, ich glaube es war das MSB.
Ich kann das Problem der Bildübertragung nicht ganz verstehen: Ihr bekommt pro Pixel einen Bytewert im Bereich zwischen 0 und 63 durch die V24 geschickt, oder? Jetzt wisst ihr, dass ihr 900 Pixel erwartet. Nach dem vollständigen Empfang bringt ihr das Bild zur Anzeige und fertig! Bei mir ist eine Baudrate von 115200 eingestellt, die Bilddaten empfange ich mit etwa 8 Bildern pro Sekunde.
Übrigens findet ihr noch mehr Info zu diesen Sensoren hier im Sensorforum.
https://www.roboternetz.de/phpBB2/viewtopic.php?t=12579

Der Pullup an MOSI ist übrigens überflüssig.

Gruß, Ruppi

VictimOfMyOwn
12.10.2005, 14:24
hi ho...

die threads über den ADNS und die wilden mausexperimente kenne ich schon.

habe im datenblatt gestern nix darüber gefunden...naja...2 uhr nachts war vielleicht auch schon etwas spät um ein solches datenblatt in sich "aufzusaugen".

zu beginn eines kompletten bildes ist das 6te bit eines pixelwertes eine "1". die restlichen 6ten bits sind dann immer "0".

also hat das byte bzw. haben die daten die man liest immer nur 6 bit...ok.

das einlesen eines bildes, sprich 900 datensätze dauert bei uns im moment ~5 sekunden. haben wie gesagt ein 12mhz quarz drauf und die software ist nocht nicht perfekt. es sind im moment noch 9600 baud eingestellt.

bei dir waren die 115200 baud doch nur ein schreibfehler oder ?

naja...wir werden uns da heute abend nochmal hinter klemmen.

mfg

Ruppi
12.10.2005, 14:35
Das war kein Schreibfehler... Ich hatte die Software mit Visual Basic geschrieben, dort gibt es ein fertiges Steuerelement für das Ansteuern der V24, allerdings geht das nur bis maximal 115200 Baud. Mein Quarz hat nur 3.68MHz.

Ruppi

VictimOfMyOwn
13.10.2005, 14:36
hi ho...

hmm...also 6 bit pro pixel können es eigentlich nicht sein. das sind meine ich schon 8 bit. denn nur so ist ein bit immer "1", komischerweise das 7te und nicht das MSB, und das 6te immer "0" außer beim ersten pixel eines bildes.

hab mal nen screenshot von meinem programm gemacht, damit du weißt was ich meine. hier lese ich jedes bit einzeln und packe jeweils 8 in eine reihe.

http://www.victimofmyown.cybton.com/stuff/empfangene_bytes.jpg

bit 7 ist hier immer "1" (im datenblatt steht MSB müsste immer "1" sein). bit 6 ist immer "0" nur eben beim ersten pixel nicht. kommt also so schon fast hin...wenn man nun in jede reihe nur 6 bit schreibt, würde es mit dem MSB = "1" etc. ja nimmer passen.

da bit 6 immer 0 ist hat man auch nur einen farbwert von 0 bis 31.

mfg

Ruppi
13.10.2005, 14:58
na da passt wohl irgendwas nicht so ganz...
Das es 6bit pro Pixel sind, steht auch im Datenblatt. Wie kommt das Minus-Zeichen des ersten Wertes zustande??
Ich habe gerade nochmal in meinem Programm geguckt: beim Lesen der Bilddaten ist das 7bit beim ersten Pixel gesetzt, nicht das MSB. Aber egal, da passt irgendwas anderes noch nicht. Hast Du den Pixel-Burst Mode aktiviert? Habe das Gefühl, dass das gar keine Bilddaten sind...

VictimOfMyOwn
13.10.2005, 15:27
hi ho...

im datenblatt steht, das bit 6 immer "0" ist und beim ersten pixel eines bildes "1". dann steht da noch, daß das MSB immer "1" ist. also MÜSSEN es mindestens 7 bit sein. sollten wir verschiedene datenblätter haben ?

wie das minus zu stande kommt habe ich mich auch schon gefragt.

also zuerst übergebe ich die adresse des frame_capture registers. das register hat die adresse 0x13. dies entspricht binär 00010011. da ich schreiben will, muss das MSB eine "1" sein. also sende ich 10010011 als adresse. dann sende ich 0x83 an dieses register, damit ein bild "gemacht" wird.

danach schicke ich die adresse 0x40 (pixel_burst register). dies entspricht 01000000. das MSB ist schon eine "0" also wird gelesen. und zwar pro takt immer ein bit.

denke schon, daß es bilddaten sind die da ankommen. wie gesagt...byte/pixel 1 hat eine "1" als 6tes bit. dann folgen 899 pixel mit einer "0" als 6tes bit. das 901te pixel hat dann wieder eine "1" im 6ten bit.

mfg

Ruppi
13.10.2005, 15:48
So wie Du's jetzt geschrieben hast, muss es gehen, das passt nur nicht zu den Werten aus deiner Software.


im datenblatt steht, das bit 6 immer "0" ist und beim ersten pixel eines bildes "1". dann steht da noch, daß das MSB immer "1" ist. also MÜSSEN es mindestens 7 bit sein. sollten wir verschiedene datenblätter haben ?

Da haben wir wohl aneinander vorbei geredet... Also nochmal: es kommt pro Pixel ein Byte, also 8Bits. Davon ist das letzte (MSB) immer 1 und das vorletzte nur beim ersten Pixel des Gesamtbildes 1. Die restlichen Bits sind dann eben der Grauwert des Pixels.
Deine Vorgehensweise ist wie gesagt richtig...

13.10.2005, 17:11
hi ho...

MSB is klar...ok. ist bit 6 nun das sechste bit also die sechste ziffer von rechts...oder geht es von bit 0 bis bit 7 ?

wenn es von bit 0 nach bit 7 geht könnte das hinkommen. nur ich verstehe unter bit 6 eigentlich das sechste bit von rechts. nun ja...egal.

demnach stimmt die ausgabe meiner software vielleicht schon fast. allerdings ist alles um ein bit verrutscht oder so. das bit, welches bei mit ganz links steht, müsste vielleicht nach ganz rechts o.ä. möglicherweise resultiert aus diesem fehler auch das minus zeichen.

hier ist mal meine lesen prozedur, welche "clockt" und die bits welche an MISO nach jedem clock anstehen an den pc sendet. pause(3) entspricht etwas mehr als 50µs. TI wird "1" wenn der sendevorgang abgeschlossen ist.



void lesen()
{
// Wert an den PC senden

for(clock_count=8; clock_count>0; clock_count--) // 8 Bit Wert senden
{
SCLK = 0;
pause(3);
SCLK = 1;
pause(3);
SBUF = MISO;
while(TI == 0)
{

}
TI = 0;
}
}


denke die prozedur ist auch ohne C kenntnisse durchschaubar. aber einen fehler sehe ich hierbei auch nicht.

mfg

VictimOfMyOwn
14.10.2005, 12:38
hi ho...

so...jetzt funktioniert das alles schon etwas besser.

hier sieht man die schrift auf einer zigarettenpapierverpackung. an der optik muss selbstverständlich noch optimiert werden.

http://www.victimofmyown.cybton.com/stuff/adns_gizeh.jpg

als nächstes gilt es erstmal die delta x und delta y daten auszulesen...zu verwerten...und auszugeben.

mfg