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

Coś Ci się zepsuło? Nie chce działać jak powinno? Opisz dokładnie swój problem a postaramy się pomóc...
Awatar użytkownika
zgf1
Posty: 185
Rejestracja: poniedziałek 19 kwie 2010, 18:39
Lokalizacja: Zywiec

Post autor: zgf1 »

@Pyra
Dziekuję bardzo za sugestie, będę optymalizował kod i bawił się programem, na pewno to się przyda :) Od wczoraj troszeczke posiedziałem, program działa można powiedzieć tak jak sobie zakładałem na początku.

-wykrywa czujniki
-przechodzi do wyświetlania temperatur z 4 czujników
-po wciśnieciu jednocześnie dwóch przycisków program przeskakuje do ustawien alarmu
-po ustawieniu wymaganej temperatury ponownie wciskamy oba przyciski, przechodzi do wyświetlania temperatur


Na razie program jest napisany tak aby działał, pewnie brzydko, będę to optymalizował dzięki Waszym sugestiom, na chwilę obecną wygląda tak:
$regfile = "m8adef.dat"
$crystal = 8000000
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


Config Pind.0 = Output
Config Pind.1 = Input
Config Pind.2 = Input
Config 1wire = Portd.5
Portd.0 = 1
Portd.1 = 1
Portd.2 = 1


S1 Alias Pind.1
S2 Alias Pind.2


Dim I1 As Integer , Ss As String * 6
Dim I2 As Integer
Dim I3 As Integer
Dim I4 As Integer
Dim Alarm As Integer
Dim Alarm1 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
Dim W As Byte


Alarm = 250
Alarm1 = Alarm


Deflcdchar 0 , 8 , 20 , 11 , 4 , 4 , 4 , 3 , 32
Deflcdchar 1 , 32 , 4 , 4 , 4 , 4 , 4 , 4 , 32
Deflcdchar 2 , 32 , 10 , 10 , 10 , 10 , 10 , 10 , 32
Deflcdchar 3 , 32 , 21 , 21 , 21 , 21 , 21 , 21 , 32
Deflcdchar 4 , 32 , 21 , 21 , 21 , 21 , 18 , 18 , 32


Cursor Off
Cls
Lcd " Termometr v0.35 ";
Wait 1
Cls
W = 1wirecount()
Lcd "Czujniki: "
Waitms 100
Lcd W
Wait 2
Cls
Dsid1(1) = 1wsearchfirst()
Dsid2(1) = 1wsearchnext()
Dsid3(1) = 1wsearchnext()
Dsid4(1) = 1wsearchnext()


If Dsid1(8) = Crc8(dsid1(1) , 7) Then
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



Pomiar:
Do
1wreset
1wwrite &H55
1wverify Dsid1(1)
1wwrite &HBE
I1 = 1wread(2)
'---------------------------------
1wreset
1wwrite &H55
1wverify Dsid2(1)
1wwrite &HBE
I2 = 1wread(2)
'---------------------------------
1wreset
1wwrite &H55
1wverify Dsid3(1)
1wwrite &HBE
I3 = 1wread(2)
'---------------------------------
1wreset
1wwrite &H55
1wverify Dsid4(1)
1wwrite &HBE
I4 = 1wread(2)
'--------konwersja temp dla wszystkich dsow
1wreset
1wwrite &HCC
1wwrite &H44
Wait 1


I1 = I1 * 10
I1 = I1 / 16
If I1 > 0 Then
Ss = Str(i1)
Ss = Format(ss , " 0.0")
Locate 1 , 1
Lcd Chr(1) ; Ss ; Chr(0) ;
Else
Ss = Str(i1)
Ss = Format(ss , " 0.0")
Locate 1 , 1
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


If I1 > Alarm Then
Reset Portd.0
End If
If I1 < Alarm Then
Set Portd.0
End If


If S1 = 0 And S2 = 0 Then
Waitms 300
Cls
Lcd "Ustawianie alarmu"
Wait 2
Goto Ustawienia
End If
Goto Pomiar


Ustawienia:
Cls
If S1 = 0 Then
Alarm = Alarm + 10
Waitms 30
End If

If S2 = 0 Then
Alarm = Alarm - 10
Waitms 30
End If

Alarm1 = Alarm
Alarm1 = Alarm1 / 10

Locate 1 , 10
Lcd "( "
Locate 1 , 12
Lcd Alarm1
Locate 1 , 15
Lcd " )"
Waitms 300

If S1 = 0 And S2 = 0 Then
Waitms 300
Cls
Locate 1 , 1
Lcd "alarm zmieniony"
Locate 2 , 1
Lcd Alarm1
Waitms 5000
Cls
Goto Pomiar
End If
Goto Ustawienia


Loop




