PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SFR08 im ANN-mode



boeser_bube
20.11.2008, 23:32
Hallo,

ich verwende den Code von RN (https://www.roboternetz.de/wissen/index.php/SRF08_mit_avr-gcc) um mit dem Sensor zu kommunizieren.

Nun habe ich ihn leicht geändert, um die Werte im ANN-Modus zu bekommen:

void SRF08_messung_starten(void)
{
if(srf08_ready())
{
i2c_start(SRF08_adress+I2C_WRITE);
i2c_write(0x01);//Gainregister
i2c_write(SRF08_gainvalue);//Gain setzen
i2c_write(SRF08_rangevalue);

i2c_rep_start(SRF08_adress+I2C_WRITE);
i2c_write(0x00);//Befehlsregister wählen
i2c_write(0x54);//Messung (ANN) starten, Ergebnis in cm

i2c_stop();
}
}

Wenn ich die Daten auslesen möchte, bekomme ich mit diesem Code zwar die richtigen Werte vom Register 0x02 und 0x03, jedoch die "ANN"-Werte ab (einschließlich) Register 0x04 sind immer 0xFF. Egal wie nah das Objekt ist:

void srf08_auslesen(void)
{
if(srf08_ready())
{
i2c_start(SRF08_adress+I2C_WRITE);
i2c_write(0x01);//Ergebnisregister Lichtsensor wählen
i2c_rep_start(SRF08_adress+I2C_READ);

SRF08_light= i2c_readAck();
SRF08_messwert = ((i2c_readAck())<<8); //highbyte
SRF08_messwert += (i2c_readNak()); //lowbyte
SRF08_ANN_value[0] = i2c_readAck(); // reg 0x04 !!! hier steht leider immer 0xFF. Auch wenn der Abstand < 35cm ist
SRF08_ANN_value[1] = i2c_readAck(); // reg 0x05
SRF08_ANN_value[2] = i2c_readAck(); // reg 0x06
SRF08_ANN_value[3] = i2c_readAck(); // reg 0x07
SRF08_ANN_value[4] = i2c_readAck(); // reg 0x08
SRF08_ANN_value[5] = i2c_readAck(); // reg 0x09
SRF08_ANN_value[6] = i2c_readAck(); // reg 0x10
SRF08_ANN_value[7] = i2c_readAck(); // reg 0x11
SRF08_ANN_value[8] = i2c_readAck(); // reg 0x12
SRF08_ANN_value[9] = i2c_readAck(); // reg 0x13
SRF08_ANN_value[10] = i2c_readAck();// reg 0x14
SRF08_ANN_value[11] = i2c_readAck();// reg 0x15
SRF08_ANN_value[12] = i2c_readAck();// reg 0x16
SRF08_ANN_value[13] = i2c_readAck();// reg 0x17
SRF08_ANN_value[14] = i2c_readAck();// reg 0x18
SRF08_ANN_value[15] = i2c_readAck();// reg 0x19
SRF08_ANN_value[16] = i2c_readAck();// reg 0x20
SRF08_ANN_value[17] = i2c_readAck();// reg 0x21
i2c_stop();
}
}

Wenn ich nachfolgenden Code verwende, bekomme ich zwar (beim ersten Durchlauf) die richtigen Werte, jedoch macht der Sensor keine weitere Messungen mehr bis der Mikrocontroller resetet wurde:

void srf08_auslesen(void)
{
if(srf08_ready())
{
i2c_start(SRF08_adress+I2C_WRITE);
i2c_write(0x01);//Ergebnisregister Lichtsensor wählen
i2c_rep_start(SRF08_adress+I2C_READ);

SRF08_light= i2c_readAck();
// SRF08_messwert = ((i2c_readAck())<<8); //highbyte // auskommentiert
// SRF08_messwert += (i2c_readNak()); //lowbyte // auskommentiert
SRF08_ANN_value[0] = i2c_readAck(); // reg 0x02 !!! hier steht das highbyte
SRF08_ANN_value[1] = i2c_readAck(); // reg 0x03 !!! hier steht das lowbyte
SRF08_ANN_value[2] = i2c_readAck(); // reg 0x04 !!! hier steht richtiger weise 0, wenn Abstand < 35cm ist
SRF08_ANN_value[3] = i2c_readAck(); // reg 0x05
SRF08_ANN_value[4] = i2c_readAck(); // reg 0x06
SRF08_ANN_value[5] = i2c_readAck(); // reg 0x07
SRF08_ANN_value[6] = i2c_readAck(); // reg 0x08
SRF08_ANN_value[7] = i2c_readAck(); // reg 0x09
SRF08_ANN_value[8] = i2c_readAck(); // reg 0x10
SRF08_ANN_value[9] = i2c_readAck(); // reg 0x11
SRF08_ANN_value[10] = i2c_readAck();// reg 0x12
SRF08_ANN_value[11] = i2c_readAck();// reg 0x13
SRF08_ANN_value[12] = i2c_readAck();// reg 0x14
SRF08_ANN_value[13] = i2c_readAck();// reg 0x15
SRF08_ANN_value[14] = i2c_readAck();// reg 0x16
SRF08_ANN_value[15] = i2c_readAck();// reg 0x17
SRF08_ANN_value[16] = i2c_readAck();// reg 0x18
SRF08_ANN_value[17] = i2c_readAck();// reg 0x19
i2c_stop();
}
}

Was ich nicht verstehe ist, dass die beiden Varianten eigentlich die absolut gleichen Ergebnisse liefern müssten. Keine von beide ist für eine durchgehende Messung verwendbar.
Ich bin nun schon sehr lange am rum rätsel und hoffe ihr könnt mir helfen.

uwegw
21.11.2008, 08:26
Du musst bei der letzen Auslesung das i2c_readNak() verwenden. Das ist das Zeichen für den Sensor, dass du dann fertig mit dem Auslesen bist. Also bei dem SRF08_messwert ein i2c_readAck() verwenden, und ganz am Schluss bei SRF08_ANN_value[17] ein i2c_readNak().

[der Code ist von mir. Ich habe bis jetzt aber noch nie den ANN-Mode oder die Mehrfachechos genutzt... Funktioniert ansonsten alles? Ich bin für Kommentare und Rückmeldungen dankbar!]

boeser_bube
21.11.2008, 09:56
Achso, dann habe ich das wohl falsch verstanden. Ich werde es gleich mal ausprobieren, wenn ich wieder daheim bin :)
Ich dachte das i2c_readNak() dient einfach nur dazu dem uC zu sagen, dass er das ACK-Bit vom Sender ignorieren kann?

