Strona 1 z 3

Atmega8 - prośba o pomoc, sterowanie diodą LED.

: środa 04 gru 2013, 16:11
autor: zgf1
Witam, kolejny raz muszę prosić Was o pomoc. Kiedyś trochę bawiłem sie mikrokontrolerami, ogólnie wiele zapomniałem, teraz zaczynam zabawę na nowo, chcę je troche poznać. Ale natrafiłem na mały problem.

Buduję można powiedzieć termometr, będą cztery kanały, czujniki to populadne DS18B20. I teraz schemat wygląda następująco:
Obrazek

Czyli pomiar temperatur działa dobrze, problemem jest sprawienie aby po przekroczeniu 85C na czujniku numer 1 zapalała się dioda LED podpięta pod jedną z nóżek układu.


Czy móglbym prosić o jakieś rady, pod którą podpiąć i jak zmodyfikować program?


Oto program:

Kod: Zaznacz cały

$regfile = "m8adef.DAT"                                     'deklaracja procesora, w tym wypadku Atmega8
$crystal = 8000000                                          'deklaracja cześtotlwiości pracy (wew oscylator 1MHz w zupełności wystarcza)
'Deklaracja portów od wyświetlacza LCD
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5

Config Lcd = 16 * 2                                         'ustawiamy typ wyświetlacza (soft jest dostosowany do pracy z wyświetlaczem 2x20, przy pracy z innym wyświetlaczem trzeba będzie skorygować wyświetlanie znaków)

'*************************************WAŻNE**********************************************
'Pamiętać o podłączeniu rezystora podciągającego o wartości 4.7kohm między linią DQ a VCC
Config 1wire = Portd.5                                      'deklaracja portu na którym będą podpięte DS18b20

Dim I1 As Integer , Ss As String * 6
Dim I2 As Integer
Dim I3 As Integer
Dim I4 As Integer

Dim Dsid1(8) As Byte
Dim Dsid2(8) As Byte
Dim Dsid3(8) As Byte
Dim Dsid4(8) As Byte
Dim B As Byte                                               'deklaracja zmiennej do odczytu kodów ID
Dim W As Byte                                               'deklaracja zmiennej do odczytu ilośc czujników

Deflcdchar 0 , 8 , 20 , 11 , 4 , 4 , 4 , 3 , 32             'znak stopnia Celsjusza
Deflcdchar 1 , 32 , 31 , 32 , 32 , 32 , 32 , 32 , 32        ' replace ? with number (0-7)           ' replace ? with number (0-7)
Deflcdchar 2 , 32 , 32 , 32 , 32 , 32 , 32 , 31 , 32        ' replace ? with number (0-7)' replace ? with number (0-7)
Deflcdchar 3 , 4 , 31 , 17 , 31 , 31 , 31 , 31 , 4          ' replace ? with number (0-7)        ' replace ? with number (0-7)
Deflcdchar 4 , 4 , 31 , 31 , 31 , 31 , 17 , 31 , 4          ' replace ? with number (0-7)        ' replace ? with number (0-7)


Cursor Off                                                  'Wyłącza kursor
Cls                                                         'Funkcja CLS czyści ekran
Lcd "    KOLEKTOR1   " ;                                    'ekran startowy (pojawia się tylko podczas włączania urządzenia)
Wait 2
Cls                                                         'Funkcja CLS czyści ekran
W = 1wirecount()
Lcd "Czujniki: "                                            'Informuje ile czujników jest podpiętych do układu (pojawia się tylko podczas włączania urządzenia)
Waitms 1000
Lcd W
Wait 2
Cls                                                         'Znajdź pierwszy czujnik podpięty do portu
Dsid1(1) = 1wsearchfirst()                                  'Znajdź kolejny czujnik podpięty do portu
Dsid2(1) = 1wsearchnext()                                   'Znajdź kolejny czujnik podpięty do portu
Dsid3(1) = 1wsearchnext()                                   'Znajdź kolejny czujnik podpięty do portu
Dsid4(1) = 1wsearchnext()

'*******************Odczyt numerów ID czujników temperatury*********************

If Dsid1(8) = Crc8(dsid1(1) , 7) Then                       'ta opcja pojawia się tylko przy włączaniu urządzenia
 Locate 1 , 1
Cls
 Lcd "T1 id:"
 Wait 1
 Locate 2 , 1
 For B = 1 To 8
 Lcd Hex(dsid1(b))
 Next
