PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 4 Stück DS1820 auslesen und anzeigen mit BASCOM



Hans55
10.02.2008, 12:32
Hallo!
Ich möchte mehrere DS1820 am 1Wire Bus auslesen und am LCD anzeigen.
Bei den 4 Stück die ich habe, hab ich die IDs ausgelesen, ich kann sie auch alle einzeln Anzeigen lassen, möchte aber, dass alle 4 in 3s Abstand die Temperatur in einer Zeile des LCD angezeigen. Wie macht man das. Im Forum hab ich schon gestöbert aber so richtig was gefunden hab ich nicht.

Mein Code ist folgender:


'///////////////////////////////////////////////////////////////////////////////
' Funktion:
' Zeigt die Temperaturen der am 1Wire Bus angeschlossenen DS1820 an
' Wichtig: der 4,7k Ohm Widerstand muß angeschlossen sein sonst gehts nicht!
' Im 64Bit ROM des DS1820 sind der Familycode (8Bit), eine Seriennummer (8x8Bit)
' die es nur einmal gibt und ein CRC-Byte (8Bit) abgelegt.
' Der DS1820 mißt die Umgebungstemperatur im Bereich von -55...+125C in 0,5Grad
' Schritten
'
' Meine 4 DS1820 haben die folgende Adressen:
' DS1820_1 => 10 6A E8 5F 01 08 00 8C
' DS1820_2 => 10 8B 23 25 01 08 00 73
' DS1820_3 => 10 7B D6 60 01 08 00 14
' DS1820_4 => 10 13 FD 5F 01 08 00 2C
'
'///////////////////////////////////////////////////////////////////////////////
$regfile = "m8def.dat"
$crystal = 14745600 'Externes Quarz 14,7456 Mhz
'Achtung: damit der ext. Quarz aktiv wird => die Fusebits entsprechend einstellen.
'Extern Cristal , bei mir alle Bits = 111 111
$baud = 9600
'-------------------------------------------------------------------------------
'/// Definitionen //////////////////////////////////////////////////////////////
'-------------------------------------------------------------------------------
'/// LCD- DISPLAY 4x20
'LCD im 4Bit I/O Mode
Config Lcd = 20 * 4
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4
Config Lcdpin = Pin , Db7 = Portd.5 , E = Portd.7 , Rs = Portd.6
Cursor Off Noblink
Cls

' Pin für 1wire Schnittstelle festlegen. => DS1820 am Port C.5
Config 1wire = Portc.5
Dim Ds1820_id(8) As Byte

'Die Adresse meines DS1820 die ich vorher ausgelesen habe:
' Adrese Erster DS1820
Ds1820_id(1) = &H10
Ds1820_id(2) = &H6A
Ds1820_id(3) = &HE8
Ds1820_id(4) = &H5F
Ds1820_id(5) = &H01
Ds1820_id(6) = &H08
Ds1820_id(7) = &H00
Ds1820_id(8) = &H8C

' Die anderen Codes wären:
' DS1820_2 => 10 8B 23 25 01 08 00 73
' DS1820_3 => 10 7B D6 60 01 08 00 14
' DS1820_4 => 10 13 FD 5F 01 08 00 2C

Dim Sc(9) As Byte
Dim T As Integer
Dim T1 As Integer
Dim I As Byte
Cls ' Clear LCD

Do
'Alle angeschlossenen DS1820 zum Messen veranlassen
1wreset '1Wire Reseten
1wwrite &HCC 'Schreibt die Variable CC= Überspringen der Adresierung?
1wwrite &H44 'Starten der Temperaturmessung
Waitus 200

'Den gewünschten Sensor auswählen
1wverify Ds1820_id(1) 'Prüft ob eine ID im 1Wire Bus zugänglich ist
' Wenn=0 zurückgeliefert wird, ist eine gültige ID vorhanden
' Wenn eine 1 geliefert wird, ist ein ERR aufgetreten

'Kommando READ SCRATCHPAD
1wwrite &HBE 'Liest alle Bytes de Scratchpad Memory.
Sc(1) = 1wread(9)

If Sc(9) = Crc8(sc(1) , 8) Then
T = Makeint(sc(1) , Sc(2)) 'komprimiert zwei Bytes in die Integervariable T

'Die Nachkommastelle entfernen
T = T / 2

'Temperatur in ganzen Grad ausgeben
Locate 1 , 11
Lcd "T1=" ; T ; " C" ' Anzeige erfolgt so: T1=23 C
Else

'Wenn Fehler, Scratchpad zur Kontrolle Hexadezimal ausgeben
Locate 2 , 1

'Ausgabe
For I = 1 To 8
Lcd Hex(sc(i))
Next
End If

'Ausgabe alle 0,5 Sekunden
Waitms 500
Loop

End

for_ro
10.02.2008, 12:55
Hallo,
schreib die IDs aller Sensoren in ein 32 Byte Array.
Dann eine Schleife über die 4 Sensoren.
In der Schleife darfst du dann nicht
Skip_rom = &HCC angeben
sondern musst du die ID übertragen

