PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RP6 Kompass



Berghuhn
29.11.2011, 06:12
Hallo,
ich würde gerne einen Kompass an meinem RP6 anbringen.
Nun wollte ich mal fragen welche Kompasse hier empfohlen werden.

Wie axel88 in diesem Beitrag ( https://www.roboternetz.de/community/threads/37180-Kompass-f%C3%BCr-RP6 ) schon gesagt hat ist es doch relativ "doof" 40€ für so einen 2D Kompass auszugeben.
Könnte man soetwas auch mit dem KMZ51 selber bauen?
Wenn ja wie ^^? Und ist eher ein 2D oder eher ein 3D Kompass zu empfehlen?
Da ich gehört habe dass der 2D Kompass paralell zur erdoberfläche verlaufen sollte, d.h. dass wenn er gekippt wird werden die Messungen ungenau oder gar falsch.

Danke schonmal im vorraus :D

RP6conrad
29.11.2011, 20:09
Ein selbst gebasteld kompass met den NXP KMZ-Sensor : https://www.roboternetz.de/community/threads/35417-Analogen-kompassensor-met-NXP-KMZ10C?highlight=MAGNET

Berghuhn
29.11.2011, 21:26
Okay sieht ja ganz interessant aus.

Gibt es eigentlich Vorteile für einen 3D kompass gegenüber einem 2D?

Wenn ja wäre etwas wie dieser hier:

http://www.pololu.com/catalog/product/1250

gut?

RP6conrad
30.11.2011, 19:36
Ein 3D kompass gibts in alle Lagen eine Richtung von Feldlinien. Ist damit von Forteil für heli. flugzeug oder quadrocopter. Ein 2D kompass kann das nicht. Grosste Nachteil von ein kompass ist die Abbiegung von das Magnetfeld durch Motoren, Stahl, Gebaude und so mehr. Innen ist dadurch das Signal meistens nicht brauchbar oder stark gestort. Aussen gehts es meistens besser.

Berghuhn
30.11.2011, 21:36
Ja, dass die Motoren stören habe ich auch schon oft gelesen. Deshalb sollte man den Kompass 20 - 30 cm davon weg Montireren. Auch das abschirmen der Motoren durch Mu-Metall soll helfen. Ich werde mir dann wohl einen 3D Kompass zulegen da mein RP6 zum Teil auch in Schräglage o.a. fährt bzw. sich befindet.
Wie Steuert man dann so einen Kompass genau an?

Berghuhn
01.12.2011, 11:14
Also ich habe einen Beispielcode gefunden.
mal angenommen ich würde den LSM303DLH nehmen, bräuchte ich doch einen I²O port richtig?
Die M32 Erweiterungsplatine, die ich bei mir als Master verwende, hat aber keinen freien I²O Port frei. Müsste ich das Modul dann an die Base anschließen oder könnte ich noch einen anderen Port dafür verwenden (z.B. ADC o.ä.)?

RP6conrad
01.12.2011, 18:55
Die RP6 Base hat eine I2C Anschluss (ist in die Stecker nach den M32, I2C bus), so in Prinzip kansst du diesen Sensor mit die Base verbinden. I2C benotigt SDA, SCL und GND. Moglich muss du auch noch 2 pull-up Wiederstande nach die 5V anschliessen (nicht notig wen M32 gebraucht wird).
Ich glaube das in die Lib von M32 schon I2C Functionen forgesehen sein, wodas der Base dan Master ist.
Wen die M32 genutzt werd, ist diese der Master, und die Base der Slave. Der LM303DLH ist eine 3 V Sensor, aber die Levelshifter sind auf die Platine forgesehen.

Berghuhn
01.12.2011, 21:24
Also heißt das ich könnte ohne Probleme den sensor an den I²O port der Base anschließen? ^^

RP6conrad
02.12.2011, 21:50
Der I2C Bus signalen sind auf verschiedene Pos. auf die Base platine forhanden : XBUS1, pin 10=SCL, pin 12=SDA, XBUS2,pin 10=SCL, pin 12=SDA,und auch an 2 Stellen (Lotpunkten) mit die name YSCL1, YSDA1 und YSCL2, YSDA2. Die pull-up Wierderstande sind schon forgesehen auf die Base (4.7 k). M32 und andere I2C Sensoren konnen gleichzeitig auf die Bus angeschlosschen werden. Al das konnen sie auch finden auf die Schaltplane von Base und M32.
M32 soll dan master sein. I2C Beispielen sind schon in die "Examples" anzusehen.

Berghuhn
11.12.2011, 21:24
Also muss ich:

Kompass XBUS2
VIN | YVDD1
GND | YGND1
SCL | SCL
SDA | SDA
INT1 | INT1
INT2 | INT2


anschließen? Die pull-up Wierderstande bruach ich ja wiegesagt nicht da sie schon vorhanden sind.

RP6conrad
12.12.2011, 18:12
INT1 und INT2 muss du nur verdrahten wen sie die auch benutzen wollen : das Kompass hat die moglichkeit um ein INT zu generieren bei programmierte Bedingungen. Es kann auch sein das diese INT1 schon verwendet ist für die Schnittstelle M32 - Base. Schau mal nach in die Schaltplane.

Berghuhn
12.12.2011, 18:23
Der XBUS2 sollte doch eigentlich unverwendet sein, da der XBUS1 für M32 - Base verwendet wird und ich noch keine weiter Platine an der M32 Platine angeschlossen hab.

RP6conrad
12.12.2011, 18:43
XBUS1 und XBUS2 sind parallel geschaltet : alle pinnen sind durchgeschaltet (siehe Schaltplan). INT1 ist verbunden met Base (pin PA4 auf Mega32) und auf M32 (pin PD2). Sie soll ich nicht verwenden, da die eigenlich forgesehen ist für die Schnittstelle M32-Base. INT2 und INT3 (PB2, PD3) sind nur verbunden mit den M32, die kannst du nach Bedarf verwenden.

Berghuhn
12.12.2011, 20:26
Achso okay,
Dann werd ich mein glück in den nächsten Tagen mal versuchen und evtl auch Bilder posten ^^
danke schonmal für eure Hilfe

Berghuhn
16.12.2011, 11:48
So,
Ich habe den Kompass mal angeschlossen und zwar an den XBUS2.
Habe ganz normal SDA an SDA, SCL an SCL und GND bzw. VDD an GND bzw. VDD angeschlossen.
Nun klappt das bis jetzt nur mit der Programmierung nicht so wie es soll.

Diesen Code:



void i2c_start(void) {
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // send start condition

while (!(TWCR & (1 << TWINT)));

}

void i2c_write_byte(char byte) {
TWDR = byte;
TWCR = (1 << TWINT) | (1 << TWEN); // start address transmission
while (!(TWCR & (1 << TWINT)));
}

char i2c_read_byte(void) {
TWCR = (1 << TWINT) | (1 << TWEA) | (1 << TWEN); // start data reception, transmit ACK
while (!(TWCR & (1 << TWINT)));
return TWDR;
}

char i2c_read_last_byte(void) {
TWCR = (1 << TWINT) | (1 << TWEN); // start data reception
while (!(TWCR & (1 << TWINT)));
return TWDR;
}

void i2c_stop(void) {
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); // send stop condition
}