End If
Wait 2

If Dsid2(8) = Crc8(dsid2(1) , 7) Then
 Locate 2 , 1
Cls
 Lcd "T2 id:"
 Wait 1
 Locate 2 , 1
 For B = 1 To 8
 Lcd Hex(dsid2(b))
 Next
End If
Wait 2

If Dsid3(8) = Crc8(dsid3(1) , 7) Then
 Locate 1 , 1
Cls
 Lcd "T3 id:"
 Wait 1
 Locate 2 , 1
 For B = 1 To 8
 Lcd Hex(dsid3(b))
 Next
End If
Wait 2

If Dsid4(8) = Crc8(dsid4(1) , 7) Then
 Locate 1 , 1
Cls
 Lcd "T4 id:"
 Wait 1
 Locate 2 , 1
 For B = 1 To 8
 Lcd Hex(dsid4(b))
 Next
End If
Wait 2
Cls

'*******************koniec odczytu ID czujników temperatury*********************

Do
   1wreset
   1wwrite &H55
   1wverify Dsid1(1)                                        'wysyłamy adres pierwszego czujnika
   1wwrite &HBE
   I1 = 1wread(2)
'---------------------------------
   1wreset
   1wwrite &H55
   1wverify Dsid2(1)                                        'wysylam adres drugiego czujnika
   1wwrite &HBE
   I2 = 1wread(2)
'---------------------------------
   1wreset
   1wwrite &H55
   1wverify Dsid3(1)                                        'wysylam adres trzeciego czujnika
   1wwrite &HBE
   I3 = 1wread(2)
'---------------------------------
   1wreset
   1wwrite &H55
   1wverify Dsid4(1)                                        'wysylam adres czwartego czujnika
   1wwrite &HBE
   I4 = 1wread(2)
'--------konwersja temp dla wszystkich dsow
   1wreset
   1wwrite &HCC
   1wwrite &H44
Wait 1

'****Jeśli pracujesz z wyświetlaczem innym niż 2x20 to tutaj trzeba wprowadzić zmiany w LOCATE********

   I1 = I1 * 10
   I1 = I1 / 16
   If I1 > 0 Then                                           'korekta przesuniecia znaku st C przy przejściu z temp ujemnej na dodatnią
   Ss = Str(i1)
   Ss = Format(ss , "  0.0")
   Locate 1 , 1                                             'Pozycja wyświetlania nazwy i temperatury (1.1 -> 1 linia 1 kolumna, 2.10 -> 2 linia 10 kolumna itd)
   Lcd Chr(1) ; Ss ; Chr(0) ;
   Else
   Ss = Str(i1)
   Ss = Format(ss , " 0.0")
   Locate 1 , 1                                             'Pozycja wyświetlania nazwy i temperatury (1.1 -> 1 linia 1 kolumna, 2.10 -> 2 linia 10 kolumna itd)
   Lcd Chr(1) ; Ss ; Chr(0) ;
   End If

   I2 = I2 * 10
   I2 = I2 / 16
   If I2 > 0 Then
   Ss = Str(i2)
   Ss = Format(ss , "  0.0")
   Locate 1 , 10
   Lcd Chr(2) ; Ss ; Chr(0) ;
   Else
   Ss = Str(i2)
   Ss = Format(ss , " 0.0")
   Locate 1 , 10
   Lcd Chr(2) ; Ss ; Chr(0)
   End If

   I3 = I3 * 10
   I3 = I3 / 16
   If I3 > 0 Then
   Ss = Str(i3)
   Ss = Format(ss , "  0.0")
   Locate 2 , 1
   Lcd Chr(3) ; Ss ; Chr(0) ;
   Else
   Ss = Str(i3)
   Ss = Format(ss , " 0.0")
   Locate 2 , 1
   Lcd Chr(3) ; Ss ; Chr(0) ;
   End If

   I4 = I4 * 10
   I4 = I4 / 16
   If I4 > 0 Then
   Ss = Str(i4)
   Ss = Format(ss , "  0.0")
   Locate 2 , 10
   Lcd Chr(4) ; Ss ; Chr(0) ;
   Else
   Ss = Str(i4)
   Ss = Format(ss , " 0.0")
   Locate 2 , 10
   Lcd Chr(4) ; Ss ; Chr(0) ;
   End If

   Loop