1wreset
1wwrite &H55 'Match_rom
1wwrite Ds1820_id(i) , 8 '8 Byte ID wird uebertragen
1wwrite &HBE 'Read_scratchpad
Sc(1) = 1wread(9)

Entweder alle zusammen neu starten
1wreset 'jetzt wird wieder die Konvertierung gestartet, alle parallel
1wwrite &HCC 'Skip_rom
1wwrite &H44 'start conversion

oder einzeln mit
1wreset
1wwrite &H55 'Match_rom
1wwrite Ds1820_id(id) , 8
1wwrite &H44 'start conversion

Gruß

Rolf

Hans55
10.02.2008, 13:37
Hallo Rolf!
Geht das nicht einfacher? Ich bin Anfänger und hab schon mal Probleme die 32 Byte in ein Array zu kriegen, geschweige denn wieder raus.
Gruß
Hans

for_ro
10.02.2008, 13:47
Ehrlich gesagt, kann ich das nicht ganz verstehen.
Du tauschst einen Befehl

1wwrite &HCC

durch zwei Befehle

1wwrite &H55
1wwrite Ds1820_id(i) , 8

aus. Noch einfacher?

Die ID vom ersten Sensor hast du doch schon im Array, also die anderen 3 auch noch da rein schreiben.
Dann

For id=1 to 25 step 8
1wreset
1wwrite &H55
1wwrite Ds1820_id(id) , 8
1wwrite &HBE
Sc(1) = 1wread(9)
... Auswerten
next id

Klar?

Gruß

Rolf

Hans55
10.02.2008, 13:57
Ok,
das hört sich gut an. Danke!
Gruß
Hans

Rofo88
10.02.2008, 14:02
Bascom bietet auch noch ein paar HIGH-Level-Befehle für 1Wire an wie 1wsearchfirst und 1wiresearchnext.
Also erst mal für jeden Sensor ein Byte-Array erstellen.

Dim Sensor_rom_1(8) As Byte
Dim Sensor_rom_2(8) As Byte
Dim Sensor_rom_3(8) As Byte
Dim Sensor_rom_4(8) As Byte

Jetzt kann man die Rom-Werte einlesen.


Sensor_rom_1(1) = 1wsearchfirst()
Sensor_rom_2(1) = 1wsearchnext()
Sensor_rom_3(1) = 1wsearchnext()
Sensor_rom_4(1) = 1wsearchnext()

Jetzt kann man von jedem Sonsor die Temperatur einlesen

1wreset 'RESET 1Wire
1wwrite &HCC 'an alle
1wwrite &H44 'Temperaturmessung
Wait 1 'ne Sekunde warten für Messung
1wverify Sensor_rom_1(1) ' nur ersten Sensor ansprechen
1wwrite &HBE ' Temperatur auslesen
Daten(1) = 1wread(9) 'Daten einlesen

for_ro
10.02.2008, 14:27
@Rofo88

Weniger Speicher braucht er dadurch auch nicht.
Dafür kann er jetzt nicht mehr eine einfache For-Schleife benutzen, da die IDs in verschiedenen Variablen stehen.

In meinen Applikationen verwende ich nie 1wsearchnext, weil ich nicht weiß, ob die Sensoren immer in der gleichen Reihenfolge antworten. Und da du normalerweise bestimmte Temperaturen (z.B. einen innen und einen außen) messen lassen möchtest, wäre eine andere Reihenfolge ziemlich schlecht.

Grundsätzlich macht man in einer Schleife die Reihenfolge anders herum, erst auslesen und dann die Konvertierung wieder starten. bis der Sensor wieder mit auslesen dran ist, ist er längst fertig. Beim ersten mal auslesen kommt dabei natürlich Blödsinn. Aber ich habe mir das Wait gespart.

Gruß

Rolf

Rofo88
10.02.2008, 14:43
@for_ro

Es ging auch nicht darum weniger Flash zu verbrauchen sondern es einfacher zu machen!

Sollte sich an den Sensoren nichts ändern liefert 1wireserchnext immer die gleiche Reihenfolge.


Grundsätzlich macht man in einer Schleife die Reihenfolge anders herum, erst auslesen und dann die Konvertierung wieder starten