habe ich ganz einfach aus der compass.c (dem Beispiel) entnommen.
Nun hängt sich der RP6 bei:


DDRC = 0;
PORTC = (1 << PC1) | (1 << PC0); // SDA | SCL
TWSR = 0;
TWBR = 17;

i2c_start();
i2c_write_byte(0x3C);
i2c_write_byte(0x02);
i2c_write_byte(0x00); // hier.....
i2c_stop();


einfach auf.
Als ich diese Zeile einfach einmal auskommentiert hab, hat er sich eine Zeile davor aufgehängt.
Bei der aktivierung des Beschleunigungssensors bleibt er übrigens auch hängen.

Weiß jemand wieso? Bzw. was daran falsch ist? Habe ich evtl etwas falsch angeschlossen?

RP6conrad
16.12.2011, 18:17
Normalerweise programmieren sie so etwas in der 'Main' Schleife. Al sie Functionen sind programmiert in die lib von RP6, die muss du nicht neu einprogrammieren. Wichtig : das I2C Kompass hat eine bestimmte Adresse. Das muss naturlich eingegeben werden : sieht dan so aus : // Define the addresses of our devices - in this simple example we only have
// our PCF8574:
#define PCF8574_8LEDS_ADR 0x70
// With this routine we write the data byte to the PCF8574 port:
I2CTWI_transmitByte(PCF8574_8LEDS_ADR, (~runningLight) );

