Onewire/DS2450 (Deutsch)
Onewire DS2450 | |
---|---|
Status | In Development
|
menuconfig | I/O->Onewire support |
Pinning | yes |
Ecmd | yes |
Control6 | yes |
Depends on | ECMD |
Requires | - |
Code | https://github.com/ethersex/ethersex/tree/master/hardware/onewire |
- Beitrag am 05.02.2016 erneuert.
Einleitung
Der DS2450 ist ein 4 Kanal ADC mit einer maximalen Auflösung von 16 Bit (vgl. Datenblatt). Die analog-digital Umwandlung erfolgt durch einen internen four-to-one multiplexer. Kanäle, die nicht als Eingänge genutzt werden, können als Ausgänge (open drain) geschaltet werden (max. 4mA und 6V).
Grundsätzlich gilt für alle Befehle:
- als erstes Argument kann optional die 64 Bit ROM Id des DS2450 angegeben werden, der angesprochen werden soll (match rom). Wird die ROM Id nicht angeben, so werden alle im Bus befindlichen 1-wire Devices (egal welchen Typs) angesprochen (skip rom). Dies macht nur Sinn, wenn sich genau ein Device im 1-wire Bus befindet (skip rom führt bei mehreren Devices unweigerlich dazu, dass mehrere Devices gleichzeitig antworten werden, was zu Bit-Salat beim bus master (d.h. Ethersex) führt, das Datenblatt spricht von "a wired-AND result").
- wird ein Kanal angeben, so ist dieser mit einem Buchstaben (entsprechend Datenblatt) zu bezeichnen (case-insensitiv).
- wird mit einem Befehl ein Wert gesetzt, so kann mit dem gleichen Befehl der Wert gelesen werden, in dem man kein Werte-Argument angibt.
ECMD Befehle
Über ECMD sind folgende Befehle für den DS2450 bekannt:
1w list 1w ds2450 power $id // Sensor id mit "1w list" auslesen 1w ds2450 res 1w ds2450 oc 1w ds2450 oe 1w ds2450 range 1w ds2450 por 1w ds2450 convert 1w ds2450 get
POWER
1w ds2450 power $id // Parameter auslesen. 1w ds2450 power $id 1 // Beispiel: Der DS2450 wird auf "normale" Spannungsversorgung konfiguriert.
Hierüber wird die Art der Spannungsversorgung des DS2450 gesetzt (global). Dieser Parameter wird durch den Anschluss an der 1-wire Bus bestimmt, vgl. die Erklärung der Anschlussmöglichkeiten. Wird der 1-wire Bus "normal" (drei-adrig) betrieben, so muss der Wert auf 1 gesetzt werden. Wird der Bus "parasitär" (zwei-adrig) betrieben, muss der Wert auf 0 gesetzt werden. (Default-Wert: 0)
RES
1w ds2450 res $id $kanal // Parameter auslesen. 1w ds2450 res $id c 08 // Beispiel: Setzt die Auflösung für Kanal C auf 0x08, d.h. 8 Bit.
Hierüber wird die Auflösung der analog-digital Umwandlung gesetzt (pro Kanal). Die Auflösung kann zw. 1 und 16 Bit eingestellt werden. Die Eingabe erfolgt als 8 Bit Hexadezimalwert, wobei eine Auflösung von 16 Bit durch den Wert 0x00 oder alternativ 0x10 erreicht wird. Außerdem ist die Kanal-Bezeichnung anzugeben. (Default-Wert: 0x08)
OC
1w ds2450 oc $id $kanal // Parameter auslesen. 1w ds2450 oc $id a 1 // Beispiel: Der Ausgangstransistor des Kanal A wird leitend.
Hierüber kann der Ausgang ein- oder ausgeschaltet werden (pro Kanal). Voraussetzung ist, dass über 1w ds2450 oe der Kanal als Ausgang geschaltet wurde (ansonsten wird das OC-Bit ignoriert). Die Eingabe erfolgt als bool über 0 (Ausgangstransistor leitend) bzw. 1 (Ausgangstransistor nicht-leitend). Außerdem ist die Kanal-Bezeichnung anzugeben. (Default-Wert: 0)
OE
1w ds2450 oe $id $kanal // Parameter auslesen. 1w ds2450 oe $id d 1 // Beispiel: Kanal A wird als Ausgang gesetzt.
Hierüber kann der Kanal als Ein- oder Ausgang gesetzt werden (pro Kanal). Eine analog-digital Umwandlung ist nur möglich, wenn das OE-Bit auf 0 gesetzt ist. In diesem Fall wird das OC-Bit ignoriert. Ist das OE-Bit auf 1 gesetzt, kann der Ausgang über 1w ds2450 oc ein- bzw. ausgeschaltet werden. Die Eingabe erfolgt als bool über 0 (Eingang für ADC) bzw. 1 (Ausgang open drain). Außerdem ist die Kanal-Bezeichnung anzugeben. (Default-Wert: 0)
RANGE
1w ds2450 range $id $kanal // Parameter auslesen. 1w ds2450 range $id b 1 // Beispiel: Für Kanal B wird bei der A/D Umwandlung der Spannungsbereich 0 bis 5,10V genutzt.
Hierüber kann der Spannungs-Bereich angegeben werden, in dem die analog-digital Umwandlung stattfinden soll. Die Eingabe erfolgt als bool über 0 (Spannungsbereich 0 bis 2,55V) bzw. 1 (Spannungsbereich 0 bis 5,10V). Außerdem ist die Kanal-Bezeichnung anzugeben. (Default-Wert: 0)
POR
1w ds2450 por $id $kanal // Parameter auslesen. 1w ds2450 por $id c 0 // Beispiel: Für Kanal C wird das power on reset Bit auf 0 gesetzt.
Hierüber kann das power on reset Bit gelesen bzw. gesetzt werden. Nach einem power-on reset cycle setzt der DS2450 das Bit auf 1. Das Bit beeinflusst die conditional search, welche in Ethersex (noch) nicht implementiert ist. Setzt der bus master das Bit auf 0, so nimmt der DS2450 nicht mehr an der conditional search teil. Die Eingabe erfolgt als bool über 0 bzw. 1. Außerdem ist die Kanal-Bezeichnung anzugeben. (Default-Wert: 1 (nach power-on reset cycle))
FixMe:
Es sieht so aus, als kann das Bit nur global gesetzt werden, d.h. wird es für einen Kanal verändert, haben danach alle anderen Kanäle den gleich POR-Bit Wert. Außerdem kann man das Bit nicht mehr auf 1 setzen, wenn es vorher schon auf 0 gesetzt wurde (das widerspricht aber dem Datenblatt!).
CONVERT
1w ds2450 convert $id // Beispiel: Für alle Kanäle wird die analog-digital Umwandlung durchgeführt.
Hierüber wird die analog-digital Umwandlung ausgelöst (analog den 1-wire Temperatursensoren). Werden keine weiteren Argumente angegeben, so wird die Umwandlung für alle 4 Kanäle des DS2450 durchgeführt (FixMe: vermutlich werden die Kanäle, bei denen das OE-Bit auf 1 steht ausgelassen, dass ist aber nicht durch Dallas dokumentiert). Optional können zwei Argumente angegeben werden (werden Argumente angegeben, müssen beide Argumente angegeben werden!):
- input select mask
- read-out control
- input select mask
Mit der input select mask kann angegeben werden, für welche Kanäle die analog-digital Umwandlung durchgeführt werden soll. Die input select mask ist ein 8 Bit Hexadezimalwert:
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|
ignore | ignore | ignore | ignore | Kanal D | Kanal C | Kanal B | Kanal A |
Eine input select mask von 0x0f bedeutet also, dass für alle 4 Kanäle die analog-digital Umwandlung durchgeführt werden soll. Eine mask von 0x00 ist (offensichtlich) sinnlos. Eine ungültige input select mask (d.h. input select mask == 0x00 oder > 0x0f) wird erkannt und führt zu einer ECMD-Fehlermeldung.
Die analog-digital Umwandlung erfolgt in der Reihenfolge von Kanal A zu Kanal D, wobei die nicht gewünschte Kanäle (sprich jene, wo das input select mask Bit auf 0 steht) übersprungen werden.
Der DS2450 braucht für jedes Bit Auflösung ca. 60 bis 80µs. Außerdem braucht das Umwandlung-Kommando generell 160µs (offset) Dies bedeutet, dass eine Umwandlung aller 4 Kanäle bei maximaler 16 Bit Auflösung also nicht länger als 4*16*80+160µs = 5280µs = 5,28ms dauern wird.
- read out control
Mit dem read out control kann angegeben werden, ob und wie das Register für die Ergebnisse der analog-digital Umwandlung vorbelegt werden soll. Das macht nur dann Sinn, wenn die Umwandlungsergebnisse schon gelesen werden sollen, während der DS2450 im Hintergrund noch die analog-digital Umwandlung durchführt (was möglich ist). Das read out control ist ein 8 Bit Hexadezimalwert:
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|
Set D | Clear D | Set C | Clear C | Set B | Clear B | Set A | Clear A |
Set bzw. Clear verhalten sich wie folgt:
Set | Clear | Ergebnis |
---|---|---|
0 | 0 | keine Veränderung am Umwandlung-Register |
0 | 1 | alle Bits des Umwandlung-Register werden auf 0 gesetzt |
1 | 0 | alle Bits des Umwandlung-Register werden auf 1 gesetzt |
1 | 1 | invalid |
Ungültige Kombinationen im read out control (d.h. Set = 1 und Clear = 1) werden erkannt und führen zu einer ECMD-Fehlermeldung.
Default-Werte:
- input select mask: 0x04
- read out control: 0x00
GET
1w ds2450 get $id // Beispiel: Die Umwandlungsergebnisse für alle 4 Kanäle werden ausgegeben.
Hierüber wird das Ergebnis der analog-digital Umwandlung ausgelesen (analog den 1-wire Temperatursensoren). Werden keine weiteren Argumente angegeben, so werden die Umwandlungsergebnisse für alle 4 Kanäle des DS2450 ausgegeben. Optional kann ein Kanal angegeben werden, dann wird nur das Umwandlungsergebniss dieses Kanals ausgegeben. Wurde seit dem letzten power-on reset cycle keine Umwandlung durchgeführt, stehen alle Bits der Register auf 0.
Die Ausgabe erfolgt als raw (unsigned integer 16 Bit - uint16_t
). Die eingelesene Spannung errechnet sich wie folgt (VAL ist die Ausgabe von 1w ds2450 get $id
):
Für Range = 0 (0,00V - 2,55V) (VAL / 2**16-1)* 2,55V
Für Range = 1 (0,00V - 5,10V) (VAL / 2**16-1)* 5,10V
Schaltungen
Beispielschaltung 1
Hier ein Beispielschaltung für den DS2450. Kanal A wird als Eingabe genutzt (range = 1). Kanal D wird als Ausgabe genutzt, über den Optokoppler kann die LED geschaltet werden.
Der Widerstand R1 muss unbedingt entsprechend dem Optokoppler dimensioniert werden. Beim 4N35 sind 1k3 ausreichend, dann fließt ein Strom von ca. 2,8mA.
Beispielschaltung 2
Hier die Beispielschaltung 2 für den DS2450. Kanal A/B/C/D wird als Eingang genutzt (Range = 1).
- I/O-A wird zb. als Tür oder Fenster Detektor genutzt.
- I/O-B wird als Eingang für den Luftfeuchtesensor genutzt.
- I/O-C wird als Eingang für den Luftdrucksensor genutzt.
- I/O-D wird genutzt um die Versorgungsspannung zu messen welche bei der Berechnung des Luftdrucksensor benötigt wird.
Weiters hängt ein DS2450 und ein DS1820 parallel am Bus um noch eine Temperatur über den Bus zu bekommen.
- Zum Initialisieren verwende ich folgende Kommandos via ecmd zb.:
1w ds2450 power $id 1 //(drei adrig) 1w ds2450 res $id c 08 //(00 / 10 = 16bit, 08 8bit) 1w ds2450 oe $id c 0 //(als eingang stetzen) 1w ds2450 range $id c 1 //(Range 0-5,10V) 1w ds2450 convert $id 1w ds2450 get $id
Berechnung in PHP
Berechnungen des Feuchtesensor
// lt. Datenblatt: // OFFSET 0.958062V bei 0%RH // SLOPE: 30.680 mV/%RH $V_Feuchte = ($Humid/65535)*5.17; $RH_Feuchte = ($V_Feuchte - 0.958062) * 34.558; //Werte nach Kalibrierung ( 34.558 Ist bei mir genauer als 30.680) $RHR = $RH_Feuchte / ((1.0305 + (0.000044 * 25) - (0.0000011 * pow(22.6,2)))); echo $RHR;
Berechnungen des Drucksensor
$ADCwert = ($Druck/65535)*5.10; $ADCVBuswert= ($Vdd/65535)*5.10; $kpawert = $ADCwert/($ADCVBuswert*0.009)+10.55; echo $kpawert*10;
Probleme
Werte des ADC schwanken beim auslesen
Lege doch mal die Versorgungsspannung direkt auf einen Eingang und schaue mal ob der Wert immer noch schwankt.
parse error 05.02.2016
debug abschalten avr-gcc >=4.7.2 verwenden
c6
Einbindung in Control6 (tcp_send)
TODO: Code testen, ur alt.
https://github.com/ethersex/ethersex/blob/master/hardware/onewire/ds2450.h
http://www.tutorials.at/c/03-dateneingabe-ausgabe.html
"ecmd?1w list" ergibt den rom code 20686414000000b5 für den ds2450
C6_HEADER(`/* This will be in control6.h */') #include "hardware/onewire/ds2450.h" uint16_t counter1 = 0; uint16_t var1 = 0; CONTROL_START CLOCK_USED() THREAD(start) var1 = 1; WAIT(5) var1 = 0; WAIT(5) THREAD_END(start) TCP_HANDLER_PERSIST(message_handler); if (var1 == 1){ ow_rom_code_t rom_code; uint16_t result; rom_code.bytewise[0] = 0x20; rom_code.bytewise[1] = 0x68; rom_code.bytewise[2] = 0x64; rom_code.bytewise[3] = 0x14; rom_code.bytewise[4] = 0x00; rom_code.bytewise[5] = 0x00; rom_code.bytewise[6] = 0x00; rom_code.bytewise[7] = 0xb5; ow_ds2450_convert(&rom_code, 0x0f, 0x00); ow_ds2450_get(&rom_code, 2, 2, &result); TCP_SEND("%u", result); WAIT(15) } TCP_HANDLER_END(); ON STARTUP DO THREAD_START(start) TCP_CONNECT(192.168.123.106, 4445, message_handler); END CONTROL_END