From 7794e3a327cf59901a6e27bb7add1c3fd74ae73d Mon Sep 17 00:00:00 2001 From: ntruchsess <> Date: Sun, 11 Aug 2013 16:49:39 +0000 Subject: [PATCH] merge internal-pullup and fix for non-functional digital pins to FRM_IN git-svn-id: https://svn.fhem.de/fhem/trunk@3670 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/20_FRM_IN.pm | 40 +++++++++++++++++++++--- fhem/FHEM/lib/Device/Firmata/Platform.pm | 36 ++++++++++----------- 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/fhem/FHEM/20_FRM_IN.pm b/fhem/FHEM/20_FRM_IN.pm index c9e7be8e3..f5750111e 100755 --- a/fhem/FHEM/20_FRM_IN.pm +++ b/fhem/FHEM/20_FRM_IN.pm @@ -32,7 +32,7 @@ FRM_IN_Initialize($) $hash->{InitFn} = "FRM_IN_Init"; $hash->{UndefFn} = "FRM_IN_Undef"; - $hash->{AttrList} = "IODev count-mode:none,rising,falling,both count-threshold reset-on-threshold-reached:yes,no loglevel:0,1,2,3,4,5 $main::readingFnAttributes"; + $hash->{AttrList} = "IODev count-mode:none,rising,falling,both count-threshold reset-on-threshold-reached:yes,no internal-pullup:on,off loglevel:0,1,2,3,4,5 $main::readingFnAttributes"; } sub @@ -41,8 +41,14 @@ FRM_IN_Init($$) my ($hash,$args) = @_; my $ret = FRM_Init_Pin_Client($hash,$args,PIN_INPUT); return $ret if (defined $ret); - my $firmata = $hash->{IODev}->{FirmataDevice}; - $firmata->observe_digital($hash->{PIN},\&FRM_IN_observer,$hash); + eval { + my $firmata = FRM_Client_FirmataDevice($hash); + $firmata->observe_digital($hash->{PIN},\&FRM_IN_observer,$hash); + if (defined (my $pullup = AttrVal($hash->{NAME},"internal-pullup",undef))) { + $firmata->digital_write($hash->{PIN},$pullup eq "on" ? 1 : 0); + } + }; + return $@ if (defined $@); if (! (defined AttrVal($hash->{NAME},"stateFormat",undef))) { $main::attr{$hash->{NAME}}{"stateFormat"} = "reading"; } @@ -162,6 +168,26 @@ FRM_IN_Attr($$$$) { } last; }; + $attribute eq "internal-pullup" and do { + eval { + my $hash = $main::defs{$name}; + my $firmata = FRM_Client_FirmataDevice($hash); + $firmata->digital_write($hash->{PIN},$value eq "on" ? 1 : 0); + }; + #ignore any errors here, the attribute-value will be applied next time FRM_IN_init() is called. + last; + }; + } + } elsif ($command eq "del") { + ARGUMENT_HANDLER: { + $attribute eq "internal-pullup" and do { + eval { + my $hash = $main::defs{$name}; + my $firmata = FRM_Client_FirmataDevice($hash); + $firmata->digital_write($hash->{PIN},0); + }; + last; + }; } } } @@ -222,7 +248,13 @@ FRM_IN_Undef($$) edges (or 'both') are counted. Defaults to 'none'
  • count-threshold <number>
    sets the theshold-value for the counter. Whenever 'count' reaches the 'count-threshold' 'alarm' is
    - set to 'on' and count is reset to 0. Use 'set alarm off' to clear the alarm.
  • + set to 'on'. Use 'set alarm off' to clear the alarm. +
  • reset-on-threshold-reached yes|no
    + if set to 'yes' reset the counter to 0 when the threshold is reached (defaults to 'no'). +
  • +
  • internal-pullup on|off
    + allows to switch the internal pullup resistor of arduino to be en-/disabled. Defaults to off. +
  • IODev
    Specify which FRM to use. (Optional, only required if there is more than one FRM-device defined.) diff --git a/fhem/FHEM/lib/Device/Firmata/Platform.pm b/fhem/FHEM/lib/Device/Firmata/Platform.pm index 82c2ee468..0f0e0c852 100644 --- a/fhem/FHEM/lib/Device/Firmata/Platform.pm +++ b/fhem/FHEM/lib/Device/Firmata/Platform.pm @@ -406,7 +406,7 @@ sub pin_mode { # -------------------------------------------------- my ( $self, $pin, $mode ) = @_; - return undef unless $self->is_supported_mode($pin,$mode); + die "unsupported mode '".$mode."' for pin '".$pin."'" unless $self->is_supported_mode($pin,$mode); PIN_MODE_HANDLER: { @@ -441,7 +441,7 @@ sub digital_write { # -------------------------------------------------- my ( $self, $pin, $state ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_OUTPUT); + die "pin '".$pin."' is not configured for mode 'INPUT' or 'OUTPUT'" unless ($self->is_configured_mode($pin,PIN_OUTPUT) or $self->is_configured_mode($pin,PIN_INPUT)); my $port_number = $pin >> 3; my $pin_offset = $pin % 8; @@ -455,7 +455,7 @@ sub digital_write { $port_state &= $pin_mask ^ 0xff; } $self->{ports}[$port_number] = $port_state; - $self->{io}->data_write($self->{protocol}->message_prepare( DIGITAL_MESSAGE => $port_number, $port_state )); + $self->{io}->data_write($self->{protocol}->message_prepare( DIGITAL_MESSAGE => $port_number, $port_state & 0x7f, $port_state >> 7 )); return 1; } @@ -470,7 +470,7 @@ sub digital_read { # -------------------------------------------------- my ( $self, $pin ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_INPUT); + die "pin '".$pin."' is not configured for mode 'INPUT'" unless $self->is_configured_mode($pin,PIN_INPUT); my $port_number = $pin >> 3; my $pin_offset = $pin % 8; my $pin_mask = 1 << $pin_offset; @@ -489,7 +489,7 @@ sub analog_read { # -------------------------------------------------- # my ( $self, $pin ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_ANALOG); + die "pin '".$pin."' is not configured for mode 'ANALOG'" unless $self->is_configured_mode($pin,PIN_ANALOG); return $self->{analog_pins}[$pin]; } @@ -503,7 +503,7 @@ sub analog_write { # Sets the PWM value on an arduino # my ( $self, $pin, $value ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_PWM); + die "pin '".$pin."' is not configured for mode 'PWM'" unless $self->is_configured_mode($pin,PIN_PWM); # FIXME: 8 -> 7 bit translation should be done in the protocol module my $byte_0 = $value & 0x7f; @@ -584,7 +584,7 @@ sub servo_write { # Sets the SERVO value on an arduino # my ( $self, $pin, $value ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_SERVO); + die "pin '".$pin."' is not configured for mode 'SERVO'" unless $self->is_configured_mode($pin,PIN_SERVO); # FIXME: 8 -> 7 bit translation should be done in the protocol module my $byte_0 = $value & 0x7f; @@ -594,7 +594,7 @@ sub servo_write { sub servo_config { my ( $self, $pin, $args ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_SERVO); + die "pin '".$pin."' is not configured for mode 'SERVO'" unless $self->is_configured_mode($pin,PIN_SERVO); return $self->{io}->data_write($self->{protocol}->packet_servo_config_request($pin,$args)); } @@ -712,19 +712,19 @@ sub scheduler_query_task { sub onewire_search { my ( $self, $pin ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_ONEWIRE); + die "pin '".$pin."' is not configured for mode 'ONEWIRE'" unless $self->is_configured_mode($pin,PIN_ONEWIRE); return $self->{io}->data_write($self->{protocol}->packet_onewire_search_request( $pin )); } sub onewire_search_alarms { my ( $self, $pin ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_ONEWIRE); + die "pin '".$pin."' is not configured for mode 'ONEWIRE'" unless $self->is_configured_mode($pin,PIN_ONEWIRE); return $self->{io}->data_write($self->{protocol}->packet_onewire_search_alarms_request( $pin )); } sub onewire_config { my ( $self, $pin, $power ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_ONEWIRE); + die "pin '".$pin."' is not configured for mode 'ONEWIRE'" unless $self->is_configured_mode($pin,PIN_ONEWIRE); return $self->{io}->data_write($self->{protocol}->packet_onewire_config_request( $pin, $power )); } @@ -755,7 +755,7 @@ sub onewire_write { sub onewire_command_series { my ( $self, $pin, $args ) = @_; - return undef unless $self->is_configured_mode($pin,PIN_ONEWIRE); + die "pin '".$pin."' is not configured for mode 'ONEWIRE'" unless $self->is_configured_mode($pin,PIN_ONEWIRE); return $self->{io}->data_write($self->{protocol}->packet_onewire_request( $pin, $args )); } @@ -779,7 +779,7 @@ sub poll { sub observe_digital { my ( $self, $pin, $observer, $context ) = @_; - return undef unless ($self->is_supported_mode($pin,PIN_INPUT)); + die "unsupported mode 'INPUT' for pin '".$pin."'" unless ($self->is_supported_mode($pin,PIN_INPUT)); $self->{digital_observer}[$pin] = { method => $observer, context => $context, @@ -789,7 +789,7 @@ sub observe_digital { sub observe_analog { my ( $self, $pin, $observer, $context ) = @_; - return undef unless ($self->is_supported_mode($pin,PIN_ANALOG)); + die "unsupported mode 'ANALOG' for pin '".$pin."'" unless ($self->is_supported_mode($pin,PIN_ANALOG)); $self->{analog_observer}[$pin] = { method => $observer, context => $context, @@ -818,7 +818,7 @@ sub observe_i2c { sub observe_onewire { my ( $self, $pin, $observer, $context ) = @_; - return undef unless ($self->is_supported_mode($pin,PIN_ONEWIRE)); + die "unsupported mode 'ONEWIRE' for pin '".$pin."'" unless ($self->is_supported_mode($pin,PIN_ONEWIRE)); $self->{onewire_observer}[$pin] = { method => $observer, context => $context, @@ -846,13 +846,13 @@ sub observe_string { sub is_supported_mode { my ($self,$pin,$mode) = @_; - die "unsupported mode '".$mode."' for pin '".$pin."'" if (defined $self->{metadata}->{capabilities} and (!(defined $self->{metadata}->{capabilities}->{$pin}) or !(defined $self->{metadata}->{capabilities}->{$pin}->{$mode}))); + return undef if (defined $self->{metadata}->{capabilities} and (!(defined $self->{metadata}->{capabilities}->{$pin}) or !(defined $self->{metadata}->{capabilities}->{$pin}->{$mode}))); return 1; } - + sub is_configured_mode { my ($self,$pin,$mode) = @_; - die "pin '".$pin."' is not configured for mode '".$mode."'" if (!defined $self->{pin_modes}->{$pin} or $self->{pin_modes}->{$pin} != $mode); + return undef if (!defined $self->{pin_modes}->{$pin} or $self->{pin_modes}->{$pin} != $mode); return 1; }