Diode mogę chyba podpiąć do nóżki 23, ale czy ktoś pomógłby zmodyfikować program?
http://i.imgur.com/KXnhdHG.jpg

: środa 04 gru 2013, 17:27
autor: pier
Dioda na schemacie jest odwrotnie podpięta.

: środa 04 gru 2013, 17:42
autor: Pyra
Witam
pier pisze:Dioda na schemacie jest odwrotnie podpięta.
Jaka dioda?
Najlepiej przelicz wartość 85 na wartość odpowiadającą odczytanej z DSa i z nią porównaj.

If I1>85 then (i tu odpowiednia instrukcja)

SET PORTB.1 - spowoduje zapalenie diody na pinie B1 podłączonej pomiędzy nim a masą
RESET PORTB.1 - spowoduje zgaszenie tej diody.
Jeśli podepniesz diody pomiędzy plusem zasilania a pinem, instrukcję będą miały odwrotne działanie.
Pozdrawiam
PS: przepraszam, że pobieżnie, ale mam pilną pracę...

: środa 04 gru 2013, 18:06
autor: zgf1
Wielkie dzięki za odzew, na chwilę obecną potrafię już gasić i zapalić LED (zwykła dioda małej mocy) podpiąłem ją pod pin 2 Atmegi przez rezystor 0.56k do plusa.

Programik do sterowania:
$regfile = "m8adef.DAT"
$crystal = 8000000
Config Portd = Output

Do
Toggle portd.0
Wait 1
Loop
End

@Pyra
Wielkie dzięki będę próbował kombinować i zrobić tą prostą sygnalizację.



PS. Jest możliwość aby zainstalować dwa przyciski i regulować nimi tą temperaturę przy której LED będzie się zapalał? (docelowo będzie to piszczyk, który ma za zadanie sygnalizować przekroczenie 85C(lub zadanej) na piecu CO)

: środa 04 gru 2013, 18:21
autor: dominos96
Bez problemu
Najpierw tworzysz sobie zmienną
np. Dim Zmienna As Byte
I potem if'em sprawdzasz sobie przyciski, i odejmujesz albo dodajesz wartość do tej zmiennej
Do tego jakiś 7-segmenstowiec na którym wyskakiwała by ci aktualna temperatura i nastawiona

: środa 04 gru 2013, 18:39
autor: zgf1
Do układu mam obecnie podpięty wyświetlacz LCD 2x16.
Czy mógłbym Cię prosić o przykład takiego programiku?

Na chwilę obecną juz opanowałem gaszenie i zapalanie LED, obecnie po przekroczeniu 25C, ale działa to odwrotnie niż napisał Pyra, czy to spowodowane portem który wybrałem do podłączenia diody, czy coś zrobiłem źle?


Fragment kodu który odpowiada za zapalenie LED w temp wyższej niż 25C(250):
If I1 > 250 Then
Reset Portd.0
Else
End If

If I1 < 250 Then
Set Portd.0
Else
End If

: środa 04 gru 2013, 19:36
autor: ElSor
Na chwilę obecną juz opanowałem gaszenie i zapalanie LED, obecnie po przekroczeniu 25C, ale działa to odwrotnie niż napisał Pyra, czy to spowodowane portem który wybrałem do podłączenia diody, czy coś zrobiłem źle?
Zamień miejscami ">" z "<" ew Set z Reset. Else możesz usunąć z kodu.

: środa 04 gru 2013, 19:43
autor: dominos96
No tutaj nie potrzeba przykładu

Najpierw deklarujesz
Dim Temp as Word

Jak chcesz zmienić wartość, robisz if'a do przycisku, i w nim wpisujesz:
np. Temp = Temp + 1 (czyli kliknięciem zmieniasz temperaturę o 0,1)

A jak chcesz zapalać diodę to po prostu przyrównujesz temperaturę nie
do jakieś liczby tylko do tej zmiennej, czyli:
If I1 > Temp Then

Tylko żeby dodać to do programu to musiałbyś pozbyć się tych wait'ów z pętli,
czyli wrzucić to do przerwań.

: środa 04 gru 2013, 22:28
autor: zgf1
Dziekuję.
Program już w sumie działa, ale mam problem z przyciskami, jak zdefiniować porty i funkcje przycisków? Siedzę nad tym już trochę ale średnio mi to wychodzi muszę przyznać... Gdybyście mogli ocenić czy dobrze podłączyłem przyciski i ewentualnie jeśli to nie kłopot to jakiś kawałek kodu do obsługi jednego przycisku... Bardzo ułatwiłoby mi to sprawę...


