2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-28 11:01:59 +00:00

OWX_DS9097: fix 1-Wire search algorithm

git-svn-id: https://svn.fhem.de/fhem/trunk@6362 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
ntruchsess 2014-08-04 21:08:27 +00:00
parent 01fe79e44c
commit 3404dc43ac
4 changed files with 48 additions and 38 deletions

View File

@ -1201,6 +1201,9 @@ sub OWX_First_SER ($$) {
#-- clear 16 byte of search data #-- clear 16 byte of search data
@owx_search=(0,0,0,0 ,0,0,0,0, 0,0,0,0, 0,0,0,0); @owx_search=(0,0,0,0 ,0,0,0,0, 0,0,0,0, 0,0,0,0);
#-- clear 8 bytes of romid:
@owx_ROM_ID = (0,0,0,0,0,0,0,0);
#-- reset the search state #-- reset the search state
$owx_LastDiscrepancy = 0; $owx_LastDiscrepancy = 0;
$owx_LastDeviceFlag = 0; $owx_LastDeviceFlag = 0;
@ -1915,9 +1918,6 @@ sub OWX_Search_9097 ($$) {
#$response = OWX_TouchByte($hash,$sp1); #$response = OWX_TouchByte($hash,$sp1);
#-- clear 8 byte of device id for current search
@owx_ROM_ID =(0,0,0,0 ,0,0,0,0);
while ( $id_bit_number <= 64) { while ( $id_bit_number <= 64) {
#loop until through all ROM bytes 0-7 #loop until through all ROM bytes 0-7
my $id_bit = OWX_TouchBit_9097($hash,1); my $id_bit = OWX_TouchBit_9097($hash,1);
@ -1977,8 +1977,8 @@ sub OWX_Search_9097 ($$) {
$rom_byte_number++; $rom_byte_number++;
$rom_byte_mask = 1; $rom_byte_mask = 1;
} }
$owx_LastDiscrepancy = $last_zero;
} }
$owx_LastDiscrepancy = $last_zero;
return 1; return 1;
} }

View File

