Beispiel für die Abfrage der Konfiguration in Python

Physikalische Werte, Controller und Chips

Die Bezeichnungen für die physikalischen Werte können einfach in Arrays gespeichert werden:

devInfo= ["","temperature","pressure","illuminance","humidity","constant", "voltage","current","VOC", "counter","CO2","resistance"]
devUnit= ["","°C","hPa","lux","%","","V","mA","ppm","","ppm","kOhm"]
devController=["","Old code","Attiny84A","Attiny44","Atmega328"]
devChip=["","DS18B20","DS2438","DS2438","DS2438","DS2450","Thermoelement","SHT21", "SHT25","DHT22","HIH9021","HDC1080","HIH4030","HIH5030","BMP280","MAX44009","CDM7160", "MAX1164/TGS8100","TGS8100","DS2423","Intern ADC","SHT35","SHT31"

Formeln

Die Auswahl der Formeln habe ich mit einer "CASE" Auswahl gelöst. Dabei werden alle RAW-Werte an die Funktion übergeben, so dass z.B. die Abhängigkeit der Luftfeuchte von der Temperatur beim HIH403X (Formel 7) berechnet werden kann.

# code - Formelcode 
# vn - Nummer des Wertes in der Liste der RAW-Werte V
# V - Liste der RAW-Werte
def calcValue(code,vn,V):
	if code==0:
		return V[vn]
	if code==1: 
		return V[vn] / 16.0; 
	if code==2:
		return V[vn]/1.6; 
	if code==3:
		return V[vn]*0.2 + 700; 
	if code==4:
		return exp(V[vn] / 160.0); 
	if code==5:
		return V[vn]*62.5 + 55000; 
	if code==6:
		return V[vn] / 256.0; 
	if code==7:
		return ((float(V[2]) / float(V[1]) - 0.16) / 0.0062) / (1.0546 - 0.00216*V[0]/256.0); 
	if code==8:
		return V[vn] / 100.0; 
	if code==9:
		return V[vn] / 65535.0*5.1; 
	if code==10:
		return V[vn] / 65535.0*2.55;
	if code==11:
		return V[vn] / 65535.0*1.1; 
	if code==12:
		return V[vn] / 10.0; 
	if code==13:
		return V[vn];  
	if code==14:
		return (V[vn] - 32767.0) / 100.0;  
	if code==15:
		return exp((V[vn]-32767.0)/1000.0);
	if code==16:
		return V[vn]/32.0;  
	if code==17:
		return V[vn]*0.2441/1000.0;  
	if code==18:
		return V[vn]/8.0;  
	return 0;

Kommunikation

Die Kommunikation mit dem 1-Wire-Device erfolgt über die Linux-Kernel-Schnittstelle mit der Routine owcom. Dabei wird in die Datei rw im Verzeichnis des Gerätes geschrieben bzw. aus ihr gelesen werden. Bei dem 1-Wire-Temperatursensor DS18B20 (und ähnliche) wird standardmäßig ein weiteres Kernelmodule aktiviert (w1_therm). Dabei wird die Datei rw ersetzt und es kann nicht mehr direkt auf das Gerät zugegriffen werden. Deswegen wird dieses Module aus dem Kernel entladen.

import subprocess

#dev - Verzeichnis des Gerätes
#send - Liste mit der Codesequenz, die an das Geraet gesendet wird
#rc - Anzahl der Bytes, die empfangen werden sollen
#return - Empfangene Bytes in einer Liste
def owcom(dev,send,rc):
	res=[]
	try:
		f=open("/sys/bus/w1/devices/%s/rw" %(dev),"r+b",0)
	except IOError:
		l=subprocess.check_output("rmmod w1_therm",shell=True)
		f=open("/sys/bus/w1/devices/%s/rw" %(dev),"r+b",0)
	f.write("".join(map(chr, send)))
	if (rc!=0):
		res=map(ord,f.read(rc))
	f.close()
	return res

Abfrage des Konfigurationscode

Nun sind alle Vorausetzungen geschaffen, um den Config-Code abzufragen. Dazu wird der Code 0x85 an das aktive 1-Wire-Device geschickt. Die Aktivierung mit MATCH-ROM übernimmt der Linux-Kernel.

def readConfig(self):
    self.config=owcom(self.owid,[0x85],26)
    print self.config
    if self.config[0]==0xFF:  #wird der Code nicht unterstuetzt, wird immer 0xFF zurueckgegeben
        print("No Deviceconfig. Not a Device form tm3d.de. Set Default");
        self.setdefaultConfig()
    else:
        #Devices mit 8-Bit CRC Berechnen auch hier nur CRC8 
        #Das letzte Byte ist 0xFF
        if self.config[25]==0xFF:  
            if crc8(self.config[0:24]):
                print("CRC Error reading Deviceconfig. Set Default")
                self.setdefaultConfig()
        else:
            #im CRC16 ist immer der Befehlscode mit enthalten
            if not(crc16([0x85]+self.config)):
                print("CRC Error reading Deviceconfig. Set Default")
                self.setdefaultConfig()

Der Quellcode ist Teil der Bibliothek owlib.py. Der Gesamte Quelltext ist in der Git Repository zu finden. Dort ist ein Objekt für 1-Wire-Devices definiert, das entsprechend der 1-Wire-Gerätefamilie eine Default-Konfiguration enthällt (setdefaultConfig).

Die Werte können dann z.B. mit den folgenden Befehlen ausgegeben werden:

for i in range(4):
    print devChip[self.config[i+9]],"\t", \
          devInfo[self.config[i*2]],"\t", \
          devUnit[self.config[i*2]],"\t"
print devController[self.config[i+9]]

Für die eigene Verwendung lohnt sich die oben angegbene Bibliothek mal genauer anzuschauen, oder die Implementation in C++ von owTools .

Zum Seitenanfang