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