PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Srf02 an Rp6



Morpheus1997
16.08.2012, 19:37
Hey Leute. Ich habe ein Problem: Ich möchte ein Programm schreiben, welches mit Hilfe des Srf02-Ultraschallsensors die Entfernung vom Rp6 zu einem erkannten Hindernis ermittelt. Doch wenn ich das Programm starte, stürzt der Rp6 ab. Der Sensor ist übrigens an der M32 Platine angeschlossen. Kann mir vielleicht jemand helfen, hat(te) vielleicht jemand ein ähnliches Problem oder hat 'gar ein vollfunktionstüchtiges Programm, welches das "macht, was ich will"?
Vielen Dank im Vorraus. LG Marcel

#include "RP6I2CmasterTWI.h"#include "RP6ControlLib.h"


// The measured distance:
uint16_t gemesseneEntfernungSRF;




/************************************************** ***************************/
// SRF02:


// The I2C slave address of the SRF ranger - default is 0xE0, but you can
// change this when you use the function changeSRFAddr() below.
// Here we changed it to 0xE0 already:
#define SRF_ADR 0xE0






/************************************************** ***************************/
// I2C Event handlers:




// I2C Data request IDs:
#define MEASURE_US_LOW 110
#define MEASURE_US_HIGH 111






// Nur Messen wenn der Sensor still steht.
uint8_t messungOkay=0;


uint16_t SRF02_zwischenergebnis=0;
uint16_t SRF02_Dist=0;
uint16_t zaehler=0;




int main (void)
{





void initSRF02(void){
startStopwatch7();
messungOkay=1;
}
void stopSRF02(void){
stopStopwatch7();
messungOkay=0;
}






void task_SRF02(void)
{
if(messungOkay>=1){
static uint8_t measureInProgress = false;
if(!measureInProgress) // Start measurement ONCE only
{
if(TWI_operation == I2CTWI_NO_OPERATION) // If there is no request in progress...
{
I2CTWI_transmit2Bytes(SRF_ADR, 0, 81); // 81 means return distance in cm
measureInProgress = true;
setStopwatch7(0);
}
}
else if(getStopwatch7() > 70) // 120ms (measurement delay)
{
I2CTWI_transmitByte(SRF_ADR, 2); // range register high byte
I2CTWI_requestDataFromDevice(SRF_ADR, MEASURE_US_HIGH, 1); // receive it
measureInProgress = false; // allow to start new measurement
setStopwatch7(0);

// Die Messung mitteln
zaehler++;
SRF02_zwischenergebnis=SRF02_zwischenergebnis+geme sseneEntfernungSRF;
}

if(zaehler>=3){
SRF02_Dist=SRF02_zwischenergebnis/zaehler;
zaehler=0;
SRF02_zwischenergebnis=0;
}

}else{
SRF02_Dist=-1;

}


}






while (true){
task_SRF02();
initSRF02();
writeString("Srf02");
writeInteger(SRF02_Dist,DEC);


}
}

Dirk
16.08.2012, 20:02
@Morpheus1997:
Das Beispiel "RP6Base_I2CMaster_03" der RP6 Demos müßte funktionieren (Fragmente daraus verwendest du ja schon!).
Du müßtest das nur auf die M32 umschreiben.

Morpheus1997
16.08.2012, 20:30
Alles klar. Ich habe das RP6Base_I2CMaster_03 Programm jetzt für die M32 umgeändert. Doch nun gibt das Programm am Terminal
I2C ERROR --> TWI STATE IS: 0x20

I2C ERROR --> TWI STATE IS: 0x48


I2C ERROR --> TWI STATE IS: 0x20
aus.
Woran liegt das?

RolfD
16.08.2012, 21:32
"Abstürzen" ist wohl etwas übertrieben... diese TWI Errors besagen das was in der Kommunikation nicht stimmt. Was - läst sich da nicht so genau sagen.
Als Ursachen kommt verschiedenes in Betracht - mir fällt auf das du z.B. I2CTWI_initMaster nicht aufrufst. Somit wird das Bus-Speed-Register nicht gesetzt. Eine falsche Zieladresse wäre aber auch möglich.... oder Verdrahtungs- bzw. Kabelsalat... weis der Geier.
TW_MR_SLA_NACK und TW_MT_SLA_NACK ( 0x20, 0x48 , man beachte das T für Transmit und R für Receive, so oder ähnlich in der .h definiert) sind "unerwartete" Nack Events im TWI Mastermodul... da passiert also was auf dem Bus (oder eben nicht), was nicht passieren soll... allerdings fängt die RP6Lib dieses auch nicht ab und es kommt eben zu diesen "Fehlerketten" im Log. "unerwartet" in so fern, das der TWI Treiber so straight geschrieben ist, das er auf bestimmte Situationen nich reagieren kann und nur stur ein bestimmtes Schema ab arbeitet, was die meisten.. aber eben auch nicht alle Devices können. Quasi eine Minimalversion. TW_MT_SLA_NACK bedeutet z.B. Master sendet und Slave antwortet nicht mit Ack. (wobei das quasi für "Device nicht erreichbar" steht, korrekter Weise bricht man hier die Übertragung schon ab und restauriert den Bus mit STOP bzw. benachrichtigt das aufrufende Programm über "device not found".) Auf die Art kann man sogar ein I2C Bus "durchpingen" wie man es von Netzwerken kennt.. vorausgesetzt man wertet solche Ereignisse auch richtig aus... Es gibt noch ein paar Dinge, die diese TWI Lib nicht kann, die aber Funktionsumfang von I2C/TWI sind... spielt aber hier allgemein und für das spezielle Problem keine gesteigerte Rolle.
Da die TWI Lib nun aber von dem Gerät auch Daten lesen will, was im ersten Anlauf schon nicht angesprochen werden kann, ... und das immer wieder.... ohne jede Fehlerprüfung... *schulterzuck
Gruß Rolf

SlyD
17.08.2012, 10:10
Hallo,




int main (void) {

void initSRF02(void){ }
void stopSRF02(void){ }
void task_SRF02(void) { }

...
}



Das ist schonmal gefährlich.
Auch wenn C solche Spielereien erlaubt wie Funktionen in Funktionen zu deklarieren,
sollte man sowas nicht tun.



allerdings fängt die RP6Lib dieses auch nicht ab

Es gibt einen Handler dafür (void I2C_transmissionError(uint8_t errorState))
wo man darauf reagieren kann wenn man mag.

Wenn so ein Fehler auftritt, dann stimmt meist sowieso was überhaupt nicht mit dem Programm

z.B. sowas:

mir fällt auf das du z.B. I2CTWI_initMaster nicht aufrufst.


;-)

Da viele Ressourcen in aufwändige Fehlerbehandlung zu investieren ist nicht sonderlich sinnvoll.
Man könnte ggf. alle weiteren Übertragungen beim ersten Fehler anhalten... dazu einfach
ein while(true); in den error Handler setzen :-)

MfG,
SlyD

Morpheus1997
19.08.2012, 17:48
Ah super, jetzt klappt es :)