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.

Pamięć do rejestratora. Nieulotna, prosta w obsłudze.

aceman 24 Paź 2006 15:29 1716 15
  • #1 24 Paź 2006 15:29
    aceman
    Poziom 11  

    Witam wszystkich serdecznie :D

    Od niedawna zacząłem programować w C. Potrzebuję wykonać rejestrator temperatury. Zastosowane w nim będzie kilka przetworników.
    Problem mam z dobraniem jakiejś nieulotnej, prostej w obsłudze pamięci zewnętrznej :?:, jednocześnie takiej, w której będę mógł zapisać sporo danych.
    Proszę doradźcie mi jakieś dobre rozwiązanie.

    Z góry dziękuję i pozdrawiam :!:

    0 15
  • Pomocny post
    #2 24 Paź 2006 15:59
    Piotr PIeczykolan
    Poziom 11  

    np. 24C1024 EEPROM I2C 128kB

    0
  • Pomocny post
    #3 24 Paź 2006 20:36
    GienekS
    Poziom 32  

    albo: AT45DB321 szybka i pojemna 32M bity z dwoma buforami po 528 bajtów

    0
  • Pomocny post
    #4 24 Paź 2006 22:15
    zumek
    Poziom 39  

    Ewentualnie: SD,CF czy MMC 8GB - miało być "sporo" :D

    Piotrek

    0
  • #5 25 Paź 2006 00:09
    aceman
    Poziom 11  

    8GB to trochę przy sporo :D.
    Wstępne założenia wyglądają następująco:
    będzie zastosowanych 8 przetworników temperatury DS18B20 w przemysłowych obudowach. Przetworniki pracują na magistrali 1Wire.
    Myśle, że 16 bitów wystarczy na zakodowanie czasu odczytu i temperatury. Temperatura będzie sczytywana co 1 minutę. Układ powinien pomieścić pomiary przynajmniej z miesiąca co daje ok 45000 pomiarów na miesiąc z jednego czujnika. x8 daje 360000 16-bitowych pomiarów.
    Czy do tego wystarczy AT45DB321??? I jak się ją obsługuje??

    0
  • Pomocny post
    #6 25 Paź 2006 01:04
    pubus
    Poziom 30  

    Coś mi się nie wydaje żeby 16 bitów wystarczyło...
    Data:
    dzień - 8
    miesiąc - 8
    rok - 8 - zkładam, że wystarczy zapis 06
    czas:
    godziny - 8
    minuty - 8
    no i pomiar 8
    Czyli w sumie 6 bajtów...

    Jak to chcesz na 16 bitach zakodować...?.?.?

    0
  • Pomocny post
    #7 25 Paź 2006 10:58
    olekewaagata
    Poziom 25  

    Ciemno widzę!
    Zamiast pytać się czy się zmieści wystarczy wpisać w google i masz wszystko o tej pamięci. I widać też piękne obudowy w których jest ta pamięć. A żeby nie był to post bez treści odpowiadam: tak w tej pamieci zmmieszczą się twoje dane, to jest pamięć 4Mb.

    0
  • Pomocny post
    #8 25 Paź 2006 11:32
    Pituś Bajtuś
    Poziom 28  

    Cytat:
    to jest pamięć 4Mb

    A ja bym powiedział, że to jest pamięc 4MB. Róznica niewielka - tylko osmiokrotna.

    0
  • Pomocny post
    #9 25 Paź 2006 17:47
    olekewaagata
    Poziom 25  

    Masz absolutną racje.

    0
  • #10 25 Paź 2006 18:58
    aceman
    Poziom 11  

    Cytat:
    Jak to chcesz na 16 bitach zakodować...?.?.?

    Oczywiście najprostszym rozwiązaniem jest zakodowanie każdego czasu pomiaru, lecz tak jak zauważyłeś zajmuje to sporo bitów.
    Ja mam zamiar inaczej to rozwiązać. Np. najstarszy bit będzie określał znacznik czasu, w którym będzie zakodowana jakaś data itd. Kolejne np 4-5 bitów będą określały odstęp czasowy między znacznikiem lub poprzednim pomiarem (sprawa do rozważenia). W ostatnich 10 bitach będzie zapisana temp. Dzięki takiemu rozwiązaniu powinno się znacznie zaoszczędzić na pamięci.
    Jeżeli ktoś ma ciekawsze rozwiązania lub krytykę co do powyższego to piszcie.

    Pozdrawiam

    0
  • Pomocny post
    #11 25 Paź 2006 22:04
    zumek
    Poziom 39  

    aceman napisał:
    ...Temperatura będzie sczytywana co 1 minutę...

    Jeśli tak to ma wyglądać , to np. na końcu pamięci rezerwujemy kilka(naście/dziesiąt) bajtów na dokładną informację , którego dnia , miesiąca , roku , rozpoczęto pomiary i ewentualnie kogo/czego te pomiary dotyczą.Następnie zapisuj 2 bajty/DS wynik pomiaru co 1 minutę ,bez dodatkowych danych.Jeśli ten zapis będzie następował w równych odcinkach czasu , to łatwo wyliczysz , gdzie w pamięci znajdują się dane dotyczące konkretnego momentu i na odwrót.Wszystko zależy od precyzji odmierzania czasu.Można np. co 1 dobę , synchronizować dane jakąś dodatkową ramką w pamięci.Myślę że możliwości jest sporo :D

    Piotrek

    0
  • #12 25 Paź 2006 22:32
    aceman
    Poziom 11  

    Powyższy pomysł jest całkiem niezły. Jedynie wadą tego rozwiązania jest to, że nie mogę zmieniać interwału czasowego, a co ma być możliwe w projektowanym układzie. Stosując znaczniki mógł bym zmieniać interwał w dowolnej chwili, nie martwiąc się o zmianę poprzednich danych.

    0
  • Pomocny post
    #13 25 Paź 2006 23:05
    zumek
    Poziom 39  

    aceman napisał:
    Powyższy pomysł jest całkiem niezły. Jedynie wadą tego rozwiązania jest to, że nie mogę zmieniać interwału czasowego, a co ma być możliwe w projektowanym układzie. Stosując znaczniki mógł bym zmieniać interwał w dowolnej chwili, nie martwiąc się o zmianę poprzednich danych.

    To ostatecznie , można temperaturę upchnąć w 10-ciu bitach , a w pozostałych 6-ciu , zapisywać interwał od ostatniego pomiaru , lub do następnego pomiaru.Utrudnieniem będzie interpretacja takich danych , bo trzeba odczytywać kolejne ramki danych , by dotrzeć do interesującego nas momentu. Jeśli to będzie robił pecet, to pryszcz , choć AVR-ek też "nie w kij dmuchał" :D

    Piotrek

    0
  • #14 26 Paź 2006 09:32
    seba_x
    Poziom 31  

    EdW z kwietnia 2004 , strona 55 i wszystko jasne

    0
  • #15 31 Paź 2006 22:18
    andre65
    Poziom 13  

    Zamiast się pocić z upychaniem tego na skompresowanym formacie po prostu użyj większej pamięci. Ja stosowałem ta AT45DB321 i jest bardzo przyjemna w obsłudze.

    0
  • #16 01 Lis 2006 01:20
    shg
    Specjalista techniki cyfrowej

    Wystarczy znać dokładny czas rozpoczęcia i zakończenia pomiarów oraz ich ilość.
    Nawet jeżeli odstęp między pomiarami nie będzie wynosił dokładnie 1 minuty, to mając powyższe dane możemy go wyznaczyć bardzo dokładnie.

    Wyniki i tak będzie pewnie obrabiał komputer, bo nie wyobrażam sobie robienia tego "na piechotę", więc problemu też nie ma, komputerowi jest wszystko jedno jaka była częstotliwość pomiaru, byle by tylko był w stanie przetworzyć taką wartość, a wszystko można uwzględnić w obliczeniach.

    Gorzej tylko jak podczas dokonywania pomiarów coś się zpsuje (na przykład padnie zasilanie), utrudnia to wtedy i to dość znacznie odtworzenie informacji o częstotliwości pomiarów.
    Na szczęście i na to jest rada, można użyć zewnętrznego RTC z podtrzymaniem, stosowane w nich kwarce 32768Hz charakteryzują się bardzo dużą dokładnością, a jeżeli nie są zabudowane wewnątrz modułu (jak w "komputerowych" RTC z Dallasa) to można jeszcze trymerkiem skorygować. Błąd poniżej minuty na miesiąc jest jak najbardziej możliwy do uzyskania (i to bez większego wysiłku).

    Z takim RTC Można już zagwarantować sobie dokładny interwał między kolejnymi pomiarami.
    A na wypadek zaników zasilania rezerwujemy sobie jeden bit w ramce ze zbieranymi danymi.
    W programie przechowujemy flagę, oznaczającą konieczność "zrzucenia" do pamięci aktualnego czasu. Domyślnie po resecie flagę ustawiamy na 1.
    Program startuje i zaczyna normalnie wykonywać pomiary.
    Składanie ramki z danymi wygląda tak:
    Zapisujemy flagę.
    Jeżeli flaga ustawiona jest na 1, to do pamięci zapisywany jest aktualny czas, potem zmienna flaga jest zerowana i procedura składania i zapisu ramki wywoływana jest rekurencyjnie (tym razem flaga = 0)
    Jeżeli flaga = 0, to zapisujemy ramkę z wynikami.
    Można też się obejść bez rekurencji, kwestia gustu.
    W ten oto sposób Uzyskujemy w pamięci strumień danych, który po każdym włączeniu zasilania ma Zapisany dokładny czas tego zdarzenia, a wyniki pomiarów pomiędzy kolejnymi znacznikami czasu są w odstępach wynoszących dokładnie minutę.

    Przy odczycie danych sprawdzamy najpierw czy pierwszy bit jest równy 0 lub 1 i w zależności od tego wywołujemy procedurę, która wyciągnie ze strumiania pomiary, albo procedurę, która odczytuje czas.

    zupełnie schematyczny kod:

    Code:
    bool poweron = true; /* globalna flaga (true lub false, czyli 1 lub 0) ustawiana zawsze po włączeniu zasilania */
    

    main() {
      while(1) {  /* wieczna petla */
      czekaj_na_RTC();  /* oczekiwanie na sygnal z RTC, podawany co minutę */
      dane = pomiar(); /* zebranie danych pomiarowych */
      zapisz_ramke(dane);  /* i zapis ramki */
      }
    }

    zapisz_ramke(dane) {
      strumien << poweron;  /* zapisanie do strumienia flagi */




      if(flaga = true) {
        strumien << czas_z_RTC();
        poweron = false;
        zapisz_ramke(dane);  /* wywolanie rekurencyjne */
      } else {  /* a to wykona sie jezeli flaga = false (0), czyli gdy od czasu poprzedniego pomiaru nie nastapil zanik zasilania */
        strumien << dane;
      }
    }


    Procedura dekodowania danych wyglada tak:
    Code:
    pomiary[N]; /* N pomiarow, wartosc N kontroler moze podac przed rozpoczeciem transmisji
    
    czasy[N]; /* wartosc czasu odpowiadajace pomiarom */ */
    czas = 0; /* poczatkowy czas, nie wiadomo jaki, zostanie i tak odczytany kiedys ze strumienia, a jak nie to przynajmniej bedzie sie od zera zaczynalo */
    c = 0;  /* aktualna pozycja w tablicy (czyli numer pomiaru)*/
    while(jest_cos_jeszcze_w_strumieniu(strumien)) {
      if(pobierz_1_bit_ze_strumiena(strumien) == 1) {
        czas = pobierz_czas(strumien);
      } else {
        pomiary[c] = pobierz_dane(strumien);
        czasy[c] = czas;
        czas = czas + 1 minuta;
        c = c+1;
      }
    }

    W ten sposob uzyskuje sie dwie tablice, jedna p[rzechowuje dane pomiarow, druga odpowiadajace im czasy, dane w takiej formie najlatwiej obrabiac za pomocą powszechnie używanego do tego oprogramowania (matlab, octave, mathcad, czy paskudny excel który tak naprawdę się do tego nie nadaje).

    Dla świętego spokoju można by jeszcze w rejestratorze dorobić dość prostą procedurę, któa zapewni, że sąsiednie wyniki będą występowały w odstępach niekrótszych niż 1 minuta, na przykład przez przeszukanie wstecz pamięci i zliczenie ilości pomiarów do poprzedniego znacznika czasu, jak będzie ich mniej niż 2, to znaczy że poprzedni zanik zasilania nastąpł mniej niż minutę temu i wtedy nowych danych nie zapisuje się.

    No i jeszcze jedna ważna rzecz - kontroler musi wiedzieć, od jakiego miejsca w pamięci ma zacząć zapis po zaniku zasilania, a do tego wykorzysta zapisywaną z każdą ramką flagę. Po włączeniu musi przeszukać całą pamięć od początku. A robi to tak, że sprawdza czy dwa razy pod rząd wystąpi ramka z czasem, czyli pierwszy jej bit będzie równy 1, właściwie to obie ramki nie będą wcale zawierały informacji o czasie, ale pierwsza z nich jako taka będzie musiała być zinterpretowana, bo nie podczas przeszukiwania strumienia niewiadomo co zawiera, a jeżeli zawiera autentyczną informację o czasie, to trzeba kontunuować dekodowanie, w drugiej natomiast wystarczy sprawdzenie tylko pierwszego bitu. Sam algorytm zapisy wyklucza możliwość pojawienia się dwóch następujących po sobie ramek z pierwszym bitem (flagą) ustawionym na 1. A włąściwośćią pamięci EEPROM jest to że w skasowanej wszystkie bity ustawione są na jeden. Jeżeli powyższa sytuacja zostanie wykryta, to za początek wolnego miejsca przyjmuje się początek pierwszej ramki z flagą ustawioną na jeden. Oczywiście po "zrzuceniu" wszystkich danych do komputera i rozpoczęciu nowej sesji pomiarowej pamięć wypada skasować, a właściwie to trzeba ją będzie kasować zanim zostanie zapisana do końca. Od biedy można też zastosować bufor kołowy, potrzebny do tego jest jeszcze jeden bit w każdej ramce. Dane można kompresować, najprościej metoda różnicowa + RLE, czyli przechowywanie różnic pomiędzy kolejnymi pomiarami, a następnie zapisywanie ilości następujących po sobie jednakowych (i niejednakowych) wartości. Przy zastosowaniu zamiast RLE jakiejś kompresji probabilistycznej (np. kodowanie Huffmana) można by zejść do średnio kilku (około 3...4) bitów na pomiar z pojedynczego czujnika. Z tym że kompresja dość znacznie komplikuje sprawę i w bnajprostszej implementacji (czyli przechowywanie sporej ilości wyników w pamięci, kompresja i zapis skompresowanych danych) pogarsza się niezawodność - przy zaniku zasilania więcej danych zostanie utracone. Oczywiście i temu można zaradzić, przez zapis danych nieskompresowanych i okresowe nadpisywanie ich danymi skompresowanymi.

    0