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

Bascom ATmega32 - zamiana znaku w string oraz tryb powerdown

marasneo 23 Gru 2013 11:32 1791 12
REKLAMA
  • #1 13090930
    marasneo
    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: text
    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: text
    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().
  • REKLAMA
  • #2 13090978
    Mateusz@
    Poziom 18  
    Kolego w arkuszu kalkulacyjnym masz funkcję zamień. Zamieniasz wszystkie kropki na przecinki i i już piękne wykresy można robić.
  • REKLAMA
  • #3 13090991
    marasneo
    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?
  • #4 13091034
    Mateusz@
    Poziom 18  
    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ć.
  • REKLAMA
  • #6 13091304
    Mundi1970
    Poziom 24  
    Przecinek w łatwiejszy sposób można uzyskać:
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #7 13091666
    marasneo
    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
    #8 13091747
    Mundi1970
    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 "#,##".
  • #9 13091754
    marasneo
    Poziom 15  
    Dzięki koledzy.
    Ktoś wie jak ugryźć pozostałe dwa problemy?
  • #10 13092911
    Mateusz@
    Poziom 18  
    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.
  • #11 13092970
    marasneo
    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: text
    Zaloguj się, aby zobaczyć kod
  • #12 13094534
    Mundi1970
    Poziom 24  
    Jeżeli masz kłopoty ze stabilnością programu, to może na początek zwiększ wartości stosów.

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #13 13094590
    marasneo
    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!
REKLAMA