// We need to invert the bits with "~" because the LEDs are
// switched on when the port is LOW. The PCF8574 can only sink
// up to 25mA of current. It is only able to source about 300µA
// of current. Thus you need to connect the cathode of the LED
// to the ports - in series with a 1K or 2K2 resistor connected to
// VDD.
So wird dan eine Byte nach das I2C Slave gesendet. Gelesen wird dan mit : I2CTWI_requestDataFromDevice(SRF_ADR, MEASURE_US_HIGH, 1);
Ist das Kompass mit der RP6 verbunden, oder mit beide (RP6 /M32).
Welchen compilierfehler hasst du ?

Dirk
16.12.2011, 19:39
@Berghuhn,

hier: https://www.roboternetz.de/community/threads/30830-RP6-Beispiel-Devantech-CMPS03

... gab es schon mal ein Programmbeispiel für den CMPS03.

Berghuhn
17.12.2011, 16:27
Dirk
@Berghuhn,

hier: https://www.roboternetz.de/community/...vantech-CMPS03 (https://www.roboternetz.de/community/threads/30830-RP6-Beispiel-Devantech-CMPS03)

... gab es schon mal ein Programmbeispiel für den CMPS03.



OKay... danke =)
werd das nacher mal ausprobieren ;)




RP6conrad
Normalerweise programmieren sie so etwas in der 'Main' Schleife. Al sie Functionen sind programmiert in die lib von RP6, die muss du nicht neu einprogrammieren. Wichtig : das I2C Kompass hat eine bestimmte Adresse. Das muss naturlich eingegeben werden : sieht dan so aus : // Define the addresses of our devices - in this simple example we only have
// our PCF8574:
#define PCF8574_8LEDS_ADR 0x70
// With this routine we write the data byte to the PCF8574 port:
I2CTWI_transmitByte(PCF8574_8LEDS_ADR, (~runningLight) );

// We need to invert the bits with "~" because the LEDs are
// switched on when the port is LOW. The PCF8574 can only sink
// up to 25mA of current. It is only able to source about 300µA
// of current. Thus you need to connect the cathode of the LED
// to the ports - in series with a 1K or 2K2 resistor connected to
// VDD.
So wird dan eine Byte nach das I2C Slave gesendet. Gelesen wird dan mit : I2CTWI_requestDataFromDevice(SRF_ADR, MEASURE_US_HIGH, 1);
Ist das Kompass mit der RP6 verbunden, oder mit beide (RP6 /M32).
Welchen compilierfehler hasst du ?




Ja ich muss es dann wohl mit Define machen ^^
Nein ich habe keinen Compilierfehler. Es Compiliert alles ganz normal so wie sonst.

Berghuhn
18.12.2011, 18:00
Also,
jetzt habe ich das ganze mal über die defines gemacht:



#ifndef LSM303
#define LSM303

#define ACC_ADDRESS (0x30)
#define MAG_ADDRESS (0x3C)


#define CTRL_REG1_A (0x20)
#define CTRL_REG2_A (0x21)
#define CTRL_REG3_A (0x22)
#define CTRL_REG4_A (0x23)
#define CTRL_REG5_A (0x24)
#define HP_FILTER_RESET_A (0x25)
#define REFERENCE_A (0x26)
#define STATUS_REG_A (0x27)

