Hallo,
ich habe jetzt meine Heizungssteuerung schon sehr weit. Jetzt ist mir aufgefallen als ich die "richtige" R zu T Wandlerroutine eingebaut habe dass meine CPU Zeit "nachgeht". Daraufhin habe ich einen Ausgang am Anfang eines Timer IRQ gesetzt, und am Ende wieder zurückgesetzt. Das Oszi zeigt mir das folgende:
Wie man hoffentlich erkennen kann, sind meine sonstigen Zeitscheiben sehr in Ordnung bis auf diese Eine, welche hier im Screenshot 2.4 ms hat. Mein Timer läuft mit 1 ms. Nach dem schrittweisen auskommentieren bin ich sehr schnell auf der Schuldigen Routine gelandet.
Ich habe eine Tabelle im Flash:
Diese gehe ich Zeile für Zeile durch bis ich die passende Zeile gefunden habe und interpoliere dann zwischen den Stütztpunkten.Code:74 const sensorvalues_flash t_kt81_110[] PROGMEM = 75 { // r t 76 { 490, -55}, 77 { 515, -50}, 78 { 567, -40}, 79 { 624, -30}, 80 { 684, -20}, 81 { 747, -10}, 82 { 815, 0}, 83 { 886, 10}, 84 { 961, 20}, 85 { 1000, 25}, 86 { 1040, 30}, 87 { 1122, 40}, 88 { 1209, 50}, 89 { 1299, 60}, 90 { 1392, 70}, 91 { 1490, 80}, 92 { 1591, 90}, 93 { 1696, 100}, 94 { 1805, 110}, 95 { 1915, 120}, 96 { 2023, 130}, 97 { 2124, 140}, 98 { 2211, 150}, 99 { 0, 0}, 100 };
Meine Randbedingung ist:Code:124 // find smallest distance of r 125 unsigned char smallest_distance_idx = 0; 126 float distance = 100000.0; 127 128 memcpy_P(&tmp, ¤t[idx+0], sizeof(sensorvalues_flash)); t1 = tmp; 129 memcpy_P(&tmp, ¤t[idx+1], sizeof(sensorvalues_flash)); t2 = tmp; 130 do 131 { 132 133 float delta = pow(r-t1.r,2)+pow(t2.r-r,2); 135 if (delta < distance) 136 { 137 distance = delta; 138 smallest_distance_idx = idx; 139 } 140 141 // read next two lines 142 ++idx; 143 memcpy_P(&tmp, ¤t[idx+0], sizeof(sensorvalues_flash)); t1 = tmp; 144 memcpy_P(&tmp, ¤t[idx+1], sizeof(sensorvalues_flash)); t2 = tmp; 145 } while (t2.r > 0); 146 147 // read the best matching lines 148 memcpy_P(&tmp, ¤t[smallest_distance_idx+0], sizeof(sensorvalues_flash)); t1 = tmp; 149 memcpy_P(&tmp, ¤t[smallest_distance_idx+1], sizeof(sensorvalues_flash)); t2 = tmp; 150 151 // interpolate 152 float dr = t2.r-t1.r; 153 154 float f = (r-t1.r)/dr; 155 return t1.t+(t2.t-t1.t)*f;
- Ich will anhand einer Stütztabelle interpolieren und nicht einfach T=f*R machen. Die Datenblätter zeigen dass es eben keine Gerade ist....
- Ist mein R ausserhalb der Tabelle, will ich den nächst, passenden Eintrag nutzen und linear interpolieren.
Ist hier das zweimalige "pow" so teuer? Ist das memcpy_P so teuer? (teuer, sprich Laufzeit).
Edit: Ersetzte ich das pow() durch abs() lande ich bei 1.4 ms. Besser aber noch nicht gut ....
Gruß
Georg








Zitieren

Lesezeichen