PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tabelle als Übergabeparameter von Subroutine?



screwdriver
09.01.2009, 09:08
Hallo zusammen!

Ich möchte die Temperaturauswertung von 5 Stck DS18S20-Sensoren meines 1-Wire-Netzwerkes eleganter programmieren.
Bisher arbeite ich diese mit globalen Variablen nacheinander ab.

Zukünftig möchte ich die Temperaturauswertung universeller gestalten. Und zwar etwa so:

SUB DS1820_TEMPERATURE_READ(byref Temperatur as Integer, DS1820_Adress as ???)

Der Übergabeparameter DS1820_Adress soll einen Zeiger auf
den Romcode des betreffenden Sensors sein, der in der Routine mit der Read-Funktion ausgelesen wird.

Sensor1:
Data 16 , 135 , 205 , 170 , 0 , 8 , 0 , 118

Als welchen Variablentyp muß ich DS1820_Adress deklarieren?

PicNick
09.01.2009, 09:34
Adressen kann man als WORD speichern und weitergeben.


DIM adr AS WORD
adr = LOADLABEL(Sensor1)


In der Sub liest man dann mittels


for x = 0 TO 7
ptr = adr+x
rombyte = CPEEK(ptr)
next


Etwas weniger tricky ist


RESTORE Sensor1
call DS1820_TEMPERATURE_READ(byref Temperatur as Integer)
RESTORE Sensor2
call DS1820_TEMPERATURE_READ(byref Temperatur as Integer)
,,,
'---------------------------------------------------------------------------
SUB DS1820_TEMPERATURE_READ(byref Temperatur as Integer)
for x = 0 TO 7
READ rombyte
next

screwdriver
09.01.2009, 11:38
@PicNick
Vielen Dank für deine Antwort.
Genau wie deine dritte Variante habe ich das bisher gehandhabt.
Ich suche jedoch eine Möglichkeit alle nötigen Parameter in den Funktionsaufrauf zu packen, also quasi den Label "Sensor1" als Übergabeparameter.
Deine erstgenannte Möglichkeit bietet diese Funktion leider auch nicht, da die Labeladresse wieder in einer global-definierten Variable steckt...

PicNick
09.01.2009, 12:42
Ganz so isses nicht: "adr" ist ja nur eine temporäre Variable für den Sub-Call



Declare Sub Ds1820_temperature_read(byref Temperatur As Integer , Byref Adr As Word)

Dim Addr As Word
Dim Temperatur As Integer

Addr = Loadlabel(sensor1)
Call Ds1820_temperature_read(temperatur , Addr)
Addr = Loadlabel(sensor2)
Call Ds1820_temperature_read(temperatur , Addr)

Addr = Loadlabel(sensor3)
Call Ds1820_temperature_read(temperatur , Addr)

End

sub DS1820_TEMPERATURE_READ(byref Temperatur as Integer, byref adr as word)
LOCAL ptr AS WORD
LOCAL x as BYTE
LOCAL rombyte as BYTE
for x = 0 TO 7
ptr = adr+x
rombyte = CPEEK(ptr)
next
End Sub


Sensor1:
Data 1, 2, 3, 4, 5, 6, 7, 8
Sensor2:
Data 1, 2, 3, 4, 5, 6, 7, 8
Sensor3:
Data 1, 2, 3, 4, 5, 6, 7, 8

for_ro
09.01.2009, 12:48
Du musst ja nicht notwendigerweise ein spezifisches Label pro Sensor übergeben. Du kannst die ROM-Adressen doch auch bei einem label alle hintereinander schreiben und dann ab einer bestimmten Adresse nach dem Label einlesen.
Dafür benutzt du die Lookup()-Funktion, wo du auch gleich den Offset ab dem Label angeben kannst. Du übergibst an die die Sub dann die Nummer des Sensors und errechnest den Offset in der Sub. Das Label bleibt dabei immer gleich.

Gruß

Rolf

screwdriver
09.01.2009, 13:37
@for_ro + @PicNick
Danke euch beiden. Eure Lösungen würden funktionieren. Aber ich finde sie verschlechtern eher die Lesbarkeit des Codes.

Ein Unterprogrammaufruf der Form

