PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : CMPS03 - Problem



pongi
20.03.2007, 20:09
Hallo!

Heute habe ich ein kleines Programm geschrieben, was die Daten vom Kompass CMPS03 ausliest, und übers UART an den PC weietersendet. Dabei ist mir aufgefallen, dass egal, wie ich den Kompass drehe, nur Werte zwischen 128 und 255 am PC ankommen. Wenn ich ihn drehe, gibt es ein Bereich um 255, wo sich trotz Drehung sich garnichts tut, und danach sprint der Wert auf 128 und steigt normal weiter.
Weiss jemand da Rat? Hab ein Atmega8, programmiert in C, I2Clib von Peter Fleury, UART zusammengeschnipselt vom AVR-GCC Tutorial, das funktioniert aber mit unterschiedlichen Strings, also daran liegts nicht.

Danke schon im Voraus!

pongi

Jon
21.03.2007, 14:32
Hasst du vielleicht irgendwo in der Nähe einen Motor, Kabel mit höherem Strom/Spannung oder ähnliches? Dieses Phänomen kenne ich nur von solchen Störquellen.

jon

pongi
21.03.2007, 14:40
Nein, darauf hab ich extra geachtet. Ausserdem ist es komisch, dass die Werte genau 128 und 255 sind. Also nie 127 und so. Irgendwie also ob die eine Hälfte der Skala abgeschnitten wäre....
Eine Idee von mir: die Werte gebe ich als ein Byte aus. Das wird dann als char interpretiert, deshalb kommen komische Zeichen in Hyperterminal heraus. Daher habe ich ein kurzes LabVIEW Programm geschrieben, was die Daten vom COM-Port des PCs liest, und dann die chars in uints umwandelt udn anzeigt. Mein Prblem kann aber nicht an der Konversion zwischen char und uint liegen oder?

jeffrey
21.03.2007, 16:19
Hallo,
ich kenn jetzt den Sensor nicht, aber kann es sein, dass das ergebnis bei der übertragung in 2 teile zerlegt wird, und ein teil nicht richtig ausgelesen wird.
mfg jeffrey

pongi
21.03.2007, 16:23
Nein, das Ergebnis vom Sensor ist ein Byte, 0-255 entsprechend 0-360°.
Man kann aber das Ergebnis auch als ein Word empfangen, vielleicht versuche ich das mal... Obwohl ich nicht genau weiss, wie ich sie dann zusammensetzen muss.

Jon
21.03.2007, 17:46
Du bekommst normalerweise ein Word gesendet. Das Word musst du dann durch 10 teilen. Nun hast du die Ausrichtung mit einer Auflösung von 0,1°.
Es kann passieren, dass es noch mehr Stellen nach dem Komma gibt, die sind aber nicht mehr genau.

jon

pongi
21.03.2007, 18:28
Nein, wenn man Register 1 liest, bekommt man nur ein Byte, siehe CMPS03 doku: http://www.robot-electronics.co.uk/htm/cmps3doc.shtml
Jetzt hab ich noch folgendes gemacht: ich lass den Atmega die Zahl in eine ASCII Zeichenkette umwandeln, und das wird an den Laptop gesandt. Leider hat das auch keine Änderung ergeben... Es scheint mir so, also ob der Kompass nur 128 "Schritte" für eine volle Umdrehung machen würde...

Jon
21.03.2007, 20:18
Macht er 100pro nicht. Es ist ein Word, das kommt.
Kannst du mal den BASCOM Code von dieser (https://www.roboternetz.de/wissen/index.php/Bascom_und_Kompass_CMPS03) Seite probieren? Vielleicht stimmt etwas an deinem Kompass nicht.

Kannst du auch mal dienen Code hier reinstellen?

jon

pongi
21.03.2007, 20:35
@Jon: erstmals vielen Dank für deinen Einsatz :D

Ich zitiere: "1 Compass Bearing as a byte, i.e. 0-255 for a full circle"
Man kann auch als Word auslesen, wenn man Register 2,3 liest, mach ich aber nicht, da ich mit einem Byte mit dem Atmega8 besser arbeiten kann, und die Genauigkeit der letzten Stellen sowieso ziemlich unsicher ist.

Leider hab ich kein Bascom Compiler, womit ich es testen könnte, ich tendiere aber auch langsam dazu, dass mit dem Kompass was nicht stimmt.... Hab auch schon an Devantech geschrieben, aber leider noch keine Antwort erhalten.

Jon
21.03.2007, 20:39
Ich zitiere: "1 Compass Bearing as a byte, i.e. 0-255 for a full circle"
Achso. Hab ich mir nicht alles durchgelesen.


Man kann auch als Word auslesen, wenn man Register 2,3 liest,
Ich lese Register 2 aus.


und die Genauigkeit der letzten Stellen sowieso ziemlich unsicher ist.
Stimmt auch wieder...


Leider hab ich kein Bascom Compiler, womit ich es testen könnte,
Kann man hier (http://www.mcselec.com/index.php?option=com_docman&task=cat_view&gid=99&Itemid=54) kostenlos als DEMO runterladen.


ich tendiere aber auch langsam dazu, dass mit dem Kompass was nicht stimmt.... Hab auch schon an Devantech geschrieben, aber leider noch keine Antwort erhalten.
Mal schauen, was die zurückschreiben.

jon

robby-fant
21.03.2007, 20:57
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

pongi
21.03.2007, 21:34
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

pongi
31.03.2007, 11:48
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.

robo junior
31.03.2007, 13:21
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.

pongi
31.03.2007, 13:36
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?

robo junior
31.03.2007, 13:39
@pongi ja, so mach ich es

Dirk
01.04.2007, 12:05
@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

p_mork
01.04.2007, 12:53
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.


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

pongi
01.04.2007, 13:43
@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:


#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

pongi
04.04.2007, 16:05
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:


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;

profMax
17.04.2007, 18:47
Hallo,

das Problem könnte auch ein Vorzeichenfehler sein
(uint ungeschickt zu int konvertiert)

Versuch doch mal alle deine Variablen auf einem Datentyp zu halten (die Form uint8_t ist am besten).

Bei der Funktion usart_putc ist char noch zu rechtfertigen, aber versuch mal unsigned char, da du die Variable in ein Register schreibst.


Viele Grüße,
Max

pongi
17.04.2007, 20:46
Danke, ich hab gerade heute mein Fehler gefunden. In der I2C Library von Peter Fleury liegen zwei Implementationen, eine ist ein hardwareunterstützter I2C Protokoll, der andere ist rein Software. Blöderweise habe ich die Softwareversion inkludiert, was anscheinend nicht so gut geklappt hat....
Jetzt geht alles wieder fein.