Ich habe mir überlegt bei den TWI-Funktionen zusätzlich noch eine Art "time_out_variable" hinzu zu fügen die immer dann hochgezählt wird, wenn der uC in einer der while-Schleifen warten muss. Somit möchte ich verhindern, dass sich das Programm aufhängt und dafür eine Fehlermeldung liefert. Glaubst du dass das ok ist? Wenn du damit einverstanden bist, dann könnte ich den ANN-Code hier einstellen, wenn er fertig ist.


zu deiner Frage:
Soweit bin ich eigentlich ganz zufrieden mit dem ANN-Mode. Was ich allerdings schade finde ist, dass in den Registern ab 0x04 nicht die Entfernungen zu weiteren Objekten stehen, sondern einfach nur 0xFF wenn er etwas "sieht". Aber anscheinend sieht er so gut wie immer etwas und somit ist diese Info auch nicht mehr sooo nützlich für mich. Ich vermute es liegt einfach daran, weil der Winkel für die Messung so groß ist und eine Wand neben dem Sensor auch schon also Objekt vor ihm erkannt wird.
Meine maximale Entfernung war somit nur ca 80cm. Dann ist leider auch schon Schluss.

uwegw
21.11.2008, 18:05
Soweit bin ich eigentlich ganz zufrieden mit dem ANN-Mode. Was ich allerdings schade finde ist, dass in den Registern ab 0x04 nicht die Entfernungen zu weiteren Objekten stehen, sondern einfach nur 0xFF wenn er etwas "sieht".
Das ist doch genau der Sinn des Modus: es wird nur angezeigt, ob in einem bestimmten Entfernungsbereich etwas vorhanden ist oder nicht!
Wenn du die Entfernungen zu allen Hindernissen brauchst, musst du den normalen Modus verwenden und die Register als 16bit-Werte auswerten. Dann bekommst du bis zu 17 Entfernungen raus.