call DS1820_TEMPERATURE_READ(Temperatur,Aussensensor)
oder
Aussentemperaur= DS1820_TEMPERATUR_READ(Aussensensor)

mit dem Label

Aussensensor:
Data 16 , 135 , 205 , 170 , 0 , 8 , 0 , 118

finde ich die eleganteste Lösung. Und da möchte ich auch hin...

In der Bascom-eigenen Graphlib glcd.lib gibts z.B. eine Funktion

Showpic x,y,label.

Da wird doch auch ein Label übergeben. Wieso klappt das denn nicht mit einer selbstdeklarierten Funktion. Muß ich denn wirklich den Umweg über eine Lib gehen? Da müßte ich mich erstmal einarbeiten. Allerdings wäre eine Lib für die DS1820 Sensoren auch schon längst überfällig.

for_ro
09.01.2009, 14:51
@for_ro + @PicNick
Danke euch beiden. Eure Lösungen würden funktionieren. Aber ich finde sie verschlechtern eher die Lesbarkeit des Codes.

Ein Unterprogrammaufruf der Form

call DS1820_TEMPERATURE_READ(Temperatur,Aussensensor)
oder
Aussentemperaur= DS1820_TEMPERATUR_READ(Aussensensor)

mit dem Label

Aussensensor:
Data 16 , 135 , 205 , 170 , 0 , 8 , 0 , 118

finde ich die eleganteste Lösung. Und da möchte ich auch hin...

In der Bascom-eigenen Graphlib glcd.lib gibts z.B. eine Funktion

Showpic x,y,label.

Da wird doch auch ein Label übergeben. Wieso klappt das denn nicht mit einer selbstdeklarierten Funktion. Muß ich denn wirklich den Umweg über eine Lib gehen? Da müßte ich mich erstmal einarbeiten. Allerdings wäre eine Lib für die DS1820 Sensoren auch schon längst überfällig.

Warum willst du dir das so schwer machen. Ich denke, dass du die Lösung mit der Lookup()-Funktion nicht wirklich durchdacht hast.

Stell dir mal sowas vor:


Const Aussensensor = 0
Const Innensensor = 1

call DS1820_TEMPERATURE_READ(Temperatur,Aussensensor)

...


Sub call DS1820_TEMPERATURE_READ(Temp,sensor_Nr)
Offset=sensor_Nr*8
For I=1 to 8
Rom(I) = Lookup(Offset,Sensor_Adressen)
Next I
...
End Sub


Sensor_Adressen:
Data 16 , 135 , 205 , 170 , 0 , 8 , 0 , 118 'Aussen
Data 16 , 135 , 205 , 171 , 0 , 8 , 0 , 119 'Innen

Für mich sieht das sehr einfach aus.

Gruß

Rolf

Edit PicNick Ich hab versucht, den quote Tags in deinem Sinne zu setzen. Wenn das ein Schuss in den Ofen war, tut's mir leid :oops:

for_ro
09.01.2009, 14:52
Da wird doch auch ein Label übergeben. Wieso klappt das denn nicht mit einer selbstdeklarierten Funktion. Muß ich denn wirklich den Umweg über eine Lib gehen? Da müßte ich mich erstmal einarbeiten. Allerdings wäre eine Lib für die DS1820 Sensoren auch schon längst überfällig.

Warum willst du dir das so schwer machen. Ich denke, dass du die Lösung mit der Lookup()-Funktion nicht wirklich durchdacht hast.

Stell dir mal sowas vor:


Const Aussensensor = 0
Const Innensensor = 1

call DS1820_TEMPERATURE_READ(Temperatur,Aussensensor)

...


Sub call DS1820_TEMPERATURE_READ(Temp,sensor_Nr)
Offset=sensor_Nr*8
For I=1 to 8
Rom(I) = Lookup(Offset,Sensor_Adressen)
Next I
...
End Sub


Sensor_Adressen:
Data 16 , 135 , 205 , 170 , 0 , 8 , 0 , 118 'Aussen
Data 16 , 135 , 205 , 171 , 0 , 8 , 0 , 119 'Innen

Für mich sieht das sehr einfach aus.

Gruß

Rolf

