Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Konwersja odczytu IEEE 754 na inny format, np. int.

tehaceole 02 Feb 2011 17:35 3484 11
  • #1
    tehaceole

    Level 28  
    Witam Kolegów

    Zostałem postawiony przed wyzwaniem jakim jest połączenie sondy hydrostatycznej Kellera z modułem telemetrycznym MT-101 Inventii. Wszystko było ok, dopóki chodziło o przesłanie do monitoringu wartości odczytu z sondy w formacie float IEEE 754. MT-101 pracuje w trybie Modbus Mirror, odczyt z sondy mapowany jest do XREG1 i XREG2 (4 bajty liczby float).

    Problem pojawił się w momencie, gdy zaistniała konieczność użycia odczytu z sondy do sterowania pracą pomp zgodnie z programem zapisanym w MT-101. Tego typu sterowanie używałem do tej pory w sterowniku XC-200 Moellera - ta bestia wyposażona jest w gotowy blok logiczny do konwersji IEEE 754 na liczbę typu real. Inventia takiego udogodnienia nie posiada :( Inwestor uparł się, że sterowanie ma odbywać się z dokładnością do 1-2cm w oparciu o sondę hydro, a dopiero w przypadku jej awarii w oparciu o pływaki lub sondy konduktometryczne. Od razu mówię, że nie wchodzi w grę odczyt pomiaru w formacie int - jest to odgórnie narzucone. Konwersji muszę dokonać w MT - 101.

    Czy któryś z Kolegów spotkał się z podobnym zadaniem?

    Wg dokumentacji Kellera mogę pominąć pierwsze 9 bitów liczby float - wycinam w ten sposób znak i całą cechę. Jednak co dalej z 23 bitami mantysy? Coś mi nie pasuje w takim podejściu do tematu.
    Po przeskalowaniu ciśnienia w barach na poziom w cm spodziewam się odczytów maksymalnych do 1000cm czyli zmieszczę się w 16-tu bitach int'a.
    W MT-101 mam do dyspozycji wyłącznie rejestry 16-to bitowe. Co prawda są pseudo 32-u bitowe rejestry DREG jednak z poziomu MT PROG i tak widzę je jako 16-to bitowe "połówki" Hi i Lo.

    Jedyne sensowne informacje w podobnym przypadku znalazłem tu: Link.

    Garść informacji o formacie IEEE 754: Link.

    Z góry serdecznie dziękuję Kolegom za pomoc.
  • #2
    jestam
    Automation specialist
    Quote:

    Wg dokumentacji Kellera mogę pominąć pierwsze 9 bitów liczby float - wycinam w ten sposób znak i całą cechę.

    Dlaczego? Sonda wysyła stałe wartości na tych bitach? Jakie? Same 0?

    Jeśli możesz, to wstaw proszę tą dokumentację sondy i dokumentację MT-101 - jakąś listę rozkazów, bloków funkcyjnych, które masz do dyspozycji. Nie znam tego urządzenia, a trudno tworzyć algorytm nie znając dostępnych rozkazów.
  • #3
    falowniki.com
    Power inverters specialist
    Witam,
    sam jakiś czas temu "walczyłem" z podobnym tematem i nie do końca FB Moellera spełniał moje warunki odczytu.
    Poradziłem sobie w CoDeSys po obejrzeniu poniższego obrazka. Nie znam możliwości Twoich urządzeń ale dzięki obrazkowi powinieneś zrozumieć zasadę przedstawiania i możliwości konwersji float..
    pozdrawiam
    Konwersja odczytu IEEE 754 na inny format, np. int.
  • #4
    helper86
    Level 14  
    jeżeli chcesz to zrobić bezpośrednio w MT-101 to zadzwoń najlepiej do ich pomocy technicznej i Ci powiedzą :)
  • #5
    tehaceole

    Level 28  
    jestam - nie jestem w stanie sprawdzić co znajduje się w bitach cechy :(
    W załączniku dokumentacja do MT - 101, dokumentacji sondy Kellera nie mam w domu w formie elektronicznej.
    Jak już pisałem - coś nie pasuje mi idei pominięcia bitów cechy...

    falowniki.com - znam zasadę konwersji float'a :) Zresztą jest to bardzo przyjaźnie opisane na wikipedii i w odnośnikach do podstron. Bez problemu napisałbym to w Assemblerze nawet dla procesora 8-io bitowego - warunek jest jeden: muszę mieć pełną kontrolę nad zawartością rejestrów i przede wszystkim nad bitami z przepełnień. W MT-101 nie mam takiej możliwości.
    W CoDeSys w języku ST używam bloku IEEE_To_Real z bilbioteki XS40_MoellerFB.
    Przykładowy zapis floata do real, a następnie konwersja ciśnienia z sondy
    na wysokość słupa wody w cm wygląda tak (sterownik Moeller xc-cpu201):
    
    		%MW700:=warMODBUSRegister[1];
    		%MW702:=warMODBUSRegister[2];
    IEEE_To_Real_(EXPO_IN:=%MB701,Mant_2_In:=%MB700,Mant_1_In:=%MB703,Mant_0_In:=%MB702,Real_Out=>);
    		cisnienie:=IEEE_To_Real_.Real_Out;
    		IF cisnienie<0 THEN
    		cisnienie:=0;
                  END_IF
    		poziom:=cisnienie* 10.19716; (*wartosc rzeczywista - przeskalowanie ciśnienia na wysokosc slupa wody*)
    		poziomCentymetry:=TRUNC(poziom*100); (*poziom w centymetrach+ odcięcie czesci po przecinku*)
    


    helper86 - problem "rozwiązany" :P Panowie z pomocy technicznej stwierdzili, że to co chcę osiągnąć jest nie możliwe... Cóż... Jutro powalczę z odczytem przez wejście 4-20mA. Swoją drogą trzeba obiektywnie przyznać, że pomoc techniczna Inventii stoi na naprawdę wysokim poziomie. Zwracałem się do nich niedawno z innym problemem i pomogli mi go rozwiązać w kilka minut - a sam męczyłem się z tym 2 dni :) hehehe
  • #6
    Waldus
    Level 13  
    Przepełnienia niby są w MT jeśli przekroczysz zakres to ustawiana jest flaga błędu chociaż nie wiem co wtedy pojawi się w rejestrze wynikowym jeśli nie wynik to można by kombinować dalej. Myślę ze możliwe ale strasznie skomplikowane by to było. No i pytanie czy w 2000 linijek się zmieści :)
  • #7
    jestam
    Automation specialist
    Quote:

    
    poziom:=cisnienie* 10.19716; (*wartosc rzeczywista - przeskalowanie ciśnienia na wysokosc slupa wody*) 
    poziomCentymetry:=TRUNC(poziom*100); (*poziom w centymetrach+ odcięcie czesci po przecinku*) 
    



    1. czyli poziomCm = cisnienie * 1019.716, spodziewasz się wartości od 0 do 1000 cm, więc cisnienie < 1.0 bar

    2. ciśnienia ujemne oraz mniejsze niż 1/1024 bara, czyli < 1 cm traktujemy jako 0, to daje wartości wykładnika od 117 (dla pomiaru 1/1024) do 127 (dla pomiaru 1)

    3. wykładnik >= 128 oznacza ciśnienie >= 2.0 bar, czyli błąd

    4. MT101 traktuje 16 bitowe rejestry jako liczby bez znaku

    Początek algorytmu (XREG1 = [znak, wykładnik, mantysa], XREG2 = [reszta mantysy]):
    1. czy XREG1 > 32767?
    1a. tak [wartość ujemna] -> poziom = 0, koniec

    2. czy XREG1 > 16383?
    2a. tak [ciśnienie >= 2.0 bar] -> sygnalizuj błąd, koniec

    3. czy XREG1 < 14976?
    3a. tak [ciśnienie < 1/1024 bar] -> poziom = 0, koniec

    [w tym miejscu jest 1/1024 <= pomiar < 2.0 bar, tj. znak = 0, 117 <= wykładnik <= 127]

    [poniżej wszystkie rejestry (zmienne) 16 bitów bez znaku, z wyjątkiem dreg, który jest 32 bitowy]

    4. Oblicz
    w1 := XREG1 >> 7 [przesunięcie bitowe w prawo o 7 bitów]
    w := 127 - w1
    m1 := XREG1 << 8 [przesunięcie bitowe w lewo o 8 bitów]
    m2 := XREG2 >> 8 [przesunięcie bitowe w prawo o 8 bitów]
    m3 := 32768 + m1 + m2
    m := m3 >> w [przesunięcie bitowe w prawo o w bitów]

    dreg := m * 10197 [mnożenie dwóch liczb 16 bitowych, wynik 32 bitowy]
    poziom_mm := dreg / 32768 [wynik w mm]

    5. Czy (poziom_mm modulo 10) < 5 ? [zaokrąglanie do cm]
    5a. tak -> poziom_cm := poziom_mm / 10, koniec
    5b. nie -> poziom_cm := (poziom_mm / 10) + 1, koniec.

    Obliczenia mają pewien zapas dokładności (stąd wielkości w mm).

    Uwaga! Algorytm jest dostosowany do tego konkretnego problemu. To nie jest ogólny algorytm konwersji IEEE-754 na liczby dziesiętne. W szczególności podstawienie innej wartości zamiast 10197 może doprowadzić do błędów w obliczeniach.

    Pytania do autora wątku:
    Czy rozkaz mnożenia dwóch 16 bitowych zmiennych może zapisać wynik do 32 bitowej zmiennej? Z dokumentacji to jasno nie wynika.
    Czy Twoje urządzenie obsługuje "funkcje dodatkowe" - rodział 9.7, str. 112?

    Edycja: uzupełnienie algorytmu.
  • #8
    tehaceole

    Level 28  
    jestam - sonda ma maksymalny zakres pomiarowy do 1 bara. Co do rejestrów 32 bitowych... W oprogramowaniu MT PROG są one widziane jako np. DREG1H, DREG1L. Nie można się do nich odwołać bezpośrednio jako DREG1. Dlatego nazwałem je "pseudo" 32-u bitowymi. Tak, funkcje dodatkowe są dostępne w moim module.

    EMEA Gateway - MT-101 to wybór inwestora i nie mam na to wpływu. Jednak dziękuję za informacje - na przyszłość napewno się przydadzą.
  • Helpful post
    #9
    jestam
    Automation specialist
    Quote:
    Co do rejestrów 32 bitowych... W oprogramowaniu MT PROG są one widziane jako np. DREG1H, DREG1L. Nie można się do nich odwołać bezpośrednio jako DREG1


    Z dokumentacji:
    Mnożenie X przez Y
    zapisz wynik (rejestr) = pobierz X (rejestr) * pobierz Y (rejestr)
    Przekroczenie zakresu sygnalizowane jest ustawieniem flagi błędu

    Czy mnożąc XREG3 * XREG4, można zapisać wynik do DREG1?
    Jeśli tak, to czy dla XREG3 = 32768 a XREG4 = 2 wynik mnożenia zapisany w DREG1 będzie 65536, czy zostanie zgłoszony błąd? Jeśli możesz, sprawdź to z urządzeniem.

    Analogiczne pytanie dla dzielenia: czy da się podzielić DREG1 przez XREG1 ?
  • #10
    tehaceole

    Level 28  
    W poniedziałek sprawdzę. Póki co męczę odczyt po wejściu 4-20mA. Wyniki są obiecujące i wszystko wskazuje, że to rozwiązanie zostanie użyte. Jednak ta konwersja nadal nie daje mi spokoju :)
  • #11
    jestam
    Automation specialist
    Jeśli nawet się nie da, to są tam operacje kopiowania rejestrów 16<->32 bit, coś się powinno dopasować. Algorytm w poście wyżej uzupełniłem, zakłada że mnożenie i dzielenie działają na 32 bitach. Sprawdź i daj znać o wynikach :)
  • #12
    tehaceole

    Level 28  
    Bardzo Kolegę przepraszam za tak późną odpowiedź, ale trochę innych zajęć mi się nawarstwiło. Przetestowałem sposób opisany przez Kolegę, lecz niestety nie działa. Temat został definitywnie zarzucony ponieważ odczyt tejże sondy poprzez wejście prądowe również pozwala uzyskać założoną rozdzielczość odczytu. Jest duuuuużo prostszy w implementacji i z parotygodniowych testów wynika, że działa wyśmienicie.

    Dziękuję za zainteresowanie.
    Temat zamykam.