naja ob das für nen Anfänger der richtige Tipp ist [-X
Wenn man weis das der erste Wert falsch ist kann man damit Arbeiten

for_ro
10.02.2008, 15:16
Sollte sich an den Sensoren nichts ändern liefert 1wireserchnext immer die gleiche Reihenfolge.

Woher weißt du das? Ich habe so eine Aussage bei Dallas noch nie gelesen.


Es ging auch nicht darum weniger Flash zu verbrauchen sondern es einfacher zu machen!

Ich denke, es ist umständlicher. Er hat die Adressen schon alle, warum sollte er sie dann jedesmal neu bestimmen.

Gerade Anfängern rate ich nie, ein Wait zu benutzen. Bei der Initialisierung von einem Display oder so ist das ok, aber nicht in einer Schleife, die dauernd ausgeführt wird, schon gar nicht von einer Sekunde.
Und schau dich mal hier im Forum nach Code zu den Sensoren um, immer steht da Konvertierung starten, warten, auslesen. Jeder kopiert das und denkt, das müsste so sein.

Wenn man vor der Schleife schon mal die Konvertierung startet, stimmt auch der erste Wert.

Aber sei's drum, jeder so wie er es mag.

Hans55
10.02.2008, 16:37
Hallo zusammen!
Ich bin noch dabei das ganze zu verarbeiten und bei mir einzubaun, das dauert noch.
Bisher geht leider noch nix. Ich verstehs aber schon besser als Gestern.
Gruß
Hans

Hans55
10.02.2008, 20:19
Hallo seid ihr noch da?
Ich fummle nun schon einige Stunden rum aber es funktioniert einfach nicht.
DS1 und DS2 zeigen irgendwas an (85C+67C) DS3 und 4 sind 0.




$regfile = "m8def.dat"
$crystal = 14745600 'Externes Quarz 14,7456 Mhz
'Achtung: damit der ext. Quarz aktiv wird => die Fusebits entsprechend einstellen.
'Extern Cristal , bei mir alle Bits = 111 111
$baud = 9600

'/// LCD- DISPLAY 4x20
'LCD im 4Bit I/O Mode
Config Lcd = 20 * 4
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4
Config Lcdpin = Pin , Db7 = Portd.5 , E = Portd.7 , Rs = Portd.6
Cursor Off Noblink
Cls

' Pin für 1wire Schnittstelle festlegen. => DS1820 am Port C.5
Config 1wire = Portc.5
Dim Ds1820id(32) As Byte

'Die Adresse aller meiner DS1820 die ich vorher ausgelesen habe:
Ds1820id(1) = &H10 'Seriennummer 1. DS1820
Ds1820id(2) = &H6A
Ds1820id(3) = &HE8
Ds1820id(4) = &H5F
Ds1820id(5) = &H01
Ds1820id(6) = &H08
Ds1820id(7) = &H00
Ds1820id(8) = &H8C

Ds1820id(9) = &H10 'Seriennummer 2. DS1820
Ds1820id(10) = &H8B
Ds1820id(11) = &H23
Ds1820id(12) = &H25
Ds1820id(13) = &H01
Ds1820id(14) = &H08
Ds1820id(15) = &H00
Ds1820id(16) = &H73

Ds1820id(17) = &H10 'Seriennummer 3. DS1820
Ds1820id(18) = &H7B
Ds1820id(19) = &HD6
Ds1820id(20) = &H60
Ds1820id(21) = &H01
Ds1820id(22) = &H08
Ds1820id(23) = &H00
Ds1820id(24) = &H14

Ds1820id(25) = &H10 'Seriennummer 4. DS1820
Ds1820id(26) = &H13
Ds1820id(27) = &HFD
Ds1820id(28) = &H5F
Ds1820id(29) = &H01
Ds1820id(30) = &H08
Ds1820id(31) = &H00
Ds1820id(32) = &H2C

Dim Sc(32) As Byte '????
Dim T1 As Integer
Dim T2 As Integer
Dim T3 As Integer
Dim T4 As Integer

Dim I As Byte
Dim Id As Byte
Cls ' Clear LCD

Do
'Alle angeschlossenen DS1820 zum Messen veranlassen
1wreset '1Wire Reseten
1wwrite &H55 'MATCHROM=>Adress.den DS1820 anhand des ROM Inhaltes
1wwrite Ds1820id(i) , 8 '8 Byte ID wird uebertragen
Waitus 200

For Id = 1 To 25 Step 8 'ID für alle 4 DS1820 1,9,17,25
1wreset '1Wire Reseten
1wwrite &H55 'MATCHROM=>Adress.den DS1820 anhand des ROM Inhaltes
1wwrite Ds1820id(id) , 8 '8 Byte ID wird uebertragen
1wwrite &HBE 'READ SCATCHPAD => Liest alle Bytes des SP Memorys
Sc(1) = 1wread(9)
Next Id

T1 = Makeint(sc(1) , Sc(2)) 'komprimiert zwei Bytes in die Integervariable T
T2 = Makeint(sc(9) , Sc(2))
T3 = Makeint(sc(17) , Sc(2))
T4 = Makeint(sc(25) , Sc(2))

'Die Nachkommastelle entfernen
T1 = T1 / 2
T2 = T2 / 2
T3 = T3 / 2
T4 = T4 / 2

'Temperatur in ganzen Grad ausgeben
Locate 1 , 11
Lcd "T1=" ; T1 ; " C" ' Anzeige erfolgt so: T1=23 C

Locate 2 , 11
Lcd "T2=" ; T2 ; " C" ' Anzeige erfolgt so: T1=23 C

Locate 3 , 11
Lcd "T3=" ; T3 ; " C" ' Anzeige erfolgt so: T1=23 C

Locate 4 , 11
Lcd "T4=" ; T4 ; " C" ' Anzeige erfolgt so: T1=23 C

'Ausgabe alle 0,5 Sekunden
Waitms 500
Loop

End






Gruß
Hans

Rofo88
10.02.2008, 21:02
Du läufst beim einlesen der Daten zwar 4 mal duch die Schleife aber mit

Sc(1) = 1wread(9)
schreibst Du die Daten immer auf die selbe stelle ( und überschreibst damit die ersten 3.)


Sc(id) = 1wread(9)
So sollte es beser funzen.

http://www.mcselec.com/index.php?option=com_content&task=view&id=75&Itemid=57

for_ro
10.02.2008, 21:49
Hallo,
du startest ja gar keine Konvertierung der Temperatur.
Die große Anzahl an Zuweisungen kannst du auch durch eine kleine Schleife ersetzen.
Deine Sensor_Ids stehen jetzt am Ende, kannst du auch ins EEProm schreiben.

Probier mal so:


$regfile = "m8def.dat"
$crystal = 14745600 'Externes Quarz 14,7456 Mhz
'Achtung: damit der ext. Quarz aktiv wird => die Fusebits entsprechend einstellen.
'Extern Cristal , bei mir alle Bits = 111 111
$baud = 9600

Match_rom Alias &H55
Skip_rom Alias &HCC
Read_scratchpad Alias &HBE
Write_scratchpad Alias &H4E
Copy_scratchpad Alias &H48
Start_conversion Alias &H44

' Pin für 1wire Schnittstelle festlegen. => DS1820 am Port C.5
Config 1wire = Portc.5
Dim Ds1820id(32) As Byte
Dim Sc(9) As Byte '????
Dim T As Integer
Dim I As Byte
Dim Id As Byte

'/// LCD- DISPLAY 4x20
'LCD im 4Bit I/O Mode
Config Lcd = 20 * 4
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4
Config Lcdpin = Pin , Db7 = Portd.5 , E = Portd.7 , Rs = Portd.6
Cursor Off Noblink
Cls


'Die Adresse aller meiner DS1820 die ich vorher ausgelesen habe:
Restore Sensor_ids
For I = 1 To 32
Read Ds1820id(i)
Next I
1wreset
1wwrite Skip_rom
1wwrite Start_conversion 'Alle angeschlossenen DS1820 zum Messen veranlassen
Waitms 500 'Ausgabe alle 0,5 Sekunden
Do
For Id = 1 To 25 Step 8 'ID für alle 4 DS1820 1,9,17,25
Incr I
1wreset '1Wire Reseten
1wwrite &H55 'MATCHROM=>Adress.den DS1820 anhand des ROM Inhaltes
1wwrite Ds1820id(id) , 8 '8 Byte ID wird uebertragen
1wwrite &HBE 'READ SCATCHPAD => Liest alle Bytes des SP Memorys
Sc(1) = 1wread(9)
T = Makeint(sc(1) , Sc(2)) 'komprimiert zwei Bytes in die Integervariable T
Shift T , Right 'Die Nachkommastelle entfernen
Locate I , 11 'Temperatur in ganzen Grad ausgeben
Lcd "T" ; I ; "=" ; T ; " C" ' Anzeige erfolgt so: T1=23 C
Next Id
I = 0
1wreset
1wwrite Skip_rom
1wwrite Start_conversion 'Alle angeschlossenen DS1820 zum Messen veranlassen
Waitms 500 'Ausgabe alle 0,5 Sekunden
Loop

End

Sensor_ids:
Data &H10 , &H6A , &HE8 , &H5F , &H01 , &H08 , &H00 , &H8C
Data &H10 , &H8B , &H23 , &H25 , &H01 , &H08 , &H00 , &H73
Data &H10 , &H7B , &HD6 , &H60 , &H01 , &H08 , &H00 , &H14
Data &H10 , &H13 , &HFD , &H5F , &H01 , &H08 , &H00 , &H2C

Kompiliert ok, ist aber nicht getestet, da ich deine Hardware nicht habe.
Schau mal, ob du die Änderungen nachvollziehen kannst.

Hans55
10.02.2008, 22:06
Mensch da tut sich ja endlich was. Ich krieg eine Anzeige von allen 4 DS1820.
Danke erst mal!!
Ich muss das erst mal blicken was du da gemacht hast. Das kann aber einige Zeit dauern.
Ich melde mich wieder.
Gruß
Hans

Papsi
10.02.2008, 23:19
Hallo,

kann mir mal einer erklären, wie ich die Sensoren bei mir auslesen kann.
Damit ich meine ID raufinden kann.

Ich habe auch schon mehrere DS18S20 am laufen gehabt, bekomme jetzt immer nur 0Grad angezeigt.
Orgendwie klappt das bei mir nicht mehr...

Hans55
11.02.2008, 19:22
Hallo Papsi!
Lade mal dieses Programm und pass es an.
Das liest dir alle ID aus und zeigt sie am LCD an.



'///////////////////////////////////////////////////////////////////////////////
' Funktion:
' Liest die Adressen von angeschlossenen DS1820 aus und zeigt sie am LCD an.
' Mit jeweils 20s Pause dazwischen.
'///////////////////////////////////////////////////////////////////////////////
$regfile = "m8def.dat"
$crystal = 14745600 'Externes Quarz 14,7456 Mhz
'Achtung: damit der ext. Quarz aktiv wird => die Fusebits entsprechend einstellen.
'Extern Cristal , Alle Bits = 111 111
$baud = 9600

'-------------------------------------------------------------------------------
'/// Definitionen //////////////////////////////////////////////////////////////

'/// LCD- DISPLAY 4x20
'LCD im 4Bit I/O Mode
Config Lcd = 20 * 4
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4
Config Lcdpin = Pin , Db7 = Portd.5 , E = Portd.7 , Rs = Portd.6
Cursor Off Noblink
Cls

'Pin für 1wire Schnittstelle festlegen
Config 1wire = Portc.5

Dim Dsid(8) As Byte 'Es werden mindestens 8Bytes für die ID benötigt
Dim I As Byte 'Für die Anzahl der Senseoren
Dim Nr As Byte

Nr = 1
Cls

Dsid(1) = 1wsearchfirst()

Locate 1 , 1 : Lcd "DS1820 Nr " ; Nr : Nr = Nr + 1
Locate 2 , 1
For I = 1 To 8
Lcd Hex(dsid(i))
Next

Wait 20 ' Das reicht zum abschreiben

'Dsid(1) = 1wsearchnext()
Do
Dsid(1) = 1wsearchnext()
'Wenn kein Fehler, dann ausgeben

If Err = 0 Then
Locate 1 , 1 : Lcd "DS1820 Nr " ; Nr : Nr = Nr + 1
Locate 2 , 1
For I = 1 To 8
Lcd Hex(dsid(i))
Next
Wait 15
End If
Loop Until Err = 1


Do
Waitms 100
Loop

End

Papsi
11.02.2008, 19:47
Hallo,

habe ich probiert:

kommt aber bei allen Sensoren 000000000000usw. raus.

Angeklemmt habe ich die so:
http://home.arcor.de/daniel_papst/Forumbilder/ds18s20.JPG

Der Mega32 ist in Grundbeschaltung mit 8Mhz ext. Quarz


:EDIT
Widerstand hinzugefügt...

Rofo88
11.02.2008, 19:52
Hast Du auch nen Pullup von 4,7k an DO? Ist zumindest in deiner Zeichnung nicht drinn.

Hans55
11.02.2008, 19:58
Mach einfach einen 4,7k Widerstand zwischen Pin2 und 3 rein, dann gehts!

Papsi
11.02.2008, 20:04
Jetzt geht´s...
Hat also nur der Widerstand gefehlt.
Komisch, als ich das früher mal getestet habe, da lief es und ich habe den R nicht drin gehabt.


Jetzt zeigt er mir:
105D677101080025

Habe nur ein 16-stelliges Display dran.
Kann das alles sein?

Und wie lasse ich mir jetzt die Temp. anzeigen?

Papsi
11.02.2008, 20:12
Jetzt hab ich auch eine Temperatur.
Habe das Beispiel von for_ro genommen und einfach nur meine Daten eingegeben.

Ich bräuchte aber die Temperatur in 0.1 Schritten !

Hans55
11.02.2008, 20:23
Nimm einfach das Beispiel von Gestern auf dieser Seite das mir for_ro geschickt hat.
Ganz am Schluß sind IDs, die du gegen deine austauschen mußt.
Allerdings kann ich dir nicht groß weiter helfen wenns nicht gehen sollte.
Ich blicke selbst noch nicht durch und bin immer noch am Grübeln wie er das gemacht hat.
Es funzt aber bis auf eine Kleinigkeit. In der letzten Zeile bei T4 wird
T4= 23 CC angezeigt. Da ist ein C zuviel. Sonst ists wunderbar.
Gruß
Hans

Hans55
11.02.2008, 20:27
Suche mal hier im Forum "DS1820". Da gibts einige Beispiele mit 1/2 Grad und mit 1/10 Grad. Da mußt du dir den Teil einfach dazukopieren.
Da die Dinger aber nicht so genau sind und es eigentlich auf ein Grad Hin oder her nicht ankommt ist es mir Wurscht.

Papsi
11.02.2008, 23:04
Hallo,

meine Sache läuft mit 4 Sensoren und 0.1Grad

Was mich nur stört sind die ganzen waitms.

Momentan lasse ich alle 5 sec. die 4 Sensoren hintereinander auslesen und dann wird mir der Wert ausgegeben.
Nur wenn ich die 4 Dinger hintereinander auslese steht mein Programm wegen den waitms so ca. 3 sec und ich kann nichts weiter machen.(Menü durchblättern usw.)

Kann man das nicht anders lösen?
Müssen die ganzen waitms da hin?

Hier mal mein Ausschnitt der auf meinem Steckbrett läuft:


$regfile = "m32def.dat"
$crystal = 8000000

Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.4 , Db7 = Portd.3 , E = Portb.7 , Rs = Portb.6
Config Lcd = 16 * 2
Config Lcdbus = 4
Cursor Off
Cls

Config 1wire = Portc.5

Dim T As Integer
Dim T1 As Integer
Dim T2 As Integer
Dim T3 As Integer
Dim T4 As String * 10
Dim T5 As String * 10
Dim T6 As Single
Dim T7 As Single
Dim Id1(8) As Byte
Dim Id2(8) As Byte
Dim Ar1(9) As Byte
Dim Ar2(9) As Byte
Dim I As Byte , Tmp As Byte , Tmp2 As Byte

Dim 1t As Integer
Dim 1t1 As Integer
Dim 1t2 As Integer
Dim 1t3 As Integer
Dim 1t4 As String * 10
Dim 1t5 As String * 10
Dim 1t6 As Single
Dim 1t7 As Single
Dim Id3(8) As Byte
Dim Id4(8) As Byte
Dim 1ar1(9) As Byte
Dim 1ar2(9) As Byte
Dim 1i As Byte , 1tmp As Byte , 1tmp2 As Byte

Id1(1) = 1wsearchfirst()
Id2(1) = 1wsearchnext()
Id3(1) = 1wsearchnext()
Id4(1) = 1wsearchnext()


Do
1wreset
1wwrite &H55
1wwrite Id1(1) , 8
1wwrite &H44

Waitms 300
1wreset
1wwrite &H55
1wwrite Id1(1) , 8
1wwrite &HBE
Ar1(1) = 1wread(9)
1wreset
Tmp = Ar1(1) And 1
If Tmp = 1 Then Decr Ar1(1)
T = Makeint(ar1(1) , Ar1(2))
T = T * 50
T = T - 25
T1 = Ar1(8) - Ar1(7)
T1 = T1 * 100
T1 = T1 / Ar1(8)
T = T + T1
T = T / 10
T6 = T / 10
T4 = Fusing(t6 , "#.#")

Waitms 500
1wreset
1wwrite &H55
1wwrite Id2(1) , 8
1wwrite &H44

Waitms 300
1wreset
1wwrite &H55
1wwrite Id2(1) , 8
1wwrite &HBE
Ar2(1) = 1wread(9)
1wreset
Tmp2 = Ar2(1) And 1
If Tmp2 = 1 Then Decr Ar2(1)
T2 = Makeint(ar2(1) , Ar2(2))
T2 = T2 * 50
T2 = T2 - 25
T3 = Ar2(8) - Ar2(7)
T3 = T3 * 100
T3 = T3 / Ar2(8)
T2 = T2 + T3
T2 = T2 / 10
T7 = T2 / 10
T5 = Fusing(t7 , "#.#")



1wreset
1wwrite &H55
1wwrite Id3(1) , 8
1wwrite &H44

Waitms 300
1wreset
1wwrite &H55
1wwrite Id3(1) , 8
1wwrite &HBE
1ar1(1) = 1wread(9)
1wreset
1tmp = 1ar1(1) And 1
If 1tmp = 1 Then Decr 1ar1(1)
1t = Makeint(1ar1(1) , 1ar1(2))
1t = 1t * 50
1t = 1t - 25
1t1 = 1ar1(8) - 1ar1(7)
1t1 = 1t1 * 100
1t1 = 1t1 / 1ar1(8)
1t = 1t + 1t1
1t = 1t / 10
1t6 = 1t / 10
1t4 = Fusing(1t6 , "#.#")

Waitms 500
1wreset
1wwrite &H55
1wwrite Id4(1) , 8
1wwrite &H44

Waitms 300
1wreset
1wwrite &H55
1wwrite Id4(1) , 8
1wwrite &HBE
1ar2(1) = 1wread(9)
1wreset
1tmp2 = 1ar2(1) And 1
If 1tmp2 = 1 Then Decr 1ar2(1)
1t2 = Makeint(1ar2(1) , 1ar2(2))
1t2 = 1t2 * 50
1t2 = 1t2 - 25
1t3 = 1ar2(8) - 1ar2(7)
1t3 = 1t3 * 100
1t3 = 1t3 / 1ar2(8)
1t2 = 1t2 + 1t3
1t2 = 1t2 / 10
1t7 = 1t2 / 10
1t5 = Fusing(1t7 , "#.#")

Locate 1 , 1 : Lcd "T1:" ; T4
Locate 1 , 10 : Lcd "T2:" ; T5
Locate 2 , 1 : Lcd "T3:" ; 1t4
Locate 2 , 10 : Lcd "T4:" ; 1t5

Waitms 500

Loop

Den Code habe ich hier aus dem Forum, habe das nur mal verdoppelt und vor die neuen Variablen ne 1 vorgehängt.

mat-sche
12.02.2008, 19:09
Hallo Papsi,

wie die ganzen Beispiele hier im Forum schon beschreiben, braucht der DS ca. 750ms für die Konvertierung.
Ich habe keine Wartezeit mit in meinem Programm verbaut, ich stoße meine Konvertierung in einem anderem Programmteil an (z.Bsp. in einer Gosub) und arbeite dann in meinem Code weiter bis zu einem späteren Zeitpunkt es zur Temp-verarbeitung kommt.
Da das Programm weiter im Text arbeitet, reicht bei mir die Zeit aus für die Konvertierung und brauche somit keine Wartezeit.
Vielleicht konnte ich Dir mit dem Tip weiter helfen.

Schönen Abend und Gruß aus Istanbul
MAT

for_ro
12.02.2008, 19:26
Ich würde den Ablauf etwa so machen:


Config TimerX = Timer , Prescale = 1024 'oder 1, 8, 64, 256
On TimerX Timer_isr 'TimerX durch beliebigen Timer ersetzen

Do
If Read_temp_counter = YYYY Then 'YYYY so wählen, dass z.B. jede Sekunde einmal ausgeführt wird
Read_temp_counter = 0
'.... jetzt alle Befehle zur Temp Berechnung und Anzeige, kein wait
End If
Loop

Timer_isr: ' Prescale * max_counts
Incr Read_temp_counter 'wird alle ----------------------- Sekunden um 1 hochgezählt
Return ' $crystal
'für einen 8-bit Timer ist max_counts 256, für einen 16-bit Timer ist es 65536

Lass die ganzen Blöcke weg:

1wreset
1wwrite &H55
1wwrite Id3(1) , 8
1wwrite &H44

und ersetze sie am Ende deiner Ausgabe durch ein

1wreset
1wwrite &HCC
1wwrite &H44

Und versuche mal die ganze Orgie durch eine Schleife zu ersetzen, die die 4 Sensoren nacheinander aufruft. Dann bracuhst du auch die Unmenge an Variablen nicht mehr. Du willst die Werte ja eh nicht abspeichern, oder?

Gruß

Rolf

Papsi
12.02.2008, 19:33
Hallo,

habe mein "Problem" gelöst.

Läuft auch mit einem Timer.
Ich lasse einfach eine Variable hochzählen und alle 1 sec. lasse ich dann die Befehle ausführen.
Somit ersetzte ich die waitms und habe dadurch keine Wartezeit im Programmablauf.
Somit habe ich so ca. alle 7-8 sec die aktuelle Temperatur pro Sensor.
Das reicht für meine Zwecke locker aus.

Gruß
Papsi

for_ro
12.02.2008, 19:38
Umso besser, wenn du es selber hinbekommen hast.

Gruß

Rolf

Papsi
12.02.2008, 19:40
Hat zwar gedauert, bis ich es hinbekommen habe, aber so langsam begreife ich das hier... ;)

