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

Atmega8/ Bascom - Multipleksowanie LED + termometr

Elektronik_Kraków 05 Lip 2014 01:16 2787 18
  • #1 05 Lip 2014 01:16
    Elektronik_Kraków
    Poziom 13  

    Witam
    Mam taki kod nie jest to całość tylko to z czym mam problem:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    problem jest z wyświetlaniem wartości temperatury na LED. Jeśli wartość zmierzona jest mniejsza niż 25,6 stopnia, to jest ok, ale dla większych wychodzi coś takiego:
    Ds_i1 = 256
    Stopnie_d = 0
    Stopnie_j = 0
    Stopnie_p = 0

    dla
    Ds_i1 = 305
    Stopnie_d = 0
    Stopnie_j = 4
    Stopnie_p = 9

    dla
    Ds_i1 = 320
    Stopnie_d = 0
    Stopnie_j = 6
    Stopnie_p = 6

    dla wartości 255, czyli 25,5 stopnia
    Ds_i1 = 255
    Stopnie_d = 2
    Stopnie_j = 5
    Stopnie_p = 5

    liczyłem to na kalkulatorze i powinny wychodzić inne wartości.

    Dodatkowo jest problem w momencie odczytu temperatury z czujnika DS18B20. Na 1 sekundę przygasa wyświetlacz. Jest to zapewne związane z blokowaniem przerwań na czas odczytu. Czy jest możliwość, żeby to "przygaszanie" zlikwidować lub przynajmniej zmniejszyć ?

    0 18
  • CControls
  • #2 05 Lip 2014 13:45
    piotrva
    Moderator na urlopie...

    Po pierwsze problemem jest 255, więc zapewne przepełnienie typu itp. - niestety w Bascom rzutowanie typów jest niejawne i pewnie całe operacje trzeba zrobić na intigerze a potem dopiero wrzucić do Byte.
    Co do przygasania - nie pokazujesz pełnego kodu programu, ale rzeczywiście na dosyć długi wyłączasz przerwania

    0
  • CControls
  • #3 05 Lip 2014 14:39
    M. S.
    Poziom 34  

    Pomiędzy zainicjowaniem pomiaru a odczytem danych z DS'a powinien upłynąć czas 750ms lub więcej.
    Wczytaj dane z DS do tablicy dwuelementowej Byte, a później oba bajty wtłocz do zmiennej integer albo word np. przez Makeinit.
    Zsynchronizuj obsługę DS'a z multipleksowaniem wyświetlacza to nie będzie migał. Dla skrócenia czasu komunikacji z DS wysyłaj lub odbieraj jednorazowo jak najmniejszą ilość danych. Np osobno:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    osobno
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #4 05 Lip 2014 19:43
    emarcus
    Poziom 35  

    M. S. napisał:


    Wczytaj dane z DS do tablicy dwuelementowej Byte, a później oba bajty wtłocz do zmiennej integer albo word np. przez Makeinit.


    Dla temperatur tylko dodatnich można użyc zmiennej word, natomiast jeżeli wystąpią temperatury ujemne bezwzględnie trzeba zastosowac tu zmienną interger; inaczej wystąpią absurdalne interpretacje odczytów temperatury.
    Dla przykładu:
    Temperatura "-25.1" i konvertowany odczyt do zmiennej integer
    wyświetla:
    Atmega8/ Bascom - Multipleksowanie LED + termometr

    natomiast ta sama temperatura ("-25.1") [przy tejsamej konversji 'makeint' do zmiennej typu word - otrzymujemy:
    Atmega8/ Bascom - Multipleksowanie LED + termometr

    Niezależnie od metody wyświtlania; LED, LCD, terminal.

    e markus

    0
  • #5 05 Lip 2014 20:41
    atom1477
    Poziom 43  

    No niestety BASCOM tak ma. Zdaje mi się że takie obliczenia kiedyś działały (operacje na integer a zwracanie wyniku do Byte). Widocznie od którejś nowej wersji już nie działają.
    No to będziesz musiał zrobić tak:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #6 05 Lip 2014 21:08
    Elektronik_Kraków
    Poziom 13  

    Kolega piotrva i atom1477 mieli oczywiście rację, teraz jest OK.

    Natomiast w kwestii migania przy odczycie temperatury, to może to rozbić na takie części

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Jeśli chodzi o zakres temperatur, to tylko dodatnie, więc makeint powinno się sprawdzić, termometr ma być dodatkiem do budzika

    0
  • #7 05 Lip 2014 21:12
    atom1477
    Poziom 43  

    Ja bym dał Disable Interrupts i Enable Interrupts pomiędzy wszystkimi operacjami 1Wire:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #8 05 Lip 2014 21:43
    M. S.
    Poziom 34  

    Cytat:
    bezwzględnie trzeba zastosowac tu zmienną interger


    ... albo prostą obróbkę zmiennej Word poprzez uzupełnienie do dwóch.

    P. S. Mam właśnie na stole taki termometr. Wyświetlacz jest multipleksowany timerem w przerwaniach co 8ms. Każde przerwanie powoduje jednokrotne uruchomienie innego fragmentu programu w pętli głównej, w tym innego fragmentu obsługi DS'a. Komunikacja z DS'em się wyrabia.

    0
  • #9 05 Lip 2014 23:02
    Elektronik_Kraków
    Poziom 13  

    [quote="M. S."]

    Cytat:

    P. S. Mam właśnie na stole taki termometr. Wyświetlacz jest multipleksowany timerem w przerwaniach co 8ms. Każde przerwanie powoduje jednokrotne uruchomienie innego fragmentu programu w pętli głównej, w tym innego fragmentu obsługi DS'a. Komunikacja z DS'em się wyrabia.


    Ale wprowadza Kolega jakieś opóźnienie pomiędzy tymi uruchomieniami ?
    Np. zliczanie przepełnień licznika
    Czyli jedna flaga zezwala w ogóle na pomiar, a druga zmienna wyznacza, który fragment ma się uruchomić.

    0
  • Pomocny post
    #10 06 Lip 2014 08:02
    M. S.
    Poziom 34  

    Timer w przerwaniu obsługuje wyświetlacz LED i inkrementuje zmienną byte, która w pętli głównej w instrukcji Case wybiera konkretne funkcjonalne fragmenty programu do wykonania, których wykonanie czasowo mieści się pomiędzy przerwaniami od timera.
    W przerwaniu od timera ustawia się także flaga przerwania, która uruchamia za pomocą If Then instrukcję Case. Pętla główna po pierwszym przebiegu kasuje tą flagę.

    0
  • #11 27 Lip 2014 14:00
    Elektronik_Kraków
    Poziom 13  

    Witam ponownie
    Sugestia Kolegi M. S. była pomocna.
    Całość wygląda tak

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Na razie mierzy dwa razy na minute, przy 20 i 40-tej sekundzie.

    Natomiast dodałem obsługę pilota NEC i tutaj mam problem. Kody odbiera prawidłowo. Mogę zmieniać co ma być wyświetlane na LED. Ale nie mogę zmienić ustawień czasu, tzn. resetuję wartość sekund, widzę to na LED, a program po odczycie PCF8563 przez przerwanie od PCF i tak pokazuje starą wartość, tak, jakby nic nie zapisał do PCF8563.
    Zakładam, że jak zmienię jedną wartość i zapiszę to pozostałe są takie jak były tuż przed zapisem.

    0
  • #12 27 Lip 2014 15:10
    atom1477
    Poziom 43  

    Przy zapisie nie powinieneś dawać impulsu Repeated Start oraz wszystkiego co z nim związane (czyli ponownego adresu, itp.).

    0
  • #13 27 Lip 2014 21:27
    Elektronik_Kraków
    Poziom 13  

    Usunąłem dwie linie:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    ale brak różnicy

    Ten kod zapisu podają również w samplach Bascoma ( co prawda tam zapis i odczyt jest w pętli FOR .. NEXT). I generalnie się sprawdza. Podobnie jak w przypadku Atmega8 + LED na MAX7219 - tutaj działa jak trzeba.

    Nawet dla testu dołożyłem zmienną, dla sekund - sekundy_ustaw i na niej operowałem przy otrzymaniu danych z pilota.

    0
  • #14 30 Lip 2014 22:24
    Elektronik_Kraków
    Poziom 13  

    No i przedobrzyłem
    Dokonałem optymalizacji kodu, oszczędzając kilkanaście procent pamięci FLASH, ale... sygnał z pilota NEC ( takie małe płaskie na baterie pastylkową ) przestał być odbierany - brak jakiejkolwiek reakcji na naciśnięcie przycisku w pilocie.

    Poniżej kod:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Kod do odbioru z pilota NEC sprawdzony w innym projekcie, odbiór w przerwaniu INT1 z wykorzystaniem Timer2. Dodałem Print Command w przerwaniu Infrared, żeby sprawdzić, czy coś odbiera - reakcji brak, jakby w ogóle nie był włączony odbiornik.

    0
  • #15 31 Lip 2014 11:30
    atom1477
    Poziom 43  

    Napisz co konkretnie zmieniłeś w momencie jak przestało działać.
    A jak nie wiesz to powoli wracaj do wersji kiedy działało.
    Np. zacznij od kodu który tylko odbiera kody od pilota a potem dodawaj po kawałku obsługę I2C, wyświetlacza, 1Wire, itd.

    0
  • #16 31 Lip 2014 11:45
    Elektronik_Kraków
    Poziom 13  

    Witam
    Zmieniłem sposób obsługi wyświetlania.
    Początkowo miałem tak :

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    czyli w przerwaniu ustawiałem tylko flagę dla wyświetlacza i zwiększałem jego numer, samo wyświetlanie było w podprogramach razem z obliczeniami, wywoływanych warunkiem określającym co ma być wyświetlane.

    ----------------------
    W drugiej wersji, kod poniżej, przeniosłem obsługę wyświeltania do przerwania, natomiast obliczenia są w pętli głównej z warunkiem określającym, które obliczenia mają być wykonywane i ich wyniki przekazywane do wyświeltania. W tej wersji jest spora oszczędność kodu, ale "zamilkł" odbiór pilot NEC w przerwaniu


    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #17 31 Lip 2014 12:26
    atom1477
    Poziom 43  

    No to masz odpowiedz.
    Wyświetlanie zajmuje za dużo czasu i przerwanie się nie wyrabia.

    0
  • #18 31 Lip 2014 12:44
    Elektronik_Kraków
    Poziom 13  

    Czyli zostaje mi korzystanie z pilota RC5 zamiast NEC ( używam takiego w projekcie z multipleksowaniem bez 74HC595 i działa pięknie i to bez przerwania ), bo ciężko będzie wrzucić obsługę pilota NEC bez przerwania - myślałem, że może by sprawdzać stan portu wejściowego odbiornika, ale to raczej nie zadziała. Szkoda, bo piloty NEC tanie i poręczne, a te RC5, które mam do telewizorów to masakra, trzeba naściskać, żeby zadziałały.

    0
  • #19 31 Lip 2014 13:09
    atom1477
    Poziom 43  

    Może być i NEC, po prostu musisz napisać kod tak żeby nie zżerał tyle procka. Wyświetlanie w pętli głównej na przykład zostawić. Albo w przerwani nie będzie ale je rzadziej wywołuj.

    0