Ein Freund hat mir seine alte Funkmaus überlassen, darin sitzt ein ADNS1620 
Laut DATENBLATT 18x18 Pixel deren Werte sich auslesen lassen... irgendwie.
Bisher habe ich mir den Code von http://www.bidouille.org/hack/mousecam angeschaut und mal die Adressierung der Register angepasst:
#define SCLK 2
#define SDIO 3
// #define PD 4
#define REG_CONFIG_BITS 0x40
#define REG_PRODUCT_ID 0x41 //Asleep-Wake
#define REG_DELTA_Y 0x42
#define REG_DELTA_X 0x43
#define REG_SQUAL 0x44
#define REG_MAXIMUM_PIXEL 0x45
#define REG_MINIMUM_PIXEL 0x46
#define PIXEL_SUM 0x47
#define PIXEL_DATA 0x48
#define REG_SHUTTER_UPPER 0x49
#define REG_SHUTTER_LOWER 0x4A
#define REG_FRAME_PERIOD 0x4B
// #define REG_REVISION_ID 0x01
// #define REG_MOTION 0x02
// #define REG_DATA_OUT_LOWER 0x0C
// #define REG_DATA_OUT_UPPER 0x0D
// #define REG_FRAME_PERIOD_LOWER 0x10
// #define REG_FRAME_PERIOD_UPPER 0x11
int dumpWidth = 324; // Number of pixels to read for each frame.
byte frame[324];
void setup() {
Serial.begin(115200);
reset();
byte productId = readRegister(REG_PRODUCT_ID);
Serial.print("ProductId ");
Serial.println(productId, HEX);
byte config = readRegister(REG_CONFIG_BITS);
config |= B00100001; // Don't sleep (LED always powered on).
writeRegister(REG_CONFIG_BITS, config);
}
void loop() {
// Allows to set the dump window by sending the number of lines to read via the serial port.
if(Serial.available() > 0) {
dumpWidth = 18 * Serial.read();
dumpWidth = constrain(dumpWidth, 0, 324);
}
// readRegister(REG_MOTION); // Freezes DX and DY until they are read or MOTION is read again.
char dx = readRegister(REG_DELTA_X);
char dy = readRegister(REG_DELTA_Y);
Serial.print("DELTA:");
Serial.print(dx, DEC);
Serial.print(" ");
Serial.println(dy, DEC);
if( dumpWidth > 0 )
dumpFrame();
}
void dumpFrame() {
byte config = readRegister(REG_CONFIG_BITS);
config |= B00000001; // PixDump
writeRegister(REG_CONFIG_BITS, config);
int count = 0;
do {
// byte data = readRegister(REG_DATA_OUT_LOWER);
// if( (data & 0x80) == 0 ) { // Data is valid
frame[count++]; // = data;
}
// }
while (count != dumpWidth);
config = readRegister(REG_CONFIG_BITS);
config &= B11110111;
writeRegister(REG_CONFIG_BITS, config);
Serial.print("FRAME:");
for(int i = 0; i < dumpWidth; i++) {
byte pix = frame[i];
if( pix < 0x10 )
Serial.print("0");
Serial.print(pix, HEX);
}
Serial.println();
}
void reset() {
pinMode(SCLK, OUTPUT);
pinMode(SDIO, INPUT);
// pinMode(PD, OUTPUT);
digitalWrite(SCLK, LOW);
// digitalWrite(PD, HIGH);
delayMicroseconds(1);
// digitalWrite(PD, LOW);
}
byte readRegister(byte address) {
pinMode (SDIO, OUTPUT);
for (byte i=128; i >0 ; i >>= 1) {
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, (address & i) != 0 ? HIGH : LOW);
digitalWrite (SCLK, HIGH);
}
pinMode (SDIO, INPUT);
delayMicroseconds(100); // tHOLD = 100us min.
byte res = 0;
for (byte i=128; i >0 ; i >>= 1) {
digitalWrite (SCLK, LOW);
digitalWrite (SCLK, HIGH);
if( digitalRead (SDIO) == HIGH )
res |= i;
}
return res;
}
void writeRegister(byte address, byte data) {
address |= 0x80; // MSB indicates write mode.
pinMode (SDIO, OUTPUT);
for (byte i = 128; i > 0 ; i >>= 1) {
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, (address & i) != 0 ? HIGH : LOW);
digitalWrite (SCLK, HIGH);
}
for (byte i = 128; i > 0 ; i >>= 1) {
digitalWrite (SCLK, LOW);
digitalWrite (SDIO, (data & i) != 0 ? HIGH : LOW);
digitalWrite (SCLK, HIGH);
}
delayMicroseconds(100); // tSWW, tSWR = 100us min.
}
Vorsicht, der Code lässt sich zwar kompilieren, funktioniert aber noch nicht.
Leider blicke ich bei dem vielen Englisch und einigen Befehlen noch nicht ganz durch. Soviel ich verstanden habe müssen noch die Timingzeiten und Reihenfolge der Bits ans Datenblatt angepasst werden, damit ich den 1620 richtig begrüßen und fragen kann wie´s den Pixeln so geht.
Kann mir da jemand weiterhelfen?