Hans55
12.02.2008, 22:06
Hallo Papsi!
Könntest du Dein Programm hier reinstellen zum abkupfern.
Meins geht zwar auch, aber man könnte sicher noch einiges verbessern.
Danke nochmal an Rolf!
Gruß
Hans

Papsi
12.02.2008, 22:26
Habe es auf meinem anderen Rechner drauf und den habe ich vor 5 minuten aus gemacht.

Wenn ich es morgen schaffe, dann hänge ich es hier an.
(Muß morgen wieder arbeiten und dazu noch länger...)

N8

Papsi
13.02.2008, 22:32
Hallo,

jetzt bin ich endlich wieder da...

Hier also mein Code für 5 Sensoren:


$regfile = "m32def.dat"
$crystal = 8000000

Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.4 , Db7 = Portd.3 , E = Portb.7 , Rs = Portb.6
Config Lcd = 16 * 2
Config Lcdbus = 4
Cursor Off
Cls

Config 1wire = Portc.5

Dim Timer As Word
Timer = 55800
Config Timer1 = Timer , Prescale = 1024
Enable Timer1
On Timer1 Sekundentakt
Enable Interrupts
Timer1 = Timer
Dim X As Byte : X = 1

Dim Tempsensor1(8) As Byte
Dim Tempsensor2(8) As Byte
Dim Tempsensor3(8) As Byte
Dim Tempsensor4(8) As Byte
Dim Tempsensor5(8) As Byte