#define OUT_X_L_A (0x28)
#define OUT_X_H_A (0x29)
#define OUT_Y_L_A (0x2A)
#define OUT_Y_H_A (0x2B)
#define OUT_Z_L_A (0x2C)
#define OUT_Z_H_A (0x2D)

#define INT1_CFG_A (0x30)
#define INT1_SOURCE_A (0x31)
#define INT1_THS_A (0x32)
#define INT1_DURATION_A (0x33)
#define INT2_CFG_A (0x34)
#define INT2_SOURCE_A (0x35)
#define INT2_THS_A (0x36)
#define INT2_DURATION_A (0x37)

#define CRA_REG_M (0x00)
#define CRB_REG_M (0x01)
#define MR_REG_M (0x02)

#define OUT_X_H_M (0x03)
#define OUT_X_L_M (0x04)
#define OUT_Y_H_M (0x05)
#define OUT_Y_L_M (0x06)
#define OUT_Z_H_M (0x07)
#define OUT_Z_L_M (0x08)

#define SR_REG_M (0x09)
#define IRA_REG_M (0x0A)
#define IRB_REG_M (0x0B)
#define IRC_REG_M (0x0C)
//////////////////////////////////////


void LSM303Init()
{


//enable magnetometer
i2c_start();
i2c_write_byte(0x3C); // (MAG_ADDRESS)
i2c_write_byte(0x02); // MR_REG_M
i2c_write_byte(0x00);
i2c_stop();
}
#endif



und in der Main versuche ich dann die Daten so zu lesen:




....

unsigned char Kompass_Data[6];
LSM303Init();

.....

i2c_start();
i2c_write_byte(0x3C);
i2c_write_byte(OUT_X_H_M); // Select register OUT_X_H_M
i2c_start();
i2c_write_byte(0x3D);

Kompass_Data[0] = i2c_read_byte();
Kompass_Data[1] = i2c_read_byte();
Kompass_Data[2] = i2c_read_byte();
Kompass_Data[3] = i2c_read_byte();
Kompass_Data[4] = i2c_read_byte();
Kompass_Data[5] = i2c_read_last_byte();
i2c_stop();




Doch mein Problem hat sich dadurch immer noch nicht gelöst.
er belibt wie davor in dieser Zeile beim ausführen hängen:

i2c_write_byte(0x3C);

Ich habe aber keine Compiler fehler oder ähnliches.

Dirk
18.12.2011, 19:21
@Berghuhn:

Der RP6 bringt ja eine eigene Library (RP6I2CmasterTWI) für die I2C-Kommunikation mit.
Die brauchst du nur einzubinden, wie ich vorgestern in dem Beispiel von 2007 gepostet hatte.

Berghuhn
18.12.2011, 21:39
Oh ja :D ganz vergessen ^^

Habe das ganze mal umgeschrieben, aber ob ich das so:




I2CTWI_transmitByte(0x3D, OUT_X_H_M);
I2CTWI_readBytes(0x3D, ACC_Data, 6);



oder so:



ACC_Data[0] = I2CTWI_readByte(OUT_X_H_M);
ACC_Data[1] = I2CTWI_readByte(OUT_X_L_M);
ACC_Data[2] = I2CTWI_readByte(OUT_Y_H_M);
ACC_Data[3] = I2CTWI_readByte(OUT_Y_L_M);
ACC_Data[4] = I2CTWI_readByte(OUT_Z_H_M);
ACC_Data[5] = I2CTWI_readByte(OUT_Z_L_M);


Es bleibt immer beim lesen hängen... :D
irgend etwas mache ich wohl falsch ^^

RP6conrad
19.12.2011, 16:37
Verwenden sie die M32 als Master ? Die I2C Schnittstelle zwischen M32 und Base functioniert also ? Nach verbinden von das Kompass functioniert noch immer die M32-Base Schnittstelle ? (muss normal so sein). Gibt diese I2C_Transmission_error() immer eine Failure ?

