Ich habe ein Problem mit dem MCP3551. Er ist wie im Anhang beschrieben verschaltet. Bei Messungen erhalte ich jetzt allerdings ein Toleranzband von 1 - 2.5°C ohne Mittelwertbildung bei einem 100 Ohm Widerstand bei konstanter Temperatur. Gibt es Möglichkeiten diese Schaltung weiter zu Entstören? MfG, Manuel
Passt deine Samplerate? Du kannst in etwa 13,75mal pro Sekunde Messen mit genauen ergebnissen. Was wird an dem Widerstand gemessen? Temperatur? Passt die Umrechnung? Du kannst noch zwischen IN+ und IN- einen Kondensator (1nF-10nF) schalten um Störungen besser blocken zu können. Am besten auch mal den Sourcecode posten. Sonst sind das nur Mutmaßungen. Gruß, Jens
Die Schaltung soll einen PT100 auf 0.1 °C genau messen. Mainschleife:
1 | PTCoolDown++; |
2 | |
3 | // PT100 Test: |
4 | if(PTCoolDown >= 100) |
5 | { |
6 | if(!SEN_PT100_MessungLaeuft) |
7 | { |
8 | // Wenn alle Teilmessungen erledigt, neue Messreihe starten: |
9 | |
10 | // PT100 Messung anregen: |
11 | mcp3551_StosseMessungAn(); |
12 | |
13 | SEN_PT100_MessungLaeuft = 1; |
14 | } |
15 | else if(BerechnePT100Temperatur(&SEN_DeciTemperatur)) |
16 | { |
17 | if(tmin > SEN_DeciTemperatur) |
18 | tmin = SEN_DeciTemperatur; |
19 | |
20 | if(tmax < SEN_DeciTemperatur) |
21 | tmax = SEN_DeciTemperatur; |
22 | |
23 | SEN_PT100_MessungLaeuft = 0; |
24 | PTCoolDown = 0; |
25 | } |
26 | } |
27 | |
28 | uint8_t stelle; |
29 | |
30 | if((SEN_DeciTemperatur % 10) < 0) |
31 | stelle = (SEN_DeciTemperatur % 10) * -1; |
32 | else |
33 | stelle = (SEN_DeciTemperatur % 10); |
34 | |
35 | sprintf(Str, "PT100: %d.%d C", (SEN_DeciTemperatur / 10), stelle); |
36 | Ft_Gpu_CoCmd_Text(Ft_DispWidth/2 + 150, 30, 27,OPT_RIGHTX|OPT_CENTERY,Str); |
37 | |
38 | if((tmin % 10) < 0) |
39 | stelle = (tmin % 10) * -1; |
40 | else |
41 | stelle = (tmin % 10); |
42 | |
43 | sprintf(Str, "min: %d.%d C", (tmin / 10), stelle); |
44 | Ft_Gpu_CoCmd_Text(Ft_DispWidth/2 + 150, 55, 27,OPT_RIGHTX|OPT_CENTERY,Str); |
45 | |
46 | if((tmax % 10) < 0) |
47 | stelle = (tmax % 10) * -1; |
48 | else |
49 | stelle = (tmax % 10); |
50 | |
51 | sprintf(Str, "max: %d.%d C", (tmax / 10), stelle); |
52 | Ft_Gpu_CoCmd_Text(Ft_DispWidth/2 + 150, 80, 27,OPT_RIGHTX|OPT_CENTERY,Str); |
53 | |
54 | _delay_ms(1); |
Die MCP-Funktionen:
1 | void mcp3551_init() |
2 | { |
3 | _delay_ms(10); |
4 | |
5 | // Init: |
6 | ConfigureCSPin(); |
7 | |
8 | // Toggle CS one time to init MCP355x |
9 | SelectMCP(); |
10 | _delay_ms(80); |
11 | |
12 | SPID.DATA = 0; |
13 | while(!(SPID.STATUS & 0x80)); |
14 | SPID.DATA = 0; |
15 | while(!(SPID.STATUS & 0x80)); |
16 | SPID.DATA = 0; |
17 | while(!(SPID.STATUS & 0x80)); |
18 | |
19 | DeselectMCP(); |
20 | _delay_ms(10); |
21 | } |
22 | |
23 | void mcp3551_StosseMessungAn() |
24 | { |
25 | int32_t tmp; |
26 | |
27 | SelectMCP(); |
28 | _delay_us(15); |
29 | |
30 | // Wenn RDY auf Low, Messung abholen: |
31 | if(IsMCPReady()) |
32 | { |
33 | tmp = mcp3551_getData(); |
34 | _delay_us(15); |
35 | |
36 | mcp3551_StosseMessungAn(); |
37 | } |
38 | |
39 | DeselectMCP(); |
40 | _delay_us(15); |
41 | } |
42 | |
43 | int32_t mcp3551_getData() |
44 | { |
45 | // CS low |
46 | SelectMCP(); |
47 | _delay_us(15); |
48 | |
49 | if(IsMCPReady()) |
50 | { |
51 | // Wenn Messung fertig: |
52 | uint32_t LSByte=0; |
53 | uint32_t MSByte=0; |
54 | uint32_t HSByte=0; |
55 | uint8_t is_neg = 0; |
56 | |
57 | SPID.DATA = 0; |
58 | while(!(SPID.STATUS & 0x80)); |
59 | HSByte=(uint32_t)SPID.DATA; |
60 | SPID.DATA = 0; |
61 | while(!(SPID.STATUS & 0x80)); |
62 | MSByte=(uint32_t)SPID.DATA; |
63 | SPID.DATA = 0; |
64 | while(!(SPID.STATUS & 0x80)); |
65 | LSByte=(uint32_t)SPID.DATA; |
66 | |
67 | // CS high |
68 | DeselectMCP(); |
69 | _delay_us(15); |
70 | |
71 | uint32_t data = LSByte; |
72 | data |= (MSByte<<8); |
73 | |
74 | if(HSByte & 32) |
75 | is_neg = 1; |
76 | |
77 | HSByte &= 0b00111111; // Clear OV and DR |
78 | data |= (HSByte<<16); |
79 | |
80 | // Check if sign bit is set |
81 | if(is_neg) |
82 | { |
83 | // Measure is negative |
84 | int32_t ret = 0xFFE00000; |
85 | |
86 | ret |= data; |
87 | return ret; |
88 | } |
89 | else |
90 | { |
91 | // Measure is positive |
92 | return (int32_t)data; |
93 | } |
94 | } |
95 | |
96 | // CS high |
97 | DeselectMCP(); |
98 | _delay_us(15); |
99 | |
100 | return 0; |
101 | } |
102 | |
103 | // Berechnung der PT100 Temperatur: |
104 | uint8_t BerechnePT100Temperatur(int16_t *Temperatur) |
105 | { |
106 | int32_t Spannung; |
107 | |
108 | float Widerstand, delta; |
109 | float Berechnung; |
110 | float A = (float)3.9083 / pow(10,3); |
111 | float B = (float)-5.775 / pow(10,7); |
112 | float R0 = (float)100; |
113 | |
114 | Spannung = mcp3551_getData(); |
115 | |
116 | if(Spannung <= (int32_t)0) |
117 | return 0; |
118 | |
119 | // Spannung über den Refferenzwiderstand: |
120 | delta = (float)2097152 - (float)Spannung; |
121 | |
122 | // Widerstand berechnen: |
123 | Widerstand = ((float)6800 / delta) * (float)Spannung; |
124 | Widerstand *= 2; |
125 | |
126 | // Wenn Temperatur tiefer als -100 ° |
127 | if(Widerstand < 60) |
128 | return 0; |
129 | |
130 | // Temperatur Polynomial berechnen: |
131 | |
132 | Berechnung = (sqrt(pow((R0*A),2)-(float)4*B*R0*(R0 - (float)Widerstand))-(A*R0)) / ((float)2*B*R0); |
133 | |
134 | *Temperatur = (int16_t)(Berechnung*(float)10); |
135 | |
136 | |
137 | return 1; |
138 | } |
Mit 10nF an V+ / V- hab ich jetzt bei einem 100 Ohm Widerstand (fest) als min 1.8 als max. 3.0. In diesem Bereich schwanken meine Messwerte. Verwendet wird ein XMega128A3u mit 32 MHz getaktet (3V3).
Selbst bei einer Referenz- und Versorgungsspannung (Nur MCP3551) von einer Knopfzelle kommt es zu diesen Messfehlern. Wähle ich den Referenzwiderstand auf 1k statt den 6k8, so grenzt sich der Fehler in der Temperatur auf .4 °C ein. Allerdings liegt dann der Messstrom höher (ca. 3 mA).
Mit welcher Sample Rate wird gemessen ? Für den ersten Test sollte man sich die Werte des ADCs direkt ansehen, also ohne die Umrechnung in die Temperatur. Beim Kondensator zwischen In+ und In- muss man ggf. aufpassen, 1-10 nF kommen mir zu wenig vor. Ein kleiner Kondensator kann zusätzliche Fehler verursachen. Wenn dann eher ein Kondensator im Bereich 220 nF - 1 µF. Testweise könnte man es mal ohne die dauernde Abfrage ob der ADC fertig ist probieren, also einfach ein Delay, dass lang genug ist. Der I2C Bus könnte bei schlechtem Layout die Messung ggf. beeinflussen. Ein Bild vom Layout wäre ggf. auch nicht schlecht.
Manuel H. schrieb: > Selbst bei einer Referenz- und Versorgungsspannung (Nur MCP3551) von > einer Knopfzelle kommt es zu diesen Messfehlern. Wähle ich den > Referenzwiderstand auf 1k statt den 6k8, so grenzt sich der Fehler in > der Temperatur auf .4 °C ein. Allerdings liegt dann der Messstrom höher > (ca. 3 mA). Da hast Du es. Der Eingangswiderstand des ADW ist relativ klein. Versuch mal 1µ und 10µ am VIN+ gegen VIN-.
Mit einem Delay habe ich bereits probiert: Ohne Erfolg. Anbei das Layout. Keine nennenswerte Signale in unmittelbarer Nähe. Der ADC gibt Werte im Intervall [15128; 15208] als Rohdaten. Die Samplerate liegt bei ca. 5 Samples/s. Variation bringt hier auch nichts.
Yoschka schrieb: > Manuel H. schrieb: >> Selbst bei einer Referenz- und Versorgungsspannung (Nur MCP3551) von >> einer Knopfzelle kommt es zu diesen Messfehlern. Wähle ich den >> Referenzwiderstand auf 1k statt den 6k8, so grenzt sich der Fehler in >> der Temperatur auf .4 °C ein. Allerdings liegt dann der Messstrom höher >> (ca. 3 mA). > > > Da hast Du es. > Der Eingangswiderstand des ADW ist relativ klein. > Versuch mal 1µ und 10µ am VIN+ gegen VIN-. Bei zweimal 4.7 µF und einmal 1 µF immernoch Schwankungen von bis zu 0.8 °C
Manuel H. schrieb: > SelectMCP(); > _delay_ms(80); > > SPID.DATA = 0; >.... > DeselectMCP(); Ich bin mir völlig sicher, daß du in deiner ADC-Bedienung den Fehler hast. Also, mach das mal etwa so: Beim Programmstart legst du einfach CS auf LOW und läßt es dort bis zum jüngsten Gericht. Der ADC wird nun im kontinuierlichen Modus messen und mit jedem Meßende sein Datenpin auf low legen, um dir anzuzeigen, daß es was abzuholen gibt. Dann holst du es ab und das Datenpin geht mit dem letzten Bit wieder auf High. Und so weiter... Wenn du dem ADC andauernd auf den Schlips trittst mit deinem Selektieren, dann muß er jedesmal seine interne Queue wegschmeißen. Versuch mal, so einen SigmaDelta-Wandler zu verstehen: Der hat nen 1-Bit Wandler, mit dem er die Eingangsspannung moduliert, daraus entsteht ein serieller Datenstrom, der dann passend tiefpaßgefiltert wird, um das Ergebnis zu liefern. Das ist ein recht kontinuierlicher Prozeß und geht eben NICHT so wie bei einem SAR-ADC. W.S.
Hallo, 1% Widerstandsänderung sind 2.5 Grad Temperatur. -> ich würde die Toleranz des 6.8K Widerstandes nochmal überdenken. Gruß Anja
Anja schrieb: > Hallo, > > 1% Widerstandsänderung sind 2.5 Grad Temperatur. > -> ich würde die Toleranz des 6.8K Widerstandes nochmal überdenken. > > Gruß Anja Erklären sich dadurch die dynamischen Schwankungen? Das müsste doch nur in den R0, also Kategorie feste Toleranzen fallen.
Hallo, 80 Digits im Rohwert erklären sich dadurch nicht. Im Datenblatt sind es "nur" ca 20. Die 20 sind allerdings bei kurzgeschlossenem Eingang. In Realität wird es bei realen Spannungen etwas mehr sein. Aber es scheint so daß irgendwo im Aufbau (Masseverdrahtung sternförmig?) etwas faul ist. Gruß Anja
W.S. schrieb: > Ich bin mir völlig sicher, daß du in deiner ADC-Bedienung den Fehler > hast. Habe verschiedene SPI-Modi und den Continuous Conversion Mode umgesetzt. Kein Erfolg. Die SCK-Leitung ging unter dem Chip lang. Gekappt und außerhalb verlegt. Kein Erfolg. Die Massefläche geht komplett außen herum. Das Einzige, was ich mir jetzt noch vorstellen könnte ist der Step-Up LED Treiber für den Touchscreen.
Hallo Manuel, es gibt einen Punkt, welcher bei diesem ADC wichtig ist, und zwar das Du die Versorgung ordentlich Abblockst, am besten mit einem Pi-Filter. Bei mir hat 10u 100nH 1R 3,3u 100n sehr gut geholfen. Du kannst auch die Referenz noch etwas abblocken, wobei Du damit das Ratiometrische Prinzip verletzt. Gruß Johannes
Guck doch erstmal mit nem Scope, ob der ADC auch "sieht", was er dir sagt. Wenns signal schon doof ist, kanns ja am ende nicht schöner sein.. Wenn das signal aufm oskar gut aussieht, liegt der fehler beim adc, emv, weißdergeierwas.
4b schrieb: > hat 10u 100nH 1R 3,3u 100n sehr gut geholfen. Wie meinst du das genau? Ein Pi-Filter ist doch nur eine Spule mit zwei Kondensatoren? Wenn ich die Touchscreen Komponenten Software seitig ausschalte zappeln die Messwerte absolut nicht mehr!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.