Dim Ar1(9) As Byte
Dim Ar2(9) As Byte
Dim Ar3(9) As Byte
Dim Ar4(9) As Byte
Dim Ar5(9) As Byte

Dim Temp1 As Single
Dim Temp2 As Single
Dim Temp3 As Single
Dim Temp4 As Single
Dim Temp5 As Single

Dim Tmp1 As Byte
Dim Tmp2 As Byte
Dim Tmp3 As Byte
Dim Tmp4 As Byte
Dim Tmp5 As Byte

Dim T1 As Integer
Dim T2 As Integer
Dim T3 As Integer
Dim T4 As Integer
Dim T5 As Integer
Dim T6 As Integer
Dim T7 As Integer
Dim T8 As Integer
Dim T9 As Integer
Dim T10 As Integer

Tempsensor1(1) = 1wsearchfirst()
Tempsensor2(1) = 1wsearchnext()
Tempsensor3(1) = 1wsearchnext()
Tempsensor4(1) = 1wsearchnext()
Tempsensor5(1) = 1wsearchnext()

Do
Locate 1 , 1 : Lcd X 'Debug :-)
Locate 1 , 4 : Lcd Fusing(temp1 , "##.#")
Locate 1 , 10 : Lcd Fusing(temp2 , "##.#")
Locate 2 , 1 : Lcd Fusing(temp3 , "##.#")
Locate 2 , 7 : Lcd Fusing(temp4 , "##.#")
Locate 2 , 13 : Lcd Fusing(temp5 , "##.#")
Wait 1 'Test
Cls 'Test
Loop