Berghuhn
19.12.2011, 17:19
Ja ich verwende die M32 Platine als Master. Die Kommunikation funktioniert so wie immer, es kommen zumindest auch keine Fehler.

Dirk
19.12.2011, 18:58
@Berghuhn:
Du machst es dir aber echt schwer, indem du alle Ratschläge jeweils nur zu 50% umsetzt und sonst wieder eigene Wege gehst...

Probier doch einfach mal das Beispiel, das ich als Post #17 verlinkt habe, auf der RP6Base aus, so wie es ist. Wenn das funktioniert, ist schonmal die Hardware ok.
Wenn du die M32 anstelle der RP6Base benutzen willst, müßte die Demo nur leicht angepaßt werden.

RP6conrad
19.12.2011, 19:03
Verwenden sie fur Lesen und Schreiben ein anders Adress ? Aus den Datasheet :
For magnetic sensor, the default (factory) 7-bit slave address is 0011110b(0x3C) for write operations, or 00111101b (0x3D) for read operations.
Moglich ist das schon in die I2Clib forgesehen, muss du mal nachshauen.

Berghuhn
21.12.2011, 22:04
So ich habe wie empfohlen den Kompass nun erstmal an die Base angeschlossen.

Hier mal mein Code (testweise nur für X Werte):




void LSM303Init()
{
I2CTWI_transmitByte(MAG_ADDRESS, 0x3C);
I2CTWI_transmitByte(MAG_ADDRESS, 0x02);
I2CTWI_transmitByte(MAG_ADDRESS, 0x00);
}

int main(void)
{
initRobotBase();

I2CTWI_initMaster(400); // 400kHz

I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError);

setLEDs(0b111111);
mSleep(500);
setLEDs(0b000000);

powerON();

LSM303Init();

PORTC &=~SCL;
PORTC &=~SDA;
DDRC &=~SDA;
DDRC &=~SCL;

unsigned char ACC_Data[6];


while(true)
{
task_I2CTWI(); // Call I2C Management routine
task_RP6System();

I2CTWI_transmitByte(MAG_ADDRESS, 0x3C);
I2CTWI_transmitByte(MAG_ADDRESS, OUT_X_H_M);

ACC_Data[0] = I2CTWI_readByte(0x3D);

I2CTWI_transmitByte(MAG_ADDRESS, 0x3C);
I2CTWI_transmitByte(MAG_ADDRESS, OUT_X_L_M);

ACC_Data[1] = I2CTWI_readByte(0x3D);

writeString_P("--------------------------- \n");
writeString_P("X High: \n");
writeIntegerLength(ACC_Data[0], DEC, 10);
writeString_P("\nX Low: \n");
writeIntegerLength(ACC_Data[1], DEC, 10);
writeString_P("\n--------------------------- \n");

mSleep(5000);

}


So das ganze funktioniert nun schonmal (zumindest bekommen ich erste Werte :D).
für X High:
0000000000

X Low:
0000000032

Egal wie der Kompass geneigt ist es kommen immer die selben. (Bei Y Werten kommen ebenfalls die selben daten wie bei den x Werten)

Dirk
22.12.2011, 18:45
Dirk schrieb:

Probier doch einfach mal das Beispiel, das ich als Post #17 verlinkt habe, auf der RP6Base aus, so wie es ist.

Berghuhn
30.01.2012, 21:33
Da ich in letzter Zeit etwas viel zu tun hatte kann ich nun endlich die Arbeit mit dem Kompass fortsetzen :D.
Ich habe das Beispiel so wie es ist einfach mal so übernommen und die Speicheradressen angepasst.
Nun bekomme ich in unregelmäßigen abständen folgende Werte:

819.2 Grad
003.2 Grad
000.0 Grad

immerhin nicht immer das gleiche aber wirklich Sinn ergibt das ganze noch nicht https://www.roboternetz.de/phpBB2/images/smiles/icon_biggrin.gif

Berghuhn
06.02.2012, 06:12
Edit: Okay die Werte kommen doch in einem regelmäßigen Abstand. Kann es sein, dass der Kompass defekt ist?