Mam jeszcze takie pytanko, jeśli ustawimy temperaturę alarmu na np 80C, do czasu odłączenia zasilania układ ładnie reaguje itp. Ale po odłączeniu zasilania oczywiście tracimy nastawy alarmu. Z tego co czytam trzeba wartość "Alarm" zapisać w eeprom (wcześniej ją odczytać).

Czy mogę prosić jeszcze o pomoc odnośnie tego?


Domyślam się, że to musze wywalić:
"Alarm = 250"

I zapisywanie do pamięci dać w tym If:
If S1 = 0 And S2 = 0 Then
Waitms 300
Cls
Locate 1 , 1
Lcd "alarm zmieniony"
Locate 2 , 1
Lcd Alarm1
Waitms 5000
Cls
Goto Pomiar
End If

Tylko jak to wykonać? ;)
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post autor: Pyra »

Witam
Na szybko:
Dim Alarm As Eram Byte At &H01
Deklaracja zmiennej, która domyślnie ma być zapisana w pierwszej komórce epromu.
Niestety nie wszystkie operacje można na niej wykonywać, dlatego możesz stworzyć zwykłą zmienną (np. Alarm1)i przepisywać jej wartość z epromu, na niej dokonywać wszelkich operacji i co jakiś czas sprawdzać
If Alarm <> Alarm1 then Alarm = Alarm1
Powoduje to, że eprom jest zapisywany tylko w momencie zmiany wartości, a zapisy do tej pamięci są limitowane jej trwałością.
Jeśli chodzi o redukcję kodu, to możesz te cztery pomiary wykonać pętli od 1 do 4 i dane wpisywać do tablicy, zamiast pojedynczych zmiennych.
Tak samo z wyświetlaniem i formatowaniem danych.

Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Awatar użytkownika
zgf1
Posty: 185
Rejestracja: poniedziałek 19 kwie 2010, 18:39
Lokalizacja: Zywiec

Post autor: zgf1 »

Mój Alarm to bylo "Integer" wiec nie mogłem przepisać wartości zmiennych, jeszcze nie umiem, czy mogę prosić o rzucenie okiem... Zrobiłem to w troszkę inny sposób.


Na początku deklaracje:
Dim Alarm As Integer
Dim Alarm1 As Integer
Dim Xa As Eram Integer

Alarm = Xa
Alarm1 = Alarm

I zapisywanie wartości do eepromu, tylko gdy wychodzę z ustawień(naciśnięcie razem dwóch przycisków):
If S1 = 0 And S2 = 0 Then
Waitms 300
Cls
Locate 1 , 1
Lcd "Alarm ustawiony"
Locate 2 , 1
Lcd Alarm1
Xa = Alarm
Waitms 5000
Cls
Goto Pomiar
End If
Goto Ustawienia



Układ pamięta ustawienia po odłączeniu zasilania.
Ale pytanie czy nic nie skopałem? :)
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post autor: Pyra »

Witam
Jaką rolę pełni Alarm1? Bo ta zmienna wydaje mi się zbędna.
Popatrz na mój przykład, podałem parametr At &H01, co określa konkretny adres w pamięci. Warto stosować, choć teoretycznie deklaracja zmiennych powoduje zapełnianie komórek od pierwszej, i dlatego działa, ale...

Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Awatar użytkownika
zgf1
Posty: 185
Rejestracja: poniedziałek 19 kwie 2010, 18:39
Lokalizacja: Zywiec

Post autor: zgf1 »

"Alarm1" zadeklarowałem ponieważ gdy wyświetlałem zadaną temperaturę "Alarm" to zamiast np. 25 na wyświetlaczu pojawiało się 250. Alarm1 to Alarm/10. Dzieki temu wyświetliłem temperaturę w stopniach.


Już poprawiłem w programie na "Dim Xa As Eram Integer At &H01"
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post autor: Pyra »

Witam
W takim razie Alarm1 wystarczy jako Byte, bo chyba nie przekroczysz temperatury 255°C

Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Awatar użytkownika
zgf1
Posty: 185
Rejestracja: poniedziałek 19 kwie 2010, 18:39
Lokalizacja: Zywiec

Post autor: zgf1 »

Wielkie dzięki!
Na chwilę obecną układ działa, zapisuje do pamięci ustawioną temp, więc wszystko jest idealnie. Orientujecie się może czy jeśli będę chciał z nóżki 2 Atmegi wysterować zamiast diody LED brzęczek piezo z generatorem to muszę go podpiąć przez tranzystor czy bezpośrednio do nóżki mogę?

Te wyprowadzenia Atmegi mają do 20mA, niestety na stronie produktu nie ma poboru energii: http://sklep.avt.pl/piezo-z-generatorem-5v.html

W sumie mam taki podobny bez generatora, ale chyba nie ma sensu budować dla niego na płytce specjalnie generatora...
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post autor: Pyra »

