Hallo,
bin gerade dabei die Steuerung für einen Unterwasserglider zu bauen. Um
die Tiefe zu wissen benötigt er einen Drucksensor (MS5535C), der über
SPI angeschlossen ist.
Um eine Temperaturkalibration durchzuführen muss ich erst 6
Koeffizienten auf den mC schieben und kann dann damit den Druck
errechnen.
Zur Kontrolle der Werte habe ich eine UART verbindung mit dem PC.
Problem: der eine Wert, der errechnet werden muss, kann nicht stimmen.
1
UT1=10000+(8*C5);
Die PuTTY Konsole gibt mir: UT1 = -31760
da ich mir C5 übertragen lasse stimmt was nicht: C5 = 2972
laut Datenblatt soll UT1 zwischen 10000 und 42760 liegen.
Ich habe schon versucht UT1, die ganzen Koeefizienten als int32_t zu
definieren...
Es kann meiner Meinung nach kein SPI sondern entweder ein Rechen- oder
UARTproblem sein.. ???
Weiss nicht mehr wo ich jetzt noch suchen soll!
Danke für eure Hilfe!
Fred
Frederik H. schrieb:> Zur Kontrolle der Werte habe ich eine UART verbindung mit dem PC.>> Problem: der eine Wert, der errechnet werden muss, kann nicht stimmen.
Meine Kristallkugel ist Spezialistin im Erraten von Code den du nicht
zeigst.
>>
1
UT1=10000+(8*C5);
> Die PuTTY Konsole gibt mir: UT1 = -31760>> da ich mir C5 übertragen lasse stimmt was nicht: C5 = 2972
8 * 2972 ergibt 23776
da dann noch 10000 dazu: 33776
Oh, oh. Das ist zuviel für einen 16 Bit signed int. Bei 32767 ist
Schluss, danach gibt es einen Overflow.
Fazit: nächstes Mal die Datentypen dazu zeigen. Höchst wahrscheinlich
reicht es schon, wann du ein wenig Sogrfalt walten lässt und alles
unsigned berechnest. Dann hast du Wertebereiche von 0 bis 65535 anstelle
von -32768 bis +32767 und das sollte dann reichen, wenn zwischendurch
keine Overflows erfolgen.
schon mal daran gedacht, dass du deine variablen als 'unsigned'
deklarien musst? wenn dies als 'signed' deklariert ist, wird die zu
übertragende Zahl sofort dann als 'negativ' bewertet, wenn das MSB
gesetzt ist, also größer/gleich 32.768...und du überträgst, wenn ich das
richtig interprtiere 33.776...also demnach 'negativ'...
Rudi
>> Die PuTTY Konsole gibt mir: UT1 = -31760>>>> 8 * 2972 ergibt 23776>> da dann noch 10000 dazu: 33776>> Oh, oh. Das ist zuviel für einen 16 Bit signed int. Bei 32767 ist> Schluss, danach gibt es einen Overflow.>
Oder die Ausgabefunbktion "interpretiert" das Ergebnis einfach falsch.
Wenn ich [uint16_t] 33776 als [int16_t] auffasse, kommt da genau -31760
raus.
>>> Die PuTTY Konsole gibt mir: UT1 = -31760>>>>>>> 8 * 2972 ergibt 23776>>>> da dann noch 10000 dazu: 33776>>>> Oh, oh. Das ist zuviel für einen 16 Bit signed int. Bei 32767 ist>> Schluss, danach gibt es einen Overflow.>>>> Oder die Ausgabefunbktion "interpretiert" das Ergebnis einfach falsch.
Mag sein.
Aber in dem Fall 'interpretiert' sie nicht einfach falsch, sondern es
wird die falsche Ausgabefunktion aufgerufen (man könnte es auch so
sagen: Der Programmierer hat seine Ausgabefunktion angelogen).
Ohne Code ist das schwer zu sagen. So gut ist meine Kugel dann auch
wieder nicht. Sie ist sich aber recht sicher, dass der 'Fehler' in
diesem Umfeld zu suchen ist, und sich nicht der Mega32 verrechnet hat,
sondern der Programmierer nicht sorgfältig genug war.
while(!(UCSRA&(1<<UDRE)));//Warten, bis Senden möglich ist
13
14
UDR=c;//schreibt das Zeichen aus 'c' auf die Schnittstelle
15
}
16
17
voidsendUSART(char*s)//*s funktiniert wie eine Art Array - auch bei einem String werden die Zeichen (char) einzeln ausgelesen - und hier dann auf die Sendeschnittstelle übertragen
18
{
19
while(*s)
20
{
21
sendchar(*s);
22
s++;
23
}
24
}
Dann liegt das Problem im itoa ? Wie kann man denn am schnellsten nen
uint in asci wandeln??
Danke!
Frederik H. schrieb:> Dann liegt das Problem im itoa ? Wie kann man denn am schnellsten nen> uint in asci wandeln??
[ ] Du hast die Antworten durchgelesen.
Es ging hier um deine Variable UT1, deren Deklaration wäre interessant.
:-)
Frederik H. schrieb:> Dann liegt das Problem im itoa ? Wie kann man denn am schnellsten nen> uint in asci wandeln??
WIe wäre es erst mal damit, die richtige Funktion zu benutzen
int -> itoa
unsigned int -> utoa
long -> ltoa
unsigned long -> ultoa
Wie schon vorher angemerkt: Der Compiler kann nichts dafür, wenn du ihn
anlügst und ihm sagst du hättest eine Zahl mit Vorzeichen (und deshalb
benutzt du itoa) wenn du in Wirklichkeit einen unsigned hast.
Ganz unschuldig ist der Compiler aber auch nicht. Der hätte immerhin die
Möglichkeit eine Warnung auszugeben wenn itoa() mit einer unsigned
Variable aufruft. Vermutlich verlangt die Spache C aber das man es da
nicht so genau mit den Typen nehmen muß.
Ulrich schrieb:> Vermutlich verlangt die Spache C aber das man es da> nicht so genau mit den Typen nehmen muß.
Eine Sprache 'verlangt' eigentlich nie, daß man Typen wild durcheinander
benutzt.
C ist relativ milde und überlässt es dem Programmierer das zu tun was er
für richtig hält. Eine Warning kann man fast immer erhalten wenn man die
Optionen entsprechend setzt und die Warnings auch liest.
Hier ist es wohl eher ein fehlendes Verständnis der Datentypen und
entsprechende Wahl der falschen.
Ohne Code ist aber auch das Spekulation.
Ulrich schrieb:> Ganz unschuldig ist der Compiler aber auch nicht. Der hätte immerhin die> Möglichkeit eine Warnung auszugeben wenn itoa() mit einer unsigned> Variable aufruft.
Wenn er das denn tut. Die Deklaration von UT1 haben wir ja immer noch
nicht gesehen ;)
Hi,
also eure Kommentare haben mich schon ein ganzes Stück weitergebracht.
Es lag natürlich an utoa - bei mir liegt die ganze Programmierung aber
schon 4 Jahre zurück und ich bin gerade wieder dabei mich
einzuarbeiten...also schon mal danke dafür.
Leider funktioniert die Druckmessung immer noch nicht. Er zeigt zwar
Werte an und die Koeffizienten liegen jetzt auch im richtigen Bereich,
nur wenn ich mit meiner Apothekenspritze den Druck verändere passiert im
Prinzip: Nichts.
Ich hab mal die entscheidenen Dateien angehängt. Vielleicht seht ihr
mehr als ich... Ist alles ein bisschen doppelt gemoppelt aber halt auch
noch lange nich fertig...
Danke für die Hilfe!!!
PS: spi.h ist wohl nicht so wichtig :)
Hier noch die ranges aus den Application Notes
MAXIMUM VALUES FOR C1-C6
min typ max
C1 (13 bit) 0 2391 8191
C2 (13 bit) 0 4888 8191
C3 (10 bit) 0 385 1023
C4 (9 bit) 0 221 511
C5 (12 bit) 0 1689 4095
C6 (7 bit) 0 58 127
MAXIMUM VALUES FOR D1, D2
min typ max
D1 0 17000 40000
D2 0 27000 45000
MAXIMUM VALUES FOR CALCULATION RESULTS
min typ max
UT1 10000 28016 42760
dT -11400 0 12350
OFF 9246 14888 18887
SENS 1298 4196 8939
P 0 14000
TEMP -400 1250
Du hast schon so schön angefangen, dir die Werte ausgeben zu lassen.
Führ das fort. Die Konstanten am Programmanfang werden ja jetzt wohl
stimmen, also kannst du diese Ausgaben wieder rausnehmen.
Allerdings machst du jetzt in derselben Tonart weiter und lässt dir mal
die gemessenen Werte ausgeben: So wie du sie vom Sensor bekommst (also
die Rohdaten) und dann deine umgerechneten Werte. Und so kreist du dein
Problem weiter ein.
Moin,
also ich hab mir alle Werte( Wörter, D1, D2) über LEDs bitweise ausgeben
lassen und alles nachgerechnet. Die UART/ASCII Übertragung stimmt damit
m.E. vollkommen. Alle Koeffizienten liegen im richtigen Bereich, die
Rechnungen stimmen... D1 und D2 entsprechen laut Datenblatt 20°C und
1bar - alles tutti..
t, p , und s habe ich einfach mal 20 groß gemacht , (wobei ja 6 Byte
reichen sollten für 5 Zahlen und ein \0 !?).
Ich bin jetzt am verzweifeln. Die Druckwerte (D1) ändern sich nicht!
Glaube langsam schon das was mit dem Sensor nicht stimmt.
Kann es sein, das was mit der SPI kommunikation nicht stimmt obwohl die
Werte immer gut sind? Und wie könnte man das überprüfen?
Vielleicht hats ja auch den Sensor zerschossen und die SPI ist heile
geblieben???
Keine Ahnung - verdammte microelektronik - und das als
Maschinenbauer....
Grüße Fred
ich würde empfehlen erst mal den simulator anzuwerfen und schritt für
schritt durchsteppen und schauen, ob nach jeder operation immer noch das
im Ergebnis steht, was man erwartet.
Was auch noch nicht gesagt wurde (oder ich habs überlesen):
egal, wie UT1 deklariert wurde, die Operationen mit den Kosntanten
werden in dem größten der beteiligten Typen gerechnet.
deine Konstanten sind 16bit.
wenn c5 auch 16bit breit ist, kommt es hier bereits zum overflow.
vor der Berechnung sollte also C5 auf einen (u)int32 gecastet werden.
Edit:
Tip für den Simulator:
nur den entsprechenden Codeteil testen und Inputwerte (wie Sensor) als
volatile definieren und einen sinnvollen Wert zum Testen zuweisen.
volatile deswegen, damit der Optimizer dir nicht alle Berechnungen
rausschmeißt wenn alle Größen von vornhinein bekannt sind.