Witam, proszę o pomoc w umieszczeniu termostatu w programie. '************************TIMER ver.testowa************************************* 'pracuja dwa TIMERY TIMER0/1 'przekazniki i wyswietlanie ok 'zajmuje 39% pamieci 'wysw. temperatury na LCD locate 1 , 7 '**************************** Konfiguracja Uc ********************************** $regfile = "m8def.dat" $crystal = 16000000 Config Portb = &B11111111 : Portb = &B11111110 Config Portc = &B11111111 : Portc = &B11111111 Config Portd = &B00000001 : Portd = &B11111111 Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5 Config Lcd = 16 * 2 Cls Cursor Off Noblink Config Timer0 = Timer , Prescale = 256 Enable Timer0 : On Timer0 Prztimer0 Config Timer1 = Timer , Prescale = 256 Enable Timer1 : On Timer1 Prztimer1 Enable Interrupts Stop Timer1 Pk_0 Alias Portb.0 'zal. przy wlaczeniu zasilania i start Pk_1 Alias Portb.1 'zal.przy T1 Pk_2 Alias Portb.2 'zal.przy T2 Pk_3 Alias Portb.3 Pk_4 Alias Portb.4 'DS18b20 na PD.1 'Buzer Alias Portd.0 'buzer wyzw.stanem 1 'Declare Sub Buzer_1 '****************************** Zmienne **************************************** Dim Licz_1s As Word , Dzielnik As Byte , Dzielnik2 As Byte Dim Flaga_4ms As Bit , Flaga_100ms As Bit , Flaga_1s As Bit Dim Sw As Byte , Stan_sw As Byte , Licznik_sw As Byte Dim T1_licz As Word , T2_licz As Word Dim Out_state As Bit Dim Help As Word , Help2 As Word , Help3 As Word Dim Poz_menu As Byte Dim Wysw_1 As Bit , Wysw_2 As Bit '***************************warunki poczatkowe********************************** Out_state = 0 Readeeprom T1_licz , 2 'czas T1 If T1_licz > 3599 Then T1_licz = 30 End If Readeeprom T2_licz , 4 'czas T2 If T2_licz > 3599 Then T2_licz = 30 End If Lcd " sterownik " Lowerline Lcd " wer.testowa " Wait 2 Cls '*****************************petla glowna************************************** Do If Flaga_4ms = 1 Then Flaga_4ms = 0 Gosub Przyciski End If If Flaga_100ms = 1 Then Flaga_100ms = 0 Gosub Wyswietlanie Gosub Wyswietlanie_1 End If Loop End '********************* przerwanie timer 0/1 ************************************ Prztimer0: Timer0 = 7 Flaga_4ms = 1 Incr Dzielnik If Dzielnik = 25 Then '25*4ms = 100ms Dzielnik = 0 Flaga_100ms = 1 Incr Dzielnik2 If Dzielnik2 = 10 Then '10*100ms=1s' Dzielnik2 = 0 End If End If Return Prztimer1: Timer1 = 3037 Flaga_1s = 1 Flaga_1s = 0 Wysw_1 = 1 Pk_0 = 0 Pk_1 = 0 Pk_2 = 1 Incr Licz_1s If Out_state = 0 Then If Licz_1s >= T1_licz Then Licz_1s = 0 Out_state = 1 End If Else Wysw_2 = 1 Pk_0 = 1 Pk_1 = 1 Pk_2 = 0 If Licz_1s >= T2_licz Then Licz_1s = 0 Out_state = 0 Stop Timer1 'stop po skonczonym cyklu Wysw_1 = 0 Wysw_2 = 0 Pk_0 = 1 Pk_1 = 1 Pk_2 = 1 End If End If Return '********************** wyswietlanie/wyswietlanie_1 **************************** Wyswietlanie: Select Case Poz_menu Case 0: Locate 1 , 1 Lcd "Temp:" Locate 2 , 7 Lcd " " Help = Licz_1s Help = Help Mod 60 'liczenie sekund Locate 2 , 3 Lcd ":" If Help < 10 Then Lcd "0" 'zero wiodace,jak mniej niz 10 Lcd Help Help = Licz_1s / 60 'liczenie minut Locate 2 , 1 If Help < 10 Then Lcd "0" 'zero wiodace dla minut Lcd Help Case 1: Locate 1 , 1 Lcd "" Locate 2 , 7 Lcd "T1-sek. " Help3 = T1_licz Help3 = Help3 Mod 60 Locate 2 , 3 Lcd ":" If Help3 < 10 Then Lcd "0" Lcd Help3 Help3 = T1_licz / 60 Locate 2 , 1 If Help3 < 10 Then Lcd "0" Lcd Help3 Case 2: Locate 1 , 1 Lcd "" Locate 2 , 7 Lcd "T1-min. " Help3 = T1_licz Help3 = Help3 Mod 60 Locate 2 , 3 Lcd ":" If Help3 < 10 Then Lcd "0" Lcd Help3 Help3 = T1_licz / 60 Locate 2 , 1 If Help3 < 10 Then Lcd "0" Lcd Help3 Case 3: Locate 1 , 1 Lcd "" Locate 2 , 7 Lcd "T2-sek. " Help2 = T2_licz Help2 = Help2 Mod 60 Locate 2 , 3 Lcd ":" If Help2 < 10 Then Lcd "0" Lcd Help2 Help2 = T2_licz / 60 Locate 2 , 1 If Help2 < 10 Then Lcd "0" Lcd Help2 Case 4: Locate 1 , 1 Lcd "" Locate 2 , 7 Lcd "T2-min. " Help2 = T2_licz Help2 = Help2 Mod 60 Locate 2 , 3 Lcd ":" If Help2 < 10 Then Lcd "0" Lcd Help2 Help2 = T2_licz / 60 Locate 2 , 1 If Help2 < 10 Then Lcd "0" Lcd Help2 End Select Return Wyswietlanie_1: If Wysw_1 = 1 Then Locate 2 , 7 Lcd "T1" End If If Wysw_2 = 1 Then Locate 2 , 7 Lcd "T2" End If '*****************************przyciski***************************************** Przyciski: Sw = Pind And &B11111100 'maskowanie nieużywanych pinów If Sw <> &B11111100 And Stan_sw = Sw Then Incr Licznik_sw If Licznik_sw = 100 Then Licznik_sw = 0 Select Case Stan_sw Case &B01111100: 'poz.menu pd7 Incr Poz_menu If Poz_menu = 5 Then 'poz.menu 0/1/2/3/4, bedzie docel.5/6 Poz_menu = 0 Writeeeprom T1_licz , 2 'zapis do pamieci czasow T1/T2, pozniej temp. Writeeeprom T2_licz , 4 End If Case &B10111100: '+sek pd6 Select Case Poz_menu Case 1: If T1_licz < 3600 Then Incr T1_licz Case 2: If T1_licz < 3540 Then T1_licz = T1_licz + 60 Case 3: If T2_licz < 3600 Then Incr T2_licz Case 4: If T2_licz < 3540 Then T2_licz = T2_licz + 60 'Case 5: 'ustawianie temperatury termostatu 'case 6: 'ustawianie histerezy termostatu End Select Case &B11011100: '-sek pd5 Select Case Poz_menu Case 1: If T1_licz > 0 Then Decr T1_licz Case 2: If T1_licz > 59 Then T1_licz = T1_licz - 60 Case 3: If T2_licz > 0 Then Decr T2_licz Case 4: If T2_licz > 59 Then T2_licz = T2_licz - 60 'case 5: 'ustawianie temperatury termostatu 'case 6: 'ustawianie histerezy termostatu End Select Case &B11101100: 'pd4 START Start Timer1 'Case &B11110100: 'pd3 'Case &B11111011 'pd2 End Select End If Else Stan_sw = Sw Licznik_sw = 80 End If Return Return '****************************koniec przyciski*********************************** DS18B20 na PD.1 ,natomiast przekaźnik termostatu PK_3.
|
|||
Odp. Timer + pomiar temp.
Jak już nie chcesz w tym grzebać to może tak: Czytać co sekunde temperature i w procedurze odczytu temperatury, już po konwersji, postawić warunek że jesli pozycja menu 0 to locate i wyświetlić temp. Jak będziesz w innej pozycji to sie nic nie nałoży. A temperature i tak bedziesz miał cały czas odczytana i termostat zadziała nawet "pod spodem" jakiegoś innego menu. Myślę też że dokładnośc do przecinka, bez dziesiętnych jest wystarczajaca, ale jak kto woli. Rezygnacja z temp ujemnych i miejsc po przecinku "ułatwia" sprawę ;) Temperaturę można wyświetlać z "garbem" :D czyli za nią ;" " i to bedzie czysciło większe liczby gdy temp spadnie.
To tak na pierwszy rzut oka ;)
Różne sa też szkoły czytania tych DSów. Jedni dzielą to na raty, czyli najpierw żądanie konwersji temp. przez DS a potem wracaja za 700ms ..a można też odczytać temp z DS`a, przeliczyc sobie i wysłać żądanie kolejnej konwersji. Tylko na czas czytania wyłączasz przerwania, więc wszystko kwestią rozpatrzenia potrzeb :P
Miłego dnia.
Ps. Na PORTD.1 jest TXD i czasem są kłopoty z czytaniem DSów na portach z RS232 bo Ci Bascom z niewyjaśnionych przyczyn włączy UART, wtedy trzeba wyłączyć UART w rejestrze UCSR.
BARTek
Moja strona
Timer + pomiar temp.
Ok,dzięki, pomiar temperatury już mi działa,DS-a przeniosłem w/g sugestii na PD.2, w pomiarze musiałem wywalić
ponieważ wszystko czekało ,nie wiem tylko czy tak może zostać.
Zostało jeszcze dorobić termostat i przyciski
Timer + pomiar Temp
Heheh pisałem Ci żeby najpierw czytać temp a potem kazać mu przygotować następną . I tak za sekunde po nia wrócisz, a tylko za pierwszym razem po resecie przez dwie sekundy nie masz odczytu.
A histerezę sobie dodaj jakąś żeby nie swirował tam i z powrotem na granicy przełączenia. tylko jakiś inny Help wolny znajdź :) Chyba że DSa dokłądnie do radiatora przymocujesz i zasłonisz od wiatru, bo one na zefirek reagują.
BARTek
Moja strona
Timer + pomiar temp.
Teraz działa bezbłędnie, histerezę ustawiłem na +/- 1 stopień, dołożyłem ustawianie temperatury przyciskami,zmieniłem trochę wyświetlanie (teraz w trakcie ustawiania T1 i T2 wyświetla czały czas bieżącą temperaturę),dołożyłem zapis do eeprom.
Wiesz może jak dołożyć kontrolę podłączonego DS-a,aby w przypadku wypięcia lub uszkodzenia wyłączyło grzanie.
jeszcze nie bardzo mi się widzi wyświetlanie tego
w trakcie działania pokazuje który czas jest liczony, trochę pomruguje ale z biedy może tak zostać.
Pomrygiwanie wyswietlacza
Wydaje mi się że to dlatego że masz potem włączone Wysw_1 = 1 i po Else Wysw_2 = 1 i potem w tym Sub Wyświetlanie obydwa If`y sa prawdziwe więc maluje najpierw T1 i na nim zaraz T2. Ja bym te Wyswietlanie_1 wywalił całkiem i wrzucił obsługe tego do tego przerwania co sekunde Timera 1 zamiast odświeżać widok co 100ms ;) Na dodatek chyba Ci sie z czegoś tam zapomniała ta Flaga_1s = 1 i zaraz potem Flaga = 0 ..to bezsens i chyba tam została z jakiegoś pomysłu. Całośc chyba powinna wyglądac tak:
Tak nie do końca chce mi sie to analizowac , ale tam chyba brakuje jakiegoś If`a na poczatku przerwania bo nawet jeśli juz liczysz T2 to i tak na poczatku przechodzisz przez stary stan T1 łacznie z ustawianiem portów.
Oczywiście wywal już Sub Wyswietlanie bo z niego wziąłem te Locate 2,7
Dwukropek oznacza w Bascom przejscie do następnej linii .
Po któreś tam..chyba nie chcialo Ci się przeczytać moich wypocin na temat wyswietlaczy LCD tu na forum. Deklaracja znaku specjalnego Deflcdchar Cie kosztuje w kodzie duuużo a możesz zamiast Chr(1) napisać Chr(223) bo taki znak jest już zdefiniowany. Wtedy Deflcdchar niepotrzebne jest..
Tu masz ściągę:
Co do wykrywania czy podłączony DS.
Funkcja
1wreset
ma wbudowane sprawdzanie i w przypadku błedu ustawia flage ERR na 1Ni etrzeba jej kasować, sama sie kasuje jak sie DS znajdzie. Wygląda to mniej wiecej tak a wykorzystasz jak chcesz po tym
Else
. Sprawdzać błąd można w odczycie i w żądaniu konwersji temperatury, ale tu skróciłem....albo po prostu tutaj zapomniałeś Wysw_1 = 0, bo chyba by pomogło..
Miłego testowania, no i miłego dnia ;)
BARTek
Moja strona
Timer + pomiar temp.
Niestety pomimo wielu kombinacji dalej pomruguje co 1 sek, ale to nie tragedia (może później z nudów powalczę.Zapis w stylu
wysypuje całkowicie wyświetlacz
Odnośnie błędu ERR dla DS-a to oczywiście wykazuje, jednak PK_3 nie wyłącza się tylko mrugnie co 1 sek,
wykożystam to do sygnalizacji akustycznej, a wyłączanie PK_3 rozwiązałem dając warunek w pętli gł.
to wystarczy ponieważ po odłączeniu jakiejkolwiek nóżki DS-a wskazuje temp 00,0 lub -0,0
Wielkie podziękowania dla EDC,naprawdę wiele można się od Ciebie nauczyć i zawsze liczyć na Twoją pomoc.
Timer - może błąd?
Marek czy masz już u siebie w programie wpisany Return w Sub Temperatura?
Kiedyś tez bez Returna skompilowałem bezproblemowo i dopiero następny Return w programie po drodze kończy wtedy operacje :D
BARTek
Moja strona
Timer + pomiar - wersja z jednym Timerem i alarmem :)
Proszę Marku. Jako, że dziś gorąco to sobie przerwe zrobiłem i postanowiłem poprawić co nieco :P
Ma nawet Alarm, a jest mniejszy :D
Zmieniłem ostatnio taktykę i w obsłudze przerwań nie robie już tych "drabinek". Jest na to czas w pętli :)
Błąd mógł sie wkraść ale sobie poprawisz może jak się przyjrzysz :D bo mi nie chce się przepinać płytki .
Ps. Tą Single Temp masz trochę niepotrzebnie dużą ale zostawiłem :)
BARTek
Moja strona
Timer + pomiar - wersja z jednym Timerem i alarmem
No muszę przyznać,że mnie teraz zaskoczyłeś, masz to wszystko pięknie uproszczone,ja niestety robiłem to wszystko na około,ale nauka nie idzie w las tylko w nas.
Działa to teraz tak jak powinno, tylko,że zawsze jest jakieś ale...
Chodzi mi jeszcze mianowicie o problem termostatu o którym wcześniej nie wspomniałem (był mało istotny),a mianowicie:
przy wczytaniu programu do Atmegi ustawia termostat na temp. -0.0*C i w takim przypadku nie mogłem już jej zmienić +/-, załatwiłem to w warunkach początkowych
nie wiem jak to zapisać w obsłudze przycisku + aby dodawało jak temp. jest ustawiona poniżej zera
Timer..
Dodaj jedna zmienna T1_word. Zaraz po tym jak masz T1. Porównujesz swoja T1_word = T1 i to odetnie tylko kropke :) i z tym wszędzie porównuj. Wynik na wyświetlaczu dalej będzie z kropką. A Temp zmień na Word i będzie po kłopocie :)
Do eeproma będzie zapisywac i czytać z niego Word . Nie powinno być kłopotu gdy FF FF bo to znaczy 65535 czyli dodatnio :)
PS. Miałeś ten Return w Temperaturze czy to jego brakowało? :P
BARTek
Moja strona
Timer + pomiar temp.
Odnośnie Return w temp. to go brakowało i sprawdziłem ,faktycznie to było przyczyną mrugania, a później wysypywania się wyświetlacza.
Przerobiłem,teraz tak jak podałeś, ale....teraz temp.zadaną wyświetla 45*C*C
i jeszcze zmieniłem to, ponieważ przy błędzie czujnika załączyło alarm ,a później nie chciało wyłączyć
1wreset ' tu kazesz DS`owi przygotować nowy odczyt
Odp> Timer i pomiar temp
Zmień
Lcd "Temp: > " ; Temp ; "" ; Chr(223) ; "C"
na
Lcd "Temp: > " ; Temp ; "" ; Chr(223) ; "C";" "
...bo ustawiana tem jest bez przecinka i jest krótsza ;)
Alarm kasował się przyciskiem Menu..takie zabezpieczenie :P
BARTek
Moja strona
Timer i pomiar temp
No i super, teraz już działa pięknie,wielkie dzięki za pomoc i cierpliwość,teraz na spokojnie mogę jeszcze raz przeanalizować Twoje zmiany i znowu być trochę mądrzejszy.
wyjaśnię jeszcze kwestię tej linijki
chodzi o to, że DS podaje alarm tylko przy utracie komunikacji z up z wyjścia pomiarowego lub przy braku minusa (wyświetla -0,0), natomiast w przypadku braku plusa wyświetla 0,0 i nie generuje alarmu (termostat nadal został by w trybie grzania).
I jeszcze jedno pytanie ,na podstawie czgo określasz
i jaki ma wpływ brak tych parametrów w takim programie
Odp.Timer i framesize
Te pierwsze to już wyjaśniałeś i zrozumiałem wczoraj to zostawiłem :D
Co do tych parametrow. Jest to temat na dłuższy opis który sobie dziś daruję :D ..ale po krótce...
Nigdy nie jest tak że tych parametrów tam nie ma. One sa zapisane w ustawieniach Bascom i automatycznie dokładane do kodu. Są w ustawieniach kompilatora -> karta Chip.
Najczęściej domyślne ustawienia sa wystarczające, ale tam sa uwzgledniające małe procki - oszczedne :D
Za każdym razem jak coś zgłasza przerwanie to procek odkłada na kupę zwana stosem wszystko, robi przerwanie a potem z tej kupy zabiera :) Tak najprosciej, im skomplikowańszy program tym więcej odkłada i kupa rosnie..może sie przewrócić :) Dane Ci umkna jakieś jak stos za mały. On odłozy i już nie odzyska. Wtedy nikt nie jest w stanie przewidzieć co się stanie.
Przerabiajac np. jakaś Single na String, albo coś do wysłania ma Print potrzebuje na to miejsca. Robi to w tej ramce (framesize) im dłuższe stringi tym większa potrzebna ramka. Taka String potrzbuje o jeden bajt więcej niż sama jest długa..bo w tym dodatkowym bajcie ma zapisany koniec itd. Niektóre trzeba liczyć razy dwa.. ale.. jak się ma Pdf`a do Atmegi8 i przeczyta że ma sie do dyspozycji tysiac bajtów to można szaleć :D
W helpie do Bascoma jest instrukcja jak to liczyć dokładnie i dodawac nawet wyrost np. +2
Pisza ile dodac jak masz przerwanie w programie..i na każde dodajesz.. Tu wpisałem "na oko" bo po co mam sie z Toba potem drapać w głowe :P Na pewno większe niż domyślne a to, plus suma wszystkich zadeklarowanych zmiennych musi sie zmiescić w procka RAM.
Warto poczytać bo jak sie bedzie chciało zrobić na odwrót, w małym gówienku ATtiny13 coś to prawie zadnej zmiennej bys nie dodał typu Word bo Bascom napisze "Out of SRAM" a to własnie przez te domyślne które tam sa w Bascom.. już za duże na te maleństwo ktore ma 64Bajty tylko. Tam na palcach sobie liczysz ile potrzebujesz na zmienne i tylko resztę możesz przeznaczyć na Hwstack i Framesize.
Swstack jest używany do zmiennych lokalnych.. tez niegłupie. Deklarujesz ja dla funkcji i tylko w funkcji , nie na poczatku, uzywasz, a jak nie używasz to to samo miejsce może wykorzystać inna funkcja na chwile. Jesli więc nie używasz zmiennych lokalnych to możesz się pokusić o zmniejszenie tego stosu a zyskasz plac na inne zmienne :D
Dlatego czasem dobrze jest samemu te dane wpisać po lekturze albo na wyrost :D jak masz z czego.
Napisze coś potem przejrzysciej w chwili natchnienia :P
Teraz walczę z jednym projektem.. mam nadzieje że w końcu zadziała tak jak chce.
Ale czas na zabawe musi być więc robie też inne mniejsze zabawki któer ciesza :D
Miłego wieczoru.
BARTek
Moja strona