RP6conrad
06.02.2012, 19:38
Was sind die Register Werte die du auslest ? Kann es sein das die Berechnung nach Graden nicht stimmt ?

Berghuhn
06.02.2012, 21:32
Dass die Berechnung nach Graden nicht stimmt, kann gut sein. Aber es müssten doch trozdem verschiedene Werte kommen wenn ich den Kompass nieige/kippe.

SlyD
06.02.2012, 22:03
Kompass wurde kalibriert?
s. CMPS Anleitung

Berghuhn
07.02.2012, 21:24
Kompass (http://www.robotikhardware.de/download/cmps03kompass.pdf) wurde kalibriert?
s. CMPS Anleitung

ouu :D
Ja das hab ich vergessen ^^ werd ich dann mal so schnell wie möglich machen.

Berghuhn
25.02.2012, 01:58
@SlyD: Ich habe den LSM303DLH und nicht den CMPS ^^


Also ich habe den Kompass wie in diesem beispiel Kalibriert:


// Returns a set of acceleration and raw magnetic readings from the cmp01a.
void read_data_raw(vector *a, vector *m)
{
// read accelerometer values
i2c_start();
i2c_write_byte(0x30); // write acc
i2c_write_byte(0xa8); // OUT_X_L_A, MSB set to enable auto-increment
i2c_start(); // repeated start
i2c_write_byte(0x31); // read acc
unsigned char axl = i2c_read_byte();
unsigned char axh = i2c_read_byte();
unsigned char ayl = i2c_read_byte();
unsigned char ayh = i2c_read_byte();
unsigned char azl = i2c_read_byte();
unsigned char azh = i2c_read_last_byte();
i2c_stop();

// read magnetometer values
i2c_start();
i2c_write_byte(0x3C); // write mag
i2c_write_byte(0x03); // OUTXH_M
i2c_start(); // repeated start
i2c_write_byte(0x3D); // read mag
unsigned char mxh = i2c_read_byte();
unsigned char mxl = i2c_read_byte();
unsigned char myh = i2c_read_byte();
unsigned char myl = i2c_read_byte();
unsigned char mzh = i2c_read_byte();
unsigned char mzl = i2c_read_last_byte();
i2c_stop();

a->x = axh << 8 | axl;
a->y = ayh << 8 | ayl;
a->z = azh << 8 | azl;
m->x = mxh << 8 | mxl;
m->y = myh << 8 | myl;
m->z = mzh << 8 | mzl;
}

// Returns a set of acceleration and adjusted magnetic readings from the cmp01a.
void read_data(vector *a, vector *m)
{
read_data_raw(a, m);

// shift and scale
m->x = (m->x - m_min.x) / (m_max.x - m_min.x) * 2 - 1.0;
m->y = (m->y - m_min.y) / (m_max.y - m_min.y) * 2 - 1.0;
m->z = (m->z - m_min.z) / (m_max.z - m_min.z) * 2 - 1.0;
}

...

read_data_raw(&a, &m);
if (m.x < cal_m_min.x) cal_m_min.x = m.x
if (m.x > cal_m_max.x) cal_m_max.x = m.x;
if (m.y < cal_m_min.y) cal_m_min.y = m.y;
if (m.y > cal_m_max.y) cal_m_max.y = m.y;
if (m.z < cal_m_min.z) cal_m_min.z = m.z;
if (m.z > cal_m_max.z) cal_m_max.z = m.z;


Das Problem bei dieser Methode ist, dass ich zum Teil falsche Werte schon beim lesen der "raw" daten wirre Sachen wie 0 oder so bekomme. Daher bringt die Kalibrierung nicht wirklich etwas.
Nach dem Kalibrieren verwende ich natürlich die read_data Methode sonst würde das Kalibrieren nichts bringen.

SlyD
25.02.2012, 10:53
Hallo,

Wo kalibrierst Du den Kompass?
Auf dem RP6 oder irgendwo weit daneben?
(die Motoren erzeugen ein Magnetfeld - kann ja sein das Du den Kompass zu nah dran hast... )

Das Teil ist ja 3.3V also 3.3V<->5V Levelshifter hast Du drin bzw. sind auf der fertigen Platine die Du verwendest?


MfG,
SlyD

Berghuhn
25.02.2012, 11:13
Hallo,

Die sind schon auf der Platine genau so wie die Pull-Up Wiederstände.
Der Kompass ist etwa 11-12 cm über der RP6 Platine und die Motoren steuere ich nicht an, gerade wegen dem Magnetfeld.

MFG,
Berghuhn

Berghuhn
27.02.2012, 15:18
Also ich habe einen Rundungsfehler gefunden und bekomme nun folgende Werte:

x: 130.15
y: 211.51
z: 154.95

diese verändern sich aber wie zuvor nicht.

MfG Berghuhn

Chypsylon
27.02.2012, 15:49
(gelöscht)

Berghuhn
27.02.2012, 21:20
Nur mal so nebenbei eine Frage.
Wir sprechen schon von den auf dem Bild Grün markierten I²C Port, oder sind die Ports für z.B. die Experemetierplatine gemeint (XBUS)?

http://imageshack.us/photo/my-images/716/rp6u.jpg/

Die Grün markierten spreche ich trozdem über PC1 und PC0 an richtig?

SlyD
28.02.2012, 12:08
Hallo,

der I2C Bus ist natürlich mit allen Pads verbunden die auf dem Mainboard mit SCL und SDA beschriftet sind.
Pullup Widerstände sind schon auf dem Mainboard vorhanden (4K7).

Beim anderen Problem kann ich leider wenig helfen da ich diesen Typ Kompass noch nie verwendet habe.

Funktioniert der I2C Bus denn allgemein noch problemlos?
Also mal mit RP6Base_I2CSlave und dem RP6-M32 mit einem der normalen Beispielprogramme laufen lassen...

MfG,
SlyD

Berghuhn
28.02.2012, 13:04
Ja der I2C Bus funktioniert noch.

Also die Kommunikation von der M32 Platine und der Base klappt einwandfrei.

Schade, ich vermute dass ich etwas beim Abrufen falsch mache aber ich habe leide keine Ahnung was.

Mfg Berghuhn

Berghuhn
28.02.2012, 21:52
Hallo,

ich hatte nun endlich, nach langem rumprobieren einen Durchbruch!

Ich habe den Fehler gefunden, an dem es lag, dass immer nur ein Wert raus kam.



//bisherige Kompassadresse:
//#define MAG_ADDRESS (0x3C)


//funktionierende Kompassadresse:
#define MAG_ADDRESS (0x3C >> 1)



Ich bin eigentlich aus zufall darauf gekommen, bin aber daraus noch nicht schlau geworden.
Wenn mir dass noch einer erklären kann wäre echt super :D .

MfG,
Berghuhn

SlyD
29.02.2012, 12:10
Die I2C Adressen sind 7 Bit lang - das unterste bit wird für lesen/schreiben verwendet.

Berghuhn
29.02.2012, 15:51
Achso, okay dann ergibt das sogar Sinn ^^.

Jetzt hätte ich noch eine frage zum Kalibrieren. Wie genau mache ich das?
Lege ich dabei einfach einen min, max Vektor fest?
Oder muss ich es schon in das register des LSM303DLH eintragen?
Wenn ja in welches?

Berghuhn
24.04.2012, 21:59
Nach langer Zeit habe ich nun endlich wieder Zeit gefunden meinen RP6 auszugraben und daran weiter zu machen ^^.
der Kompass ist nur auf der M32 Platine angeschlossen und dass auslesen funktioniert fast ohne probleme ;D.

Mein Problem ist, dass beim auslesen immer folgender Error kommt:
I2C ERROR - TWI STATE: 0x20

dieser wird durch folgenden Code verursacht:




void read_data_raw(vector *a, vector *m)
{

// read accelerometer values
I2CTWI_transmitByte(0x30, 0x30);
I2CTWI_transmitByte(0x30, OUT_X_L_A);

unsigned char axl = I2CTWI_readByte(0x31);

I2CTWI_transmitByte(0x30, OUT_X_H_A);
unsigned char axh = I2CTWI_readByte(0x31);

I2CTWI_transmitByte(0x30, OUT_Y_L_A);
unsigned char ayl = I2CTWI_readByte(0x31);

I2CTWI_transmitByte(0x30, OUT_Y_H_A);
unsigned char ayh = I2CTWI_readByte(0x31);

I2CTWI_transmitByte(0x30, OUT_Z_L_A);
unsigned char azl = I2CTWI_readByte(0x31);

I2CTWI_transmitByte(0x30, OUT_Z_H_A);
unsigned char azh = I2CTWI_readByte(0x31);

// read magnetometer values

I2CTWI_transmitByte(MAG_ADDRESS, 0x3C);
I2CTWI_transmitByte(MAG_ADDRESS, OUT_X_H_M);

unsigned char mxh = I2CTWI_readByte(0x3D);


//I2CTWI_transmitByte(MAG_ADDRESS, OUT_X_L_M);
unsigned char mxl = I2CTWI_readByte(0x3D);

//I2CTWI_transmitByte(MAG_ADDRESS, OUT_Y_H_M);
unsigned char myh = I2CTWI_readByte(0x3D);

//I2CTWI_transmitByte(MAG_ADDRESS, OUT_Y_L_M);
unsigned char myl = I2CTWI_readByte(0x3D);

//I2CTWI_transmitByte(MAG_ADDRESS, OUT_Z_H_M);
unsigned char mzh = I2CTWI_readByte(0x3D);

//I2CTWI_transmitByte(MAG_ADDRESS, OUT_Z_L_M);
unsigned char mzl = I2CTWI_readByte(0x3D);


a->x = axh << 8 | axl;
a->y = ayh << 8 | ayl;
a->z = azh << 8 | azl;
m->x = mxh << 8 | mxl;
m->y = myh << 8 | myl;
m->z = mzh << 8 | mzl;

}

//...
// in der main ist noch folgendes:
I2CTWI_initMaster(100); // muss ich diese zahl evtl höher machen?
I2CTWI_setRequestedDataReadyHandler(I2C_requestedD ataReady);
I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError);