screwdriver
09.01.2009, 16:45
@for_ro
Dein Lösungsvorschlag ist ja auch vollkommen in Ordnung, da gibts nichts dran auszusetzen. Der Schönheitsfehler ist jedoch, daß für jeden Sensor zusätzlich eine laufende Nummer zugewiesen werden muß, mit der du ja dann die absolute Position des Romcodes in der Subroutine ermittelst. Aber das ist eigentlich unnötig, weil es gerade dafür Labels gibt.

@Alle
Für diejenigen, die nicht so richtig wissen, worauf ich hinaus will, poste ich hier noch einen funktionsfähigen Code zum Auslesen mehrer DS1820 Temperatursensoren. Das ist wohl die Bascom-Handbuchlösung, wie ich derzeit benutze und PicNick ebenfalls vorgeschlagen hat.


'************************************************* ******************************
'*** Temperaturmessung mit mehreren DS1820 Sensoren ***
'************************************************* ******************************
'*** Autor: Screwdriver ***
'*** Datum: 09.01.2008 ***
'************************************************* ******************************

'************************************************* ******************************
'*** Konfiguration ***
'************************************************* ******************************
Config 1wire = Portb.4 '1Wire-Anschluß festlegen

'1wire Konstanten
Const Ds1820 = &H10
Const Skip_rom = &HCC
Const Read_rom = &H33
Const Convertt = &H44
Const Match_rom = &H55
Const Read_ram = &HBE
Const Copy_ram = &H48
Const Recallee = &HB8
Const Readpower = &HB4

'************************************************* ******************************
'*** Variablen ***
'************************************************* ******************************
Dim Temperatur_aussen As Integer 'Temperaturen mit einer Nachkommastelle
Dim Temperatur_kessel As Integer
Dim Temperatur_hzg_vl As Integer
Dim Temperatur_hzg_rl As Integer

Dim Scratch(9) As Byte 'Scratch-Pad DS1820 Sensoren

'************************************************* ******************************
'*** Deklaration Unterprogramme ***
'************************************************* ******************************
Declare Sub Ds1820_convert_all()
Declare Sub Ds1820_temperature_read(temperature As Integer)

'************************************************* ******************************
'*** HAUPTPROGRAM ***
'************************************************* ******************************
Do
Call Ds1820_convert_all() 'Alle Sensoren Temperaturwandlung
Waitms 750

Restore Aussensensor
Call Ds1820_temperature_read(temperatur_aussen)
Print Temperatur_aussen

Restore Kesselsensor
Call Ds1820_temperature_read(temperatur_kessel)
Print Temperatur_kessel

Restore Hzg_vl_sensor
Call Ds1820_temperature_read(temperatur_hzg_vl)
Print Temperatur_hzg_vl

Restore Hzg_rl_sensor
Call Ds1820_temperature_read(temperatur_hzg_rl)
Print Temperatur_hzg_rl
Loop
End 'end program

'************************************************* ******************************
'*** Unterprogramme ***
'************************************************* ******************************
Sub Ds1820_convert_all()
1wreset
1wwrite Skip_rom
1wwrite Convertt
End Sub

'************************************************* ******************************
Sub Ds1820_temperature_read(temperature As Integer)
Local Ds1820_temp As Byte 'Zählvariable
Local Ds1820_data As Byte 'Bytevariable

1wreset
1wwrite Match_rom

For Ds1820_temp = 1 To 8 'Romcode aus Flash lesen
Read Ds1820_data
1wwrite Ds1820_data
Next Ds1820_temp

1wwrite Read_ram
Scratch(1) = 1wread(9) 'DS1820 auslesen

If Crc8(scratch(1) , 8) = Scratch(9) Then 'CRC8-Check
Temperature = Makeint(scratch(1) , Scratch(2))
Temperature = Temperature * 5 'Entspricht 10facher Temperatur
End If
End Sub

'************************************************* ******************************
'*** DS1820 Romcodes ***
'************************************************* ******************************
Aussensensor:
Data 16 , 135 , 205 , 170 , 0 , 8 , 0 , 158
Kesselsensor:
Data 16 , 121 , 191 , 192 , 0 , 8 , 0 , 154
Hzg_vl_sensor:
Data 16 , 5 , 16 , 219 , 0 , 8 , 0 , 143
Hzg_rl_sensor:
Data 16 , 101 , 203 , 192 , 0 , 8 , 0 , 206