2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-25 15:59:21 +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

@ -1198,9 +1198,12 @@ sub OWX_Complex_SER ($$$$) {
sub OWX_First_SER ($$) {
my ($hash,$mode) = @_;
#-- clear 16 byte of search data
@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
$owx_LastDiscrepancy = 0;
$owx_LastDeviceFlag = 0;
@ -1915,9 +1918,6 @@ sub OWX_Search_9097 ($$) {
#$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) {
#loop until through all ROM bytes 0-7
my $id_bit = OWX_TouchBit_9097($hash,1);
@ -1977,8 +1977,8 @@ sub OWX_Search_9097 ($$) {
$rom_byte_number++;
$rom_byte_mask = 1;
}
$owx_LastDiscrepancy = $last_zero;
}
$owx_LastDiscrepancy = $last_zero;
return 1;
}

View File

@ -3,38 +3,44 @@
# OWX_ASYNC.pm
#
# 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 connecting to FHEM via Ethernet
#
# Norbert Truchsess
# Prof. Dr. Peter A. Henning
# based on 00_OWX.pm written by Prof. Dr. Peter A. Henning
#
# $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
#
# where <name> may be replaced by any name string
# <serial-device> is a serial (USB) device
# <arduino-pin> is an Arduino pin
#
# get <name> alarms => find alarmed 1-Wire devices (not with CUNO)
# get <name> devices => find all 1-Wire devices
# get <name> version => OWX_ASYNC version number
# get <name> alarms => find alarmed 1-Wire devices (not with CUNO)
# get <name> devices => find all 1-Wire devices
# get <name> version => OWX_ASYNC version number
#
# set <name> interval <seconds> => set period for temperature conversion and alarm testing
# set <name> followAlarms on/off => determine whether an alarm is followed by a search for
# alarmed devices
# set <name> interval <seconds> => set period for temperature conversion and alarm testing
# set <name> followAlarms on/off => determine whether an alarm is followed by a search for
# alarmed devices
#
# attr <name> dokick 0/1 => 1 if the interface regularly kicks thermometers on the
# bus to do a temperature conversion,
# and to make an alarm check
# 0 if not
# attr <name> buspower real/parasitic => for devices that steal power from data-line
#
# attr <name> interval <seconds> => set period for temperature conversion and alarm testing
# attr <name> dokick 0/1 => 1 if the interface regularly kicks thermometers on the
# bus to do a temperature conversion,
# and to make an alarm check
# 0 if not
#
# 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.
#
########################################################################################
#
@ -127,7 +133,7 @@ my %attrs = (
);
#-- some globals needed for the 1-Wire module
$owx_async_version=5.12;
$owx_async_version=5.13;
#-- Debugging 0,1,2,3
$owx_async_debug=0;
@ -1054,6 +1060,12 @@ sub OWX_ASYNC_RunToCompletion($$) {
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($) {
my ( $master ) = @_;
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)) {
my $task = $current->{queue}->[0];
$master->{".runningtask"} = $task;
my $timeout = $task->{TimeoutTime};
if ($task->PT_SCHEDULE()) {
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);
#new timeout or timeout did change:
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);
}
last;

View File

@ -125,13 +125,9 @@ sub reset() {
sub 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 );
foreach my $bit (split //,unpack "b*",$block) {
$serial->bit($bit);
}
} else {
die "no USBDev";
main::Log3($serial->{name},5, "OWX_DS9097 block: ".unpack "H*",$block) if ( $main::owx_async_debug > 1 );
foreach my $bit (split //,unpack "b*",$block) {
$serial->bit($bit);
}
}
@ -149,20 +145,22 @@ sub bit($) {
sub pt_query($) {
my ( $serial, $query ) = @_;
my @bitsout = split //,$query;
my $numbits = @bitsout;
my $bitsin = "";
my $bit;
return PT_THREAD(sub {
my ( $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 ($serial->poll()) {};
$serial->{string_raw} = "";
while (defined ($bit = shift @bitsout)) {
while ($serial->poll()) {};
$serial->{string_raw} = "";
$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_END;
});
@ -207,8 +205,6 @@ sub pt_next ($$) {
} else {
$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
@ -262,6 +258,7 @@ sub pt_next ($$) {
}
# serial number search direction write bit
$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
# and shift the mask rom_byte_mask
$id_bit_number++;
@ -271,9 +268,8 @@ sub pt_next ($$) {
$rom_byte_number++;
$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;
});
}

View File

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