-
dein modul musst du neu kalibrieren. wie das gemacht wird, steht in der anleitung. nimm nicht die i2c sondern die kontaktüberbrückungsmethode zum kalibrieren.
musst ihn nach norden ausrichten und dann die brücke kurz verbinden(druckschalter mini) und dann nach der beschreibung die anderen 3 richtungen. kauf dir ein kompass für 2 euro zum ausrichten.
mfg
-
Bist du dir da sicher, dass ich es an der Kalibration liegt? Wie konnte er es denn überhaupt vergessen? Naja, ich warte mal auf die Antwort von Devantech, und dann seh ich weiter.
Wenn inzwischen andere Ideen auftauchen, bitte nicht für Euch behalten :D
-
Heute hab ich den Kompass neu kalibriert, jetzt kommt immer nur 82 als Ergebnis raus... Langsam weiss ich nicht weiter.
Da ich von Devantech bis jetzt keine Antwort bekommen habe, werde ich das Modul nächste zum Verkäufer zurückbringen, und einen Ersatz anfordern.
-
Hallo
Ich hab auch den CMPS03. Allerdings werte ich das PWM Signal aus. Probier das doch einfach mal, vielleicht funktioniert ja einfach die I2C Sache nicht richtig.
-
Daz bräuchte ich einen Timer, und die hab ich schon alle am Proz verbraucht. Ansonsten wäre das ein Ansatz.
Und die I2C Kommunikation funktioniert ja...
Wie wertest du PWM aus? Signal auf InterruptPin, und die Zeit zwischen zwei IRQ-s messen?
-
@pongi ja, so mach ich es
-
@pongi:
Wenn ich diesen Thread lese, gäbe es viele Möglichkeiten, warum es bei dir nicht klappt. Angefangen von der Char-Umwandlung bis hin zu anderen Auswertungs- (d.h. Software-) Problemen sind auch andere Fehlerquellen (Anschluß der Hardware, Störungen) nicht auszuschließen.
So kommt es dann, dass alle, die dir helfen wollen, eigentlich nur raten können, was denn da nicht richtig läuft.
Woran liegt's:
1. Du schließt Software-Probleme als Ursache am Anfang schon aus.
2. Du stellst nicht einmal einen Teil deiner Auswertungssoftware hier ein.
3. Viele Lösungsansätze scheitern daran, dass die Anleitung zum CMPS03 nicht komplett gelesen wurde.
4. Logische Verständnisprobleme: Du willst jetzt die (ungenauere) PWM benutzen. Das wird aber nicht klappen, wenn die Kalibrierung die Ursache aller Probleme sein sollte. Dann wird nämlich die PWM auch falsche Infos enthalten.
Also: Wenn Hilfe sinnvoll möglich sein soll, must du möglichst viele Infos hier einstellen. Deine Software wird kein Industriegeheimnis sein und auch von ganz vielen Leuten schon so oder ähnlich umgesetzt worden sein. Also hier einstellen! Dann kann geholfen und nicht nur geraten werden. Auch eine Hardware-Beschreibung hilft immer (z.B. Pullup-Widerstände am Bus?)
Gruß Dirk
-
Hallo,
ich weiss zwar nicht, ob das hilft, aber ich poste mal meinen Code zum auslesen des Moduls hier rein, denn bei mir funktioniert es problemlos. Die Funktion "compass()" liefert den Wert von Register 1.
Code:
unsigned char compass()
{
unsigned char var;
i2c_start(0xC0);
i2c_write(1);
i2c_rep_start(0xC1);
var=i2c_readNak();
i2c_stop();
return var;
};
MfG Mark
-
@p_mork
Meine Funktion sieht genauso aus. Troztdem danke!
@Dirk
1 u 2. Software-Probleme habe ich nicht ausgeschlossen, halte sie aber für unwahrscheinlich, da Werte ankommen. (Siehe aber Code weiter unten)
3. Weiss nicht, woraus du schliesst, dass ich die Anleitung nicht gelesen habe, das hab ich mehrmals ausführlich gemacht (ohne das wende ich mich nie ans Forum).
4. Ich will keine PWM benutzen, es ist nur als Kontrolle dafür gedacht, ob im Compass-Modul was falsch ist, oder die Kommunikation nicht funktioniert. Mir ist es bewusst, dass PWM ungenau ist, es sollte aber auswertbare Werte liefern, die das Problem vielleicht eingrenzt.
5. Pullup Widerstände sind am Bus installiert.
Also nocheimal der Problemablauf:
1. Ohne vorherige Kalibrierung (=Werkseinstellung) konnte ich nur Werte zw. 128 u. 255 mit I2C lesen
2. Das nach der Kalibrierung nur 82 angekommen ist, war ein Softwarefehler gestern. Weiterhin ist Problem 1 erhalten: Werte kommen nur zwischen 128 und 255.
Code:
Code:
#include "uart.h" //aus RN-Wissen AVR-GCC Tutorial
#include "i2cmaster.h" //I2C lib von Peter Fleuy
#include <util/delay.h>
#include <stdlib.h>
#ifndef F_CPU
#define F_CPU 4000000
#endif
#define BAUDRATE 9600
#define CMPS03 0xc0
unsigned char read_compass(unsigned char regadress);
void uart_puts (const char *s);
static inline uint8_t uart_getc_wait();
int main (void){
uint8_t twidata;
char s[3];
uint8_t i;
uart_init();
i2c_init();
twidata='I';
uart_putc(twidata); //Abschluss der Initialisation wird mit einem I in HyperTerminal bestätigt
while(1){
twidata='R';
if(twidata==uart_getc_wait()){ //wenn R ankommt, wird über I2C ein Wert gelesen
twidata=read_compass(1);
utoa(twidata,s,10); //uint -->char Umwandlung
uart_puts(s); //senden per UART
uart_putc(10);
uart_putc(13);
i=0;
while(i!=10){
_delay_ms(200);
i++;}
}
}
return 0;
}
void uart_init()
{
/*uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
UBRRH = (uint8_t) (ubrr>>8);
UBRRL = (uint8_t) (ubrr);*/
UBRRL = 25;
// UART Receiver und Transmitter anschalten
// Data mode 8N1, asynchron
UCSRB = (1 << RXEN) | (1 << TXEN);
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
// Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte)
do
{
UDR;
}
while (UCSRA & (1 << RXC));
}
unsigned char read_compass(unsigned char regadress){
unsigned char twidata;
i2c_start(CMPS03+I2C_WRITE);
i2c_write(regadress);
i2c_rep_start(CMPS03+I2C_READ);
//i2c_write(0xFF);
twidata=i2c_readNak();
i2c_stop();
return twidata;
}
void uart_puts (const char *s)
{
do
{
uart_putc (*s);
}
while (*s++);
}
Vielen Dank nocheinmal für die Mühe.
MfG
pongi
-
Update:
Um Fehler durch die Konvertierung zwischen uint und char auszuschliessen, habe ich eine kleine Routine geschrieben, die 1B in zwei Nibbles (4Bit) zerlegt, und diese dann entsprechend der Hexa-Charakter umwandelt (also 0-9 u. A-F). Leider erhalte ich auch so Werte zwischen 0x80 (=128) und 0xFF (=255). Es lag also nicht an der Konvertierung. Hat noch jemand Ideen?
(Das PWM Signal konnte ich noch nicht vermessen, da ich kein Oszi habe, und an der Uni alles überlastet ist...)
Code:
Code:
int main (void){
uint8_t twidata;
//char s[3];
uint8_t i;
uart_init();
i2c_init();
twidata='I';
uart_putc(twidata);
while(1){
uint8_t twidata2;
twidata='R';
if(twidata==uart_getc_wait()){
twidata=read_compass(1);
//utoa(twidata,s,10);
//uart_puts(s);
twidata2=twidata;
twidata&=0xF0;
twidata=swap(twidata);
twidata2&=0x0F;
uart_putc('0');
uart_putc('x');
uart_putc(convert(twidata));
uart_putc(convert(twidata2));
uart_putc(10);
uart_putc(13);
i=0;
while(i!=10){
_delay_ms(200);
i++;}
}
}
return 0;
}
uint8_t convert(uint8_t data){
if(data<10){
data+=48; //kleiner 10, +48, damit man bei ASCII 0 ist
}
else{
data+=55;//größer 9, +55, damit man bei 10 bei ASCII A ist
}
return data;