Witam wszystkich.
Wykonałem sobie stację lutowniczą ,jednak natknąłem się na problemy związane z opóźnieniem pętli głównej. Zacznę od sposobu funkcjonowania stacji.
Do nóżek uC atmega 16 pd.3-5 został podpięty Max6675(interfejs spi), który według zamierzeń projektu ma odmierzać temperaturę co 200ms .Zmierzona temperatura jest porównywana z zadaną i ich różnica jest zapisywana do zmiennej odchyłka, dzięki której jest dobierana moc grzałki.Ta zaś zostanie wykorzystana do regulatora mocy PWM.W projekcie zastosowano Encoder z przyciskiem ,umożliwiając nastawienie temperatury zadane. Moja koncepcja jest następująca : w pętli głównej znajduje się opóźnienie 1Ms(tak aby obsłużyć encoder i przycisk oraz regulator mocy PWM , który liczy do 100 dając 1S) oraz licznik liczący do 200 (pomiar temp. co 200ms).
Problem w ,tym że pomiar temperatury jest znacznie opóźniony o kilka sekund natomiast obsługa encodera oraz przycisku jest dobra.Z ciekawości wyeliminowałem licznik liczący do 200 i zmieniłem opóźnienie z 1 ms na 200ms pomiar był prawidłowy ,lecz encoder gubił impulsy ,a generator PWM działał nieprawidłowo . Desperacko nawet zmieniłem licznik do pomiaru temp. na pętle for ... next ,w której było opóźnienie 1 ms oraz sprawdzanie encodera i przycisku oraz regulacja mocy (pętla liczyła od 0 do 200) , poza pętlą pomiar temperatury, który był również opóźniony o kilka sekund.Dopiero skrócenie pętli for ...next od 0 do 6 dało zamierzony efekt ,lecz tylko na ok 1 min po ,czym stacja grzała "do oporu". Fuse bity ustawione i odczytane (hfuse:C9; lfuse:FF) na pracę z zewnętrznym kwarcem 16Mhz.
Bardzo proszę o porady, gdyż mam niewielkie doświadczenie w programowaniu i ciągle się uczę
$regfile = "m16def.dat"
$crystal = 16000000
Dim Maxdata As Word
Dim T_nastawy As Word
Dim Uspienie As Bit
Const T_uspienia = 150
Dim S_pomoc As Bit
Dim Stan_encoder As Byte
Dim T_grota As Word
Dim Odchylka As Integer
Dim Flaga_t As Bit
Dim Licznik_t As Word
Dim Moc As Byte
Dim Licznik_imp As Byte
Config Pind.2 = 1
Config Pind.4 = 0
Config Pind.5 = 1
Config Pind.3 = 1
Config Pind.0 = 0
Config Pinb.6 = 0
Config Pinb.7 = 0
Config Pind.7 = 1
Config Portc = &B11111111
Portd.3 = 1
Portd.5 = 0
Portd.4 = 1
Portd.7 = 0
Portd.0 = 1
Portb.7 = 1
Portb.6 = 1
Portd.2 = 1
T_nastawy = 150
Portc = 255
Config Spi = Soft , Din = Pind.4 , Dout = Pind.3 , Ss = None , Clock = Pind.5
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
Deflcdchar 1 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
So Alias Pind.4
Sck Alias Portd.5
Cs Alias Portd.3
Buzzer Alias Portd.7
Grzalka Alias Portd.2
Cls
Cursor Off
Lcd "Stacja by David"
Lowerline
Lcd "With BASCOM AVR"
Waitms 500
Buzzer = 1
Waitms 1500
Buzzer = 0
Cls
Do
Waitms 1 'opóznienie(odświeżnie) 1MS
Incr Licznik_t 'licznik pomiaru temp co 200MS
If Licznik_t = 200 Then
Licznik_t = 0
Cs = 0
Shiftin So , Sck , Maxdata , 0 , 16
Cs = 1
End If
T_grota = Maxdata 'otrzymanie tem. w stopniach
Shift T_grota , Right , 3
T_grota = T_grota / 4
'obsługa przycisku usypiania
Debounce Pind.0 , 0 , Slep , Sub
Stan_encoder = Encoder(pinb.6 , Pinb.7 , Lewo , Prawo , 0) 'zwiększnie zmniejszanie TEMP.
If S_pomoc = 1 Then
S_pomoc = 0
If Uspienie = 1 Then
Buzzer = 1
Wait 1
Buzzer = 0
T_nastawy = T_uspienia
Display Off
Else
Buzzer = 1
Wait 1
Buzzer = 0
Display On
End If
End If
Incr Licznik_imp 'regulacja mocy PWM
If Licznik_imp = Moc Then
Set Grzalka
End If
If Licznik_imp = 100 Then
Licznik_imp = 0
End If
If Licznik_imp = 0 Then
If Moc <> 0 Then
Reset Grzalka
End If
End If
Reset Odchylka
Odchylka = T_nastawy - T_grota 'porónanie temeratury zadanej i
Select Case Odchylka
Case Is <= 0
Moc = 0
Portc = 255
Case 1 To 4
Moc = 10
Portc = 127
Case 5 To 15
Moc = 15
Portc = 63
Case 16 To 20
Moc = 20
Portc = 31
Case 21 To 30
Moc = 25
Portc = 15
Case 31 To 45
Moc = 30
Portc = 7
Case 46 To 55
Moc = 45
Portc = 3
Case 56 To 99
Moc = 75
Portc = 1
Case Is >= 100
Moc = 100
Portc = 0
End Select
If Maxdata.2 = 0 Then 'procedura wyświetlania danych na LCD
Locate 1 , 1
Lcd "T.GROTA:" ; T_grota ; Chr(1) ; "C " ; " "
Lowerline
Lcd "T.NASTAWY:" ; T_nastawy ; Chr(1) ; "C" ; " "
Else
Locate 1 , 1
Lcd "Awaria Kolby!!" ; " "
Lowerline
Lcd " "
End If
If T_nastawy = 451 Then
T_nastawy = 450
End If
Loop
End
Lewo: ' Podprogramy
Decr T_nastawy
Return
Prawo:
Incr T_nastawy
Return
Slep:
Set S_pomoc
Toggle Uspienie
Return
Złe odmierzanie czasu/Bascom AVR
-
- Posty: 7
- Rejestracja: 29 lis 2016, 19:16
- niveasoft
- Posty: 1216
- Rejestracja: 17 sie 2015, 12:13
- Kontakt:
Re: Złe odmierzanie czasu/Bascom AVR
Nie umieściłeś w kodzie ustawień $hwstack, $swstack i $framesize
Kiedy ich nie ma to kompilator bierze je z ustawień IDE (czyli edytora Bascom)
Tak to wygląda i ciekawi mnie jak masz ustawione u siebie.
Mikrokontroler Mega16 ma tysiąc bajtów pamięci SRAM która możesz dysponować do woli.
Lepiej umieścić te ustawienia w kodzie - po prostu - jedna rzecz do rozważań mniej.
Napisz też jakiej wersji Bascom używasz.
Kiedy ich nie ma to kompilator bierze je z ustawień IDE (czyli edytora Bascom)
Tak to wygląda i ciekawi mnie jak masz ustawione u siebie.
Mikrokontroler Mega16 ma tysiąc bajtów pamięci SRAM która możesz dysponować do woli.
Lepiej umieścić te ustawienia w kodzie - po prostu - jedna rzecz do rozważań mniej.
Napisz też jakiej wersji Bascom używasz.
-
- Posty: 7
- Rejestracja: 29 lis 2016, 19:16
Re: Złe odmierzanie czasu/Bascom AVR
Obecnie używam Bascom AVR 2.0.7.5 w wersji demo .Poniżej screen ustawień
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
- kaktus
- Posty: 32
- Rejestracja: 19 sie 2015, 15:13
- Lokalizacja: opolskie
- Kontakt:
Re: Złe odmierzanie czasu/Bascom AVR
czy na pewno?David pisze:Witam wszystkich.
Do nóżek uC atmega 16 pd.3-5 został podpięty Max6675 (interfejs spi),
teraz życie można rozdzielić między NOP i SLEEP
- Pikczu
- Posty: 390
- Rejestracja: 17 sie 2015, 13:46
- Lokalizacja: Dublin, Ireland
- Kontakt:
Re: Złe odmierzanie czasu/Bascom AVR
Przydał by się cały kod.
Zdecydowanie bez dwóch zdań wywal wszelkiego rodzaju wait i waitms zastąp timerem.
Zdecydowanie bez dwóch zdań wywal wszelkiego rodzaju wait i waitms zastąp timerem.
-
- Posty: 7
- Rejestracja: 29 lis 2016, 19:16
Re: Złe odmierzanie czasu/Bascom AVR
Problem został rozwiązany. Napisałem nowy program. Wyeliminowywałem wszystkie "waity" z pętli głównej zastępując je przerwaniem od timera co 0,5s.
Teraz wszystko jest ok,pomiar jest prawidłowy. Lutownica spisuje się bardzo dobrze.
Myślę, że problemem było zastosowanie opóźnienia przez co komunikacja z MAX6675 była nieprawidłowa.
Dziękuję Bartkowi,Kaktusowi i Pikczu za niezbędne porady.
David
Teraz wszystko jest ok,pomiar jest prawidłowy. Lutownica spisuje się bardzo dobrze.
Myślę, że problemem było zastosowanie opóźnienia przez co komunikacja z MAX6675 była nieprawidłowa.
Dziękuję Bartkowi,Kaktusowi i Pikczu za niezbędne porady.
David
- niveasoft
- Posty: 1216
- Rejestracja: 17 sie 2015, 12:13
- Kontakt:
Re: Złe odmierzanie czasu/Bascom AVR
Ciesze się, że udało Ci się program napisać tak by spełniał Twoje oczekiwania bo to jest najważniejsze.
Myślę że problemów w tym kodzie było więcej i może nowy styl napisania go pomógł
Nawet czytając opis instrukcji Encoder można przeczytać, że czytając stan enkodera odpowiednio często można nie zgubić żadnego kroku.
Po tej wypowiedzi następuje następna- że wiele procesorów ma możliwość przerwania od zmiany stanu na pinie czyli PCINT.
Czytając między wierszami można się domyślić, że instrukcji Encoder nie umieszcza się pętli głównej bezpośrednio. Funkcję sprawdzająca enkoder powinno się wywoływać, albo Timerem, albo od przerwania wywołanego pokręceniem...
Tak samo spowolnić program może umieszczenie Getrc5() w pętli głównej bez wyzwalania jej poprzez przerwanie.
Czasem zmieniając tylko jedną rzecz w programie i nie widząc efektu można ulec wrażeniu że ta zmiana nic nie wnosi..a często liczą się dopiero wszystkie.
Myślę że problemów w tym kodzie było więcej i może nowy styl napisania go pomógł
Nawet czytając opis instrukcji Encoder można przeczytać, że czytając stan enkodera odpowiednio często można nie zgubić żadnego kroku.
Po tej wypowiedzi następuje następna- że wiele procesorów ma możliwość przerwania od zmiany stanu na pinie czyli PCINT.
Czytając między wierszami można się domyślić, że instrukcji Encoder nie umieszcza się pętli głównej bezpośrednio. Funkcję sprawdzająca enkoder powinno się wywoływać, albo Timerem, albo od przerwania wywołanego pokręceniem...
Tak samo spowolnić program może umieszczenie Getrc5() w pętli głównej bez wyzwalania jej poprzez przerwanie.
Czasem zmieniając tylko jedną rzecz w programie i nie widząc efektu można ulec wrażeniu że ta zmiana nic nie wnosi..a często liczą się dopiero wszystkie.
-
- Posty: 7
- Rejestracja: 29 lis 2016, 19:16
Re: Złe odmierzanie czasu/Bascom AVR
No właśnie co do encodera to to jest jedyna wada mojej stacji. Przy szybkim kręceniu wartość zmienia się skokowo mimo to da się wyregulować co do stopnia. Nie jest to wielki problem, gdyż temperatura zmieniana jest "raz na ruski rok" . Reszta jest ok .Jestem bardzo zadowolony, że udało mi się zrobić coś takiego po roku nauki Bascoma teraz mam ochotę na więcej . Fajnie też , że poznałem ludzi piszących w Bascomie, lepszych niż ja
DaVid
DaVid