Witam
Jeśli miał byś wolną 15 lub 16 (wyjścia sygnału PWM) to można by bardzo prosto generować sygnał.
Dodanie tranzystora z rezystorem 10k&#937; na bazie, nie powinno stanowić żadnego problemu, a ochroni procka przed ewentualnym uszkodzeniem.

Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Awatar użytkownika
zgf1
Posty: 185
Rejestracja: poniedziałek 19 kwie 2010, 18:39
Lokalizacja: Zywiec

Post autor: zgf1 »

Niestety PWM mam zajęte przez wyświetlacz. W sumie zastanawiam się obecnie połączenia z wyświetlaczem wyglądają tak:


Atmega/Wyświetlacz
14 -> D4
15 -> D5
16 -> D6
17 -> D7
18 -> E
19 -> RS

W programie zdefiniowany LCD jest:
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5

Czy mogę zrobić tak: (to uprościłoby mi płytkę drukowaną, zwolniło PWM)
28 -> RS
27 -> E
26 -> D4
25 -> D5
24 -> D6
23 -> D7
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5

Nie mam pojęcia czy mogę w ten sposób podłączyć wyświetlacz, mogę? :)
Te piny oczywiście mam wolne, ale w atmedze opisane one są "Analog Input".


Obrazek
Awatar użytkownika
pier
Posty: 1467
Rejestracja: poniedziałek 21 lut 2011, 09:02
Lokalizacja: Biłgoraj-Sól

Post autor: pier »

Nic nie stoi na przeszkodzie aby tak zrobić.
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post autor: Pyra »

Witam
Analog input, to alternatywne funkcje, związane z wejściami przetwornika analogowo-cyfrowego. Oczywiście trzeba tą funkcję uaktywnić aby działała.
Swoją drogą nie operuj numerami nóżek tylko nazwami portów, tak będzie łatwiej zrozumieć.
Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Awatar użytkownika
zgf1
Posty: 185
Rejestracja: poniedziałek 19 kwie 2010, 18:39
Lokalizacja: Zywiec

Post autor: zgf1 »

Kurczę jak to zrobić, myślę, myślę i nie umiem wymyślić.
Chciałem dorobić również sygnalizację gdy temperatura spadnie poniżej zadanej.

Np.
Sygnał gdy temp jest powyżej 85C (piec CO) - aby przeciwdziałać zagotowaniu się wody. Ale również sygnalizację jeśli temperatura na piecu spada poniżej 40C - sygnalizacja aby nie wygasło.


Załóżmy, że Alarm to temp powyżej której układ ma sygnalizować gotowanie. Alarm2 to temp poniżej której układ ma sygnalizować zbyt niską temp.


Na chwilę obecną napisałem:
If I1 > Alarm Or I1 < Alarm2 Then
Set Portd.0
End If
Waitms 500

If I1 < Alarm or I1 > Alarm2 Then
Reset Portd.0
End If

No ale to nie działa. Jeśli temp jest niższa (sygnalizacja zbyt niskiej) LED miga, jeśli temp jest pomiędzy zbyt niską, a zbyt wysoką LED nie świeci, jeśli temp jest wyższa niż (sygnalizacja gotowania) znów LED miga.
Jak to ustabilizować aby LED świeciła nie migała.

Rozumiem dlaczego miga, ponieważ wtedy spełnia jakby dwa warunki. Ale jak zapisać to poprawnie, możecie jakąś wskazówke?
Awatar użytkownika
ElSor
Site Admin
Posty: 5041
Rejestracja: niedziela 13 wrz 2009, 12:52
Lokalizacja: Ozimek

Post autor: ElSor »

If i1 > alarm then
If i1 > Alarm 2 then
xxx (wlaczenie zbyt wysokiego)
else yy (wylaczenie alarmu)


i odpowiednio to samo tylko "if i1 < Alarm2 ....."

ew można użyć CASE (poszukaj dokładnie w helpie jak się używa). Chyba nawet CASE zjada mniej pamięci.
Awatar użytkownika
zgf1
Posty: 185
Rejestracja: poniedziałek 19 kwie 2010, 18:39
Lokalizacja: Zywiec

Post autor: zgf1 »

Dziekuje! Dziala :)
If I1 > Alarm Then
If I1 > Alarm2 Then
Set Portd.0
Else
Reset Portd.0
End If
End If

If I1 < Alarm Then
If I1 < Alarm2 Then
Set Portd.0
Else
Reset Portd.0
End If
End If

A wlaśnie, na początku definiuję sobie zmienną w eeprom:
Dim Xa As Eram Integer At &H01

Załóżmy, że chcę kolejną umieścić w eeprom, to będzie:
Dim Xa As Eram Integer At &H02

Chodzi o te adresy (At &H02).
Awatar użytkownika
ElSor
Site Admin
Posty: 5041
Rejestracja: niedziela 13 wrz 2009, 12:52
Lokalizacja: Ozimek

Post autor: ElSor »

Integer to zmienna 2 bajtowa, także adres w pamięci zawierający kolejną zmienną po integer musi być większy o 2 a nie o 1.
ODPOWIEDZ