2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

new module FRM_STEPPER

git-svn-id: https://svn.fhem.de/fhem/trunk@5128 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
ntruchsess 2014-03-04 17:59:05 +00:00
parent 6dddd99102
commit 2d86b5e030
8 changed files with 451 additions and 24 deletions

View File

@ -325,6 +325,8 @@ sub FRM_DoInit($) {
$main::defs{$name}{onewire_pins} = join(",", sort{$a<=>$b}(@$onewirepins)) if (defined $onewirepins and scalar @$onewirepins);
my $encoderpins = $device->{metadata}{encoder_pins};
$main::defs{$name}{encoder_pins} = join(",", sort{$a<=>$b}(@$encoderpins)) if (defined $encoderpins and scalar @$encoderpins);
my $stepperpins = $device->{metadata}{stepper_pins};
$main::defs{$name}{stepper_pins} = join(",", sort{$a<=>$b}(@$stepperpins)) if (defined $stepperpins and scalar @$stepperpins);
if (defined $device->{metadata}{analog_resolutions}) {
my @analog_resolutions;
foreach my $pin (sort{$a<=>$b}(keys %{$device->{metadata}{analog_resolutions}})) {
@ -353,6 +355,13 @@ sub FRM_DoInit($) {
}
$main::defs{$name}{encoder_resolutions} = join(",",@encoder_resolutions) if (scalar @encoder_resolutions);
}
if (defined $device->{metadata}{stepper_resolutions}) {
my @stepper_resolutions;
foreach my $pin (sort{$a<=>$b}(keys %{$device->{metadata}{stepper_resolutions}})) {
push @stepper_resolutions,$pin.":".$device->{metadata}{stepper_resolutions}{$pin};
}
$main::defs{$name}{stepper_resolutions} = join(",",@stepper_resolutions) if (scalar @stepper_resolutions);
}
$found = 1;
} else {
select (undef,undef,undef,0.01);

View File

@ -79,11 +79,11 @@ FRM_ROTENC_Init($$)
sub
FRM_ROTENC_observer
{
my ( $data, $hash ) = @_;
my ( $encoder, $value, $hash ) = @_;
my $name = $hash->{NAME};
Log3 $name,5,"onEncoderMessage for pins ".$hash->{PINA}.",".$hash->{PINB}." encoder: ".$data->{encoderNum}." position: ".$data->{value}."\n";
Log3 $name,5,"onEncoderMessage for pins ".$hash->{PINA}.",".$hash->{PINB}." encoder: ".$encoder." position: ".$value."\n";
main::readingsBeginUpdate($hash);
main::readingsBulkUpdate($hash,"position",$data->{value}, 1);
main::readingsBulkUpdate($hash,"position",$value, 1);
main::readingsEndUpdate($hash,1);
}

325
fhem/FHEM/20_FRM_STEPPER.pm Executable file
View File

@ -0,0 +1,325 @@
#############################################
package main;
use strict;
use warnings;
#add FHEM/lib to @INC if it's not allready included. Should rather be in fhem.pl than here though...
BEGIN {
if (!grep(/FHEM\/lib$/,@INC)) {
foreach my $inc (grep(/FHEM$/,@INC)) {
push @INC,$inc."/lib";
};
};
};
use Device::Firmata::Constants qw/ :all /;
#####################################
my %sets = (
"reset" => "noArg",
"position" => "",
"step" => "",
);
my %gets = (
"position" => "noArg",
);
sub
FRM_STEPPER_Initialize($)
{
my ($hash) = @_;
$hash->{SetFn} = "FRM_STEPPER_Set";
$hash->{GetFn} = "FRM_STEPPER_Get";
$hash->{DefFn} = "FRM_Client_Define";
$hash->{InitFn} = "FRM_STEPPER_Init";
$hash->{UndefFn} = "FRM_Client_Undef";
$hash->{AttrFn} = "FRM_STEPPER_Attr";
$hash->{StateFn} = "FRM_STEPPER_State";
$hash->{AttrList} = "restoreOnReconnect:on,off restoreOnStartup:on,off speed acceleration deceleration IODev $main::readingFnAttributes";
main::LoadModule("FRM");
}
sub
FRM_STEPPER_Init($$)
{
my ($hash,$args) = @_;
my $u = "wrong syntax: define <name> FRM_STEPPER [DRIVER|TWO_WIRE|FOUR_WIRE] directionPin stepPin [motorPin3 motorPin4] stepsPerRev [id]";
return $u unless defined $args;
my $driver = shift @$args;
return $u unless ( $driver eq 'DRIVER' or $driver eq 'TWO_WIRE' or $driver eq 'FOUR_WIRE' );
return $u if (($driver eq 'DRIVER' or $driver eq 'TWO_WIRE') and (scalar(@$args) < 3 or scalar(@$args) > 4));
return $u if (($driver eq 'FOUR_WIRE') and (scalar(@$args) < 5 or scalar(@$args) > 6));
$hash->{DRIVER} = $driver;
$hash->{PIN1} = shift @$args;
$hash->{PIN2} = shift @$args;
if ($driver eq 'FOUR_WIRE') {
$hash->{PIN3} = shift @$args;
$hash->{PIN4} = shift @$args;
}
$hash->{STEPSPERREV} = shift @$args;
$hash->{STEPPERNUM} = shift @$args;
eval {
FRM_Client_AssignIOPort($hash);
my $firmata = FRM_Client_FirmataDevice($hash);
$firmata->stepper_config(
$hash->{STEPPERNUM},
$driver,
$hash->{STEPSPERREV},
$hash->{PIN1},
$hash->{PIN2},
$hash->{PIN3},
$hash->{PIN4});
$firmata->observe_stepper(0, \&FRM_STEPPER_observer, $hash );
};
if ($@) {
$@ =~ /^(.*)( at.*FHEM.*)$/;
$hash->{STATE} = "error initializing: ".$1;
return "error initializing '".$hash->{NAME}."': ".$1;
}
$hash->{POSITION} = 0;
$hash->{DIRECTION} = 0;
$hash->{STEPS} = 0;
if (! (defined AttrVal($hash->{NAME},"stateFormat",undef))) {
$main::attr{$hash->{NAME}}{"stateFormat"} = "position";
}
main::readingsSingleUpdate($hash,"state","Initialized",1);
return undef;
}
sub
FRM_STEPPER_observer
{
my ( $stepper, $hash ) = @_;
my $name = $hash->{NAME};
Log3 $name,5,"onStepperMessage for pins ".$hash->{PIN1}.",".$hash->{PIN2}.(defined ($hash->{PIN3}) ? ",".$hash->{PIN3} : ",-").(defined ($hash->{PIN4}) ? ",".$hash->{PIN4} : ",-")." stepper: ".$stepper;
my $position = $hash->{DIRECTION} ? $hash->{POSITION} - $hash->{STEPS} : $hash->{POSITION} + $hash->{STEPS};
$hash->{POSITION} = $position;
$hash->{DIRECTION} = 0;
$hash->{STEPS} = 0;
main::readingsSingleUpdate($hash,"position",$position,1);
}
sub
FRM_STEPPER_Set
{
my ($hash, @a) = @_;
return "Need at least one parameters" if(@a < 2);
shift @a;
my $name = $hash->{NAME};
my $command = shift @a;
if(!defined($sets{$command})) {
my @commands = ();
foreach my $key (sort keys %sets) {
push @commands, $sets{$key} ? $key.":".join(",",$sets{$key}) : $key;
}
return "Unknown argument $command, choose one of " . join(" ", @commands);
}
COMMAND_HANDLER: {
$command eq "reset" and do {
$hash->{POSITION} = 0;
main::readingsSingleUpdate($hash,"position",0,1);
last;
};
$command eq "position" and do {
my $position = $hash->{POSITION};
my $value = shift @a;
my $direction = $value < $position ? 1 : 0;
my $steps = $direction ? $position - $value : $value - $position;
my $speed = shift @a;
$speed = AttrVal($name,"speed",30) unless (defined $speed);
my $accel = shift @a;
$accel = AttrVal($name,"acceleration",undef) unless (defined $accel);
my $decel = shift @a;
$decel = AttrVal($name,"deceleration",undef) unless (defined $decel);
$hash->{DIRECTION} = $direction;
$hash->{STEPS} = $steps;
eval {
# $stepperNum, $direction, $numSteps, $stepSpeed, $accel, $decel
FRM_Client_FirmataDevice($hash)->stepper_step($hash->{STEPPERNUM},$direction,$steps,$speed,$accel,$decel);
};
last;
};
$command eq "step" and do {
my $value = shift @a;
my $direction = $value < 0 ? 1 : 0;
my $steps = abs $value;
my $speed = shift @a;
$speed = AttrVal($name,"speed",100) unless (defined $speed);
my $accel = shift @a;
$accel = AttrVal($name,"acceleration",undef) unless (defined $accel);
my $decel = shift @a;
$decel = AttrVal($name,"deceleration",undef) unless (defined $decel);
$hash->{DIRECTION} = $direction;
$hash->{STEPS} = $steps;
eval {
# $stepperNum, $direction, $numSteps, $stepSpeed, $accel, $decel
FRM_Client_FirmataDevice($hash)->stepper_step($hash->{STEPPERNUM},$direction,$steps,$speed,$accel,$decel);
};
last;
};
}
}
sub
FRM_STEPPER_Get
{
my ($hash, @a) = @_;
return "Need at least one parameters" if(@a < 2);
shift @a;
my $name = $hash->{NAME};
my $command = shift @a;
return "Unknown argument $command, choose one of " . join(" ", sort keys %gets) unless defined($gets{$command});
}
sub FRM_STEPPER_State($$$$)
{
my ($hash, $tim, $sname, $sval) = @_;
STATEHANDLER: {
$sname eq "value" and do {
if (AttrVal($hash->{NAME},"restoreOnStartup","on") eq "on") {
FRM_STEPPER_Set($hash,$hash->{NAME},$sval);
}
last;
}
}
}
sub
FRM_STEPPER_Attr($$$$) {
my ($command,$name,$attribute,$value) = @_;
if ($command eq "set") {
ARGUMENT_HANDLER: {
$attribute eq "IODev" and do {
my $hash = $main::defs{$name};
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) {
$hash->{IODev} = $defs{$value};
FRM_Init_Client($hash) if (defined ($hash->{IODev}));
}
last;
};
$main::attr{$name}{$attribute}=$value;
}
}
}
1;
=pod
=begin html
<a name="FRM_STEPPER"></a>
<h3>FRM_STEPPER</h3>
<ul>
represents a stepper-motor attached to digital-i/o pins of an <a href="http://www.arduino.cc">Arduino</a> running <a href="http://www.firmata.org">Firmata</a><br>
Requires a defined <a href="#FRM">FRM</a>-device to work.<br><br>
<a name="FRM_STEPPERdefine"></a>
<b>Define</b>
<ul>
<code>define &lt;name&gt; FRM_STEPPER [DRIVER|TWO_WIRE|FOUR_WIRE] &lt;directionPin&gt &lt;stepPin&gt [motorPin3 motorPin4] stepsPerRev [stepper-id]</code><br>
Defines the FRM_STEPPER device.
<li>[DRIVER|TWO_WIRE|FOUR_WIRE] defines the control-sequence being used to drive the motor.
<ul>
<li>DRIVER: motor is attached via a smart circuit that is controlled via two lines: 1 line defines the direction to turn, the other triggers one step per impluse.</li>
<li>FOUR_WIRE: motor is attached via four wires each driving one coil individually.</li>
<li>TWO_WIRE: motor is attached via two wires. This mode makes use of the fact that at any time two of the four motor
coils are the inverse of the other two so by using an inverting circuit to drive the motor the number of control connections can be reduced from 4 to 2.</li>
</ul>
</li>
<li>
<ul>
<li>The sequence of control signals for 4 control wires is as follows:<br>
<br>
<code>
Step C0 C1 C2 C3<br>
1 1 0 1 0<br>
2 0 1 1 0<br>
3 0 1 0 1<br>
4 1 0 0 1<br>
</code>
</li>
<li>The sequence of controls signals for 2 control wires is as follows:<br>
(columns C1 and C2 from above):<br>
<br>
<code>
Step C0 C1<br>
1 0 1<br>
2 1 1<br>
3 1 0<br>
4 0 0<br>
</code>
</li>
</ul>
</li>
<li>
If your stepper-motor does not move or does move but only in a single direction you will have to rearrage the pin-numbers to match the control sequence.<br>
that can be archived either by rearranging the physical connections, or by mapping the connection to the pin-definitions in FRM_STEPPERS define:<br>
e.g. the widely used cheap 28byj-48 you can get for few EUR on eBay including a simple ULN2003 driver interface may be defined by<br>
<code>define stepper FRM_STEPPER FOUR_WIRE 7 5 6 8 64 0</code><br>
when being connected to the arduio with:<br>
<code>motor pin1 <-> arduino pin5<br>
motor pin2 <-> arduino pin6<br>
motor pin3 <-> arduino pin7<br>
motor pin4 <-> arduino pin8<br>
motor pin5 <-> ground</code><br>
</li>
</ul>
<br>
<a name="FRM_STEPPERset"></a>
<b>Set</b><br>
<ul>
<code>set &lt;name&gt; reset</code>
<li>resets the reading 'position' to 0 without moving the motor</li>
<br>
<code>set &lt;name&gt; position &lt;position&gt; [speed] [acceleration] [deceleration]</code>
<li>moves the motor to the absolute position specified. positive or negative integer<br>
speed (10 * revolutions per minute, optional), defaults to 30, higher numbers are faster) At 2048 steps per revolution (28byj-48) a speed of 30 results in 3 rev/min<br>
acceleration and deceleration are optional.<br>
</li>
<br>
<code>set &lt;name&gt; step &lt;stepstomove&gt; [speed] [accel] [decel]</code>
<li>moves the motor the number of steps specified. positive or negative integer<br>
speed, accelleration and deceleration are optional.<br>
</li>
</ul>
<a name="FRM_STEPPERget"></a>
<b>Get</b><br>
<ul>
N/A
</ul><br>
<a name="FRM_STEPPERattr"></a>
<b>Attributes</b><br>
<ul>
<li>restoreOnStartup &lt;on|off&gt;</li>
<li>restoreOnReconnect &lt;on|off&gt;</li>
<li><a href="#IODev">IODev</a><br>
Specify which <a href="#FRM">FRM</a> to use. (Optional, only required if there is more
than one FRM-device defined.)
</li>
<li>>speed (same meaning as in 'set position')</li>
<li>acceleration (same meaning as in 'set position')</li>
<li>deceleration (same meaning as in 'set position')</li>
<li><a href="#eventMap">eventMap</a><br></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a><br></li>
</ul>
</ul>
<br>
=end html
=cut

