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.

Atmega16+PCF8583+BASCOM

marrog 27 Maj 2009 21:51 8774 60
  • #31 27 Maj 2009 21:51
    janbernat
    Poziom 38  

    To w Bascomie w opcjach "programmer" spróbuj wpisać "delay" 10-100.

  • #32 27 Maj 2009 22:26
    marrog
    Poziom 22  

    Rano wypróbuje.
    Nie wiem co z tym RS jest nie tak, wpisałem praktycznie tak jak jest w pdf z ep kod i nie działa.

  • #33 27 Maj 2009 23:08
    janbernat
    Poziom 38  

    A sprawdziłeś to co napisał Andy74?
    Komunikacja z PC po RS232.
    485 ma takie same parametry komunikacji tylko jest to pętla prądowa i ma większy zasięg.
    Jak sprawdzisz komunikację z PC to będziesz wiedział że protokół jest dobry.
    A potem można sprawdzać czy 1km kabla jakiś kretyn szpadlem nie przeciął.
    I w EP te programy są na ATmega8-a Ty masz
    ATtiny2313.

  • #34 28 Maj 2009 07:34
    Andy74
    Poziom 24  

    Te kondensatory odsprzęgające zasilanie MAX485 też nie znalazły się na schemacie przypadkowo. Proponuję je wlutować, i to jak najbliżej nóżek układu. Nie zaszkodzi też dać przynajmniej po 100nF między Vcc a GND procesorów.
    Nie lekceważ filtracji zasilania, bo to się często mści.

  • #35 28 Maj 2009 16:03
    marrog
    Poziom 22  

    Witam

    Dzięki za odpowiedzi, zaraz mykam do elektronika i wlutuje, to napiszę co z tego wszystkiego wyszło.

    Dodano po 4 [godziny] 12 [minuty]:

    Witam

    Wiec tak, wlutowalem rezonatory i kondensatory pod MAX a takze na zasilaniu uP.
    Chcialem zmienic rezonator przy ATmedze wybralem odpoweidni i dalem Write FS i pojawilo sie okno ze "READLB entry not found"wiec dalem OK i teraz nie moge zidentyfikowac ani ATmegi ani ATTiny, dodam ze przy Attiny nic nie zmienilem. Wyskakuje mi ze nie moze zidentyfikowac chip-a tak jakby programator byl odpiety.

    Port lpt jest ok.

    Attiny rozpoznaje a ATmegi nic :/ Pewnie czeka mnie podróż po nową ATmege16 ( co za urok - od wczoraj nic nie wychodzi)

    Dodano po 1 [godziny] 22 [minuty]:

    Chyba go nie zblokowalem, tylko zel ustawilem mu zegar, zamiast 8MHz wyszlo mi że ma pracować na kwarcu 1-3MHz :/, dopiero po przeczytaniu art. Ustawienia_Fusy widzę jak namieszałem.

    Dodano po 46 [minuty]:

    Uch odratowany ATmega16 troszke sie pobawiłem, ale uratowałem go :-)

    Dodano po 9 [minuty]:

    Teraz to się troche boje go przestawiać na te 8MHz ( może mi ktos podać jak w BASCOmie poprawnie mam go ustawić,aby chodził na tych 8MHz (kwarc)

    Dodano po 1 [godziny] 11 [minuty]:

    Nie wiem czy dobrze wyczytałem z pdf.-a ATmega16 w BASCOM-ie ustawiam:
    Ext.Crystal/Resonator high freq, start up time 1K CK+64ms (CKSEL=1111 SUT=00)
    CKOPT = 1 ?
    A teraz mam jak wyżej z tym że CKOPT=0 i korzysta z zewn 14MHz z hakiem.

    A dla ATtiny2313
    Ext.Crystal Osc; Freq 3.0-8.0MHz Start-up time 14Ck+65ms (CKSEL=1101 SUT=00)

  • #36 28 Maj 2009 16:41
    janbernat
    Poziom 38  

    Zrób sobie generator 1-5Mhz na HC14 na jakimś ogryzku płytki uniwersalnej jak masz takie "skłonności" do lekkomyślnego ustawiania fusebitów.
    Podczepiasz do OSC1 i w większości przypadków procesor startuje.
    KLA987 111111 ustaw dla ATmega32-zresztą w Bascomie masz podpowiedzi co to jest.
    A co z ATtiny?

    Dodano po 6 [minuty]:

    Ja ustawiam 16CLK+64ms jak start po resecie nie jest krytyczny.
    Dla 8Mhz CKOPT=1, dla 16Mhz CKOPT=0-bo nie wystartuje.
    Pośrednich częstotliwości nie sprawdzałem.

    Dodano po 4 [minuty]:

    Kup sobie listwę gniazdek (taka "odwrotność" goldpinów) i po odłamaniu trzech wlutuj zamiast kwarcu.
    Wtedy wpinasz taki kwarc jaki chcesz bez lutowania.
    Do projektowania b. wygodne.

  • #37 28 Maj 2009 22:36
    marrog
    Poziom 22  

    Witam

    Już ustawiłem ( z pomocą kolegi z forum ), i ATtiny i Atmega działają na 8MHz.
    Okazało się że to nie moje skłonności do fusbitów ale połączenie na pcb ( pająk) zawiodził przy rezonatorach i nie działały attiny- przelutowałem i jest OK.
    Teraz pozostaje ten nieszczęsny RS-485

    Dodano po 1 [godziny] 37 [minuty]:

    Podpiałem pod attiny LCD i wpisałem w różnych miejscach kodu SLAVE jakiś tekst na LCD zatrzymuje mi się do "Pasi Adres" a dalej juz nie idzie, tzn że nie rozpoznaje znaku ENTER w kodzie ASCI 13.
    Ciekawa sprawa, moze sprobuje jakis inny znak mu dac jeszcze :-)

    Dodano po 16 [minuty]:

    No i zaczyna coś działać w obu kierunkach :-)

    Dodano po 4 [minuty]:

    No teraz dziala jak powinno. troszke zmieniłem program z EP i w końcu ruszyło :-)

    Dodano po 3 [godziny] 3 [minuty]:

    Zaczyna mnie ten rs wykańczać, wszystko działało jak należy, dodałem parę komentarzy i usunąłem kilka niepotrzebnych rzeczy które kontrolnie miały się wyświetlać na LCD no i lipa, znowu nie działa.
    Może to wina że teraz programuje go z innego kompa i coś poprzez BASCOM-a i PonyProg nie mogę zapisać do Atmega16 wyskakuje że zapisywanie nieudane.

    Dodano po 34 [minuty]:

    Zauważyłem, że inny program wpisuje normalnie,a ten główny ( zajmuje ponad 53%) coś nie chce zapisać. Spróbuje jutro na swoim kompie. Mam nadzieję że będzie OK.

  • #38 29 Maj 2009 08:49
    marrog
    Poziom 22  

    Witam No i nadal nie moge zaprogramować tego ATmega16, wyskakuje przy weryfikacji w PonyProg Write Failed, a w BASCOM-ie Difference at........... i tu jakaś komórka, nie zawsze ta sama.
    Dodam, że w połączeniu na PCB nic nie zmieniałem, dodałem w programie kilka komentarzy i usunąłem niepotrzebne napisy które testowo miały pojawiać się na LCD.
    Kasować zawartość procka idzie.
    To na zapisywanie ma wpływ kod po kompilacji ( już sam nie wiem co o tym myśleć - dziwna sprawa).

    Dodano po 25 [minuty]:

    Sprobowałem coś takiego zrobić w PonyProg, dałem czyść procka,następnie czytaj jego zawartośc i wgraj to samo, no i czyścić ok, ale już przy wgrywaniu nie da rady.
    czyżby procek, a może programator?

  • #39 29 Maj 2009 11:49
    Andy74
    Poziom 24  

    Witam.
    Trochę mnie nie było.
    Miałem takie same problemy z programowaniem µP za pomocą STK200 jak Ty. Długo wszystko było OK, aż pewnego dnia zaczęły się kłopoty. Z początku procesor dawał się zaprogramować poprawnie dopiero za dziesiątym - dwudziestym razem (błąd weryfikacji), później problem znikał aż do restartu komputera. Doprowadzało mnie to do szewskiej pasji, ale cierpliwie szukałem recepty na tą przypadłość - nie znalazłem. W końcu już żaden procesor nie dał się zaprogramować programatorem na LPT, pomimo, że zrobiłem nowy. O dziwo jeden i drugi STK działa do dziś poprawnie na laptopie (Dell D610), a nie działa na stacjonarnym (LPT sprawny - sprawdzony drukarką). Na obydwu komputerach mam Win XP Pro aktualizowany na bieżąco.
    Wkurzyłem się i polutowałem USBAsp. Używam do dziś w połączeniu z AVRDUDE - sprawuje się świetnie, nigdy mnie nie zawiódł. Tobie też polecam jego budowę - nie będziesz żałował włożonej w niego pracy, choć jeśli wolisz, możesz też zakupić gotowy np. na Allegro.

    Pozdrawiam
    Andy

    PS. Obszerny temat o USBAsp

  • #40 29 Maj 2009 13:21
    marrog
    Poziom 22  

    Witam
    Andy74 zakupiłem dzisiaj nawet nowego uP i jest to samo, błą weryfikacji. Jak mi przyjdzie jeszcze budować nowy programator, to się chyba zastrzelę, jakiś nie fart pod koniec tego tygodnia? A było tak pięknie RS485 działał, na SLAVE dałem wartość która się zmieniała i wysyłał ją do ATmegi, wszystko łądnie i pięknie, aż do momentu następnego proghramowania, od tej chwili nie chce ruszyć ATmega z tym programem.
    Jestem zdesperowany po prostu i załamany.
    No cena bez obudowy to ok 35zł tylko nie wiem czy mogę podać link do sklepu w którym to mają w obudowie kosztuje 59zł

    Dodano po 53 [minuty]:

    Przeczytałem topic na elektrodzie i ktoś opisał, aby zmienic na wewn. taktowanie, więc tak zrobiłem i wgrywa do procka kod. Jednak dziwne jest to, że program nie działa - wyskakuje mi jakis krzaczek na LCD i stoi. Usuwam ( zaznaczm jako koment) linie w kodzie :

    Code:

    Set Re_de
    Waitms 1
    Print "{008}1r"
    Waitms 1
    Reset Re_de
    Call Odczyt_zn
    If Czekaj > 100 Then
       Lcd "t=?"
       Wait 1
    Else
       Temp_odcz = Val(zm_lan)
       Lcd ":" ; Temp_odcz
       Wait 2
    End If

    a tutaj podprogram Odczyt_zn
    Code:

    Sub Odczyt_zn
       Czekaj = 0
       Zm_lan = ""
          Do
             Incr Czekaj
             Zn = Inkey()
             If Zn >= "0" And Zn <= "9" Then
               Zm_lan = Zm_lan + Zn
             End If
             Waitms 1
          Loop Until Zn = "w" Or Czekaj > 100
    End Sub

    kompiluje wgrywam i program rusza, tzn. odczytuje z DS18B20 i mogę wchodzić w menu ( wszystko to co miałem przed RS485 działa) - czary jakieś czy coś ??

    -=pozdrawiam=-

    Dodano po 5 [minuty]:

    A jeszce takie pytanie, do ilu BASCOM kompiluje kod? Tzn czy jest jakies ograniczenie w wersji 1.11.9.0 ? wiem że starsze wersje miały do iluś kB kod a dopiero pełna wersja umożliwiała wgrywanie większego kodu ( i jego kimpilacje)

  • #41 29 Maj 2009 13:57
    Andy74
    Poziom 24  

    Do 4kB bodajże. Nie jestem pewien bo mam pełną wersję (którą kupiłem - żeby nie było). Ale z tego co pamiętam, jeśli przekroczysz, to powinieneś dostać błąd już podczas kompilacji.
    Co do błędnej pracy procesora - też mi się zdarzało, że program niby się wgrywał poprawnie, ale później nie działał, lub działał źle. Ten sam (skompilowany w pełnej wersji) wgrany za pomocą laptopa i wersji demo Bascoma działał prawidłowo... Trochę włosów wyrwałem z głowy, zanim doszedłem, że błąd nie występuje w programie, tylko podczas programowania...

  • #42 29 Maj 2009 15:09
    marrog
    Poziom 22  

    W koncu udalo sie uruchomic RS-a przelutowalem na pcb kilka wyprowadzen ale dzial tylko w jedna strone, tzn attiny odbiera wywolanie i wysyla dane, ale atmega juz nie odbiera tego co powinna.

    Dodano po 21 [minuty]:

    Spiałem same procki razem tzn na krzyz RxD ->Txd TxD ->RxD no i przesyła dane po rs232, więc wina leży chyba w hardware a nie w kodzie. Moze te maxy są jakieś dziwne.

  • #43 29 Maj 2009 15:37
    Andy74
    Poziom 24  

    Właśnie przeglądnąłem listingi programów, które mi przysłałeś i nie dopatrzyłem się jakichś błędów. Jeśli wprowadził bym zmiany, to raczej kosmetyczne.

    Cytat:
    W koncu udalo sie uruchomic RS-a przelutowalem na pcb kilka wyprowadzen ale dzial tylko w jedna strone ...

    To znaczy, że problem był w jakości lutów, czy może podpiąłeś się pod nie te piny?
    Cytat:
    Spiałem same procki razem tzn na krzyz RxD ->Txd TxD ->RxD no i przesyła dane po rs232, więc wina leży chyba w hardware a nie w kodzie. Moze te maxy są jakieś dziwne.

    O! Dawno to radziłem. Może są jeszcze jakieś błędy na PCB? MAX-ów bym nie podejrzewał, bo choć ich jeszcze nie używałem, to na własne oczy widziałem działającą na nich transmisję pomiędzy dwoma procesorami AVR + konwerter RS485/USB i PC. No chyba, że je już też podrabiają...

  • #44 29 Maj 2009 15:55
    marrog
    Poziom 22  

    Witam

    Przelutowałem jedna końcówkę od gniazda dla MAX-a przy Attiny ( robie całość na pająku - prototyp) i gdzieś kenar nie łączył, niby sie trzymał a jednak.
    Po tym zabiegu w jednym kierunku ruszyło.
    Więc tak jak radziłeś podpiąłem 1:1 czyli RS232 i chul już ponad godzinę przesyła różne dane z attiny do Atmega16.
    No tylko że wczoraj RS485 działał a nie RS232 jak dzisiaj.
    No ale skoro mówisz że jest poprawny kod, to mogę pisać dalej, bo w sumie widać że wina leży w hardware a nie software.
    Teraz czas na opracowanie algorytmu sterowania, chyba największy problem będzie przy załączaniu o określonej godzinie urządzeń, ale myślałem to robić w ten sposób, że nastawy zapisane w EEPROM 24c04 porównuje z poszczególnymi wartościami odczytanymi z PCF8583 czyli min z min_nast i h z h_nast i jeśli się zgadza to uruchom na czas określony w nastawie. Czyli aby działało to musze zrobić

    Code:

    if h=h_nast then
       if min=min_nast then
           uruchom
           sprawdzaj czas dzialania urzadzenia
       end if
    end if


    No co do kosmetyki to wiem, ale to wersja robocza, żeby tylko działało, a kosmetyka w swoim czasie :-)

    Jeszcze raz dzięki Andy

  • #45 29 Maj 2009 16:26
    Andy74
    Poziom 24  

    Masz na pokładzie PCF8583, a on ma funkcję alarmu o nastawionej godzinie (PIN /INT) - może by to wykorzystać? Zakładam, że pomiar czasu będziesz podtrzymywał bateryjnie? Takie rozwiązanie ma jedną dużą zaletę w porównaniu z Twoją propozycją. Co będzie, gdy akurat w porze załączenia urządzenia zabraknie zasilania przez czas dłuższy niż minutę? Jeśli jednak będziesz sterował więcej niż jednym urządzeniem, to sprawa się komplikuje.

    Wracając do RS485, to jedyną istotną różnicą w porównaniu do RS232 jest sterowanie kierunkiem transmisji i tutaj szukał bym teraz źródła problemów. Sprawdź, czy w obydwu układach pin PD2 procesora jest prawidłowo połączony z /RE, oraz DE MAX485 (zwarte piny 2 i 3). Najlepiej podłącz sobie pomiędzy Vcc a PD2 obydwu procesorów diody LED (+ rezystory oczywiście). Będziesz mógł śledzić jak przełącza się kierunek nadawania. W spoczynku obydwie diody powinny świecić, jeśli dany układ nadaje jego dioda gaśnie, natomiast nigdy nie powinna zdarzyć się sytuacja kiedy obydwie diody są zgaszone jednocześnie, bo to by znaczyło, że obydwa układy są w trybie nadawania w tym samym czasie.
    Powodzenia i nie ma za co - temat też mnie interesuje. Właśnie jadą do mnie zamówione MAX485 - też będę się mierzył z RS485, tylko u mnie będzie 6 slave'ów na początek :)
    Pozdrawiam
    Andy

  • #46 29 Maj 2009 16:38
    marrog
    Poziom 22  

    Wątek 1:
    No chciałem wykorzystać alarm wbudowany w PCF8583,ale tak jak napisałeś "Jeśli jednak będziesz sterował więcej niż jednym urządzeniem, to sprawa się komplikuje." bo muszę wysterować w sumie 16-ma urządzeniami i każdy ma przypisaną nastawę czasową, więc pozostaje chyba moje rozwiązanie.

    Co do wątku drugiego, - z tymi diodami to w sumie dobry pomysł, tylko bym musiał zwiększyć czas przy set pd2 i reset pd2 tak żebym spokojnie mógł obserwować.

    Teraz zająłem się algorytmem sterowania.
    Heh ciekawe jak pójdzie jeszcze na końcu z SHT11 i jego odczytem przez ATtiny i wysyłka po rs485. boje się, że attiny będzie miał za mało pamięci na kod, bo w sumie dla samego RS wyszło coś ponad połowa chyba, a gdzie tu odczytywanie danych i ich konwersja, może będzie trzeba zrobić na atmega8 ?
    U mnie slave-ow na RS będzie 2 szt. więcej nie ma sensu, no chyba że dojdzie później jakiś zdalny pulpit oddalony od sterownika, no ale wówczas w sterowniku do kodu będzie trzeba dopisać parę linii kodu.

    -=pozdrawiam=-

  • #47 29 Maj 2009 17:06
    Andy74
    Poziom 24  

    Cytat:
    Heh ciekawe jak pójdzie jeszcze na końcu z SHT11 i jego odczytem przez ATtiny i wysyłka po rs485. boje się, że attiny będzie miał za mało pamięci na kod, bo w sumie dla samego RS wyszło coś ponad połowa chyba, a gdzie tu odczytywanie danych i ich konwersja, może będzie trzeba zrobić na atmega8 ?

    ATtiny sobie poradzi, jeśli będziesz nim tylko odczytywał dane i przesyłał w postaci surowej, a konwersją zajmie się master, którego w razie potrzeby możesz łatwo podmienić na M32 :).

  • #48 29 Maj 2009 17:46
    marrog
    Poziom 22  

    Chyba o jednym myslimy :-)
    Też myślałem nad M32 w ostateczności. tylko nie wiem czy nie lepiej przesyłać juz "obrobionej danej do Mastera, tylko wtedy wymusi to zastosowanie większego procka M8.

    Teraz zastanawiam się nad zrobieniem regulacji temp. w pomieszczeniu, mam 2 koncepcje:
    Jedna to:
    Ustawić T_max i T_min i w tym przedziale starac się utrzymywać, wtedy nie ma histerezy jako parametru.
    A druga, to:
    Ustawić T_min i Hist i wówczas przedział oscylacji to T_min +- Hist, a T_max jako parametr Alarmu

  • #49 29 Maj 2009 18:19
    Andy74
    Poziom 24  

    Nie wiem czym będziesz to pomieszczenie grzał, czy też ewentualnie chłodził (wietrzył? ;)), dlatego trudno doradzić co lepiej wybrać. Jedno źródło ciepła ma większą bezwładność, inne mniejszą... Generalnie przy dużej bezwładności cieplnej lepiej sprawdza się sterowanie z histerezą, tyle, że wyłączenie grzania lepiej zrobić przy nastawionej temperaturze, a włączenie przy T-hist. Najlepsze jest sterowanie za pomocą algorytmu PID, ale to już wyższa szkoła jazdy, no i chyba nie potrzebujesz mieć w pomieszczeniu np. 23,6°C ±0,1°C...

    Ponownie (uparcie :D) wracając do RS485 - napisałeś, że slave odbiera polecenie od mastera i wysyła mu dane, ale master ich już nie odbiera? Jeśli tak, to proponuję jeszcze wstawić opóźnienie (kilkanaście ms) w ATtiny przed przełączeniem jego MAX'a w tryb nadawania. Może być tak, że slave rozpoczyna nadawanie swoich danych, kiedy master nie jest jeszcze w trybie odbioru. Pisałeś, że wszystko zaczęło działać, gdy dodałeś w różnych miejscach kodu wyświetlanie stanu programu na LCD - to by potwierdzało moją teorię.
    Powodzenia
    Andy

  • #50 29 Maj 2009 18:57
    marrog
    Poziom 22  

    Witam

    Co do PID-a nie potrzebuje, reguluje i grzaniem i chlodzeniem poprzez wentylacji i zamglawianie pomieszczenia. Zrobilem przedzial temperatury i wilgotności w pomieszczeniu i będę próbował w ten sposób sterować czyli między T_max a T_min.

    Co do RS485,
    Powiem Ci że działa juz chyba ze 4h ale RS232 ATmega wysyła żądanie i otrzymuje odpowiedź od Attiny, natomiast jak podepnę pod MAX to juz RS485 nie działa. Wczoraj działał.
    Musze dać te diody i zobaczyc co i jak "mrygają" czy czasem faktycznie Master nie za krótko odbiera - ale jak działa po RS232, to po rs485 powinno też śmigać??

  • #51 29 Maj 2009 19:32
    Andy74
    Poziom 24  

    Cytat:
    Co do PID-a nie potrzebuje, reguluje i grzaniem i chlodzeniem poprzez wentylacji i zamglawianie pomieszczenia. Zrobilem przedzial temperatury i wilgotności w pomieszczeniu i będę próbował w ten sposób sterować czyli między T_max a T_min.

    No chyba, że tak. W takim razie najlepszą odpowiedź na twoje pytanie dadzą testy praktyczne. W końcu zmiana sposobu sterowania wiąże się tylko ze zmianą programu, więc nie widzę problemu.

    Cytat:
    jak działa po RS232, to po rs485 powinno też śmigać??

    Jeśli wszystko prawidłowo połączyłeś, i MAX'y są sprawne, to jedyną różnicą dla procesora jest konieczność sterowania kierunkiem przepływu danych. Dlatego tutaj dopatruję się źródła problemów.

  • #52 29 Maj 2009 20:01
    marrog
    Poziom 22  

    Czyli pozostaje dioda i sprawdzenie czasu czy przypadkiem nie sa za krótkie, może faktycznie wczoraj dodając kilka linii z poleceniem LCD akurat trafiłem w czas i działało, a jak je usunąłem, to się teraz nie zgrywają.

    Narazie pracuję nad nastawianiem zegara :-)

  • #53 29 Maj 2009 20:46
    janbernat
    Poziom 38  

    Ale szybkie postępy!
    Dwa programy obsługi PID są do ściągnięcia z MCS Electronics.
    PCF8583 może też generować prostokąt 1Hz-co można wykorzystać do "odpytywania" o czas w pętli Do...Loop lub w przerwaniach.
    PCF8583 ma też kilka? dziesiąt bajtów RAM-które można wykorzystać do nastaw.
    Zwłaszcza przy zasilaniu z baterii przy wyłączonym zasilaniu układu.

  • #54 29 Maj 2009 21:58
    marrog
    Poziom 22  

    Witam

    janbernat
    czas goni :-) wiec siedze calymi dniami nad tym, najwiecej czasu zeszlo nad RS - 3 dni siedziałem i nie mogłem dojść gdzie leży błąd. :-(

    No mam juz w sumie zrobione nastawy w AT24C04, poczatkowo chcialem zrobic nastawy liczb zmiennoprzecinkowych, ale mija sie to z celem, gdyz nie stosuje ( i raczej nie bede) PID-a więc i tak na sterowaniu typu ON/OFF nie da rady uzyskać tak dużej dokładności.
    Druga kwestia, to zapis do pamięci 24c04 liczby zmiennoprzecinkowej, hmm. nie robiłem nigdy tego, nie bardzo wiedziałem jak to ugryźć.

  • #55 29 Maj 2009 22:52
    Andy74
    Poziom 24  

    Cytat:
    Druga kwestia, to zapis do pamięci 24c04 liczby zmiennoprzecinkowej, hmm. nie robiłem nigdy tego, nie bardzo wiedziałem jak to ugryźć.

    Sprawa jest generalnie prosta. Liczba typu single zajmuje cztery bajty, wystarczy więc ją rozbić na pojedyncze bajty i zapisać każdy z osobna. Przy odczycie robisz dokładnie odwrotnie. Powiesz pewnie "no dobra, ale JAK rozbić?" To też jest prostsze niż myślisz. Wystarczy odpowiednio zadeklarować zmienne. Zasymuluj sobie ten krótki programik:
    Code:
    $regfile "Attiny2313.dat"
    
    $crystal = 1000000

    Dim A As Single
    Dim A_byte(4) As Byte At A Overlay

    A = 12345.6789

    Print A
    Print A_byte(1) ; " " ; A_byte(2) ; " " ; A_byte(3) ; " " ; A_byte(4)

    A = 0

    Print A
    Print A_byte(1) ; " " ; A_byte(2) ; " " ; A_byte(3) ; " " ; A_byte(4)

    A_byte(1) = 183
    A_byte(2) = 230
    A_byte(3) = 64
    A_byte(4) = 70

    Print A
    Print A_byte(1) ; " " ; A_byte(2) ; " " ; A_byte(3) ; " " ; A_byte(4)

    End

    Tablica A_byte() nie zajmuje miejsca w pamięci RAM, bo jest tylko odwzorowaniem A w tych samych komórkach. W ten sam sposób można uzyskać poszczególne bajty każdej zmiennej, włącznie ze String. Często z tego korzystam, bo jest wygodne i oszczędza RAM na dodatkowe zmienne. Podaję Ci tą metodę jako ciekawostkę, bo osobiście w swoich programach unikam zmiennych typu Single i Long jak ognia i Tobie też polecam. Zobacz ile pamięci zajmuje powyższy krótki programik, tylko dlatego, że użyłem w nim jednej zmiennej typu Single i wykonałem na niej kilka operacji... A spróbuj jeszcze wykonać dzielenie!
    Często ten sam efekt (kosztem niewielkiego pogorszenia dokładności) można uzyskać nie stosując RAM-o i ROM-o żernych zmiennych. Przykładem może być np. zapis temperatury z dokładnością do jednego miejsca po przecinku. Przecież wystarczy do tego zwykły, dwubajtowy Integer - wystarczy przechowywać w nim temperaturę pomnożoną przez dziesięć. Można na takiej liczbie przeprowadzać wszystkie potrzebne operacje, a tylko do wyświetlania odpowiednio ją formatować. Na koniec dodam, że zdarzało mi się poprawiać kod po początkujących programistach. Raz program, który ledwie mieścił się w ATmega8 upchnąłem w ATtiny2313 nie pogarszając jego funkcjonalności. Nie piszę tego bynajmniej po to by się chwalić, tylko by uzmysłowić jak ważne jest rozsądne gospodarowanie zasobami.
    Się rozpisałem...
    Pozdrawiam,
    Andy

    PS. Dokładność z jaką w symulacji wyświetlana jest liczba 12345.6789 nie wynika z błędu w programie, tylko z dokładności z jaką Bascom i procesor operują na takich liczbach. Skąd to się bierze jest opisane w Help'ie Bascom'a w rozdziale "Language Fundamentals".

  • #56 30 Maj 2009 03:03
    marrog
    Poziom 22  

    Hej Andy " Ty to masz głowe nie od parady :-)

    Powiem szczerze, że myślałem nad rozbiciem na pojedyncze bajty, tylko nie wiedziałem jak to zrobić, przeglądnąłem HELP-a w poszukiwaniu jakieś funkcji typu np. MAKEBCD itp.
    Co do RS-a
    Powiem tak, podpiąłem diody, wgrałem kod jeszcze raz i śmiga na RS485, więc szczerze nie wiem sam co jest grane, może te MAX-y są jakieś felerne albo coś.

    Na prawdę jeszcze raz wielkie dzięki :-)

  • #57 30 Maj 2009 10:04
    marrog
    Poziom 22  

    Witam ponownie

    No ja walczę z całym kodem, żeby go trochę zoptymalizować, ale nie bardzo się daje.
    zajęte 77% a nie mam konwersji danych z sht11 jeszcze zrobionych, coś mi się wydaję, że będzie trzeba się przesiąść na M32.

    Cytat:

    Przykładem może być np. zapis temperatury z dokładnością do jednego miejsca po przecinku. Przecież wystarczy do tego zwykły, dwubajtowy Integer - wystarczy przechowywać w nim temperaturę pomnożoną przez dziesięć. Można na takiej liczbie przeprowadzać wszystkie potrzebne operacje, a tylko do wyświetlania odpowiednio ją formatować.


    Możesz podrzucić przykład w BASCOM-ie jak to realizujesz??
    Ja właśnie operuje na singlu i widzę że zbyt dożo miejsca zabiera.
    Normalnie mam odczyt temp z DS18B20 w funkcji, która zwraca wartość Single, następnie ją do wyświetlenia
    Code:

    Rez = Fusing(t_ds , "#.#")

    a do porównywania z nastawami:
    Code:

    T_zew = Round(t_ds)


    Dodano po 27 [minuty]:

    Mam jeszcze pytanie odnośnie WATCHDOG-a. Kiedyś na uP ( chyba z 10 lat temu) miałem architekturę 8051, no ale to było dawno i już poszło w zapomnienie.
    Czytam w HELP-ie, że można go ustawić
    Code:
     config watchdog=czas
    gdzie czas to odp. 16,32,...,2048 ms.
    Pytanie jakie mnie nurtuję, to jak mam go ustawić aby się samoczynnie resetował po wykonaniu pętli ale nie zresetował mi programu prędzej, tzn gdy program jeszcze działa ( poprawnie. Heh troche zamotałem.
    powiedzmy że program ( petla) wykonuje się ok 5s , a Watchdog max 2048ms czyli w zaokrągleniu 2s, więc mój program się nie zrealizuje do końca bo watchdog go zresetuje.

    Chyba że:
    Code:

    config watchdog = 2048

    Do ' petla glowna
       START WATCHDOG
       instrukcja 1
       instrukcja 2 ' czas wykonywania obu to ok 2s
       RESET WATCHDOG
       instrukcja 3
       instrukcja 4  ' czas wykonywania instr 3 i 4 to ok 2s
       RESET WATCHDOG
    loop

    Bęzie ok?? czy źłe kombinuje??

  • #58 30 Maj 2009 12:30
    Andy74
    Poziom 24  

    Tak na szybko, bo wychodzę do pracy. Na przykładzie DS18B20.
    Zakładam, że komunikację z czujnikiem masz opanowaną, więc odczytałeś z czujnika dane i masz je w dziewięciobajtowej tablicy - u mnie to Sc(9). Do obliczania odebranej temperatury korzystam z funkcji, którą deklaruję tak:

    Code:
    Declare Function Decigrades(byval Sc(9) As Byte) As Integer

    Tak się do niej odwołuję:
    Code:
    Dg1 = Decigrades(sc(9))

    Gdzie Dg1 jest typu Integer i jest to jedna z moich zmiennych przechowujących odczytaną temperaturę.
    Tak wygląda właściwa funkcja:
    Code:
    Function Decigrades(byval Sc(9) As Byte)
    

       Decigrades = Makeint(sc(1) , Sc(2))
       Decigrades = Decigrades * 10
       Decigrades = Decigrades / 16

    End Function

    Jak widzisz operuję tylko na Byte, oraz Integer. Po wywołaniu funkcji Decigrades w zmiennej Dg1 mam temperaturę * 10, czyli np. dla 23,6°C jest to liczba 236, dla -10,3°C liczba -103.
    Na takich liczbach operuję w całym programie (np. zapamiętywanie wartości max/min zmierzonych temperatur itp.) i tylko do wyświetlania je odpowiednio formatuję, czyli dodaję kropkę pomiędzy ostatnią, a przedostatnią cyfrą.

    Co do Watchdog'a, to dobrze kombinujesz, ale polecenie START WATCHDOG wystarczy wydać raz przed pętlą, a w samej pętli tylko go resetować. Polecenia Reset Watchdog musisz mądrze rozmieścić w całym programie tak, by czas wykonania pomiędzy dwoma z nich nigdy nie przekroczył tego ustawionego podczas normalnej pracy programu. :D
    Zamotałem, bo się spieszę ...
    Powodzenia
    Andy

  • #59 30 Maj 2009 15:58
    marrog
    Poziom 22  

    Witam
    Ja mam w ten sposób:

    Code:

    Function Pomiar_temp_zew(i As Byte)as Integer

     'Funkcja zwraca wartosc temperatury zewnetrznej z czujnika DS18B20
     'znajdujacego sie na magistrali 1-Wire

       Id_urz_1wire(1) = 1wsearchfirst()                        'odczytaj ID pierwszego urzadzenie 1wire
       For I = 1 To 8                                           'wpisz do tablicy ID 8 bajtów
          Print Hex(id_urz_1wire(i));
       Next I
       1wreset
       1wwrite Pomin_rom
       1wwrite Konwertuj_temp
       Waitus 200
       1wreset
       1wwrite Dopasuj_rom
       1wwrite Id_urz_1wire(1) , 8
       1wwrite Czytaj_scratchpad
       Msb = 1wread(1)
       Lsb = 1wread(1)
       1wreset
       Pomiar_temp_zew = Makeint(msb , Lsb)
       Pomiar_temp_zew = Pomiar_temp_zew * 10
       Pomiar_temp_zew = Pomiar_temp_zew / 16
     End Function

    Tylko teraz zastanawiam się jak to poprawnie wyświetlić na LCd i jak później porównywać z nastawami z pamięci chyba, że nastawy *10 i wtedy porównywać. a na lCD wyświetlić tylko przecinek.
    Przedtem jak miałem typu Single to stosowałem funckję ROUND i po sprawie, ale jak zmieniłem na INt to trochę pamięci zyskałem jakieś 8-9% :-) a to dość sporo.

    Dodano po 1 [godziny] 23 [minuty]:

    Może tak będzie dobrze:
    Code:

    Dim Rez As String * 1

    I użycie funkcji:
    Code:
     
    
       Rez = Str(t_ds)
       Rez = Format(rez , "##.#")


    A Ty Andy jak robisz??

  • #60 31 Maj 2009 00:50
    Andy74
    Poziom 24  

    Witam ponownie.

    Cytat:
    Może tak będzie dobrze:
    Code:
    Dim Rez As String * 1
    

    I użycie funkcji:
    Code:
     
    
       Rez = Str(t_ds)
       Rez = Format(rez , "##.#")

    A Ty Andy jak robisz??

    Właśnie tak. No prawie. :)
    String to trzeba by zadeklarować * 5, bo trzy cyfry, kropka no i ewentualny minus.
    A formatowanie robię (jeśli dobrze pamiętam - nie mogę tutaj podejrzeć żadnego swojego programu) tak:
    Code:
    Rez = Format(rez , " 0.0")

    Odczyt z DS-ów robię do tablicy w tym programie, którego fragment wkleiłem dlatego, że liczę jeszcze CRC, bo najdalszy czujnik mam na ok. 35m kabla i zdarzają się błędy transmisji.

    Cytat:
    ...jak zmieniłem na INt to trochę pamięci zyskałem jakieś 8-9%...

    Nie uwzględniłeś jeszcze oszczędności pamięci RAM, jednak 8-9% to coś niezbyt dużo, spodziewałem się że będzie więcej. Nie używasz przypadkiem w innych częściach programu Single, lub (co nie daj Boże :)) Long? Nie mówię wcale, że trzeba zawsze, wszędzie i za wszelką cenę dążyć do wyeliminowania takich zmiennych, bo nie zawsze się da. Na pewno jednak warto się zastanowić nad kodem, i zrobić to tam gdzie to możliwe.
    Zapisywać nastawy możesz w liczbach typu Integer w ten sam sposób jaki Ci podałem wcześniej - poprzez odpowiednią deklarację zmiennych. Ja na ten przykład w ten sposób zapisuję sobie zmierzone temperatury MAX i MIN do pamięci RAM PCF8583. To w końcu tylko dwa bajty na każdą temperaturę. Zastanawiałeś się przecież nad zapisywaniem liczb zmiennoprzecinkowych, a to już po cztery bajty na zmienną.
    Tak na marginesie - istnieje jeszcze inny sposób rozbijania liczb typu Integer na dwa bajty, ale wymaga dodatkowych zmiennych byte. Zobacz w Helpie polecenia LOW() i HIGH().

    Pozdrawiam
    Andy