Hallo zusammen,
ich habe hier das ez430-RF2500 Set von TI. Es handelt sich dabei um 2
Platinen mit jeweils einem MSP430-2274 drauf, welche über das SimpliciTI
Protokoll miteinander kommunzieren. Es gibt von TI eine Demo, wo auf
beiden Seiten die Temperaturen gemessen und über den USB Debugger
(virtueller Comport) als String ausgegeben wird.
Der vollständige Sourcecode findet sich hier:
http://www.ti.com/litv/zip/slac139c
Problem besteht nun am AP/HUB mit der Temperaturerfassung. Die
Temperatur schwankt sehr stark, daher habe ich versucht einen Mittelwert
zu bilden über 64 Werte. Grundlegend funktioniert es auch, die
Temperatur ist recht "stabil". Allerdings stürzt das Programm meist so
nach ca. 3h ab. Es bleibt einfach stehen. Im Programm werden an mehreren
Stellen noch die LEDs geschaltet; beim Absturz ist der Zustand immer
unterschiedlich, was mich vermuten lässt, dass das Problem nicht immer
an der selben Stelle auftritt.
Das original Programm von TI läuft fehlerfrei durch.
Zunächst poste ich erstmal den relevanten Code aus der main_AP.c
1
// if it is time to measure our own temperature...
for( degC = 240; degC > 0; degC-- ); // delay to allow reference to settle
14
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
15
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
16
results[0] = ADC10MEM;
17
18
ADC10CTL0 &= ~ENC;
19
...
Ich habe nun ganz pragmatisch einfach eine for-Schleife um den ADC Teil
gesetzt, aufsummiert und am Ende durch 64 geteilt (bzw 6 Bit nach rechts
geschoben)
1
// if it is time to measure our own temperature...
for( degC = 240; degC > 0; degC-- ); // delay to allow reference to settle
19
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
20
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
21
// results[0] = ADC10MEM;
22
adcsum += ADC10MEM;
23
24
ADC10CTL0 &= ~ENC;
25
}
26
adcsum = adcsum>>6;
27
results[0] = (int) adcsum;
28
...
Das sind die einzigen Änderungen.. was ist daran falsch, so dass der
Controller/das Programm nach ca. 3h (manchmal früher, manchmal später)
einfach stoppt?
Grüße,
devzero
> Ich habe nun ganz pragmatisch einfach eine for-Schleife
Wenn das die einzige Änderung ist, dann hast du evtl. die Laufzeit so
ungünstig verändert, dass du jetzt irgendwo festhängst...
> Die Temperatur schwankt sehr stark,
Tut sie das? Oder schwankt dein Messwert?
Falls ja: was ist die Ursache?
Ja, die Messung schwankt massiv. Woher es kommt weiss ich leider nicht.
Der Code ist ansich genau so wie an der Node, wo es stabil läuft. Die
Versorgungsspannung kommt vom USB Debugger, wird aber da irgendwie auf
3,6V runtergeregelt. Als Referenz für den ADC werden die internen 1,5V
benutzt.
Watchdog wird nirgends verwendet, ausserdem müsste er ja dann neustarten
und sollte somit nur Probleme mit seinen dann nicht mehr connecteten
Nodes haben. Die Nodes scheinen auch noch weiter zu senden; sie blinken
noch grün. Sobald man das Modul vom Strom entfernt blinken diese rot.
Damit fällt meine mögliche Theorie, dass er nicht ausm Schlaf aufwacht
aber auch hin. Im ADC Code wird der Controller schlafen geschickt, bis
die Wandlung fertig ist und dann per Interrupt wieder aufgeweckt wird.
Ich stehe gerade etwas verloren mit dem Problem da, da ich einfach nicht
weiss, was da schief läuft. Wenn es gar nicht gehen würde, würde ich mir
ja denken "ok, ich bin da zu lange.. der ganze SimpliciTI kram wird
nicht mehr oft genug angesprochen" - aber dann gäbe es auch bzw viel
mehr Probleme mit der Funkverbindung. Das läuft alles einwandfrei, nur
stürzt der AP halt meist so nach 3h ab.
PS: Wollte das Problem mal bei http://e2e.ti.com schildern, allerdings
finde ich da keinen New Post Button oder sowas in der Richtung.. muss
man dafür erstmal auf mehrere Posts geantwortet haben? Registriert habe
ich mich natürlich.
// the temperature is transmitted as an integer where 32.1 = 321
41
// hence 4230 instead of 423
42
43
temp=results[0];
44
degC=(((temp-673)*4230)/1024);
45
if((*tempOffset)!=0xFFFF)
46
{
47
degC+=(*tempOffset);
48
}
49
degC-=40;// temperature is too high - minus 4°C
50
51
temp=results[1];
52
volt=(temp*25)/512;
53
54
msg[0]=degC&0xFF;
55
msg[1]=(degC>>8)&0xFF;
56
msg[2]=volt;
57
transmitDataString(1,addr,rssi,msg);
58
BSP_TOGGLE_LED1();
59
sSelfMeasureSem=0;
60
}
Das läuft in der main(). Der Interrupt der durch den ADC ausgelöst wird,
schaltet die CPU wieder ein. Das sSelfMeasureSem wird durch einen
Timerinterrupt gesetzt, ca. jede Sekunde.
Der original Source ist im Prinzip wie dieser, nur ohne die for und ohne
i und adcsum. Zusätzlich ziehe ich noch 4°C ab, aber das betrifft ja
nicht das Problem.
Dies hatte ich testweise auch schon ausserhalb der for
for( degC = 240; degC > 0; degC-- ); // delay to allow
reference to settle
Ich bin mir da nicht sicher, an welche Stelle das kommt. Am Anfang ist
klar, danach wird die Referenz ja nicht mehr verändert, allerdings
dachte ich mir, dass eine kleine Pause zwischen den Messungen auch nicht
schadet.
@avion23: Der Stack? Die Stackgröße kann man in IAR Embedded Workbench
einstellen. Im Projekt ist das seitens TI auf 200 gesetzt. Wenn man das
Beispiel (von TI ohne Änderungen) mitm Debugger laufen lässt und anhält,
warnt er, dass der Stack mit 100% voll ist. Ich habe das testweise und
aktuell mal auf 360 gesetzt, damit hab ich die Meldung nicht mehr
erhalten. Was ich davon halten soll weiss ich nicht so recht, da das
original wie gesagt stabil läuft.