DDRC = 0;
PORTC = (1 << PC1) | (1 << PC0); // enable pull-ups on SDA and SCL, respectively


Danke schonmal im vorraus =)

SlyD
25.04.2012, 15:03
Hallo,

was das 0x20 heisst findest Du in der RP6I2CMasterTWI.h aufgelistet dann wirds vermutlich klarer ;-)
(Not-Acknowledge (NACK) received!)

Die Adresse des Sensors ist 0x30 und nicht 0x31.
Die I2C Funktionen kümmern sich selbst ums setzen des Read/Write Bits.

MfG,
SlyD

Berghuhn
08.05.2012, 21:59
Okay dass mit dem 0x20 hat sich geklärt danke =)

Meine Frage wäre nun,
könnte man mit einem 2D Kompass (wie z.B. der CMPS03 wenn er senkrecht hingestellt wird) auch die Inklination messen oder kann man damit nur die Deklination messen?

MfG,
Berghuhn

RolfD
10.05.2012, 02:10
Elektrisch gesehen wird nur eine Feldstärke gemessen und aus welcher Richtung die kommt ist dem Modul recht egal... so lange es seine Lage/Winklel in der Feldlinie feststellen kann. Aber die Inklination misst man ja sinnvollerweise gegen die Pole... was dabei rum kommt wenn man das ganze um 90 Grad dreht.. also entlang der geographischen Breite misst.. keine Ahnung.. aber vermutlich nichts Sinnvolles. Dementsprechend wären Messungen im Bereich von 1 bis 89° bzw. -1 bis -89° Abweichung vom Nordpol mit steigender Abweichung schnell ungenauer. Das sagt mir zumindest die Logik.
LG Rolf