Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[atmega8][bascom] Lampka RGB z podwójnym termometrem

00gtw00 25 Nov 2008 23:24 3700 6
  • #1
    00gtw00
    Level 15  
    Witam,
    jak w temacie - pracuje nad lampka RGB sterowaną jednym przyciskiem który odpowiada za szybkość przechodzenia kolorów. Dodatkowo lampka ma wyświetlacz 2x16 który wyświetla powitanie, pasek informujący o danej szybkości przechodzenia kolorów oraz na głównym ekranie tremometr pokazujący temp wewnątrz i na zewnątrz.
    Co do czujnika wybór padł na DS18S20 i magistrale 1wire dlatego nawet żeby nie było problemu z zakłóceniami na dłuższym przewodzie wychodzącym na zewnątrz.

    [atmega8][bascom] Lampka RGB z podwójnym termometrem

    Konkrety:
    Pierwszy problem -> Mógłby ktoś mi pomóc zrobić 2 czujniki na jednej magistrali? Jak to zaimplementować w kodzie. Przeszukałem elektrodę i żaden ze sposobów nie chce mi zadziałać.

    Drugi problem -> Jak odświeżać co najmniej raz na ok. 30sek czujniki kiedy wykonuje się fragment programu odpowiedzialny za diody? Skakać
    poleceniem gosub Termometr na końcu każdego z If'ów? Może coś bardziej optymalnego.

    Oczywiście czekam też na poprawki :) To mój pierwszy program w Bascomie i pierwszy kontakt z mikrokontorerami.

    Code:
    $regfile = "m8def.dat"
    
    $crystal = 8000000
    Dim R1 As Byte
    Dim G1 As Byte
    Dim B1 As Byte
    Dim Licznikpwm As Byte
    Dim Licznik As Integer
    Dim Zmiana1 As Byte
    Dim Przycisk As Byte
    Dim I As Byte
    Dim Ii As Byte
    Dim T(2) As Byte
    Dim Temp As Single
    Dim War As Byte
    Config Portc = &B010111
    Portc = &B111111
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portb.0 , Rs = Portb.1
    Config 1wire = Portb.2
    R1 = 255
    Zmiana1 = 1
    Przycisk = 0
    Deflcdchar 0 , 32 , 4 , 31 , 2 , 4 , 8 , 31 , 32            ' litera ż
    Deflcdchar 1 , 32 , 31 , 31 , 31 , 31 , 31 , 32 , 32        ' kratka
    Deflcdchar 2 , 32 , 32 , 14 , 17 , 31 , 16 , 14 , 2         ' litera ę
    Deflcdchar 3 , 32 , 4 , 14 , 16 , 14 , 1 , 30 , 32          ' litera ś
    Deflcdchar 4 , 32 , 4 , 14 , 16 , 16 , 17 , 14 , 32         ' litera ć
    Deflcdchar 5 , 6 , 9 , 9 , 6 , 32 , 32 , 32 , 32            ' stopien celciusza
    1wreset
    1wwrite &HCC
    1wwrite &H44
    Waitms 750
    1wreset
    1wwrite &HCC
    1wwrite &HBE
    T(1) = 1wread()
    T(2) = 1wread()
    1wreset

     Sound , Portc.4 , 1000 , 500
     Cls
     Cursor Off Noblink
     Lcd "   LAMPKA RGB"
     Waitms 500
     Lowerline
     Lcd "Sebastian I" ; Chr(0) ; "****"
     Waitms 2500
     Cls
     Lcd "POWITANIE 1234567890"
     Lowerline
     Lcd "1234567890 POWITANIE"
     For I = 1 To 16
       Shiftlcd Left
       Waitms 200
     Next I
       Waitms 2500
        For I = 1 To 16
       Shiftlcd Left
       Waitms 200
     Next I


     Gosub Obsluga_przycisku

      '====================================================
    Glowna_czesc:
    Do
      Incr Licznikpwm
      If Licznikpwm > 255 Then Licznikpwm = 0
      Incr Licznik

      If T(2) = 0 Then
      Temp = T(1) / 2
      Else
      Ii = 256 - T(1)
      End If
      If T(2) > 0 Then Lcd "-"

      Debounce Pinc.3 , 0 , Obsluga_przycisku



      If Licznik = 8000 Then

       Select Case Przycisk
       Case 1
          Licznik = 0
        Case 2
          Licznik = 4000
       Case 3
          Licznik = 6000
       Case 4
          Licznik = 7000
        Case 5
          Licznik = 7500
       Case 6
          Licznik = 7900
       Case 7
          Licznik = 7950
       Case 8
          Licznik = 7975
       End Select

        If Zmiana1 = 1 Then
          Incr B1
          If B1 = 255 Then Zmiana1 = 2
        End If

        If Zmiana1 = 2 Then
          Decr R1
          If R1 = 0 Then Zmiana1 = 3
        End If

        If Zmiana1 = 3 Then
          Incr G1
          If G1 = 255 Then Zmiana1 = 4
        End If

        If Zmiana1 = 4 Then
          Decr B1
          If B1 = 0 Then Zmiana1 = 5
        End If

        If Zmiana1 = 5 Then
          Incr R1
          If R1 = 255 Then Zmiana1 = 6
        End If

        If Zmiana1 = 6 Then
          Decr G1
          If G1 = 0 Then Zmiana1 = 1
        End If

      End If

      If Licznikpwm <= R1 Then Reset Portc.2 Else Set Portc.2
      If Licznikpwm <= B1 Then Reset Portc.1 Else Set Portc.1
      If Licznikpwm <= G1 Then Reset Portc.0 Else Set Portc.0
    Loop

    Obsluga_przycisku:
       Sound , Portc.4 , 100 , 500
       Incr Przycisk
       If Przycisk = 9 Then Przycisk = 1
       Cls
       Lcd "Pr" ; Chr(2) ; "dko" ; Chr(3) ; Chr(4) ; " zmiany:"
       Lowerline
       Select Case Przycisk
       Case 1
          Lcd "[              ]"
          Gosub Termometr
       Case 2
          Lcd "[" ; Chr(1) ; Chr(1) ; "            ]"
          Gosub Termometr
       Case 3
          Lcd "[" ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; "          ]"
          Gosub Termometr
       Case 4
          Lcd "[" ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; "        ]"
          Gosub Termometr
       Case 5
          Lcd "[" ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; "      ]"
          Gosub Termometr
       Case 6
          Lcd "[" ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; "    ]"
          Gosub Termometr
       Case 7
          Lcd "[" ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; "  ]"
          Gosub Termometr
       Case 8
          Lcd "[" ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; Chr(1) ; "]"
          Gosub Termometr
       End Select
       Gosub Glowna_czesc
    End

    Termometr:
     For War = 0 To 10
     Debounce Pinc.3 , 0 , Obsluga_przycisku
     Waitms 150
     Next T
     Cls
     Lcd "Temp zew: " ; Temp ; Chr(5) ; "C"
     Lowerline
     Lcd "Temp wew: " ; Temp ; Chr(5) ; "C"
     Gosub Glowna_czesc
    End


    Jeden "obrazek", w zupełności wystarczy.
    [zumek]
  • #2
    skynet_2
    Level 26  
    jako że bascoma nie znam napisze ci jak należy to zrobić

    najpierw przeczytaj ;)

    Code:
    reset;
    
    skip_rom czyli zapis na magistrale 0xcc;//wszystkie czujniki słuchają
    convert_t zapis 0x44;//1 i 2 czujnik przetwarza temperature
    czekasz 800ms przy 12bitowej dokładności;//zawsze lepiej trochę dłużej poczekać zamiast 750ms.

    reset;
    match_rom zapis 0x55;
    i wysłanie 8 bajtów odkeślających adres czujnika[rom czujnika 1]
    teraz słucha 1 czujnik
    read_scratchpad zapis 0xbe;
    i odczyt 8 bajtów danych(2 pierwsze zawierają informacje o tempetaturze)

    reset;
    match_rom zapis 0x55;
    i wysłanie 8 bajtów odkeślających adres czujnika[rom czujnika 2]
    teraz słucha 2 czujnik
    read_scratchpad zapis 0xbe;
    i odczyt 8 bajtów danych(2 pierwsze zawierają informacje o tempetaturze)

    odczyt pamięci rom możesz zrealizować tylko na 1 czujniku czyli
    wkładasz 1 czujnik, reset, read_rom, spisujesz z wyświetlacza 8 bajtów rom na kartkę ;);
    wkładasz 2 czujnik, reset, read_rom, spisujesz z wyświetlacza 8 bajtów rom na kartkę ;);
    read_rom nie działa jak masz 2 czujniki na magistrali

    read_rom;//rom odczytujesz tak
    reset;
    read_rom zapis 0x33;
    odczyt 8 bajtów pamięci rom;

    PS. zapis/wysłanie to samo

    PS 2. jest jeszcze search_rom czyli funkcja szukania czujników ale jest bardzo skomplikowana i jeszcze się przez nią nie przegryzłem.


    edit: w code ładniej wygląda ;)

    Pozdrawiam
  • #3
    mirley
    Level 17  
    Witam

    Oto przykładowy program w BASCOM AVR obsługujący dwa czujniki o znanych numerach seryjnych:

    Code:

    '***********************************************
    'Konfiguracja AVR
    '***********************************************
    $regfile = "m162def.dat"
    $crystal = 16000000

    $baud = 2400

    Config Porta = 255
    Porta = 255
    Config Portb = 255
    Portb = 255
    Config Portc = 255
    Portc = 255
    Config Portd = 255
    Portd = 255
    Config Porte = 255
    Porte = 255

    Config 1wire = Pind.7

    Config Lcdpin = Pin , Db4 = Porta.5 , Db5 = Porta.4 , Db6 = Porta.3 , Db7 = Porta.2 , E = Porta.0 , Rs = Porta.1
    Config Lcd = 20 * 2
    Cls
    Cursor Off Noblink

    Enable Interrupts
    '///////////////////////////////////////////////

    '***********************************************
    'Zmienne
    '***********************************************
    Dim Lsb As Byte
    Dim Msb As Byte
    Dim Tempa As Single
    Dim Ds1(8) As Byte , Ds2(8) As Byte
    Dim Tekst1 As String * 10
    Dim Tekst2 As String * 10
    '///////////////////////////////////////////////

    Lcd "test DS18B20"
    Wait 1

    'Numery wpisane na sztywno
    Ds2(1) = 40
    Ds2(2) = 55
    Ds2(3) = 181
    Ds2(4) = 1
    Ds2(5) = 1
    Ds2(6) = 0
    Ds2(7) = 0
    Ds2(8) = 207

    Ds1(1) = 16
    Ds1(2) = 171
    Ds1(3) = 224
    Ds1(4) = 167
    Ds1(5) = 0
    Ds1(6) = 8
    Ds1(7) = 0
    Ds1(8) = 220

    Do
      1wreset

      1wwrite &HCC
      1wwrite &H44
      Waitms 250
      Waitms 250

      1wreset

      1wwrite &H55
      1wwrite Ds2(1) , 8
      1wwrite &HBE

      Lsb = 1wread():
      Msb = 1wread():

      Tempa = Msb * 256
      Tempa = Tempa + Lsb
      Tempa = Tempa / 16
      Tekst1 = Fusing(tempa , "#.##")


      1wreset

      1wwrite &H55
      1wwrite Ds1(1) , 8
      1wwrite &HBE

      Lsb = 1wread():
      Msb = 1wread():

      Tempa = Msb * 256
      Tempa = Tempa + Lsb
      Tempa = Tempa / 16
      Tekst2 = Fusing(tempa , "#.#")

      Cls
      Lcd "DS18B20= " ; Tekst1
      Lowerline
      Lcd "DS18B20= " ; Tekst2
    Loop
    End


    Jest to prosty program testowy nie zawierający timera ani przerwań, napisalem go dawno temu jak miałem pewne problemy z dwoma czujnikami na jednej magistrali.

    Kod ten obsługuje dwa czujniki DS18B20 o znanych numerach seryjnych, więc najpierw musisz je odczytać i wpisać do programu albo napisać procedurę rejestrującą czujniki. Nigdy nie udało mi sie napisać tak aby czujniki same się zgłaszały i odczytywać ich numery.

    Podany kod nie obsługuje ujemnych temperatur. Może posłużyć przy wstępnych testach z dwoma DS18B20 lub DS18S20 po zmianie linijek

    Code:

    Tempa = Msb * 256
    Tempa = Tempa + Lsb
    Tempa = Tempa / 16


    na:

    Code:

    Tempa = Lsb/2


    Pamiętaj że jeśli będziesz używał przerwań to mogą być problemy z transmisją 1-Wire i trzeba będzie okresowe je wyłączać albo tak wysyłać dane po 1-Wire aby napewno transmisja sie zakończyła do następnego przerwania
  • #5
    dawid512
    Level 32  
    Tę część
    Code:
    $crystal = 8000000 
    też skopiowałeś z forum? Oczywiście masz ustawione na 8MHz prawda?
  • #6
    00gtw00
    Level 15  
    Tak mam ustawione wew. 8MHz

    Poniżej zamieszczam program który działa z dwoma sztukami DS18S20 i sam je wyszukuje.

    Code:
    $regfile = "m8def.dat"
    
    $crystal = 8000000

    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portb.0 , Rs = Portb.1

    Config 1wire = Portb.2
    Deflcdchar 0 , 6 , 9 , 9 , 6 , 32 , 32 , 32 , 32

    Dim I As Byte
    Dim T(2) As Byte
    Dim Y(2) As Byte
    Dim Temp1 As Single
    Dim Temp2 As Single
    Dim Dsid1(8) As Byte
    Dim Dsid2(8) As Byte

    Cursor Off
    Cls
    Do

    Dsid1(1) = 1wsearchfirst()
    Dsid2(1) = 1wsearchnext()

     1wreset
       1wwrite &H55
       1wverify Dsid1(1)
       1wwrite &HBE
       T(1) = 1wread()
       T(2) = 1wread()

       1wreset
       1wwrite &H55
       1wverify Dsid2(1)
       1wwrite &HBE
       Y(1) = 1wread()
       Y(2) = 1wread()

    1wreset
    1wwrite &HCC
    1wwrite &H44
    Waitms 750

      If T(2) = 0 Then
      Temp1 = T(1) / 2
      Else
      I = 256 - T(1)
      End If

      If T(2) > 0 Then
       Locate 1 , 4
       Lcd "-"
      End If
     '**************************
      If Y(2) = 0 Then
      Temp2 = Y(1) / 2
      Else
      I = 256 - Y(1)
      End If

      If Y(2) > 0 Then
       Locate 2 , 4
       Lcd "-"
      End If


    Cls
    Lcd "Zew: " ; Temp1 ; Chr(0) ; "C"
    Lowerline
    Lcd "Wew: " ; Temp2 ; Chr(0) ; "C"

    Loop
    End
  • #7
    leo71
    Level 10  
    takie pytanie: o co w tym chodzi?

    Quote:

    Tempa = Msb * 256
    Tempa = Tempa + Lsb
    Tempa = Tempa / 16

    Dlaczego akurat to tak sie robi?

    Czytałem o LSB i MSb ale zrozumieć nie mogę o co w tym chodzi....