Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[BASCOM] 1 Wire i 12xDS18B20 po raz tysięczny..

adambehnke 20 Feb 2010 22:04 4883 21
  • #1
    adambehnke
    Level 24  
    Witam
    Pewnie zaraz mnie tu Napadniecie ale walczę z dwunastoma czujnikami DS18B20.

    Otóż:
    Domyślnie w systemie ma pracować 12 sztuk czujników (ale chciałbym mieć możliwość dołożenia kolejnych).
    Oczywiście muszę sterować nimi znając ich seriale. Nie chcę umieszczać ich seriali w programie na stałe bo jak coś padnie to będzie lipa. Więc muszę wyszukać i odpytać każdy z istniejących czujników i zapisać serial każdego do zmiennej. Robię to (wg. mnie błędnie- ale seriale zapisuje) tak :

    Code:
    W = 1wirecount()
    
    Locate 3 , 1
    Lcd "Ilosc wykrytych czujnikow :" ; W

    Wait 1

    If W > 0 Then
    Dsid1(1) = 1wsearchfirst()                                  'Znajd? kolejny czujnik podpięty do portu
    Ds(1) = 1
    End If

    If W > 1 Then
    Dsid2(1) = 1wsearchnext()                                   'Znajd? kolejny czujnik podpięty do portu
    Ds(2) = 1
    End If

    If W > 2 Then
    Dsid3(1) = 1wsearchnext()                                   'Znajd? kolejny czujnik podpięty do portu
    Ds(3) = 1
    End If

    If W > 3 Then
    Dsid4(1) = 1wsearchnext()                                   'Znajd? kolejny czujnik podpięty do portu
    Ds(4) = 1
    End If

    If W > 4 Then
    Dsid5(1) = 1wsearchnext()                                   'Znajd? kolejny czujnik podpięty do portu
    Ds(5) = 1
    End If

    If W > 5 Then
    Dsid6(1) = 1wsearchnext()                                   'Znajd? kolejny czujnik podpięty do portu
    Ds(6) = 1
    End If

    If W > 6 Then
    Dsid7(1) = 1wsearchnext()                                   'Znajd? kolejny czujnik podpięty do portu
    Ds(7) = 1
    End If

    If W > 7 Then
    Dsid8(1) = 1wsearchnext()                                   'Znajd? kolejny czujnik podpięty do portu
    Ds(8) = 1
    End If

    If W > 8 Then
    Dsid9(1) = 1wsearchnext()                                   'Znajd? kolejny czujnik podpięty do portu
    Ds(9) = 1
    End If

    If W > 9 Then
    Dsid10(1) = 1wsearchnext()                                  'Znajd? kolejny czujnik podpięty do portu
    Ds(10) = 1
    End If

    If W > 10 Then
    Dsid11(1) = 1wsearchnext()                                  'Znajd? kolejny czujnik podpięty do portu
    Ds(11) = 1
    End If

    If W > 11 Then
    Dsid12(1) = 1wsearchnext()                                  'Znajd? kolejny czujnik podpięty do portu
    Ds(12) = 1
    End If


    Pewnie mógłbym to zrobić lepiej tak:

    Code:
     
    
    W = 1wirecount()

    For i = 1 to W
    Dsid(i) = 1wsearchnext()
    DS(i) =1
    next


    Ale nie sprawdzałem czy to zadziała poprawnie.


    Gdzie
    Code:
    Ds(x) = 1
    informuje system że czujnik numer X jest podłączony lub nie.

    Teraz przyszła kolej na ID i robię to tak:

    Code:

    If Dsid1(8) = Crc8(dsid1(1) , 7) Then
       Locate 4 , 1
       Lcd "CRC OK Czujnik 1 ID: "
       Locate 4 , 23
       For B = 1 To 8
       Lcd Hex(dsid1(b))
    Next
    End If

    If Dsid2(8) = Crc8(dsid2(1) , 7) Then
       Locate 5 , 1
       Lcd "CRC OK Czujnik 2 ID: "
       Locate 5 , 23
       For B = 1 To 8
       Lcd Hex(dsid2(b))
    Next
    End If

    If Dsid3(8) = Crc8(dsid3(1) , 7) Then
       Locate 6 , 1
       Lcd "CRC OK Czujnik 3 ID: "
       Locate 6 , 23
       For B = 1 To 8
       Lcd Hex(dsid3(b))
    Next
    End If

    If Dsid4(8) = Crc8(dsid4(1) , 7) Then
       Locate 7 , 1
       Lcd "CRC OK Czujnik 4 ID: "
       Locate 7 , 23
       For B = 1 To 8
       Lcd Hex(dsid4(b))
    Next
    End If

    If Dsid5(8) = Crc8(dsid5(1) , 7) Then
       Locate 8 , 1
       Lcd "CRC OK Czujnik 5 ID: "
       Locate 8 , 23
       For B = 1 To 8
       Lcd Hex(dsid5(b))
    Next
    End If

    If Dsid6(8) = Crc8(dsid6(1) , 7) Then
       Locate 9 , 1
       Lcd "CRC OK Czujnik 6 ID: "
       Locate 9 , 23
       For B = 1 To 8
       Lcd Hex(dsid6(b))
    Next
    End If

    If Dsid7(8) = Crc8(dsid7(1) , 7) Then
       Locate 10 , 1
       Lcd "CRC OK Czujnik 7 ID: "
       Locate 10 , 23
       For B = 1 To 8
       Lcd Hex(dsid7(b))
    Next
    End If

    If Dsid8(8) = Crc8(dsid8(1) , 7) Then
       Locate 11 , 1
       Lcd "CRC OK Czujnik 8 ID: "
       Locate 11 , 23
       For B = 1 To 8
       Lcd Hex(dsid8(b))
    Next
    End If

    If Dsid9(8) = Crc8(dsid9(1) , 7) Then
       Locate 12 , 1
       Lcd "CRC OK Czujnik 9 ID: "
       Locate 12 , 23
       For B = 1 To 8
       Lcd Hex(dsid9(b))
    Next
    End If

    If Dsid10(8) = Crc8(dsid10(1) , 7) Then
       Locate 13 , 1
       Lcd "CRC OK Czujnik 10 ID: "
       Locate 13 , 23
       For B = 1 To 8
       Lcd Hex(dsid10(b))
    Next
    End If

    If Dsid11(8) = Crc8(dsid11(1) , 7) Then
       Locate 14 , 1
       Lcd "CRC OK Czujnik 11 ID: "
       Locate 14 , 23
       For B = 1 To 8
       Lcd Hex(dsid11(b))
    Next
    End If

    If Dsid12(8) = Crc8(dsid12(1) , 7) Then
       Locate 15 , 1
       Lcd "CRC OK Czujnik 12 ID: "
       Locate 15 , 23
       For B = 1 To 8
       Lcd Hex(dsid12(b))
    Next
    End If


    Mam zamiar to znacznie skrócić ale nie bardzo mam pojęcie jak. Chyba zrobię to w pętli.

    Pełne ID zapisuję sobie do zmiennej (jako nazwę czujnika) tak:



    Code:
    Ntemp(1) = Str(dsid1(1)) + Str(dsid1(2)) + Str(dsid1(3)) + Str(dsid1(4)) + Str(dsid1(5)) + Str(dsid1(6)) + Str(dsid1(7)) + Str(dsid1(8) )


    Poprawcie mnie znowu jak można to zrobić prościej. Generalnie muszę mieć ID każdego z czujnika wyświetlone w menu jako nazwa tego czujnika.


    W systemie mam sobie zrobione coś na wzór wielowątkowości i wykorzystuję timer który steruje skokami do podprogramów po ściśle odliczonym czasie.
    Muszę przy takiej ilości czujników zrezygnować z paskudnego
    Code:
    Waitms 750
    i chciałbym w jednym z "impulsów" timera wysłać polecenia odczytu do DS-ów a przy jakimś kolejnym odczytać odpowiedzi. Tym samym pozbędę się problemu z czekaniem na konwersję. Ale znowu motam się z tym jak tego dokonać.

    Generalnie mając już ID każdego z istniejących czujników chciałbym mieć możliwość odpytania sobie dowolnego DS-a i nie musieć odczytywać wszystkich na raz. Wiem , wiem powiecie że wałkowane było to setki razy i rzeczywiście czytałem to wiele razy ale jak usiadłem to tego to.... pustka.

    Jak na razie korzystam z przerostu formy nad treścią w taki sposób:

    Code:
    If Ds(1) = 1 Then
    
       1wreset
       1wwrite &H55
       1wverify Dsid1(1)                                        'wysyłamy adres 1 czujnika
       1wwrite &HBE
       I1 = 1wread(2)
    End If

    If Ds(2) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid2(1)                                        'wysylam adres 2 czujnika
       1wwrite &HBE
       I2 = 1wread(2)
    End If

    If Ds(3) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid3(1)                                        'wysylam adres 3 czujnika
       1wwrite &HBE
       I3 = 1wread(2)
    End If

    If Ds(4) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid4(1)                                        'wysylam adres 4 czujnika
       1wwrite &HBE
       I4 = 1wread(2)
    End If

    If Ds(5) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid5(1)                                        'wysylam adres 5 czujnika
       1wwrite &HBE
       I5 = 1wread(2)
    End If

    If Ds(6) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid6(1)                                        'wysylam adres 6 czujnika
       1wwrite &HBE
       I6 = 1wread(2)
    End If

    If Ds(7) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid7(1)                                        'wysylam adres 7 czujnika
       1wwrite &HBE
       I7 = 1wread(2)
    End If

    If Ds(8) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid8(1)                                        'wysylam adres 8 czujnika
       1wwrite &HBE
       I8 = 1wread(2)
    End If

    If Ds(9) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid9(1)                                        'wysylam adres 9 czujnika
       1wwrite &HBE
       I9 = 1wread(2)
    End If

    If Ds(10) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid10(1)                                       'wysylam adres 10 czujnika
       1wwrite &HBE
       I10 = 1wread(2)
    End If

    If Ds(11) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid11(1)                                       'wysylam adres 11 czujnika
       1wwrite &HBE
       I11 = 1wread(2)
    End If

    If Ds(12) = 1 Then
       1wreset
       1wwrite &H55
       1wverify Dsid12(1)                                       'wysylam adres 12 czujnika
       1wwrite &HBE
       I12 = 1wread(2)
    End If

    '--------konwersja temp dla wszystkich dsow
    1wreset
    1wwrite &HCC
    1wwrite &H44


    'Return


    '******************************************************************************'
    '**************************PROCEDURA 1WIRE-TEMPERATURA_READ********************'
    '******************************************************************************'
    'Temp_read:


    I1 = I1 * 10
    I1 = I1 / 16
    Ss = Str(i1)
    Ss = Format(ss , " 0.0")
    Temp(1) = Ss

    I2 = I2 * 10
    I2 = I2 / 16
    Ss = Str(i2)
    Ss = Format(ss , " 0.0")
    Temp(2) = Ss

    I3 = I3 * 10
    I3 = I3 / 16
    Ss = Str(i3)
    Ss = Format(ss , " 0.0")
    Temp(3) = Ss

    I4 = I4 * 10
    I4 = I4 / 16
    Ss = Str(i4)
    Ss = Format(ss , " 0.0")
    Temp(4) = Ss

    I5 = I5 * 10
    I5 = I5 / 16
    Ss = Str(i5)
    Ss = Format(ss , " 0.0")
    Temp(5) = Ss

    I6 = I6 * 10
    I6 = I6 / 16
    Ss = Str(i6)
    Ss = Format(ss , " 0.0")
    Temp(6) = Ss

    I7 = I7 * 10
    I7 = I7 / 16
    Ss = Str(i7)
    Ss = Format(ss , " 0.0")
    Temp(7) = Ss

    I8 = I8 * 10
    I8 = I8 / 16
    Ss = Str(i8)
    Ss = Format(ss , " 0.0")
    Temp(8) = Ss

    I9 = I9 * 10
    I9 = I9 / 16
    Ss = Str(i9)
    Ss = Format(ss , " 0.0")
    Temp(9) = Ss

    I10 = I10 * 10
    I10 = I10 / 16
    Ss = Str(i10)
    Ss = Format(ss , " 0.0")
    Temp(10) = Ss

    I11 = I11 * 10
    I11 = I11 / 16
    Ss = Str(i11)
    Ss = Format(ss , " 0.0")
    Temp(11) = Ss

    I12 = I12 * 10
    I12 = I12 / 16
    Ss = Str(i12)
    Ss = Format(ss , " 0.0")
    Temp(12) = Ss


    Wg. mnie robię to bezsensownie . I rzeczywiście tak jest bo przy 2-3 czujnikach pracuje to poprawnie ale przy 12 pojawiają się błędy bo nie czekam na konwersję.
    Nie mam pojęcia jak to ogarnąć.

    Reasumując, bo trochę namąciłem sporą ilością kodu.
    Używając timera generuję sobie "polecenia" skoku do podprogramów i np.
    - przy pierwszym impulsie od timera wysyłam zapytanie do czujników (może być do wszystkich na raz)
    - przy kolejnym impulsie (mogę sobie ustawić że 1s później niż zapytanie) odczytuję sobie temperaturę z czujników ( może być od jednego lub od wszystkich)

    Zatem:

    1.Chciałbym na początku programu sprawdzić ile jest podłączonych czujek ( ale to wiem jak)
    2.Odczytać ID każdego istniejącego czujnika (wszystkie na raz)
    3.Zapisać ID każdego czujnika do zmiennej (najlepiej String)
    4.W jakimś momencie chciałbym wyslać zapytanie do czujnika np.10
    5.W jakimś kolejnej chwili chciałbym zczytać sobie temperaturę z wybranego czujnika.

    Trochę zamieszałem ale nie potrafię tego napisać prościej.
  • Helpful post
    #2
    Logan
    Level 30  
    Co powiesz na to:
    Code:

    Dim i as byte

    adres(1)=1wsearchfirst()
    i=2
    Do
    adres(i)=1wsearchnext()
    incr i
    Loop Until Err=1

    ?
  • Helpful post
    #4
    Logan
    Level 30  
    Jeśli chodzi o ID to chyba najprościej będzie zrobić funkcje i z głównego programu przekazywać do niej ID czujnika, natomiast funkcja będzie zwracać np bit 1/0 OK/ERROR. Podobnie chyba można zrobić z odczytem temperatury.
  • #5
    adambehnke
    Level 24  
    No tak to jest dobry pomysł .Funkcja z przekazywaniem parametrów. Czyli jedna funkcja wysyłała by zapytanie do czujnika a druga odczytywała by z tego czujnika, i tym samym pominął bym czas oczekiwania na konwersję gdyż po prostu mógłbym sobie odczekać moment zanim podam parametry czujki do odczytu do tej drugiej funkcji. Ale powoli , powoli. Stary już jestem i muszę robić wszystko po kolei :)
    Najpierw odebrać ID do zmiennej z każdego podłączonego czujnika.

    Robiłem to tak ale na pewno można prościej:

    Code:

    If Dsid1(8) = Crc8(dsid1(1) , 7) Then
       Locate 4 , 1
       Lcd "CRC OK Czujnik 1 ID: "
       Locate 4 , 23
       For B = 1 To 8
       Lcd Hex(dsid1(b))


    Ntemp(1) = Str(dsid1(1)) + Str(dsid1(2)) + Str(dsid1(3)) + Str(dsid1(4)) + Str(dsid1(5)) + Str(dsid1(6)) + Str(dsid1(7)) + Str(dsid1(8) )           


    Dodano po 47 [minuty]:

    Niestety ale chyba bez pomocy się nie obejdzie :/
  • Helpful post
    #6
    morson
    Level 14  
    Ja bym wyszukiwanie zrobił tak
    Code:

    Dim Ids(64) as Byte 'Maksymalna liczba czujników * 8
    Dim I as Byte
    Dim J as Byte
    Dim L as Byte
    Dim Count as Byte
    Dim TempCount as Byte

    ' Wyszukiwanie
    Count = 0
    TempCount = 1wirecount()
    If TempCount > 0 Then
     I = 1
     J = I + 7
     Ids(1) = 1wsearchfirst()
     Do
      If Ids(J) = Crc8(Ids(i), 7) Then
       I = I + 8
       J = J + 8
       Count = Count + 1
      End If
      Ids(I) = 1wsearchnext()
     Loop Until Err = 1
    Else
     ' Jakiś komunikat
    End If
    ' W count będziesz miał dostępną liczbę czujników
    J = 1


    A odczyt czujników to w przerwaniu coś w stylu jeśli będą co np 20ms

    Code:

    If TStep = 0 Then
     ' tu start przetwarzania DS'ów
     TStep = TStep + 1
    Else If TStep > 33 Then ' > 750 / 20
     If J <= Count Then
      I = J * 8
      I = I - 7
      ' odczyt DS'a z identyfikatorem Ids(I)
      ' wyniki sobie zapisuj do jakiejś tablicy np Dim Temps(n) as Integer
      ' i przetwarzaj je na tekst dopiero w momencie wyświetlania
      J = J + 1
      TStep = TStep + 1
     Else
      J = 1
      TStep = 0
     End If
    End If


    Powinno działać (nie przepadam za Bascomem)
  • #7
    adambehnke
    Level 24  
    Tak,to rozumiem. Ale mi chodzi o coś innego.

    Mając już ID każdego z istniejących DS-ów chciałbym odpytać jeden z czujników np tak:

    W jednej funkcji (z przekazywaniem parametrów) przesyłał bym adres do wybranego DS-a:

    Code:
    '#####################czujnik 1##
    
    1wverify Ds1(1)                                             'Czy jest na magistrali urządzenie o adresie z Ds1(1) ???
    If Err = 1 Then                                             'Nie ma :(((
    'BRAK UKLADU O TAKIM ID'

    Else


    1wreset                    'Resecik
    1wwrite &H55                                                'Będzie odpowiadało  urządzenie , którego numer zaraz podam
    1wwrite Ds1(1) , 8                                          'Podaję numer urządzenia
    1wwrite &HBE

    end if




    a w drugiej funkcji (z przekazywaniem parametrów) odczytywał bym sobie z niego temperaturę:


    Code:

    I3 = 1wread(2)


    Proszę mnie poprawić jeśli robię źle. Nie mam wielkiego doświadczenia z 1Wire.


    Ale jest taka jeszcze sprawa. Chodzi mi o to czy jak chcę użyć tej drugiej funkcji to czy muszę podawać na nowo adres tego ds-a którego chcę odczytać?
    Czy mogę w jakiś sposób nakazać wszystkim istniejącym DS-om przygotowanie danych a potem odpytać po kolei każdy z nich podając ich adresy?
    Proszę o jakiś przykład bo chyba zwariuję...
  • Helpful post
    #8
    morson
    Level 14  
    Jeśli te funkcje będą następować po sobie (niezależnie jak długi jest odstęp, bo na taki pozwala specyfikacja 1wire), to będzie to działać. Jeśli coś jakaś aktywność na linii będzie pomiędzy, to całą komunikację zerwie.

    Przygotowanie danych to
    Code:

    1wreset
    1wwrite &HCC ' SKIP ROM czyli do wszystkich
    1wwrite &H44 ' Start conversion

    i po 750 ms możesz odpytywać je w dowolnej kolejności i ilości
  • #9
    adambehnke
    Level 24  
    Tak właśnie mam tak zrobione.

    Ale wolałbym jednak móc podawać ID czujnika do odczytania do funkcji np tak:

    Code:

    Declare Function Myfunction(Byval I As byte) As string





    Z = Dsid1(1)                                                ' ID czujnika 1

    T = Myfunction(z)



    Function Myfunction(byval I As Byte ) As String

       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid12(1) , 8                                    'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")

      Myfunction = Ss
    End Function 


    i w sumie powinienem podstawić zmienną I zamiast
    Code:
     Dsid12(1) ,8 
    ale nie działa i otrzymuję wynik 0. Nie za bardzo wiem jak mam to podstawić czy tak?

    Code:
     i ,8 
    bo to nie działa gdyż tracę część ID robiąc tak Z = Dsid1(1) .
    A jeśli zostawię wstawiony gotowy adres
    Code:
    Dsid12(1) ,8 
    to dostaję ładnie wynik. Ale o to ma chodzić w tej funkcji że adres mam sobie tu podawać dowolnego czujnika.

    A tak odczytuje sobie ID na początku programu z DS-ów:

    Code:
    W = 1wirecount()                                            ' ilość aktualnie podłączonych czujników
    

    For I = 1 To W
      If I = 1 Then Dsid1(1) = 1wsearchfirst()
      If I = 2 Then Dsid2(1) = 1wsearchnext()
      If I = 3 Then Dsid3(1) = 1wsearchnext()
      If I = 4 Then Dsid4(1) = 1wsearchnext()
      If I = 5 Then Dsid5(1) = 1wsearchnext()
      If I = 6 Then Dsid6(1) = 1wsearchnext()
      If I = 7 Then Dsid7(1) = 1wsearchnext()
      If I = 8 Then Dsid8(1) = 1wsearchnext()
      If I = 9 Then Dsid9(1) = 1wsearchnext()
      If I = 10 Then Dsid10(1) = 1wsearchnext()
      If I = 11 Then Dsid11(1) = 1wsearchnext()
      If I = 12 Then Dsid12(1) = 1wsearchnext()
      Ds(i) = 1
      Waitms 100                                                'Czekam na wszelki wypadek
    Next I


    I odczytuje poprawnie.

    Dodano po 1 [godziny] 48 [minuty]:

    OK. Zrobiłem tak :

    Code:
    '*******************************************************************************'
    
    '******************KONFIGURACJA TYPU I PRĘDKOŚCI MIKROPRPCESORA*****************'
    '*******************************************************************************'
    $regfile = "m2560def.DAT"                                   'ATMEGA 2560 16AU 256KB PLASH

    $crystal = 16000000
    $hwstack = 512
    $swstack = 128
    $framesize = 128


    '*******************************************************************************'
    '****************************KONFIGURACJA LCD** ********************************'
    '*******************************************************************************'
    Config Graphlcd = 240 * 128 , Dataport = Porta , Controlport = Portc , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Fs = 5 , Mode = 6       'WYŚWIETLACZ LCD


    '*******************************************************************************'
    '************************KONFIGURACJA TIMERÓW SYSTEMOWYCH***********************'
    '*******************************************************************************'
    Config Timer3 = Timer , Prescale = 1                        '0,004s * 256 cykli = 1s

    On Timer3 Myisr                                             'pseudo-przerwania
    Enable Timer3

    Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down       'regulacja jasności LCD(na pwm1a)

    Enable Interrupts
    '*******************************************************************************'
    '************************Deklaracja zmiennych systemowych***********************'
    '*******************************************************************************'

    Dim W As Byte                                               'deklaracja zmiennej do odczytu ilo?c czujników
    Dim Trx(3) As Integer
    Dim Flaga(3) As Integer
    Dim I As Integer                                            'zmienna służąca do wyszukiwanie czujek
    Dim Ntemp(16) As String * 20                                'nazwa czujników temperatury

        Dim Dsid1(8) As Byte                                    'czujnik1
        Dim Dsid2(8) As Byte                                    'czujnik2
        Dim Dsid3(8) As Byte                                    'czujnik3
        Dim Dsid4(8) As Byte                                    'czujnik4
        Dim Dsid5(8) As Byte                                    'czujnik5
        Dim Dsid6(8) As Byte                                    'czujnik6
        Dim Dsid7(8) As Byte                                    'czujnik7
        Dim Dsid8(8) As Byte                                    'czujnik8
        Dim Dsid9(8) As Byte                                    'czujnik9
        Dim Dsid10(8) As Byte                                   'czujnik10
        Dim Dsid11(8) As Byte                                   'czujnik11
        Dim Dsid12(8) As Byte                                   'czujnik12
        Dim Dsid13(8) As Byte                                   'czujnik13
        Dim Dsid14(8) As Byte                                   'czujnik14
        Dim Dsid15(8) As Byte                                   'czujnik15
        Dim Dsid16(8) As Byte                                   'czujnik16



        Dim I1 As Integer , Ss As String * 6                    'czujnik1 -16
        Dim Ds(17) As Integer


     Dim Temp(16) As String * 6
    '*******************************************************************************'
    '**************************Konfiguracja ****************************************'
    '*******************************************************************************'
    Config 1wire = Portd.4                                      'pin pod którym obsługiwane jest 1Wire


    Config Portd.6 = Output                                     'BUZZER
    Config Portc.6 = Output                                     'LED 2
    Config Portc.7 = Output                                     'LED 1

    Portd.6 = 1                                                 'BUZZER WYCISZONY
    Portc.6 = 1                                                 'LED CL2 = ZGASZONA
    Portc.7 = 1                                                 'LED CL1 = ZGASZONA


    Pwm1a = 130

    Cursor Off
    Cls



    '*******************************************************************************'
    '********PRZESZUKIWANIE MAGISTRALI 1WIRE , DODAWANIE CZUJNIKÓW , NAZWY**********'
    '*******************************************************************************'

    'SPRAWDZANIE ILOŚCI OBECNYCH DS-ów I POBRANIE ICH ID

    W = 1wirecount()                                            ' ilość aktualnie podłączonych czujników

    For I = 1 To W
      If I = 1 Then Dsid1(1) = 1wsearchfirst()
      If I = 2 Then Dsid2(1) = 1wsearchnext()
      If I = 3 Then Dsid3(1) = 1wsearchnext()
      If I = 4 Then Dsid4(1) = 1wsearchnext()
      If I = 5 Then Dsid5(1) = 1wsearchnext()
      If I = 6 Then Dsid6(1) = 1wsearchnext()
      If I = 7 Then Dsid7(1) = 1wsearchnext()
      If I = 8 Then Dsid8(1) = 1wsearchnext()
      If I = 9 Then Dsid9(1) = 1wsearchnext()
      If I = 10 Then Dsid10(1) = 1wsearchnext()
      If I = 11 Then Dsid11(1) = 1wsearchnext()
      If I = 12 Then Dsid12(1) = 1wsearchnext()
      If I = 13 Then Dsid13(1) = 1wsearchnext()
      If I = 14 Then Dsid14(1) = 1wsearchnext()
      If I = 15 Then Dsid15(1) = 1wsearchnext()
      If I = 16 Then Dsid16(1) = 1wsearchnext()

      Ds(i) = 1
      Waitms 100                                                'Czekam na wszelki wypadek
    Next I




    'ZAPISANIE ICH PEŁNEGO ID DO ZMIENNEJ TEKSTOWEJ

    Ntemp(1) = Str(dsid1(1)) + Str(dsid1(2)) + Str(dsid1(3)) + Str(dsid1(4)) + Str(dsid1(5)) + Str(dsid1(6)) + Str(dsid1(7)) + Str(dsid1(8) )
    Ntemp(2) = Str(dsid2(1)) + Str(dsid2(2)) + Str(dsid2(3)) + Str(dsid2(4)) + Str(dsid2(5)) + Str(dsid2(6)) + Str(dsid2(7)) + Str(dsid2(8) )
    Ntemp(3) = Str(dsid3(1)) + Str(dsid3(2)) + Str(dsid3(3)) + Str(dsid3(4)) + Str(dsid3(5)) + Str(dsid3(6)) + Str(dsid3(7)) + Str(dsid3(8) )
    Ntemp(4) = Str(dsid4(1)) + Str(dsid4(2)) + Str(dsid4(3)) + Str(dsid4(4)) + Str(dsid4(5)) + Str(dsid4(6)) + Str(dsid4(7)) + Str(dsid4(8) )
    Ntemp(5) = Str(dsid5(1)) + Str(dsid5(2)) + Str(dsid5(3)) + Str(dsid5(4)) + Str(dsid5(5)) + Str(dsid5(6)) + Str(dsid5(7)) + Str(dsid5(8) )
    Ntemp(6) = Str(dsid6(1)) + Str(dsid6(2)) + Str(dsid6(3)) + Str(dsid6(4)) + Str(dsid6(5)) + Str(dsid6(6)) + Str(dsid6(7)) + Str(dsid6(8) )
    Ntemp(7) = Str(dsid7(1)) + Str(dsid7(2)) + Str(dsid7(3)) + Str(dsid7(4)) + Str(dsid7(5)) + Str(dsid7(6)) + Str(dsid7(7)) + Str(dsid7(8) )
    Ntemp(8) = Str(dsid8(1)) + Str(dsid8(2)) + Str(dsid8(3)) + Str(dsid8(4)) + Str(dsid8(5)) + Str(dsid8(6)) + Str(dsid8(7)) + Str(dsid8(8) )
    Ntemp(9) = Str(dsid9(1)) + Str(dsid9(2)) + Str(dsid9(3)) + Str(dsid9(4)) + Str(dsid9(5)) + Str(dsid9(6)) + Str(dsid9(7)) + Str(dsid9(8) )
    Ntemp(10) = Str(dsid10(1)) + Str(dsid10(2)) + Str(dsid10(3)) + Str(dsid10(4)) + Str(dsid10(5)) + Str(dsid10(6)) + Str(dsid10(7)) + Str(dsid10(8) )
    Ntemp(11) = Str(dsid11(1)) + Str(dsid11(2)) + Str(dsid11(3)) + Str(dsid11(4)) + Str(dsid11(5)) + Str(dsid11(6)) + Str(dsid11(7)) + Str(dsid11(8) )
    Ntemp(12) = Str(dsid12(1)) + Str(dsid12(2)) + Str(dsid12(3)) + Str(dsid12(4)) + Str(dsid12(5)) + Str(dsid12(6)) + Str(dsid12(7)) + Str(dsid12(8) )
    Ntemp(13) = Str(dsid13(1)) + Str(dsid13(2)) + Str(dsid13(3)) + Str(dsid13(4)) + Str(dsid13(5)) + Str(dsid13(6)) + Str(dsid13(7)) + Str(dsid13(8) )
    Ntemp(14) = Str(dsid14(1)) + Str(dsid14(2)) + Str(dsid14(3)) + Str(dsid14(4)) + Str(dsid14(5)) + Str(dsid14(6)) + Str(dsid14(7)) + Str(dsid14(8) )
    Ntemp(15) = Str(dsid15(1)) + Str(dsid15(2)) + Str(dsid15(3)) + Str(dsid15(4)) + Str(dsid15(5)) + Str(dsid15(6)) + Str(dsid15(7)) + Str(dsid15(8) )
    Ntemp(16) = Str(dsid16(1)) + Str(dsid16(2)) + Str(dsid16(3)) + Str(dsid16(4)) + Str(dsid16(5)) + Str(dsid16(6)) + Str(dsid16(7)) + Str(dsid16(8) )


    '*******************************************************************************'
    '*****************PĘTLA GŁÓWNA**************************************************'
    '*******************************************************************************'
    Do


    If Flaga(1) = 1 Then Gosub Ds_send
    If Flaga(2) = 1 Then Gosub Ds_receive
    If Flaga(3) = 1 Then Gosub Disp                             'DISPLAY





    Loop

    '*******************************************************************************'
    '*******************************************************************************'
    '*******************************************************************************'



    '*******************************************************************************'
    '*****************PROCEDURA ZAPYTANIA DS-ów*************************************'
    '*******************************************************************************'
    Ds_send:

    1wreset
    1wwrite &HCC
    1wwrite &H44

    Flaga(1) = 0
    Portc.6 = 1
    Return




    '*******************************************************************************'
    '*****************PROCEDURA ODCZYTU** DS-ów*************************************'
    '*******************************************************************************'
    Ds_receive:


    'DS-1
    If Ds(1) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid1(1) , 8                                     'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(1) = Ss
    End If

    'DS-2
    If Ds(2) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid2(1) , 8                                     'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(2) = Ss
    End If

    'DS-3
    If Ds(3) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid3(1) , 8                                     'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(3) = Ss
    End If

    'DS-4
    If Ds(4) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid4(1) , 8                                     'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(4) = Ss
    End If

    'DS-5
    If Ds(5) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid5(1) , 8                                     'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(5) = Ss
    End If

    'DS-6
    If Ds(6) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid6(1) , 8                                     'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(6) = Ss
    End If

    'DS-7
    If Ds(7) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid7(1) , 8                                     'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(7) = Ss
    End If

    'DS-8
    If Ds(8) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid8(1) , 8                                     'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(8) = Ss
    End If

    'DS-9
    If Ds(9) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid9(1) , 8                                     'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(9) = Ss
    End If

    'DS-10
    If Ds(10) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid10(1) , 8                                    'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(10) = Ss
    End If

    'DS-11
    If Ds(11) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid11(1) , 8                                    'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(11) = Ss
    End If

    'DS-12
    If Ds(12) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid12(1) , 8                                    'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(12) = Ss
    End If

    'DS-13
    If Ds(13) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid13(1) , 8                                    'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(13) = Ss
    End If

    'DS-14
    If Ds(14) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid14(1) , 8                                    'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(14) = Ss
    End If

    'DS-15
    If Ds(15) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid15(1) , 8                                    'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(15) = Ss
    End If

    'DS-16
    If Ds(16) = 1 Then
       1wreset                                                  'Resecik
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam !
       1wwrite Dsid16(1) , 8                                    'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")
       Temp(16) = Ss
    End If


    Flaga(2) = 0
    Portc.7 = 1
    Return




    '*******************************************************************************'
    '*****************PROCEDURA WYŚWIETLANIA****************************************'
    '*******************************************************************************'
    Disp:

    Locate 1 , 1 : Lcd "Ilosc DS-ow :" ; W


    Locate 2 , 1 : Lcd "Adres 1:" ; Ntemp(1)
           Locate 2 , 25 : Lcd "TEMP: " ; Temp(1)

    Locate 3 , 1 : Lcd "Adres 2:" ; Ntemp(2)
           Locate 3 , 25 : Lcd "TEMP: " ; Temp(2)

    Locate 4 , 1 : Lcd "Adres 3:" ; Ntemp(3)
           Locate 4 , 25 : Lcd "TEMP: " ; Temp(3)

    Locate 5 , 1 : Lcd "Adres 4:" ; Ntemp(4)
           Locate 5 , 25 : Lcd "TEMP: " ; Temp(4)

    Locate 6 , 1 : Lcd "Adres 5:" ; Ntemp(5)
           Locate 6 , 25 : Lcd "TEMP: " ; Temp(5)

    Locate 7 , 1 : Lcd "Adres 6:" ; Ntemp(6)
           Locate 7 , 25 : Lcd "TEMP: " ; Temp(6)

    Locate 8 , 1 : Lcd "Adres 7:" ; Ntemp(7)
           Locate 8 , 25 : Lcd "TEMP: " ; Temp(7)

    Locate 9 , 1 : Lcd "Adres 8:" ; Ntemp(8)
           Locate 9 , 25 : Lcd "TEMP: " ; Temp(8)

    Locate 10 , 1 : Lcd "Adres 9:" ; Ntemp(9)
           Locate 10 , 25 : Lcd "TEMP: " ; Temp(9)

    Locate 11 , 1 : Lcd "Adres10:" ; Ntemp(10)
           Locate 11 , 25 : Lcd "TEMP: " ; Temp(10)

    Locate 12 , 1 : Lcd "Adres11:" ; Ntemp(11)
           Locate 12 , 25 : Lcd "TEMP: " ; Temp(11)

    Locate 13 , 1 : Lcd "Adres12:" ; Ntemp(12)
           Locate 13 , 25 : Lcd "TEMP: " ; Temp(12)

    Flaga(3) = 0
    Return










    Myisr:                                                      'PSEUDO_PRZERWANIA
    'przerwanie od Timera wywoływane co 0,004 sekundy czyli 4 milisekundy
    'trzeba zliczyć w tym przerwaniu do 250 aby osiągnąć 1 sekundę



    'DS 18B20 WYSŁANIE ZAPYTANIA
    Trx(1) = Trx(1) + 1                                         'skok co 2 sekundy
    If Trx(1) = 500 Then
       Flaga(1) = 1                                             'TEMP_SET
       Portc.6 = 0
    End If

    'DS 18B20 ODBIÓR DANYCH
    If Trx(1) = 750 Then                                        'skok co 3 sekundy
       Flaga(2) = 1                                             'TEMP_READ
       Trx(1) = 0
       Portc.7 = 0
    End If


    'LCD DISPLAY
    Trx(2) = Trx(2) + 1                                         'skok co 0,5 sekundy
    If Trx(2) > 125 Then
       Flaga(3) = 1                                             'LCD DISPLAY
       Trx(2) = 0
    End If



    Return


    Działa poprawnie chociaż wolał bym użyć funkcji. Wszelkie uwagi mile widziane.
  • Helpful post
    #10
    Logan
    Level 30  
    Ostrzegam, że nie jestem pewny jak to zrobić, tylko głośno myślę.

    Mamy 12 czujników, adres każdego zajmuje 8 bajtów, deklarujemy sobie więc
    Code:
    DS_ID(96) as Byte
    jak odczytać adresy to już wiesz. Czyli w bajtach od 1 do 8 będziesz mieć ID czujnika nr 1, od 9 do 16 ID czujnika nr 2, itd. Teraz do funkcji proponuję przekazywać adres z pierwszym bajtem każdego czujnika, czyli najpierw 1, potem 9, potem 17, itd. W funkcji musimy mieć pętle od DS_ID(a) do DS_ID(a+8 ), gdzie a to będzie nasz przekazywany pierwszy bajt adresu (1, 9, 17, itd.). Takie są założenia, teraz pytanie jak to wprowadzić w życie ? :)
  • #11
    adambehnke
    Level 24  
    A więc udało się :)

    Oczywiście korzystam z funkcji tak jak chciałem.

    Deklaracja:
    Code:
     
    
    Declare Function Ds_odczyt(byref Stringi As Byte ) As String


    Wyszukiwanie:
    Code:
    ' Wyszukiwanie
    

    Ds_count = 0
    Ds_tempcount = 1wirecount()
    If Ds_tempcount > 0 Then

     Ds_i = 1
     Ds_j = Ds_i + 7
     Ds_id(1) = 1wsearchfirst()

     Do
      If Ds_id(ds_j) = Crc8(ds_id(ds_i) , 7) Then
       Ds_i = Ds_i + 8
       Ds_j = Ds_j + 8
       Ds_count = Ds_count + 1
      End If
      Ds_id(ds_i) = 1wsearchnext()
     Loop Until Err = 1

    Else

     ' Jakiś komunikat
    End If


    Przepisywanie ID czujników do zmiennych tekstowych:
    Code:
    For Z(9) = 1 To Ds_tempcount
    

        Z(1) = Z(9) * 8 : Z(1) = Z(1) - 7                       '1 bajt
        Z(2) = Z(9) * 8 : Z(2) = Z(2) - 6                       '2 bajt
        Z(3) = Z(9) * 8 : Z(3) = Z(3) - 5                       '3 bajt
        Z(4) = Z(9) * 8 : Z(4) = Z(4) - 4                       '4 bajt
        Z(5) = Z(9) * 8 : Z(5) = Z(5) - 3                       '5 bajt
        Z(6) = Z(9) * 8 : Z(6) = Z(6) - 2                       '6 bajt
        Z(7) = Z(9) * 8 : Z(7) = Z(7) - 1                       '7 bajt
        Z(8) = Z(9) * 8                                         '8 bajt

        Ntemp(z(9)) = Str(ds_id(z(1))) + Str(ds_id(z(2))) + Str(ds_id(z(3))) + Str(ds_id(z(4))) + Str(ds_id(z(5))) + Str(ds_id(z(6))) + Str(ds_id(z(7))) + Str(ds_id(z(8)))

    Next Z(9)




    Konwersja:
    Code:

    Ds_send:

    1wreset
    1wwrite &HCC
    1wwrite &H44

    Return


    Odczyt przy użyciu wyniku zwracanego z funkcji:
    Code:
    Temp(1) = Ds_odczyt(ds_id(1))



    Funkcja:
    Code:
    Function Ds_odczyt(byref Stringi As Byte ) As String
    


       1wreset                                                  'Reset
       1wwrite &H55                                             'Będzie odpowiadało tylko urządzenie , którego numer zaraz podam
       1wwrite Stringi , 8                                       'Podaję numer urządzenia , które zapytam ,a reszta milczy aż pojawi się reset.
       1wwrite &HBE                                             'Poproszę zawartość scratchpad'a
       I1 = 1wread(2)                                           'Konwersja
       I1 = I1 * 10
       I1 = I1 / 16
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")

       Ds_odczyt = Ss

    End Function


    [BASCOM] 1 Wire i 12xDS18B20 po raz tysięczny..
    Wszystko działa poprawnie.

    Dodano po 10 [minuty]:

    Dziękuję wszystkim za naprowadzenie mnie na trop. W sumie to pierwszy raz korzystałem z własnej funkcji i teraz dopiero zacznę używać ich na poważnie gdyż sporo ułatwiają i upraszczają program.
  • Helpful post
    #12
    morson
    Level 14  
    Zamiast identyfikatorów Str(Id(x)) mógłbyś użyć Hex(Id(x)) wtedy identyfikatory by ładniej wyglądały i były stałej długości
  • #13
    adambehnke
    Level 24  
    Tak też zrobię. W sumie i tak identyfikatory będą widoczne tylko w jednej sekcji menu ale jednak. Teraz dopiero biorę się za uporządkowanie i uproszczenie tego kodu i nadanie "normalnych" nazw zmiennym :) ,bo te nadawałem będąc kierowany emocjami :D

    EDIT:
    Jeszcze jedno. W sumie nic nie stoi na przeszkodzie aby podłączać więcej niż te 12-16 czujek. Generalnie ogranicza mnie tylko ta tablica i wprowadzony w niej rozmiar :

    Code:
    Dim Ds_id(130) As Byte


    Jak ( i czy da się ) zrobić tak aby tablica nie miała zadeklarowanej wielkości i była dynamicznie powiększana /zmniejszana zależnie od ilości podłączonych ds-ów ??
  • #14
    adambehnke
    Level 24  
    Jest jeszcze jedna sprawa. Otóż do mojej magistrali 1Wire będę miał podłączone nie tylko DS18B20 ale i inne kostkii Maxim-a pracujące na 1Wire jak np. IButton , switche ,itp.
    I teraz pytanie:

    Wiem że "serial" jaki zwraca dana kostka (dla przykładu DS18B20) zawiera:

    8bit family Code + 48bit serial + 8bit CRC

    Z tego co widzę to dla DS18B20 ten Family Code to : 28 (w formie HEX)
    I po tym mógłbym identyfikować co to za chip na magistali.

    Ale jak i gdzie znaleźć jakie są te Family Code dla innych Maxim-ów?
    Nie mam jeszcze innych kostek poza 18B20 i dlatego nie mogę tego osobiście sprawdzić. Może Ma ktoś z Was jakieś informacje na ten temat?

    Dodano po 6 [minuty]:

    Chyba znalazłem. Przykładowo dla DS2401 to 01(hex). Proszę o poprawienie jeśli się mylę.
    NOTA
  • #16
    adambehnke
    Level 24  
    O mistrzu to jest to czego szukałem !! Dzięki.

    Ale znów nasuwa mi się pytanie. W systemie będę miał 4-6 pastylek DS1990A i oczywiście adaptery do tego. Nigdy jeszcze ich nie używałem i zastanawiam się jak one się rejestrują i komunikują.

    Wydaje mi się że tak:

    1.Rejestruję sobie taką pastylkę "nr.1" -czyli przykładam do adaptera-czytnika i uruchamiam sobie funkcję przeszukiwania 1Wire(tak jak szukałem sobie DS18B20) i znajduje mi pięknie jej Family Code,serial,crc.
    2.Jak już mam ją zarejestrowane czyli znam jej serial to powinienem odczytać zapisany w niej kod jak temperaturę z DS18b20 , i zapisać sobie ten kodzik w systemie jako kod autoryzacyjny, tak?
    3.Jak już mam jej serial to uruchamiam ciągłe przeszukiwanie 1Wire i odpytuję sobie pastylkę o takim adresie jak znalazłem wcześniej i jeśli jest akurat przyłożona do czytnika to poda mi swój unikalny numer i tym samym będę wiedział że przyłożono dokładnie tą pastylkę którą sobie wcześniej zarejestrowałem gdyż porównam sobie kod odebrany i ten wcześniej zapisany , tak?

    Czyli mam rozumieć że z pastylką i w sumie innymi kostkami na 1Wire postępuję tak jak ze zwykłym DS18B20 ? Tak ja to przynajmniej rozumiem ale jeśli się mylę to proszę o poprawienie mnie.

    Czyli rozumiem że aby poprawnie "zadać zapytanie" konkretnej kostce na 1Wire muszę zaadresować ją podając jej pierwszy bajt z odczytanego seriala a pozostałe 7 bajtów procedura 1Wire wysyła sama? Bo na to wygląda.Nie podaję jej przecież całego odczytanego ciągu czyli Family Code,serial,CRC.
    Przepraszam za głupie pytania ale człowiek uczy się na błędach i takiego pytania już raczej nie zadam jeśli zrozumiem jak to działa.
  • Helpful post
    #17
    morson
    Level 14  
    Według dokumentacji

    Sprawdzasz sobie co jakiś czas
    Code:

     1wreset
     If Err = 0 Then 'czy jest przyłożony układ
      1wwrite &H33 'lub &H0F
      ds(1) = 1wread(8)
      If ds(8) = Crc8(ds(1), 7) Then
       'układ poprawnie podpięty i CRC Ok
       'tu sobie sprawdzasz, czy numer jest zarejestrowany, lub dopisujesz go do listy
      EndIf
     EndIf


    To zadziała jeśli czytnik będziesz miał podpięty do osobnego pinu, a nie z DS18B20, bo wtedy one się zgłoszą przy 1wreset

    Lepsze są do tego karty bezstykowe UNIQUE, można dostać tanio czytniki łączące się portem szeregowym (po zbliżeniu czytnik wysyła pakiet danych z identyfikatorem karty).
  • #18
    adambehnke
    Level 24  
    Do osobnego pinu? Nie ,ja wolę aby wszystko było na jednej magistrali.
    Przecież będę znał adres pastylki prawda? I mogę zaadresować ją i odczytać jeśli będzie przyłożona. prawda? A jeśli nie będzie przyłożona to po prostu nie odpowie. Tylko musiałbym sprawdzać dość często (pewnie co 1s) czy przyłożono tą pastylkę. Chyba że nie rozumiem zasady jej działania, co możliwe.
  • #19
    morson
    Level 14  
    Niestety przy tych pastylkach niema czegoś takiego jak potwierdzenie, że jest po podaniu jej ID. Ona obsługuje tylko 2 instrukcje READ_ROM (odczytanie ID) i SEARCH_ROM (wyszukiwanie ID wszystkich). Tak, że musiałbyś wyszukiwać wszystkie wykluczając id DS18B20 i sprawdzać czy jest jakiś ,,inny'' na linii.
    A w Bascom'ie każdej funkcji 1wire możesz osobno przypisać pin na którym ma być wykonana, co Ci nie komplikuje programu, a zajmuje tylko 1 pin więcej.

    Piszesz np
    Code:

    1wreset Pinb, 2  'i wysyła na PB2
    1wwrite(&H0F,Pinb,2)
    itd.
  • #20
    adambehnke
    Level 24  
    I to jest dla mnie bardzo dobre rozwiązanie , które znacznie ułatwi dalszą pracę.
    Dziękuję.



    Dodano po 33 [minuty]:

    Dopiero teraz załapałem (chyba) o co chodzi z tą pastylką i czym ona jest. To dokładnie to samo co ds18B20 ale nie ma ona żadnej funkcji (jak ds18b20-termometr) tylko sam serial który to właśnie jest kodem jaki muszę uwierzytelnić w systemie :D
    Czyli sprawdzam ją na zasadzie ciągłego wyszukiwania i jeśli coś znajdę to porównuję odebrany serial z tym w mojej bazie "kluczy".A po przyłożeniu pastylki do adaptera jest ona zasilana na zasadzie Parasite ? Pewnie tak. Ale mi to opornie idzie ...
    Jeśli znów się mylę to proszę o sprostowanie.
  • #21
    adambehnke
    Level 24  
    Mam jeszcze jedno może banalne pytanie.
    Otóż mam do jednej linii 1WIRE wychodzącej z jednego procesora podłączone 12 czujników DS18B20. Czy jest mozliwość że mógłbym podpiąć drugi moduł z kolejnym procesorem pod tą samą linię aby i on mógł odczytywać sobie temperatury z czujników? Czy muszę zrobić sobie osobny moduł który tylko i wyłącznie będzie obsługiwał czujniki temperatury a pozostałe moduły będą go sobie odpytywały np poprzez RS485. Sprawa z wyglądu prosta ale taki dodatkowy moduł trochę komplikuje sprawę.
  • Helpful post
    #22
    dj_max84
    Level 13  
    w przypadku uzycia niewielkiej ilosci modulow i czujnikow obie wersje sa do przyjecia ale jesli chcesz rozbudowac system do wiekszych rozmiarow to opcja 2 wyglada na lepsza. masz jeden modul trzymajacy dane a reszta go odpytuje. nie masz wtedy tak duzego ruchu na linii 1W i masz mozliwosc dodania kolejnych czujnikow i modulow w dowolnej (prawie) ilosci.
    jesli chcesz wybrac opcje 1 to musisz dopisac procedure (dla obu procow) ktora bedzie sprawdzala czy ten drugi sie aktualnie nie komunikuje z czujnikami i ew odczekac az linia bedzie wolna ale i to moze wprowadzic zaklocenia na 1W wiec opcja 2 jest najlepsza.