logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega8][Bascom] - licznik oddechów - doszlifowanie kodu

marciu11 05 Sie 2008 15:24 2320 5
REKLAMA
  • #1 5410287
    marciu11
    Poziom 15  
    Witam
    Dość długo podchodziłem do tego zagadnienia.
    Początkowo chciałem zrealizować to na mikrofonie i wzmacniaczu.
    Ostatecznie po poszukiwaniach i analizie postanowiłem to zrobić na odczycie temperatury przy nosie.

    Wdech omiata termometr powietrzem otoczenia i go ochładza, a wydech podnosi temperaturę powietrzem z płuc.

    W zasadzie to działa, ale sam algorytm wymaga małego dopieszczenie i podniesienia selektywności i tu za bardzo nie wiem co zrobić. Więc swoje kroki kieruję do bardziej doświadczonych programistów.

    Mianowicie wygląda to tak iż za czujnik temperatury robi najbanalniejszy DS18b20 ustawiony na odczyt 9bitowy (dla zmniejszenia czasu oczekiwania na konwersję A-D)

    Wynik jest porównywany z poprzednim odczytem i gdy jest wyższy to zwiększa się licznik oddechu.
    
    Do
    ...
    If Flaga = 1 And Temperatura > Temperatura_temp Then
       Flaga = 0
       Incr Oddech   
       Set Portb.0
    End If
    
    If Flaga = 0 And Temperatura < Temperatura_temp Then
       Flaga = 1
       Reset Portb.0
    End If
    Temperatura_temp = Temperatura
    ...
    Loop
    


    Wprowadzenie dodatkowej zmiennej "FLAGA" zapobiega ponownemu zwiększeniu licznika "oddech" przy tym samym wydechu. Gdyż aby ponownie "flaga" została ustawiona, musi być odczyt temperatury niższy od poprzedniego, czyli nastąpić wdech.

    Dodatkowo dla wprawek nad procedurą zapala się dioda sygnalizująca nastąpienie wydechu. Ale to tak dla wizualizacji.

    W zasadzie taka procedura działa i w 90% spełnia swoją funkcję, ale zdarza się iż niekiedy i tak podwójnie zliczy oddech (szczególnie przy długich wdechach), lub gdy leży nieużywany czujnik na stole, sam z siebie zlicza impulsy gdyż odczyty temperatur wahają się same z siebie o jakieś ułamki.

    Chciałem ograniczyć trochę czułość pomiaru stosując zaokrąglenie wyniku, A właściwie jego części po przecinku (różnica temperatur pomiędzy wdechem a wydechem - zaobserwowane około 0,7C) procedurą Fusing (Temperatura, "#.##") Ale działa mi to jedynie w momencie wyświetlania wyniku na LCD. Gdy chcę to zrobić na zmiennej (single) i dopiero wynik wyświetlić na LCD, to w wyniku dostaję liczbę w formacie 0.00000xxxx

    Temperatura = Fusing(temperatura , "#.##")


    Więc też stanowczo nie tak. A wydaje mi się, że to załatwiło by to sprawę rozbiegu dokładności, gdyż był by mniejszy rozbieg po przecinku.

    Będę wdzięczy za pomoc w poprawieniu. lub naprowadzeniu na procedurę poprawiającą selektywność pomiaru.
  • REKLAMA
  • REKLAMA
  • #3 5410459
    marciu11
    Poziom 15  
    Balu napisał:
    Bo fusing robi stringa proszę szanownego kolegi:)

    To nie tędy droga...PS może nie zaokrąglanie a histereza?:)


    Wiem właśnie.
    I dla tego takie głupoty wychodziły.
    Ale gdy dam dodatkową zmienną string i tak "zfusuje" wartość temperatury a następnie ponownie przepiszę ją do zmiennej single procedurą Val to ponownie zamiast xx.xx mam xx.xxxxxxxxx.


    
    A = Fusing (temperatura, "#.##") ' A jest stringiem - LCD wyświetla dobrze zformatowaną liczbę
    Temperatura = Val(a)  'zmienna ma wartość X.9 miejsc po przecinku, wiec jeszcze większy bigos
    


    O Histerezie też myślałem ale nie za bardzo wiem jak to ugryź w realizacji.

    Teoretyczne wyglądało by to tak:
    Zmierz wartość temperatury,
    porównaj z zapisaną poprzednio w TEMP'ie,
    jeżeli jest o X procent większa lub mniejsza to zareaguj na to.

    Ale jak to wykonać w programie?? Nie za bardzo wiem.

    MarCiu
  • REKLAMA
  • #4 5410518
    BoskiDialer
    Poziom 34  
    Może lepiej było by rejestrować minimalną i maksymalną temperaturę. Jeśli temperatura by przekroczyła te nastawy, to byś je odpowiednio zwiększał. Aby minimum i maksimum było odpowiednio dopasowane, możesz minimalną zwiększać a maksymalną zwiększać co sekundę o np 10% różnicy (lub prowadzić wartość średnią w innej zmiennej i zmniejszać o 10% różnicy ze średnią). Na wdech przełączał byś się, gdyby doszło do spełnienia warunku Tcurr < Tlo + 0.4(Thi-Tlo) a na wydech, gdyby doszło do spełnienia warunku Tcurr > Tlo + 0.6(Thi-Tlo).

    Inna możliwość, jeśli był wdech(zimno), rejestrujesz minimalną temperaturę jaka wystąpiła(od momentu przełączenia się na wdech) i na wydech(ciepło) przełączasz się, gdy temperatura będzie wyższa o np 2 stopnie, podobnie w drugą stronę - jak się przełączysz na wydech(ciepło), rejestrujesz aktualną maksymalną, na zimno(wdech) przełączasz się, gdy temperatura będzie niższa o np 2 stopnie od maksymalnej.

    Rozwiązanie pierwsze jest samokalibrujące się, drugie wymaga ustalenia różnicy temperatury potrzebnej do przełączania się, chociaż można też chwilowe minima i maksima wykorzystać do dynamicznego ustalania wartości progowej.
  • REKLAMA
  • Pomocny post
    #5 5410583
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    marciu11 napisał:

    O Histerezie też myślałem ale nie za bardzo wiem jak to ugryź w realizacji.

    Teoretyczne wyglądało by to tak:
    Zmierz wartość temperatury,
    porównaj z zapisaną poprzednio w TEMP'ie,
    jeżeli jest o X procent większa lub mniejsza to zareaguj na to.

    Ale jak to wykonać w programie?? Nie za bardzo wiem.


    Prosto.

    Do histerezy musisz mieć:
    * dwa poziomy (górny i dolny) - możesz mieć "środek" +/- histereza, albo "środek" +/- x% * środek,
    * flagę wskazującą ostatni stan (powyżej górnego, czy poniżej dolnego)

    temp = get_temp();
    if flaga then
       if temp < poziom_dolny then
          (obsluga przelaczenia)
          flaga = false;
       end if;
    else
       if temp > poziom_gorny then
          (obsluga przelaczenia)
          flaga = true;
       end if;
    end if;
    


    (sorry za kod, nigdy nie pisalem w BASICU :P )

    PS. a myślałeś, co będzie jak ktoś będzie oddychał ustami? :)

    Pozdrawiam,
    Dr.Vee
  • #6 5413385
    marciu11
    Poziom 15  
    Panowie dzięki za pomoc :)

    Wprowdzie Histerezę ustawiłem na sztywno w procedurze, ale Wasza pomoc naprowadziła mnie na to rozwiązanie - dzięki.

    Problem z czułością rozwiązałem w ten sposób:
    
    If Flaga = 1 Then
       If Temperatura > Temp_max Then
          Set Portb.0
          Flaga = 0
       End If
    Else
       If Temperatura < Temp_min Then
          Reset Portb.0
          Flaga = 1
          Incr Oddech
       End If
    End If
    
    Temp_max = Temperatura + 0.1
    Temp_min = Temperatura - 0.05
    


    Dzięki temu uzyskałem selektywność licznika na poziomie +-1 oddechu na minutę i licznik sam z siebie nie zlicza impulsów z powietrza. A taka dokładność jest mi wystarczająca.

    O oddechy przez usta nie martwie się.
    Licznik będzie zastosowany w zabawce, więc nawet jeżeli taki fakt nastąpi nic złego się nie stanie.

    Tak więc ten problem jest już rozwiązany. Gdy na dalszym etapie prac nad programem będę miał jeszcze jakieś problemy pozwolę sobie zadać dalsze pytania.

    Na razie dzięki za pomoc.

    MarCiu
REKLAMA