Re: Peripetie s termočlánky (Vianocna list..

balu balu na k-net.fr
Středa Prosinec 25 11:55:12 CET 2024


Teplota je obycajne velmi pomaly fenomen, vypoctova narocnost nebola az tak velky problem. V nasom pripade prevodnik vzorkoval tusim desiatky vzoriek za sekundu, teplota sa pocitala par krat za sekundu. Zvladla aj atmega328. 


> On 25 Dec 2024, at 11:34, Miroslav Mraz <mrazik na volny.cz> wrote:
> 
> Koukal jsem na to a trochu si hrál s překladačem a jak definovat polynomy. Zkusil jsem 3 způsoby
> 
> static constexpr int coeff [] = {1,2,3,4,5};
> // default optimize -Os
> int poly_a (const int x) {
>  int y = coeff[4];
>  int t = x;
>  y += coeff[3] * t;  t *= x;
>  y += coeff[2] * t;  t *= x;
>  y += coeff[1] * t;  t *= x;
>  y += coeff[0] * t;
>  return y;
> }
> int poly_b (const int x) {
>  return  ((((coeff[0]  * x)
>            + coeff[1]) * x
>            + coeff[2]) * x
>            + coeff[3]) * x
>            + coeff[4];
> }
> [[using gnu: optimize("O3")]] // unroll loop
> int poly_c (const int x) {
>  int y = 0;
>  for (auto c : coeff) { y *= x; y += c; }
>  return y;
> }
> 
> Způsob a) je podobný kódu, co poslal balu, odděleně počítá mocninu argumentu, což není příliš efektivní. Způsob b) vyplyne z toho, pokud polynom napíšeme podle definice a uvědomíme si, že x je z toho možné povytýkat, ozávovorkovat to a je to jednodušší. A nakonec způsob c) jednoduchou smyčkou umožní to celé napsat jednodušeji.
> 
> Ale proč to píšu. Uvědomil jsem si jak chytré jsou moderní překladače. Když donutím překladač, aby smyčku rozvinul, výsledný kód pro b) a c) jsou (pro RISC-V, ale zřejmě i jinde) naprosto stejné. Překladač pozná, že první násobení 0 je zbytečné a vyhodí ho. A nejen to - pozná i zbytečnost násobení 1 (1. koeficient, je konstatní), neprovádí ho.
> 
> Mrazík
> 
>> On 24. 12. 24 16:13, Daniel Valuch wrote:
>> poslane sukromne...
>> Ano, ja som to tiez minuly rok studoval spracovanie signalov od RTD a termoclankov cele vianoce. Zaujimava problematika. Dokumenty priamo z BIPM na temu ITS-90 a tabulky koeficientov pre RTD aj termoclanky od NISTu su velmi dobry zaklad a su velmi informativne.
>> Prikladam vycuc z kodu
>>   if (MeasureTC1) {
>>       // measure cold junction temperature first
>>       RColdJunction = (float)ADCavrgCJ / (float)ADCavrgRef * R0; // scaling of cold junction and reference cancels out
>>       TemperatureCJ = RTDpolynomial(WCorrection(RColdJunction/R0nominal)); // calculate cold junction temperature
>>       VCJ = ThermoCoupleK_TtoE(TemperatureCJ - 273.16); // equivalent Cold Junction voltage
>>       VTC1raw = (float)ADCavrgTC1 * QueueBitShift * LSBmV * TC1InvGain;  // convert measured ADC number to voltage in mV
>>       VTC1raw = VTC1raw - TC1offsetVoltage;                              // suppress analogue offset (e.g. from the op-amp)
>>       VTC1comp = VTC1raw + VCJ;                                          // cold junction voltage added to measured voltage
>>       TemperatureTC1 = ThermoCoupleK_EtoT(VTC1comp);
>>       // 0=Celsius, 1=Kelvin, 2=Farenheit, 3=Ohm, 4=microVolt
>>       if (unit == 0) {
>>         PrepareText(TemperatureTC1, 0);
>>       } else if (unit == 1) {
>>         PrepareText(TemperatureTC1 + 273.15, 1);
>>       } else if (unit == 2) {
>>         PrepareText(TemperatureTC1 * 1.8 + 32.0, 2);
>>       } else if (unit == 3) {
>>         PrepareText(VTC1raw, 4);
>>       }
>>     }
>> float ThermoCoupleK_EtoT(float e) {
>>   // type K ITS-90 polynomial
>>   // https://srdata.nist.gov/its90/type_k/kcoefficients_inverse.html
>>   const float d0m = 0.0e0;
>>   const float d1m = 2.5173462e1;
>>   const float d2m = -1.1662878e0;
>>   const float d3m = -1.0833638e0;
>>   const float d4m = -8.9773540e-1;
>>   const float d5m = -3.7342377e-1;
>>   const float d6m = -8.6632643e-2;
>>   const float d7m = -1.0450598e-2;
>>   const float d8m = -5.1920577e-4;
>>   const float d0p = 0.000000e0;
>>   const float d1p = 2.508355e1;
>>   const float d2p = 7.860106e-2;
>>   const float d3p = -2.503131e-1;
>>   const float d4p = 8.315270e-2;
>>   const float d5p = -1.228034e-2;
>>   const float d6p = 9.804036e-4;
>>   const float d7p = -4.413030e-5;
>>   const float d8p = 1.057734e-6;
>>   const float d9p = -1.052755e-8;
>>   float E = 0.0;
>>   float t90 = 0.0;
>>   E = e;
>>   if (e < 0.00) {  // negative temperature
>>     t90 = t90 + d1m * E;
>>     E = E * e;
>>     t90 = t90 + d2m * E;
>>     E = E * e;
>>     t90 = t90 + d3m * E;
>>     E = E * e;
>>     t90 = t90 + d4m * E;
>>     E = E * e;
>>     t90 = t90 + d5m * E;
>>     E = E * e;
>>     t90 = t90 + d6m * E;
>>     E = E * e;
>>     t90 = t90 + d7m * E;
>>     E = E * e;
>>     t90 = t90 + d8m * E;
>>   } else if (e >= 0 && e < 20.644) {  // positive temperature <500 C
>>     t90 = t90 + d1p * E;
>>     E = E * e;
>>     t90 = t90 + d2p * E;
>>     E = E * e;
>>     t90 = t90 + d3p * E;
>>     E = E * e;
>>     t90 = t90 + d4p * E;
>>     E = E * e;
>>     t90 = t90 + d5p * E;
>>     E = E * e;
>>     t90 = t90 + d6p * E;
>>     E = E * e;
>>     t90 = t90 + d7p * E;
>>     E = E * e;
>>     t90 = t90 + d8p * E;
>>     E = E * e;
>>     t90 = t90 + d9p * E;
>>   } else {
>>     t90 = -273.0;
>>   }
>>   return t90;
>> }
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
> 




Další informace o konferenci Hw-list