Obrazek


Kodu swojego na razie raczej nie będę wrzucał aby nie śmiecić, kiedyś udawało mi się oprogramować przycisk ale teraz za Chiny nie potrafię...

: środa 04 gru 2013, 22:31
autor: ElSor
Musisz ustawić piny PD1 i PD2 jako wejścia i ustawić na nich stan wysoki (wewnętrznie podciągnięcie przez rezystor do Vcc). Po tej operacji sprawdzasz / odczytujesz w pętli czy jest stan niski i jeśli tak to coś tam robisz.
PS i weź sobie naukę na spokojnie, bo zapomnisz jutro wszystko :wink: tym bardziej, że obsługując klawisze warto a wręcz trzeba zadbać o wyeliminowanie drgań styków a to już nieco większy problem.

: środa 04 gru 2013, 22:34
autor: dominos96
Najpierw konfigurujesz port jako wejście
Np. Config Pind.0 = Input (Pin piszemy gdy mamy wejście, a Port gdy wyjście)

Warto jeszcze podciągnąć port do zasilania (kiedy przyciski zwierają do masy)
Np. Portd.0 = 1 lub Set Portd.0

A potem sprawdzasz sobie normalnie If'em
Np. If Pind.0 = 0 then

Edit: Widze że kolega mnie uprzedził

A co do drgania styków to można zrobić coś takiego
Debounce Pind.0 , 0 , Podprogram , Sub

lub po prostu dołożyć jakiegoś wait'a w if'ie co by nie wyszedł z niego za szybko

: środa 04 gru 2013, 22:53
autor: zgf1
Podpięty mam przycisk pod pin 3 w Atmedze(PD1) i oczywiście do masy. (sprawdzone)


Teraz mój programik wygląda tak:
Config Pind.1 = Input
Portd.1 = 1



Do

Ala:
If Pind.1 = 0 Then
Waitms 300
Lcd "nacisniety"
Goto Ala
End If

Lcd "nie nacisniety"
Waitms 700
Cls

Loop
End


Pisze "Pind.1" ponieważ do "Pind.0" podpięta jest dioda LED.
Teraz gdzie zrobiłem błąd? Oczywiście na naciśniecie przycisku program nie reaguje.

: środa 04 gru 2013, 22:58
autor: dominos96
A po co te "ala" ?
Jak chcesz przeciągać program tak długa jak przycisk jsst wciśnięty to w if'ie zrób pętle warunkową
Do
Loop until pind1 = 0


Edit:
Zresztą mam nadzieje że to nie jest cały.program, i gdzieś tam skonfigurowałeś ten wyświetlacz.

: środa 04 gru 2013, 23:09
autor: zgf1
O dzięki przyda się ta sugestia, dopiero w sumie zaczynam. Dziekuję bardzo!
Już przycisk działa, przepraszam za zamieszanie, sprawdzałem wiele razy, okazało się, że zamiast do masy podciągnąłem go do plusa - ślepnę na starość widać ;)

Jutro będę kombinował aby zrobić to ustawianie temperatury zadanej(sygnalizacja). Pewnie nie obędzie się bez kłopotów, zatem mam prośbę do Was abyście czasem zaglądnęli do tego wątku :)



PS.
Oczywiście wyświetlacz jest skonfigurowany, ale nie wrzucałem tego aby nie śmiecic.
Wyświetlacz pracuje ok :)

: środa 04 gru 2013, 23:44
autor: Pyra
Witam
Do sprawdzania przycisków jest instrukcja DEBOUNCE.
Np.: DEBOUNCE PIND.1, 0, GOTO ... (i tu adres programu obsługi przycisku)
Ta instrukcja jest o tyle wygodniejsza, że już ma wbudowana eliminację drgania styków i detekcję ponownego przyciśnięcia.
Do zwiększania wartości zmiennej, korzystniej jest używać:
Increse zmienna
lub do zmniejszania
Decrese zmienna.
zajmuje mniej miejsca w pamięci niż:
zmienna = zmienna +1
Pozdrawiam
PS: Ja aktualnie męczę się z kalibracją pomiaru napięcia ogniwa...