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

[Atmega8][Bascom] kilka menu - sprawdzenie kodu

moons 27 Sie 2011 12:31 3012 26
  • #1 27 Sie 2011 12:31
    moons
    Poziom 13  

    Wymyśliłem sobie takie coś, działa tak jak trzeba ale pozostaje pytanie czy tak to się powinno robić i czy nie będzie powodować kłopotów dalej. Jest to zwykły komputerek samochodowy z kilkoma menu.
    W każdym menu coś tam będzie odczytywane czy wyliczane, temperatura, droga spalanie.
    w tej chwili po naciśnięciu przycisku bardzo ładnie menu się zmieniają ale coś tak czuje że marnotrawię kod i powinno się to robić zupełnie inaczej.

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Pozdrawiam

    0 26
  • Pomocny post
    #2 27 Sie 2011 12:36
    piotrva
    Moderator na urlopie...

    Strasznie szybko sobie zjedziesz EEPROM - ma przecież tylko 10 000 razy cykl zapisu gwarantowany, czyli po 10 000 zmian możesz mieć poważne problemy - komórka padnie. Albo zmieniaj co jakiś czas komórki, albo zapisuj dane przy wyłączeniu urządzenia - dodaj większy kondensator podtrzymujący zasilanie i jak wykryjesz spadek napięcia zasilania przed kondensatorem to szybciutkio zapisujesz dane do eeprom, zanim się kondek rozładuje.

    0
  • Pomocny post
    #3 27 Sie 2011 12:38
    Jaca
    Poziom 28  

    piotrva napisał:
    Strasznie szybko sobie zjedziesz EEPROM - ma przecież tylko 10 000 razy cykl zapisu gwarantowany, czyli po 10 000 zmian możesz mieć poważne problemy - komórka padnie. Albo zmieniaj co jakiś czas komórki, albo zapisuj dane przy wyłączeniu urządzenia - dodaj większy kondensator podtrzymujący zasilanie i jak wykryjesz spadek napięcia zasilania przed kondensatorem to szybciutkio zapisujesz dane do eeprom, zanim się kondek rozładuje.


    100 000 :)

    0
  • #4 27 Sie 2011 12:49
    moons
    Poziom 13  

    hmm, generalnie to ma być tak żeby po włączeniu komputerek wracał do ostatnio wyświetlanego menu. Czyli zapis takiej danej jak numer menu w EEPROM to nie jest dobry pomysł? Jak to można inaczej rozwiązać. Przecież jeszcze kilka innych danych będzie musiało być zapisywanych w EEPROMie.
    Pozdrawiam

    0
  • #6 27 Sie 2011 13:05
    moons
    Poziom 13  

    Nie no trochę mnie nastraszyłeś, ale chyba nie będzie tak źle :)
    100 000 / (powiedzmy 10 razy dziennie zmiana menu) / 365 = 27 lat. A tyle to moje auto na pewno nie wytrzyma.
    Nadal pozostaje pytanie czy ze strony programowej jest to do zaakceptowania, bo działać działa.
    Pozdrawiam

    0
  • Pomocny post
    #8 27 Sie 2011 20:49
    snnaap
    Poziom 25  

    Po co jest "Readeeprom Nr_menu , 1" po "Debounce S1 , 0 , Zmiana , Sub"?
    To raczej nic nie wnosi do działania programu, ponieważ po "Debounce..." w zmiennej nr_menu już masz aktualny numer menu.

    "Readeeprom Nr_menu , 1" powinno być przed "Do".
    Wtedy aktualną pozycję menu odczytujesz tylko raz przy włączeniu zasilania i na ekranie wyświetlasz menu które było ostatnio wyświetlane.

    Dodano po 3 [minuty]:

    Ogólnie zasada jest taka:
    1. czytasz z epprom ostatnią pozycję menu
    2. wyświetlasz dane menu
    3. czekasz na przycisk
    4. zapisujesz aktualną pozycję do eprom.

    0
  • #9 27 Sie 2011 22:59
    moons
    Poziom 13  

    Faktycznie wystarczy raz odczytać tylko na początku. To poprawiłem i dopisałem jeszcze najprostsze czyli pomiar temp z dwóch DS18B20 i nastąpiła kupa całkowita :(
    Znaczy działa tylko już nie tak jak na początku. Można przechodzić po menu tylko że trzeba trafić w odpowiedni moment. Bo jak rozumiem te Waitms 750 w odczycie temperatury wszystko zakłóca. No i jak teraz wybrnąć z tego klopsa? Od razu wytłumaczę się dlaczego odczyt temperatury ma byś prowadzony cały czas, bo zależnie od temperatury zewnętrznej pewna kontrolka ma zapalić się najpierw na pomarańczowo a jeśli temperatura spadnie jeszcze niżej to zapalić się na czerwono. W tej chwili w kodzie jest trochę inaczej, ale to tylko kwestia wartości granicznych i znaków większości, tak jak jest teraz łatwiej mi to sprawdzić. I chyba coś namieszałem z obliczaniem temp bo mam teraz 28,5 stopni, co prawda przed monitorem kompa ale chyba trochę zawyża.


    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Pozdrawiam

    0
  • #11 28 Sie 2011 00:03
    moons
    Poziom 13  

    No chyba jednak trzeba będzie przejść na przerwania bo tak nie idzie tego obsługiwać, załapuje raz na 4, 5 naciśnięć przycisku. Tylko czy nie będzie problemu z brakiem końcówek INT bo na nie czekają też inne rzeczy :). Choć pewnie i tak Atmega8 nie pociągnie tego co chciałbym zrobić. Ale to już jutro nad tym posiedzę.
    Pozdrawiam

    0
  • #13 28 Sie 2011 01:00
    moons
    Poziom 13  

    A jednak dziś jeszcze przepisałem to INT0. Działa choć czasem są problemy z odczytem temperatury, ale to pewnie dlatego że za dużo powstawiałem disable/enable interrups. No i przestawiłem moją Atmegę na trochę szybszą:)
    W takim razie spróbuję jeszcze z Timerem. A jaką najmniejszą rozsądną jednostkę odmierzania czasu sobie przyjąć żeby było O.K.? 1 ms pewnie jest bez sensu, natomiast 100 ms to już chyba za duża jednostka, 10 czy 50 ms. Dołożę pewnie jeszcze do tego pomiar z czujnika prędkości VSS i pewnie wtedy kolejny Timer?
    Pozdrawiam

    edit:
    No więc tak błędy przy odczycie temp były spowodowane badziewnym przewodem do łączenia pól na płytce prototypowej. Wymieniony i działa jak trza. Zmniejszyłem czasy czekania na odczyt temp do 100 ms oraz wróciłem do obsługi przycisku przez Debounce. Jednak przerwania to nie to bo czasem było trudno trafić w menu. Teraz czas na wymianę wait na normalne odliczanie czasu.
    Tak się zastanawiam czy jest możliwym takie rozwiązanie żeby sekundę podzielić na określone zadania. Czyli temp już zajmuje 200 ms więc pozostaje 800 ms na inne zadania.

    0
  • #14 28 Sie 2011 14:42
    piotrva
    Moderator na urlopie...

    A kto powiedział, że musisz czekać?
    Wystawiasz sobie 2 flagi w przerwaniu timera co określony czas i potem w pętli głównej (która "leci" cały czas bez milisekundy zwłoki) sprawdzasz i jak trafisz na flagę to ją kasujesz i wykonujesz jej zadania. Jednocześnie jeśli w przerwaniu wiesz, że flaga jest skasowana z programu głównego, to wtedy wiesz że zadanie zostało wykonane (czyli np. że została wysłana komenda Convert_T) i możesz zacząć liczyć czas do wykonania odczytu. Tymczasem pętla główna może robić co innego, a Timer można dodatkowo wykorzystać do innych rzeczy, np. zamiast funkcji debounce możesz napisać własny odpowiednik nie wstrzymujący działania programu. Na forum kiedyś o tym trochę pisałem i nawet z tego co pamiętam jakieś niezoptymalizowane gotowce nawet się pojawiały.

    0
  • #15 28 Sie 2011 18:07
    moons
    Poziom 13  

    Ustawiłem sobie Timer0 tak że liczy mi równo po 8 ms. Teraz jak rozumiem dążymy do takiego rozwiązania:
    ustawiam dwie flagi, np przy 0 ms do startu odczytu a potem przy np 104 ms do odczytu
    teraz tylko gdzie ustawić resztę komend, zostawić w GoSub: czy przenieść to wszystko do pętli głównej?
    Pozdrawiam

    0
  • Pomocny post
    #16 28 Sie 2011 19:49
    xury
    Poziom 38  

    Patrząc na Twój kod zastanawiam się po co te Gosub'y ?
    Co prawda w tym przypadku niczego nic złego się nie dzieje, ale na przyszłość na Twoim miejscu starałbym się ograniczać ilość "gołsabów", by nie wpaść w problemy ze stosami.
    Przecież te dwie linijki możesz śmiało napisać pod Case, a nie skakać do podprogramów, które i tak są używane tylko raz na pętlę. Teki podprogram miałby sens, gdyby był tylko jeden z przekazywaniem odpowiednich parametrów do jego "wnętrza"
    Co do timerów to wybierasz sobie taką rozdzielczość jaka Ci odpowiada i ustawiasz sobie tyle flag ile Ci jest potrzebne.

    0
  • #17 28 Sie 2011 21:30
    moons
    Poziom 13  

    No i coś popełniłem z timerem ale jest coś nie tak odczyt jest strasznie niestabilny i do tego strasznie mrugający. Pewnie źle rozbiłem pomiar temperatury flagami, ale próbuję poprawić a wychodzi tylko coraz gorzej.
    Co do tych Subów, to pomyślałem że tak będzie bardziej elegancko
    Pozdrawiam

    0
  • #18 28 Sie 2011 23:17
    xury
    Poziom 38  

    Masz błąd setki razy omawiany:

    Code:
    Load Timer0 = 250

    Zajrzyj do helpa i sprawdź jeszcze raz skladnię tego polecenia.
    Code:
    Load Timer0, 250

    lub
    Code:
    Timer0 = 6



    edit. Sorry pomyłka już późno było. Teraz wartości są poprawne.

    0
  • #20 28 Sie 2011 23:55
    moons
    Poziom 13  

    @xury, mój błąd korzystałem z książki o programowaniu w Bascomie Pana Wiązania i myślałem że jest O.K. Ale nawet jeśli ja tam znalazłem błędy w innych listingach to znaczy że trzeba bardziej uważać przy korzystaniu z tej lektury.
    @piotrva chyba nie do końca bo według dataszeta przy rozdzielczości 9 bitowej to potrzebuje tylko 93,75 ms.

    Poprawiłem ten błąd ale niestety nic to nie dało, nadal menu z wyświetlaniem temp strasznie mruga i odczyty są od zera do jakichś krzaków.
    Pozdrawiam

    0
  • Pomocny post
    #21 29 Sie 2011 08:31
    snnaap
    Poziom 25  

    1.

    Cytat:
    odczyty są od zera do jakichś krzaków

    Przed każdą instrukcją związaną z komunikacją 1-wire
    musisz wyłączyć wszystkie przerwania ponieważ 1-wire będzie się rozjeżdżał i będą wychodzić głupoty.

    2.
    Cytat:
    nadal menu z wyświetlaniem temp strasznie mruga

    Nie ma się co dziwić, że mruga jeżeli masz tak to napisane:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    W tym ciągu napisanym przez ciebie zasada jest taka, że co chwile obojętnie czy zmienisz menu czy nie czyścisz ekran i coś na nim wyświetlasz.
    1. Po pierwsze powinieneś czekać, aż coś się zmieni czyli albo zmieni się numer menu albo zmieni się temperatura.
    2. Zmiana aktualnie wyświetlanej temperatury powinna być gdy Cz_odw = 1 lub Cz_odz = 1.
    3. Przy uaktualnianiu temperatury używaj Locate a nie czyść cały ekran.

    0
  • #22 29 Sie 2011 16:13
    moons
    Poziom 13  

    snnaap napisał:
    Przed każdą instrukcją związaną z komunikacją 1-wire
    musisz wyłączyć wszystkie przerwania ponieważ 1-wire będzie się rozjeżdżał i będą wychodzić głupoty.


    No to próbowałem to tak zrobić. Czy wystarczy samo Disable Interrupts czy każde przerwanie trzeba z osobna? Niestety dalej krzaki, często 0 stopni, rozsunąłem nawet flagi a dalej nie jest dobrze. Natomiast z wyświetlaniem jeszcze nawet nie próbowałem. Zastanawiam się jak to można zrobić żeby menu odświeżyć przy zmianie lub numeru menu lub zmianie temp.

    Muszę gdzieś jednak znaleźć jakiś podobny komputerek żeby zobaczyć jak to powinno wyglądać.

    Pozdrawiam

    Żeby być pewnym na 100% to jak odczytać temperaturę z 2 czujników DS18B20?
    pierwszy czujnik:
    1wreset
    1wwrite &H55
    1wverify ID pierwszego układu
    1wwrite &HBE
    odczekać czas na pomiar
    temperatura1 = 1wread(2)

    drugi czujnik
    1wreset
    1wwrite &H55
    1wverify ID drugiego układu
    1wwrite &HBE
    odczekać czas na pomiar
    temperatura2 = 1wread(2)

    Czy coś jeszcze trzeba? Bo ja już namieszałem ostro przy tych czujnikach

    0
  • Pomocny post
    #23 29 Sie 2011 19:51
    snnaap
    Poziom 25  

    moons napisał:


    Żeby być pewnym na 100% to jak odczytać temperaturę z 2 czujników DS18B20?
    pierwszy czujnik:
    1wreset
    1wwrite &H55
    1wverify ID pierwszego układu
    1wwrite &HBE
    odczekać czas na pomiar
    temperatura1 = 1wread(2)

    drugi czujnik
    1wreset
    1wwrite &H55
    1wverify ID drugiego układu
    1wwrite &HBE
    odczekać czas na pomiar
    temperatura2 = 1wread(2)

    Czy coś jeszcze trzeba? Bo ja już namieszałem ostro przy tych czujnikach


    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod








    Albo mi się zdaje albo coś namieszałeś.


    prawidłowa kolejność obsługi czujnika wygląda tak:

    //start konwersji
    1wreset
    1wwrite &H55
    wysłanie ID pierwszego układu
    1wwrite &H44
    odczekać czas na pomiar

    //odczyt temperatury
    1wreset
    1wwrite &H55
    wysłanie ID pierwszego układu
    1wwrite &HBE
    temperatura1 = 1wread(2)


    i tak samo dla drugiego.



    Lub dla obu czujników to robisz inaczej:


    1wreset
    1wwrite &HCC
    1wwrite &H44
    odczekać czas na pomiar

    W tym momencie oba naraz "konwertują" temperaturę.

    a następnie odczytujesz układy w sposób jak powyżej.


    A tym masz jakoś namieszane w programie ponieważ w procedurze "odbioru temperatury" masz

    1wwrite &HCC
    1wwrite &H44
    czyli start konwersji

    Sposobem na błędy w transmisji może być zawsze CRC.
    w przypadku błędnego CRC wynik pomijasz i już.

    0
  • #24 29 Sie 2011 21:28
    moons
    Poziom 13  

    No poprawiłem trochę ten kod, przy okazji zaoszczędziłem dwie flagi i teraz odczyty chyba są O.K. ale tylko chyba bo nadal czasem wyskoczy 0 ale to pewnie dlatego że nie potrafię jeszcze się pozbyć tych waitms z wyświetlania menu. Zupełnie nie mam pojęcia jaka można by to zrobić. Bo Cls przecież musi być żeby wyczyścić menu po zmianie. Np przez kolejne flagi ustawione po odczycie?
    Pozdrawiam

    Poprawiłem też menu. W tej chwili nic nie mruga temperatura wyświetla się dobrze ale po starcie nie wyświetla się nic dopiero po pierwszym naciśnięciu przycisku. No i jeszcze poczytam o tym CRC żeby nie łapać śmieci które pewnie będą się pojawiać.

    0
  • #25 30 Sie 2011 09:07
    snnaap
    Poziom 25  

    Musisz dodać sobie tymczasowe zmienne takie jak poprzednia temperatura oraz poprzednie menu i zmieniać zawartość wyświetlacza wtedy gdy poprzednie menu i nowe menu są różne od siebie i tak samo z temperaturą jeżeli masz wyświetlone menu 1 i temperatura zmierzona w poprzednim cyklu jest różna niż w obecnym to zmieniasz zawartość wyświetlacza.

    Ps. nie wrzucaj spakowanego kodu, wklejaj go do postu tak jak to robiłeś na początku.

    0
  • #27 30 Sie 2011 23:59
    moons
    Poziom 13  

    @xury zastanawia mnie jedna rzecz i widzę to nie tylko u Ciebie w kodzie ale w kilku które znalazłem w sieci. Chodzi o komendę wysyłaną do DS:
    u Ciebie
    1wwrite Dsadres1(1) , 8
    u mnie
    1wverify Dsid1(1)

    jak u siebie przerabiam na write to nie mam odczytu temperatury. Reszta komend jest taka sam u ciebie i u mnie. O co chodzi z tym write i verify. Wydaje mi się że powinno być write a u mnie nie idzie.
    Pozdrawiam

    0