Sekundentakt:
Timer1 = Timer
Incr X
If X = 2 Then
'Waitms 500
1wreset
1wwrite &H55
1wwrite Tempsensor1(1) , 8
1wwrite &H44
End If

If X = 3 Then
'Waitms 300
1wreset
1wwrite &H55
1wwrite Tempsensor1(1) , 8
1wwrite &HBE
Ar1(1) = 1wread(9)
1wreset
Tmp1 = Ar1(1) And 1
If Tmp1 = 1 Then Decr Ar1(1)
T1 = Makeint(ar1(1) , Ar1(2))
T1 = T1 * 50
T1 = T1 - 25
T2 = Ar1(8) - Ar1(7)
T2 = T2 * 100
T2 = T2 / Ar1(8)
T1 = T1 + T2
T1 = T1 / 10
Temp1 = T1 / 10
End If

If X = 4 Then
'Waitms 500
1wreset
1wwrite &H55
1wwrite Tempsensor2(1) , 8
1wwrite &H44
End If

If X = 5 Then
'Waitms 300
1wreset
1wwrite &H55
1wwrite Tempsensor2(1) , 8
1wwrite &HBE
Ar2(1) = 1wread(9)
1wreset
Tmp2 = Ar2(1) And 1
If Tmp2 = 1 Then Decr Ar2(1)
T3 = Makeint(ar2(1) , Ar2(2))
T3 = T3 * 50
T3 = T3 - 25
T4 = Ar2(8) - Ar2(7)
T4 = T4 * 100
T4 = T4 / Ar2(8)
T3 = T3 + T4
T3 = T3 / 10
Temp2 = T3 / 10
End If