@ -3,18 +3,20 @@
# OWX_ASYNC.pm # OWX_ASYNC.pm
# #
# FHEM module to commmunicate with 1-Wire bus devices # FHEM module to commmunicate with 1-Wire bus devices
# * via an active DS2480 bus master interface attached to an USB port # * via an active DS2480 bus master interface attached to a serial port, USB or Ethernet<->Serial interface
# * via a passive DS9097 bus master interface attached to a serial port
# * via an Arduino running ConfigurableFirmata attached to USB # * via an Arduino running ConfigurableFirmata attached to USB
# * via an Arduino running ConfigurableFirmata connecting to FHEM via Ethernet # * via an Arduino running ConfigurableFirmata connecting to FHEM via Ethernet
# #
# Norbert Truchsess # Norbert Truchsess
# Prof. Dr. Peter A. Henning # based on 00_OWX.pm written by Prof. Dr. Peter A. Henning
# #
# $Id$ # $Id$
# #
######################################################################################## ########################################################################################
# #
# define <name> OWX_ASYNC <serial-device> for USB interfaces or # define <name> OWX_ASYNC <serial-device> for serial or USB interfaces (both DS2480 and DS9097)
# define <name> OWX_ASYNC <ip:port> for DS2480 over Ethernet
# define <name> OWX_ASYNC <arduino-pin> for a Arduino/Firmata (10_FRM.pm) interface # define <name> OWX_ASYNC <arduino-pin> for a Arduino/Firmata (10_FRM.pm) interface
# #
# where <name> may be replaced by any name string # where <name> may be replaced by any name string
@ -29,6 +31,8 @@
# set <name> followAlarms on/off => determine whether an alarm is followed by a search for # set <name> followAlarms on/off => determine whether an alarm is followed by a search for
# alarmed devices # alarmed devices
# #
# attr <name> buspower real/parasitic => for devices that steal power from data-line
#
# attr <name> dokick 0/1 => 1 if the interface regularly kicks thermometers on the # attr <name> dokick 0/1 => 1 if the interface regularly kicks thermometers on the
# bus to do a temperature conversion, # bus to do a temperature conversion,
# and to make an alarm check # and to make an alarm check
@ -36,6 +40,8 @@
# #
# attr <name> interval <seconds> => set period for temperature conversion and alarm testing # attr <name> interval <seconds> => set period for temperature conversion and alarm testing
# #
# attr <name> IODev <frm-device> => required when there's more than a single frm-device defined.
#
######################################################################################## ########################################################################################
# #
# This programm is free software; you can redistribute it and/or modify # This programm is free software; you can redistribute it and/or modify
@ -127,7 +133,7 @@ my %attrs = (
); );
#-- some globals needed for the 1-Wire module #-- some globals needed for the 1-Wire module
$owx_async_version=5.12; $owx_async_version=5.13;
#-- Debugging 0,1,2,3 #-- Debugging 0,1,2,3
$owx_async_debug=0; $owx_async_debug=0;
@ -1054,6 +1060,12 @@ sub OWX_ASYNC_RunToCompletion($$) {
return $task->PT_RETVAL(); return $task->PT_RETVAL();
} }
sub OWX_ASYNC_TaskTimeout($$) {
my ( $master, $timeout ) = @_;
die "OWX_ASYNC_TaskTimeout: no task running" unless defined $master->{".runningtask"};
$master->{".runningtask"}->{TimeoutTime} = $timeout;
}
sub OWX_ASYNC_RunTasks($) { sub OWX_ASYNC_RunTasks($) {
my ( $master ) = @_; my ( $master ) = @_;
if ($master->{STATE} eq "Active") { if ($master->{STATE} eq "Active") {
@ -1090,6 +1102,7 @@ sub OWX_ASYNC_RunTasks($) {
} }
if (defined (my $current = @queue_waiting ? shift @queue_waiting : @queue_ready ? shift @queue_ready : @queue_initial ? shift @queue_initial : undef)) { if (defined (my $current = @queue_waiting ? shift @queue_waiting : @queue_ready ? shift @queue_ready : @queue_initial ? shift @queue_initial : undef)) {
my $task = $current->{queue}->[0]; my $task = $current->{queue}->[0];
$master->{".runningtask"} = $task;
my $timeout = $task->{TimeoutTime}; my $timeout = $task->{TimeoutTime};
if ($task->PT_SCHEDULE()) { if ($task->PT_SCHEDULE()) {
my $state = $task->PT_STATE(); my $state = $task->PT_STATE();
@ -1114,7 +1127,7 @@ sub OWX_ASYNC_RunTasks($) {
Log3 $master->{NAME},5,"OWX_ASYNC_RunTasks: $current->{device} task waiting for data or timeout" if ($owx_async_debug>2); Log3 $master->{NAME},5,"OWX_ASYNC_RunTasks: $current->{device} task waiting for data or timeout" if ($owx_async_debug>2);
#new timeout or timeout did change: #new timeout or timeout did change:
if (!defined $timeout or $timeout != $task->{TimeoutTime}) { if (!defined $timeout or $timeout != $task->{TimeoutTime}) {
Log3 $master->{NAME},5,sprintf("OWX_ASYNC_RunTasks: $current->{device} task schedule for timeout at %.6f",$task->{TimeoutTime}); Log3 $master->{NAME},5,sprintf("OWX_ASYNC_RunTasks: $current->{device} task schedule for timeout at %.6f",$task->{TimeoutTime}) if ($owx_async_debug>1);
InternalTimer($task->{TimeoutTime}, "OWX_ASYNC_RunTasks", $master,0); InternalTimer($task->{TimeoutTime}, "OWX_ASYNC_RunTasks", $master,0);
} }
last; last;

View File

@ -125,14 +125,10 @@ sub reset() {
sub block($) { sub block($) {
my ( $serial, $block ) = @_; my ( $serial, $block ) = @_;
if (defined (my $hwdevice = $serial->{hash}->{USBDev})) {
main::Log3($serial->{name},5, "OWX_DS9097 block: ".unpack "H*",$block) if ( $main::owx_async_debug > 1 ); main::Log3($serial->{name},5, "OWX_DS9097 block: ".unpack "H*",$block) if ( $main::owx_async_debug > 1 );
foreach my $bit (split //,unpack "b*",$block) { foreach my $bit (split //,unpack "b*",$block) {
$serial->bit($bit); $serial->bit($bit);
} }
} else {
die "no USBDev";
}
} }
sub bit($) { sub bit($) {
@ -149,20 +145,22 @@ sub bit($) {
sub pt_query($) { sub pt_query($) {
my ( $serial, $query ) = @_; my ( $serial, $query ) = @_;
my @bitsout = split //,$query; my @bitsout = split //,$query;
my $numbits = @bitsout;
my $bitsin = ""; my $bitsin = "";
my $bit; my $bit;
return PT_THREAD(sub { return PT_THREAD(sub {
my ( $thread ) = @_; my ( $thread ) = @_;
PT_BEGIN($thread); PT_BEGIN($thread);
main::Log3($serial->{name},5, "OWX_DS9097 pt_query out: ".$query) if( $main::owx_async_debug > 1 ); main::Log3($serial->{name},5, "OWX_DS9097 pt_query out: ".$query) if( $main::owx_async_debug );
while (defined ($bit = shift @bitsout)) {
while ($serial->poll()) {}; while ($serial->poll()) {};
$serial->{string_raw} = ""; $serial->{string_raw} = "";
while (defined ($bit = shift @bitsout)) {
$serial->bit($bit); $serial->bit($bit);
PT_WAIT_UNTIL(length($serial->{string_raw}) > 0);
$bitsin .= substr($serial->{string_raw},0,1) eq ($bit == 1 ? "\xFF" : "\x00") ? "1" : "0";
}; };
main::Log3($serial->{name},5,"OWX_DS9097 pt_query in: ".$bitsin) if ( $main::owx_async_debug > 1 ); main::OWX_ASYNC_TaskTimeout($serial->{hash},gettimeofday+1);
PT_WAIT_UNTIL(length($serial->{string_raw}) >= $numbits);
$bitsin = join "", map { ($_ == 0xFF) ? "1" : "0" } unpack "C*",$serial->{string_raw};
main::Log3($serial->{name},5,"OWX_DS9097 pt_query in: ".$bitsin) if ( $main::owx_async_debug );
PT_EXIT($bitsin); PT_EXIT($bitsin);
PT_END; PT_END;
}); });
@ -207,8 +205,6 @@ sub pt_next ($$) {
} else { } else {
$serial->block("\xEC"); $serial->block("\xEC");
} }
#-- clear 8 byte of device id for current search
$context->{ROM_ID} = [0,0,0,0 ,0,0,0,0];
#-- Response search data parsing operates bitwise #-- Response search data parsing operates bitwise
@ -262,6 +258,7 @@ sub pt_next ($$) {
} }
# serial number search direction write bit # serial number search direction write bit
$serial->bit($search_direction); $serial->bit($search_direction);
main::Log3 ($serial->{name},5,"id_bit_number: $id_bit_number, search_direction: $search_direction, LastDiscrepancy: $last_zero ROM_ID: ".sprintf("%02X.%02X%02X%02X%02X%02X%02X.%02X",@{$context->{ROM_ID}})) if ($main::owx_async_debug);
# increment the byte counter id_bit_number # increment the byte counter id_bit_number
# and shift the mask rom_byte_mask # and shift the mask rom_byte_mask
$id_bit_number++; $id_bit_number++;
@ -271,9 +268,8 @@ sub pt_next ($$) {
$rom_byte_number++; $rom_byte_number++;
$rom_byte_mask = 1; $rom_byte_mask = 1;
} }
$context->{LastDiscrepancy} = $last_zero;
main::Log3 ($serial->{name},5,"id_bit_number: $id_bit_number, search_direction: $search_direction, LastDiscrepancy: $context->{LastDiscrepancy} ROM_ID: ".sprintf("%02X.%02X%02X%02X%02X%02X%02X.%02X",@{$context->{ROM_ID}})) if ($main::owx_async_debug > 2);
} }
$context->{LastDiscrepancy} = $last_zero;
PT_END; PT_END;
}); });
} }

View File

@ -368,6 +368,7 @@ sub first($) {
$thread->{LastDiscrepancy} = 0; $thread->{LastDiscrepancy} = 0;
$thread->{LastDeviceFlag} = 0; $thread->{LastDeviceFlag} = 0;
$thread->{LastFamilyDiscrepancy} = 0; $thread->{LastFamilyDiscrepancy} = 0;
$thread->{ROM_ID} = [0,0,0,0,0,0,0,0];
} }
sub next_response($) { sub next_response($) {