Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Bascom ATmega32 - zamiana znaku w string oraz tryb powerdown

23 Gru 2013 11:32 1617 12
  • Poziom 15  
    Witam kolegów serdecznie tuż przed świętami.
    Piszę program realizujący pomiar temperatury i zapisujący uzyskane dane do pliku zlokalizowanego na karcie SD.
    Powoli wtrącam timery zamiast wait().
    Mam w sumie trzy problemy.

    1) Formatuje uzyskane dane przez zapisem do pliku. Niestety nie wiem jak w stringu zamienić kropkę na przecinek i dopiero taki format zapisać. Chodzi o to, że chciałbym, aby arkusz kalkulacyjny zobaczył liczbę, a nie string ;). Czy da się?

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    2) Timer1 odlicza wybrany przez użytkownika czas trwania pomiarów (Menu_czasu). W tym czasie czujnik dokonuje pomiaru co kilka sekund a dane są zapisywane aż Licz_przepelnien=0. Wtedy wychodzimy z pętli głównej programu, obliczamy statystykę, zapisujemy ją na koniec pliku i wchodzimy w tryb powerdown aż do resetu proca.

    Skoro korzystam z przerwania Timer1, jak przerobić ten algorytm tak, aby urządzenie wchodziło w tryb powerdown zaraz po Przygotowanie_pliku i
    Menu_czasu? Chodzi o to aby wybudzał się co przerwanie na wykonanie pomiaru i zapis do pliku, a później dalej szedł spać.

    Czy ustawienie wszystkich portów jako wyjścia przed wejściem w tryb powerdown zmniejszy pobór energii?

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    3) Gdy wykorzystuję Timer1 do odliczania czasu od wartości licznika przepełnienia do 0 i dalej nic więcej, wszystko jest ok.
    Próbowałem jednak zrealizować odstęp między kolejnymi pomiarami wewnątrz Do...Loop na Timer1. W przerwaniu zaznaczyłem -
    zlicz od A do Licz_przepelnien. Jesli A>Licz_przepelnien then A=0.
    I powtarzam od nowa. Fakt, działa! Mierzy temperaturę co x sekund. Problem polega na tym, że za każdym razem mierzy ją 5 razy z rzędu, x sekund przerwy, 5 x pomiar i tak dalej...
    W programie nie miałem błędu. Gdy usunąłem Do...Loop, wykonało pomiar tylko raz. Rzecz jasna bez Do...Loop to długo nie podziała i słusznie. Jednak widzę, że połączenie Do...Loop oraz Timer1 wewnątrz pętli to nic dobrego.

    Dlaczego mierzył 5 razy co mniej więcej domyślne 750ms dla czujnika DS18b20? Powinien zmierzyć tylko raz, poczekać x sekund, znowu...
    Na razie w tej części programu jestem zdany na Wait().
  • Poziom 17  
    Kolego w arkuszu kalkulacyjnym masz funkcję zamień. Zamieniasz wszystkie kropki na przecinki i i już piękne wykresy można robić.
  • Poziom 15  
    Kolego Mateusz, zgadza się, jest taka opcja.
    Jednak, jeśli można zrobić to już na poziomie uC, wolałbym iść w tę stronę.
    Pytanie, czy się da?
  • Poziom 17  
    Spróbuj zrobić dwie zmienne, jedną dla części całkowitych drugą dla części ułamkowych i podczas zapisu na kartę rozdzielić je przecinkiem. Nie sprawdzałem tego ale powinno zadziałać.
  • Poziom 24  
    Przecinek w łatwiejszy sposób można uzyskać:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod
  • Poziom 15  
    Kolego Mundi1970,
    przedstawiony sposób jest interesujący.
    Niestety w obu wersjach nie działa...
    Dp - nieznany parametr oraz dodatkowe błędy dotyczące , w Fusing.
  • Pomocny post
    Poziom 24  
    Config DP działa od wersji 2.0.1.0, jeżeli masz tą lub nowszą wersje Bascom'a w Fusing zamień "#.##" na "#,##".
  • Poziom 15  
    Dzięki koledzy.
    Ktoś wie jak ugryźć pozostałe dwa problemy?
  • Poziom 17  
    Sposób kolegi Mundi1970 działa na 100%. Specjalnie to sprawdzałem.
    Kolego może dał bym radę Ci pomóc z tymi problemami ale potrzebuje całego kodu do analizy i symulacji.
  • Poziom 15  
    Koledzy, poniżej kod.
    Zauważyłem poważny problem. Timer1 mi się sypie zanim dojdzie do 0.
    Tzn, nagle, zanim upłynie zadany czas, uC zwiesi się i przestanie wykonywać pętlę Do ... Loop until.
    Nie wejdzie w stan Powerdown i nadal będę mógł wywołać przerwanie Int0 - czyli zawiesza się w pętli Do...loop.
    Zdaje się, że nieszczęsne Wait 1 wewnątrz tej pętli psuje sprawę.
    Dla czasów typu 10 minut zadziała, ale 60 minut i więcej - wykrzacza się po kilkuset pomiarach. Dioda przestaje migać, w pliku bzdury lub wszystko ok ale pomiary urwane.

    Wait 1 wewnątrz pętli DO w programie głównym określa co jaki okres czasu wykonać pomiar i zapisać dane.
    Wiem, że to nieeleganckie, ale nie znam innego sposobu - próbowałem na przerwaniach, ale wewnątrz pętli to nie działa dobrze.

    Czy przerwanie działa tutaj niezależnie od Wait1? Czy to teoretycznie może dobrze, STABILNIE działać?


    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod
  • Poziom 24  
    Jeżeli masz kłopoty ze stabilnością programu, to może na początek zwiększ wartości stosów.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod
  • Poziom 15  
    Dzięki spróbuję.
    Pozbyłem się problemu stabilności.
    Powodem był wpływ timera1 na zapis do pliku. Nie wiem dlaczego, ale tak.
    Wewnątrz do...loop zatrzymuję timer1 zaraz po procedurze Pomiar_temperatury - on zajmuje trochę czasu, przynajmniej 750 ms, wykonuje się w ramach timer1.
    Zaraz po kodzie:
    Formatowanie_danych
    Zapis_do_pliku
    Suma_wartosci_temp
    Incr Nr
    wznawiam timer1. Takie rozwiązanie pozwala na stabilną pracę programu. Testowałem cały wieczór i noc, działa. Czas pracy w pętli jest o pojedyncze sekundy dłuższy od zakładanego ze względu na obecność wait() po wznowieniu timer1.
    Postaram się wyrzucić wait() zastępując przerwaniem timer0 - chyba mogę uruchomić dwa timery w trybie timer na raz??

    Nadal nie wiem jak sprawić, by uC znajdował się w trybie uśpienia zawsze gdy nie dokonuje pomiaru ani nic nie zlicza w tej pętli (w trakcie trwania wait() - później timer0).

    Dodatkowe pytanie do kolegów... jak sprawić, by urządzenie samo odłączyło się od zasilania po zakończeniu pracy?

    Wesołych i Szczęśliwych Świąt Wam wszystkim!