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","wind speed","wind speed max","wind direction","wind direction variation"]
devUnit= ["","°C","hPa","lux","%","","V","mA","ppm","","ppm","kOhm","m/s","m/s","degree","degree"]
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 .