If X = 6 Then
'Waitms 500
1wreset
1wwrite &H55
1wwrite Tempsensor3(1) , 8
1wwrite &H44
End If

If X = 7 Then
'Waitms 300
1wreset
1wwrite &H55
1wwrite Tempsensor3(1) , 8
1wwrite &HBE
Ar3(1) = 1wread(9)
1wreset
Tmp3 = Ar3(1) And 1
If Tmp3 = 1 Then Decr Ar3(1)
T5 = Makeint(ar3(1) , Ar3(2))
T5 = T5 * 50
T5 = T5 - 25
T6 = Ar3(8) - Ar3(7)
T6 = T6 * 100
T6 = T6 / Ar3(8)
T5 = T5 + T6
T5 = T5 / 10
Temp3 = T5 / 10
End If

If X = 8 Then
'Waitms 500
1wreset
1wwrite &H55
1wwrite Tempsensor4(1) , 8
1wwrite &H44
End If

If X = 9 Then
'Waitms 300
1wreset
1wwrite &H55
1wwrite Tempsensor4(1) , 8
1wwrite &HBE
Ar4(1) = 1wread(9)
1wreset
Tmp4 = Ar4(1) And 1
If Tmp4 = 1 Then Decr Ar4(1)
T7 = Makeint(ar4(1) , Ar4(2))
T7 = T7 * 50
T7 = T7 - 25
T8 = Ar4(8) - Ar4(7)
T8 = T8 * 100
T8 = T8 / Ar4(8)
T7 = T7 + T8
T7 = T7 / 10
Temp4 = T7 / 10
End If