View File

@ -19,7 +19,7 @@ Version 0.50
=cut
our $VERSION = '0.53';
our $VERSION = '0.54';
our $DEBUG = 0;

View File

@ -214,6 +214,7 @@ use constant (
EXTENDED_ANALOG => 0x6F, # analog write (PWM, Servo, etc) to any pin
SERVO_CONFIG => 0x70, # set max angle, minPulse, maxPulse, freq
STRING_DATA => 0x71, # a string message with 14-bits per char
STEPPER_DATA => 0x72, # control a stepper motor
ONEWIRE_DATA => 0x73, # OneWire read/write/reset/select/skip/search request + read/search reply
SHIFT_DATA => 0x75, # shiftOut config/data message (34 bits)
I2C_REQUEST => 0x76, # send an I2C read/write request
@ -233,7 +234,8 @@ use constant (
SERVO => 0x04, # digital pin in Servo output mode
SHIFT => 0x05, # shiftIn/shiftOut mode
I2C => 0x06, # pin included in I2C setup
ONEWIRE => 0x07,
ONEWIRE => 0x07, # pin configured for 1-Wire commuication
STEPPER => 0x08, # pin configured for stepper motor
# Deprecated entries
deprecated => [
@ -267,6 +269,7 @@ use constant (
EXTENDED_ANALOG => 0x6F, # analog write (PWM, Servo, etc) to any pin
SERVO_CONFIG => 0x70, # set max angle, minPulse, maxPulse, freq
STRING_DATA => 0x71, # a string message with 14-bits per char
STEPPER_DATA => 0x72, # control a stepper motor
ONEWIRE_DATA => 0x73, # OneWire read/write/reset/select/skip/search request + read/search reply
SHIFT_DATA => 0x75, # shiftOut config/data message (34 bits)
I2C_REQUEST => 0x76, # send an I2C read/write request
@ -286,8 +289,8 @@ use constant (
SERVO => 0x04, # digital pin in Servo output mode
SHIFT => 0x05, # shiftIn/shiftOut mode
I2C => 0x06, # pin included in I2C setup
ONEWIRE => 0x07,
ONEWIRE => 0x07, # pin configured for 1-Wire commuication
STEPPER => 0x08, # pin configured for stepper motor
# Deprecated entries
deprecated => [
qw( FIRMATA_STRING SYSEX_I2C_REQUEST SYSEX_I2C_REPLY SYSEX_SAMPLING_INTERVAL )

View File

@ -28,6 +28,8 @@ use Device::Firmata::Base
analog_resolutions => {},
pwm_resolutions => {},
servo_resolutions => {},
stepper_resolutions => {},
encoder_resolutions => {},
ports => [],
pins => {},
pin_modes => {},
@ -87,6 +89,8 @@ sub detach {
$self->{sysex_observer} = undef;
$self->{i2c_observer} = undef;
$self->{onewire_observer} = [];
$self->{stepper_observer} = [];
$self->{encoder_observer} = [];
$self->{scheduler_observer} = undef;
$self->{tasks} = [];
$self->{metadata} = {};
@ -111,6 +115,8 @@ sub system_reset {
$self->{sysex_observer} = undef;
$self->{i2c_observer} = undef;
$self->{onewire_observer} = [];
$self->{stepper_observer} = [];
$self->{encoder_observer} = [];
$self->{scheduler_observer} = undef;
$self->{tasks} = [];
$self->{metadata} = {};
@ -279,9 +285,11 @@ sub sysex_handle {
}
if ($capabilities->{$pin}->{PIN_STEPPER+0}) {
push @stepperpins, $pin;
$self->{metadata}{stepper_resolutions}{$pin} = $capabilities->{$pin}->{PIN_STEPPER+0}->{resolution};
}
if ($capabilities->{$pin}->{PIN_ENCODER+0}) {
push @encoderpins, $pin;
$self->{metadata}{encoder_resolutions}{$pin} = $capabilities->{$pin}->{PIN_ENCODER+0}->{resolution};
}
}
}
@ -349,7 +357,11 @@ sub sysex_handle {
};
$sysex_message->{command_str} eq 'STEPPER_DATA' and do {
#TODO implement handling of STEPPER_DATA and call observer.
my $stepperNum = $data->{stepperNum};
my $observer = $self->{stepper_observer}[$stepperNum];
if (defined $observer) {
$observer->{method}( $stepperNum, $observer->{context} );
};
last;
};
@ -358,7 +370,7 @@ sub sysex_handle {
my $encoderNum = $encoder_data->{encoderNum};
my $observer = $self->{encoder_observer}[$encoderNum];
if (defined $observer) {
$observer->{method}( $encoder_data, $observer->{context} );
$observer->{method}( $encoderNum, $encoder_data->{value}, $observer->{context} );
}
};
last;
@ -769,6 +781,20 @@ sub onewire_command_series {
return $self->{io}->data_write($self->{protocol}->packet_onewire_request( $pin, $args ));
}
sub stepper_config {
my ( $self, $stepperNum, $interface, $stepsPerRev, $directionPin, $stepPin, $motorPin3, $motorPin4 ) = @_;
die "unsupported mode 'STEPPER' for pin '".$directionPin."'" unless $self->is_supported_mode($directionPin,PIN_STEPPER);
die "unsupported mode 'STEPPER' for pin '".$stepPin."'" unless $self->is_supported_mode($stepPin,PIN_STEPPER);
die "unsupported mode 'STEPPER' for pin '".$motorPin3."'" unless (!(defined $motorPin3) or $self->is_supported_mode($motorPin3,PIN_STEPPER));
die "unsupported mode 'STEPPER' for pin '".$motorPin4."'" unless (!(defined $motorPin4) or $self->is_supported_mode($motorPin4,PIN_STEPPER));
return $self->{io}->data_write($self->{protocol}->packet_stepper_config( $stepperNum, $interface, $stepsPerRev, $directionPin, $stepPin, $motorPin3, $motorPin4 ));
}
sub stepper_step {
my ( $self, $stepperNum, $direction, $numSteps, $stepSpeed, $accel, $decel ) = @_;
return $self->{io}->data_write($self->{protocol}->packet_stepper_step( $stepperNum, $direction, $numSteps, $stepSpeed, $accel, $decel ));
}
sub encoder_attach {
my ( $self, $encoderNum, $pinA, $pinB ) = @_;
die "unsupported mode 'ENCODER' for pin '".$pinA."'" unless $self->is_supported_mode($pinA,PIN_ENCODER);
@ -872,7 +898,12 @@ sub observe_onewire {
}
sub observe_stepper {
#TODO implement observe_stepper
my ( $self, $stepperNum, $observer, $context ) = @_;
#TODO validation? die "unsupported mode 'STEPPER' for pin '".$pin."'" unless ($self->is_supported_mode($pin,PIN_STEPPER));
$self->{stepper_observer}[$stepperNum] = {
method => $observer,
context => $context,
};
return 1;
}

View File

@ -78,6 +78,12 @@ our $STEPPER_COMMANDS = {
STEPPER_STEP => 1,
};
our $STEPPER_INTERFACES = {
DRIVER => 1,
TWO_WIRE => 2,
FOUR_WIRE => 4,
};
our $ENCODER_COMMANDS = {
ENCODER_ATTACH => 0,
ENCODER_REPORT_POSITION => 1,
@ -307,7 +313,7 @@ sub sysex_parse {
};
$command == $protocol_commands->{STEPPER_DATA} and do {
#TODO implement and call handle_stepper_response
$return_data = $self->handle_stepper_response($sysex_data);
last;
};
@ -867,18 +873,68 @@ sub handle_scheduler_response {
}
}
#TODO packet_stepper_config
# stepper_data 0
# stepper_config 1
# devicenum 2 (0 < devicenum < 6)
# interface (DRIVER | TWO_WIRE | FOUR_WIRE) 3
# stepsPerRev 4+5 (14bit)
# directionPin 6
# stepPin 7
# motorPin3 8 (interface FOUR_WIRE only)
# motorPin4 9 (interface FOUR_WIRE only)
sub packet_stepper_config {
my ( $self ) = @_;
my $packet = $self->packet_sysex_command('STEPPER_DATA', $STEPPER_COMMANDS->{STEPPER_CONFIG});
my ( $self, $stepperNum, $interface, $stepsPerRev, $directionPin, $stepPin, $motorPin3, $motorPin4 ) = @_;
die "invalid stepper interface ".$interface unless defined ($STEPPER_INTERFACES->{$interface});
my @configdata = ($stepperNum,$STEPPER_INTERFACES->{$interface});
push_value_as_two_7bit($stepsPerRev, \@configdata);
push @configdata, $directionPin;
push @configdata, $stepPin;
if ($interface eq 'FOUR_WIRE') {
push @configdata, $motorPin3;
push @configdata, $motorPin4;
}
my $packet = $self->packet_sysex_command('STEPPER_DATA',$STEPPER_COMMANDS->{STEPPER_CONFIG},@configdata);
return $packet;
}
#TODO packet_stepper_step
# stepper_data 0
# stepper_step 1
# devicenum 2
# stepDirection 3 0/>0
# numSteps 4,5,6 (21bit)
# stepSpeed 7,8 (14bit)
# accel 9,10 (14bit, optional, aber nur zusammen mit decel)
# decel 11,12 (14bit, optional, aber nur zusammen mit accel)
sub packet_stepper_step {
my ( $self ) = @_;
my $packet = $self->packet_sysex_command('STEPPER_DATA', $STEPPER_COMMANDS->{STEPPER_STEP});
my ( $self, $stepperNum, $direction, $numSteps, $stepSpeed, $accel, $decel ) = @_;
my @stepdata = ($stepperNum, $direction);
push @stepdata, $numSteps & 0x7f;
push @stepdata, ($numSteps >> 7) & 0x7f;
push @stepdata, ($numSteps >> 14) & 0x7f;
push_value_as_two_7bit($stepSpeed, \@stepdata);
if (defined $accel and defined $decel) {
push_value_as_two_7bit($accel, \@stepdata);
push_value_as_two_7bit($decel, \@stepdata);
}
my $packet = $self->packet_sysex_command('STEPPER_DATA', $STEPPER_COMMANDS->{STEPPER_STEP},@stepdata);
return $packet;
}
sub handle_stepper_response {
my ( $self, $sysex_data ) = @_;
my $stepperNum = shift @$sysex_data;
return {
stepperNum => $stepperNum,
};
}
sub packet_encoder_attach {
my ( $self,$encoderNum, $pinA, $pinB ) = @_;
my $packet = $self->packet_sysex_command('ENCODER_DATA', $ENCODER_COMMANDS->{ENCODER_ATTACH}, $encoderNum, $pinA, $pinB);
@ -904,7 +960,7 @@ sub packet_encoder_reset_position {
}
sub packet_encoder_report_auto {
my ( $self,$arg ) = @_; #TODO clarify encoder_report_auto $arg
my ( $self,$arg ) = @_;
my $packet = $self->packet_sysex_command('ENCODER_DATA', $ENCODER_COMMANDS->{ENCODER_REPORT_AUTO}, $arg);
return $packet;
}

View File

@ -61,12 +61,15 @@ FHEM/17_SIS_PMS.pm painseeker http://forum.fhem.de Sonstiges
FHEM/18_CUL_HOERMANN.pm rudolfkoenig http://forum.fhem.de SlowRF
FHEM/19_Revolt.pm martinppp/mehf http://forum.fhem.de SlowRF
FHEM/20_FRM_AD.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_FRM_ROTENC.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_FRM_I2C.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_FRM_IN.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_FRM_LCD.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_FRM_OUT.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_FRM_PWM.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_FRM_RBG.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_FRM_SERVO.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_FRM_STEPPER.pm ntruchsess http://forum.fhem.de Sonstiges
FHEM/20_OWFS.pm mfr69bs http://forum.fhem.de 1Wire (deprecated)
FHEM/20_X10.pm borisneubert http://forum.fhem.de SlowRF
FHEM/20_ROOMMATE.pm loredo http://forum.fhem.de Automatisierung
@ -149,7 +152,7 @@ FHEM/70_USBWX.pm wherzig http://forum.fhem.de Sonstiges
FHEM/70_VIERA.pm teevau http://forum.fhem.de Sonstiges
FHEM/70_WS3600.pm Josch http://forum.fhem.de Sonstiges
FHEM/70_XBMC.pm dennisb http://forum.fhem.de Multimedia
FHEM/70_Pushover.pm Johannes_B http://forum.fhem.de Unterstützende Dienste
FHEM/70_Pushover.pm Johannes_B http://forum.fhem.de Unterst<EFBFBD>tzende Dienste
FHEM/71_LISTENLIVE.pm betateilchen http://forum.fhem.de Multimedia
FHEM/71_YAMAHA_AVR.pm markusbloch http://forum.fhem.de Multimedia
FHEM/71_YAMAHA_BD.pm markusbloch http://forum.fhem.de Multimedia
@ -197,7 +200,7 @@ FHEM/98_RandomTimer.pm dietmar63 http://forum.fhem.de Unterstue
FHEM/98_SVG.pm rudolfkoenig http://forum.fhem.de Frontends
FHEM/98_THRESHOLD.pm damian-s http://forum.fhem.de Automatisierung
FHEM/98_WeekdayTimer.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
FHEM/98_WOL.pm dietmar63 http://forum.fhem.de Unterstützende Dienste
FHEM/98_WOL.pm dietmar63 http://forum.fhem.de Unterst<EFBFBD>tzende Dienste
FHEM/98_XmlList.pm rudolfkoenig http://forum.fhem.de Automatisierung
FHEM/98_autocreate.pm rudolfkoenig http://forum.fhem.de Automatisierung
FHEM/98_average.pm rudolfkoenig http://forum.fhem.de Automatisierung