Author Topic: one wire bricklet, ds18b20 temperatur unter null°C auslesen mit python  (Read 563 times)

DrJoe

  • Newbie
  • *
  • Posts: 6
    • View Profile
Hallo,
bitte um mithilfe  ;)
wenn der ds18b20 sensor mit dem Python script Temperaturen unter null °C ausliest, ergeben sich fehlerhafte werte: Sensor2: 4094.81 °C ?
Herausgefunden habe ich das durch einfaches tauschen der Position der sensoren von innen/aussen.
hat jemand eine Idee?
hier der Code:
Code: [Select]
#!/usr/bin/env python
# -*- coding: utf-8 -*-

HOST = "localhost"
PORT = 4223
UID = "GGW" # Change XYZ to the UID of your One Wire Bricklet

import time

from tinkerforge.ip_connection import IPConnection
from tinkerforge.bricklet_one_wire import BrickletOneWire

if __name__ == "__main__":
    ipcon = IPConnection() # Create IP connection
    ow = BrickletOneWire(UID, ipcon) # Create device object

    ipcon.connect(HOST, PORT) # Connect to brickd
    # Don't use device before ipcon is connected

    ids = ow.search_bus().identifier     
    print ids                           #id 13114784581154432808L

    ow.write_command(13114784581154432808L, 78) # WRITE SCRATCHPAD
    ow.write(0) # ALARM H (unused)
    ow.write(0) # ALARM L (unused)
    ow.write(127) # CONFIGURATION: 12 bit mode

    # Read temperature 2 times
    for i in range(2):
        ow.write_command(13114784581154432808L, 68) # CONVERT T (start temperature conversion)
        time.sleep(2) # Wait for conversion to finish
        ow.write_command(13114784581154432808L, 190) # READ SCRATCHPAD

        t_low = ow.read().data
        t_high = ow.read().data

        temperature1 = ('{:6.2f}'.format((t_low | (t_high << 8)) / 16.0))     

       
        print "Sensor1: %s °C" % temperature1         


   
    ipcon.disconnect()




if __name__ == "__main__":
    ipcon = IPConnection() # Create IP connection
    ow = BrickletOneWire(UID, ipcon) # Create device object

    ipcon.connect(HOST, PORT) # Connect to brickd
    # Don't use device before ipcon is connected

   
   
    ow.write_command(15348569994255425064L, 78)

   
    ow.write(0) # ALARM H (unused)
    ow.write(0) # ALARM L (unused)
    ow.write(127) # CONFIGURATION: 12 bit mode

    # Read temperature 2 times
    for i in range(2):
       
        ow.write_command(15348569994255425064L, 68)       
       
        time.sleep(2) # Wait for conversion to finish
       
        ow.write_command(15348569994255425064L, 190)       

        t_low = ow.read().data
        t_high = ow.read().data
       
        temperature2 = ('{:6.2f}'.format((t_low | (t_high << 8)) / 16.0))
                       
        print "Sensor2: %s °C" % temperature2 



   
    ipcon.disconnect()

Ausgabe:
Code: [Select]
(15348569994255425064L, 13114784581154432808L)
Sensor1:  20.25 °C
Sensor1:  20.31 °C
Sensor2: 4095.69 °C
Sensor2: 4095.69 °C

???? ;D

rtrbt

  • Tinkerforge Staff
  • Administrator
  • Full Member
  • *****
  • Posts: 133
    • View Profile
Das ist ein Bug in unserem Beispiel. Damit negative Temperaturen funktionieren, muss der Code wie folgt abgeändert werden:
Code: [Select]
temperature1 = ('{:6.2f}'.format((t_low | (t_high << 8)) / 16.0))     muss stattdessen
Code: [Select]
temperature1 = (t_low | (t_high << 8))
if temperature1 > 1 << 12:
    temperature1 -= 1 << 16 # Negative 12-bit values are sign-extended to 16-bit two's complement.
temperature1 /= 16.0 # 12 bit mode measures in units of 1/16°C.
temperature1 = '{:6.2f}'.format(temperature1)
sein, bei temperature2 analog.

Das Problem ist, dass der Temperatursensor eine 12 Bit lange Zahl in Zweier-Komplement-Form ausgibt (und die aufgeblasen auf 16 Bit, damit sie zwei Byte füllt). Das hat der Beispielcode bisher nicht beachtet. Ich behebe das mal in den Beispielen aller Sprachen.
« Last Edit: December 19, 2018, 12:09:37 by rtrbt »

DrJoe

  • Newbie
  • *
  • Posts: 6
    • View Profile
 :D it works:
Code: [Select]
(15348569994255425064L, 13114784581154432808L)
Sensor1:  20.69 °C
Sensor1:  20.69 °C
Sensor2:  -0.25 °C
Sensor2:  -0.25 °C

Vielen Dank 8)