If X = 10 Then
'Waitms 500
1wreset
1wwrite &H55
1wwrite Tempsensor5(1) , 8
1wwrite &H44
End If

If X = 11 Then
'Waitms 300
1wreset
1wwrite &H55
1wwrite Tempsensor5(1) , 8
1wwrite &HBE
Ar5(1) = 1wread(9)
1wreset
Tmp5 = Ar5(1) And 1
If Tmp5 = 1 Then Decr Ar5(1)
T9 = Makeint(ar5(1) , Ar5(2))
T9 = T9 * 50
T9 = T9 - 25
T10 = Ar5(8) - Ar5(7)
T10 = T10 * 100
T10 = T10 / Ar5(8)
T9 = T9 + T10
T9 = T9 / 10
Temp5 = T9 / 10
X = 1
End If

Return

Hans55
14.02.2008, 20:08
Danke!
Gruß
Hans

stefangem
15.12.2014, 17:33
Hallo Papsi ,

bei mir wird nur jeweils -0.2 angezeigt. Ich habe ds1820 und ds18b20 getestet immer dasselbe.

wenn er die kennung nicht auslesen sollte muss doch wenigsten ein default wert angezeigt werden aber nicht so ein unrunder
Wert.

Hat da jemand ne Lösung?

Gruss
Stefan

peterfido
15.12.2014, 18:32
Ja. Da kommt gar nix an. Also keine Daten von den Sensoren. Die 0.2 sind Rundungsfehler. Die Pullups sind in der Schaltung vorhanden? Der richtige Port und Pin ist gewählt?

stefangem
15.12.2014, 18:40
Danke,

hab die Pullups vergessen :)

peterfido
15.12.2014, 19:04
Woher ich das wohl wusste ;) Ein Pullup reicht übrigens pro 1-Wire Bus.