mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-06 18:28:44 +00:00
FRM: new module FRM_ROTENC for rotary-encoders attached to arduino
git-svn-id: https://svn.fhem.de/fhem/trunk@5074 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
1d874e81b8
commit
5ac7bd694e
@ -323,6 +323,8 @@ sub FRM_DoInit($) {
|
||||
$main::defs{$name}{i2c_pins} = join(",", sort{$a<=>$b}(@$i2cpins)) if (defined $i2cpins and scalar @$i2cpins);
|
||||
my $onewirepins = $device->{metadata}{onewire_pins};
|
||||
$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);
|
||||
if (defined $device->{metadata}{analog_resolutions}) {
|
||||
my @analog_resolutions;
|
||||
foreach my $pin (sort{$a<=>$b}(keys %{$device->{metadata}{analog_resolutions}})) {
|
||||
@ -344,6 +346,13 @@ sub FRM_DoInit($) {
|
||||
}
|
||||
$main::defs{$name}{servo_resolutions} = join(",",@servo_resolutions) if (scalar @servo_resolutions);
|
||||
}
|
||||
if (defined $device->{metadata}{encoder_resolutions}) {
|
||||
my @encoder_resolutions;
|
||||
foreach my $pin (sort{$a<=>$b}(keys %{$device->{metadata}{encoder_resolutions}})) {
|
||||
push @encoder_resolutions,$pin.":".$device->{metadata}{encoder_resolutions}{$pin};
|
||||
}
|
||||
$main::defs{$name}{encoder_resolutions} = join(",",@encoder_resolutions) if (scalar @encoder_resolutions);
|
||||
}
|
||||
$found = 1;
|
||||
} else {
|
||||
select (undef,undef,undef,0.01);
|
||||
|
224
fhem/FHEM/20_FRM_ROTENC.pm
Executable file
224
fhem/FHEM/20_FRM_ROTENC.pm
Executable file
@ -0,0 +1,224 @@
|
||||
#############################################
|
||||
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",
|
||||
);
|
||||
|
||||
my %gets = (
|
||||
"position" => "noArg",
|
||||
);
|
||||
|
||||
sub
|
||||
FRM_ROTENC_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{SetFn} = "FRM_ROTENC_Set";
|
||||
$hash->{GetFn} = "FRM_ROTENC_Get";
|
||||
$hash->{AttrFn} = "FRM_ROTENC_Attr";
|
||||
$hash->{DefFn} = "FRM_Client_Define";
|
||||
$hash->{InitFn} = "FRM_ROTENC_Init";
|
||||
$hash->{UndefFn} = "FRM_ROTENC_Undef";
|
||||
|
||||
$hash->{AttrList} = "IODev $main::readingFnAttributes";
|
||||
main::LoadModule("FRM");
|
||||
}
|
||||
|
||||
sub
|
||||
FRM_ROTENC_Init($$)
|
||||
{
|
||||
my ($hash,$args) = @_;
|
||||
|
||||
my $u = "wrong syntax: define <name> FRM_ROTENC pinA pinB [id]";
|
||||
return $u unless defined $args and int(@$args) > 1;
|
||||
my $pinA = @$args[0];
|
||||
my $pinB = @$args[1];
|
||||
my $encoder = defined @$args[2] ? @$args[2] : 0;
|
||||
|
||||
$hash->{PINA} = $pinA;
|
||||
$hash->{PINB} = $pinB;
|
||||
|
||||
$hash->{ENCODERNUM} = $encoder;
|
||||
|
||||
eval {
|
||||
FRM_Client_AssignIOPort($hash);
|
||||
my $firmata = FRM_Client_FirmataDevice($hash);
|
||||
$firmata->encoder_attach($encoder,$pinA,$pinB);
|
||||
$firmata->observe_encoder($encoder, \&FRM_ROTENC_observer, $hash );
|
||||
};
|
||||
if ($@) {
|
||||
$@ =~ /^(.*)( at.*FHEM.*)$/;
|
||||
$hash->{STATE} = "error initializing: ".$1;
|
||||
return "error initializing '".$hash->{NAME}."': ".$1;
|
||||
}
|
||||
|
||||
if (! (defined AttrVal($hash->{NAME},"stateFormat",undef))) {
|
||||
$main::attr{$hash->{NAME}}{"stateFormat"} = "position";
|
||||
}
|
||||
main::readingsSingleUpdate($hash,"state","Initialized",1);
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub
|
||||
FRM_ROTENC_observer
|
||||
{
|
||||
my ( $data, $hash ) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
Log3 $name,5,"onEncoderMessage for pins ".$hash->{PINA}.",".$hash->{PINB}." encoder: ".$data->{encoderNum}." position: ".$data->{value}."\n";
|
||||
main::readingsBeginUpdate($hash);
|
||||
main::readingsBulkUpdate($hash,"position",$data->{value}, 1);
|
||||
main::readingsEndUpdate($hash,1);
|
||||
}
|
||||
|
||||
sub
|
||||
FRM_ROTENC_Set
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
return "Need at least one parameters" if(@a < 2);
|
||||
my $command = $a[1];
|
||||
my $value = $a[2];
|
||||
if(!defined($sets{$command})) {
|
||||
my @commands = ();
|
||||
foreach my $key (sort keys %sets) {
|
||||
push @commands, $sets{$key} ? $key.":".join(",",$sets{$key}) : $key;
|
||||
}
|
||||
return "Unknown argument $a[1], choose one of " . join(" ", @commands);
|
||||
}
|
||||
COMMAND_HANDLER: {
|
||||
$command eq "reset" and do {
|
||||
eval {
|
||||
FRM_Client_FirmataDevice($hash)->encoder_reset_position($hash->{ENCODERNUM});
|
||||
};
|
||||
last;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
sub
|
||||
FRM_ROTENC_Get($)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
return "Need at least one parameters" if(@a < 2);
|
||||
my $command = $a[1];
|
||||
my $value = $a[2];
|
||||
if(!defined($gets{$command})) {
|
||||
my @commands = ();
|
||||
foreach my $key (sort keys %gets) {
|
||||
push @commands, $gets{$key} ? $key.":".join(",",$gets{$key}) : $key;
|
||||
}
|
||||
return "Unknown argument $a[1], choose one of " . join(" ", @commands);
|
||||
}
|
||||
my $name = shift @a;
|
||||
my $cmd = shift @a;
|
||||
ARGUMENT_HANDLER: {
|
||||
$cmd eq "position" and do {
|
||||
return ReadingsVal($hash->{NAME},"position","0");
|
||||
};
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub
|
||||
FRM_ROTENC_Attr($$$$) {
|
||||
my ($command,$name,$attribute,$value) = @_;
|
||||
my $hash = $main::defs{$name};
|
||||
my $pin = $hash->{PIN};
|
||||
if ($command eq "set") {
|
||||
ARGUMENT_HANDLER: {
|
||||
$attribute eq "IODev" and do {
|
||||
if (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $value) {
|
||||
$hash->{IODev} = $defs{$value};
|
||||
FRM_Init_Client($hash) if (defined ($hash->{IODev}));
|
||||
}
|
||||
last;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub
|
||||
FRM_ROTENC_Undef($$)
|
||||
{
|
||||
my ($hash, $name) = @_;
|
||||
my $pinA = $hash->{PINA};
|
||||
my $pinB = $hash->{PINB};
|
||||
eval {
|
||||
my $firmata = FRM_Client_FirmataDevice($hash);
|
||||
$firmata->encoder_detach($hash->{ENCODERNUM});
|
||||
$firmata->pin_mode($pinA,PIN_ANALOG);
|
||||
$firmata->pin_mode($pinB,PIN_ANALOG);
|
||||
};
|
||||
if ($@) {
|
||||
eval {
|
||||
my $firmata = FRM_Client_FirmataDevice($hash);
|
||||
$firmata->pin_mode($pinA,PIN_INPUT);
|
||||
$firmata->digital_write($pinA,0);
|
||||
$firmata->pin_mode($pinB,PIN_INPUT);
|
||||
$firmata->digital_write($pinB,0);
|
||||
};
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
=begin html
|
||||
|
||||
<a name="FRM_ROTENC"></a>
|
||||
<h3>FRM_ROTENC</h3>
|
||||
<ul>
|
||||
represents a rotary-encoder attached to two 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_ROTENCdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> FRM_ROTENC <pinA> <pinB> [id]</code> <br>
|
||||
Defines the FRM_ROTENC device. <pinA>> and <pinA>> are the arduino-pins to use.<br>
|
||||
[id] is the instance-id of the encoder. Must be a unique number per FRM-device (rages from 0-4 depending on Firmata being used, optional if a single encoder is attached to the arduino).<br>
|
||||
</ul>
|
||||
|
||||
<br>
|
||||
<a name="FRM_ROTENCset"></a>
|
||||
<b>Set</b><br>
|
||||
<li>reset<br>
|
||||
resets to value of 'position' to 0<br></li>
|
||||
<a name="FRM_ROTENCget"></a>
|
||||
<b>Get</b>
|
||||
<ul>
|
||||
<li>position<br>
|
||||
returns the position of the rotary-encoder attached to pinA and pinB of the arduino<br></li>
|
||||
</ul><br>
|
||||
<a name="FRM_ROTENCattr"></a>
|
||||
<b>Attributes</b><br>
|
||||
<ul>
|
||||
<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><a href="#eventMap">eventMap</a><br></li>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a><br></li>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
=end html
|
||||
=cut
|
@ -19,7 +19,7 @@ Version 0.50
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = '0.52';
|
||||
our $VERSION = '0.53';
|
||||
our $DEBUG = 0;
|
||||
|
||||
|
||||
|
@ -28,6 +28,7 @@ use constant (
|
||||
PIN_I2C => 6,
|
||||
PIN_ONEWIRE => 7,
|
||||
PIN_STEPPER => 8,
|
||||
PIN_ENCODER => 9,
|
||||
PIN_LOW => 0,
|
||||
PIN_HIGH => 1,
|
||||
}
|
||||
@ -293,6 +294,65 @@ use constant (
|
||||
],
|
||||
|
||||
}, # /Constants for Version 2.5
|
||||
|
||||
V_2_06 => {
|
||||
|
||||
MAX_DATA_BYTES => 64, # max number of data bytes in non-Sysex messages
|
||||
|
||||
# message command bytes (128-255/0x80-0xFF)
|
||||
DIGITAL_MESSAGE => 0x90, # send data for a digital pin
|
||||
ANALOG_MESSAGE => 0xE0, # send data for an analog pin (or PWM)
|
||||
REPORT_ANALOG => 0xC0, # enable analog input by pin #
|
||||
REPORT_DIGITAL => 0xD0, # enable digital input by port pair
|
||||
SET_PIN_MODE => 0xF4, # set a pin to INPUT/OUTPUT/PWM/etc
|
||||
REPORT_VERSION => 0xF9, # report protocol version
|
||||
SYSTEM_RESET => 0xFF, # reset from MIDI
|
||||
START_SYSEX => 0xF0, # start a MIDI Sysex message
|
||||
END_SYSEX => 0xF7, # end a MIDI Sysex message
|
||||
|
||||
# extended command set using sysex (0-127/0x00-0x7F)
|
||||
RESERVED_COMMAND => 0x00, # 2nd SysEx data byte is a chip-specific command (AVR, PIC, TI, etc).
|
||||
ENCODER_DATA => 0x61, # receive rotary-encoders current positions
|
||||
ANALOG_MAPPING_QUERY => 0x69, # ask for mapping of analog to pin numbers
|
||||
ANALOG_MAPPING_RESPONSE => 0x6A, # reply with mapping info
|
||||
CAPABILITY_QUERY => 0x6B, # ask for supported modes and resolution of all pins
|
||||
CAPABILITY_RESPONSE => 0x6C, # reply with supported modes and resolution
|
||||
PIN_STATE_QUERY => 0x6D, # ask for a pin's current mode and value
|
||||
PIN_STATE_RESPONSE => 0x6E, # reply with a pin's current mode and value
|
||||
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
|
||||
I2C_REPLY => 0x77, # a reply to an I2C read request
|
||||
I2C_CONFIG => 0x78, # config I2C settings such as delay times and power pins
|
||||
REPORT_FIRMWARE => 0x79, # report name and version of the firmware
|
||||
SAMPLING_INTERVAL => 0x7A, # set the poll rate of the main loop
|
||||
SCHEDULER_DATA => 0x7B, # createtask/deletetask/addtotask/schedule/querytasks/querytask request and querytasks/querytask reply
|
||||
SYSEX_NON_REALTIME => 0x7E, # MIDI Reserved for non-realtime messages
|
||||
SYSEX_REALTIME => 0x7F, # MIDI Reserved for realtime messages
|
||||
|
||||
# pin modes
|
||||
INPUT => 0x00, # digital pin in digitalOut mode
|
||||
OUTPUT => 0x01, # digital pin in digitalInput mode
|
||||
ANALOG => 0x02, # analog pin in analogInput mode
|
||||
PWM => 0x03, # digital pin in PWM output mode
|
||||
SERVO => 0x04, # digital pin in Servo output mode
|
||||
SHIFT => 0x05, # shiftIn/shiftOut mode
|
||||
I2C => 0x06, # pin included in I2C setup
|
||||
ONEWIRE => 0x07, # pin configured for 1-Wire commuication
|
||||
STEPPER => 0x08, # pin configured for stepper motor
|
||||
ENCODER => 0x09, # pin configured for rotary-encoders
|
||||
|
||||
|
||||
# Deprecated entries
|
||||
deprecated => [
|
||||
qw( FIRMATA_STRING SYSEX_I2C_REQUEST SYSEX_I2C_REPLY SYSEX_SAMPLING_INTERVAL )
|
||||
],
|
||||
|
||||
}, # /Constants for Version 2.6
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -31,6 +31,7 @@ use Device::Firmata::Base
|
||||
ports => [],
|
||||
pins => {},
|
||||
pin_modes => {},
|
||||
encoders => [],
|
||||
|
||||
# To notify on events
|
||||
digital_observer => [],
|
||||
@ -38,6 +39,8 @@ use Device::Firmata::Base
|
||||
sysex_observer => undef,
|
||||
i2c_observer => undef,
|
||||
onewire_observer => [],
|
||||
stepper_observer => [],
|
||||
encoder_observer => [],
|
||||
scheduler_observer => undef,
|
||||
string_observer => undef,
|
||||
|
||||
@ -242,6 +245,9 @@ sub sysex_handle {
|
||||
my @shiftpins;
|
||||
my @i2cpins;
|
||||
my @onewirepins;
|
||||
my @stepperpins;
|
||||
my @encoderpins;
|
||||
|
||||
foreach my $pin (keys %$capabilities) {
|
||||
if (defined $capabilities->{$pin}) {
|
||||
if ($capabilities->{$pin}->{PIN_INPUT+0}) {
|
||||
@ -271,6 +277,12 @@ sub sysex_handle {
|
||||
if ($capabilities->{$pin}->{PIN_ONEWIRE+0}) {
|
||||
push @onewirepins, $pin;
|
||||
}
|
||||
if ($capabilities->{$pin}->{PIN_STEPPER+0}) {
|
||||
push @stepperpins, $pin;
|
||||
}
|
||||
if ($capabilities->{$pin}->{PIN_ENCODER+0}) {
|
||||
push @encoderpins, $pin;
|
||||
}
|
||||
}
|
||||
}
|
||||
$self->{metadata}{input_pins} = \@inputpins;
|
||||
@ -281,6 +293,8 @@ sub sysex_handle {
|
||||
$self->{metadata}{shift_pins} = \@shiftpins;
|
||||
$self->{metadata}{i2c_pins} = \@i2cpins;
|
||||
$self->{metadata}{onewire_pins} = \@onewirepins;
|
||||
$self->{metadata}{stepper_pins} = \@stepperpins;
|
||||
$self->{metadata}{encoder_pins} = \@encoderpins;
|
||||
last;
|
||||
};
|
||||
|
||||
@ -332,7 +346,23 @@ sub sysex_handle {
|
||||
$observer->{method}( $data->{string}, $observer->{context} );
|
||||
}
|
||||
last;
|
||||
}
|
||||
};
|
||||
|
||||
$sysex_message->{command_str} eq 'STEPPER_DATA' and do {
|
||||
#TODO implement handling of STEPPER_DATA and call observer.
|
||||
last;
|
||||
};
|
||||
|
||||
$sysex_message->{command_str} eq 'ENCODER_DATA' and do {
|
||||
foreach my $encoder_data ( @$data ) {
|
||||
my $encoderNum = $encoder_data->{encoderNum};
|
||||
my $observer = $self->{encoder_observer}[$encoderNum];
|
||||
if (defined $observer) {
|
||||
$observer->{method}( $encoder_data, $observer->{context} );
|
||||
}
|
||||
};
|
||||
last;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -739,6 +769,38 @@ sub onewire_command_series {
|
||||
return $self->{io}->data_write($self->{protocol}->packet_onewire_request( $pin, $args ));
|
||||
}
|
||||
|
||||
sub encoder_attach {
|
||||
my ( $self, $encoderNum, $pinA, $pinB ) = @_;
|
||||
die "unsupported mode 'ENCODER' for pin '".$pinA."'" unless $self->is_supported_mode($pinA,PIN_ENCODER);
|
||||
die "unsupported mode 'ENCODER' for pin '".$pinB."'" unless $self->is_supported_mode($pinB,PIN_ENCODER);
|
||||
return $self->{io}->data_write($self->{protocol}->packet_encoder_attach( $encoderNum, $pinA, $pinB ));
|
||||
}
|
||||
|
||||
sub encoder_report_position {
|
||||
my ( $self, $encoderNum ) = @_;
|
||||
return $self->{io}->data_write($self->{protocol}->packet_encoder_report_position( $encoderNum ));
|
||||
}
|
||||
|
||||
sub encoder_report_positions {
|
||||
my ( $self ) = @_;
|
||||
return $self->{io}->data_write($self->{protocol}->packet_encoder_report_positions());
|
||||
}
|
||||
|
||||
sub encoder_reset_position {
|
||||
my ( $self, $encoderNum ) = @_;
|
||||
return $self->{io}->data_write($self->{protocol}->packet_encoder_reset_position( $encoderNum ));
|
||||
}
|
||||
|
||||
sub encoder_report_auto {
|
||||
my ( $self, $enable ) = @_;
|
||||
return $self->{io}->data_write($self->{protocol}->packet_encoder_report_auto( $enable ));
|
||||
}
|
||||
|
||||
sub encoder_detach {
|
||||
my ( $self, $encoderNum ) = @_;
|
||||
return $self->{io}->data_write($self->{protocol}->packet_encoder_detach( $encoderNum ));
|
||||
}
|
||||
|
||||
=head2 poll
|
||||
|
||||
Call this function every once in a while to
|
||||
@ -809,6 +871,21 @@ sub observe_onewire {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub observe_stepper {
|
||||
#TODO implement observe_stepper
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub observe_encoder {
|
||||
my ( $self, $encoderNum, $observer, $context ) = @_;
|
||||
#TODO validation? die "unsupported mode 'ENCODER' for pin '".$pin."'" unless ($self->is_supported_mode($pin,PIN_ENCODER));
|
||||
$self->{encoder_observer}[$encoderNum] = {
|
||||
method => $observer,
|
||||
context => $context,
|
||||
};
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub observe_scheduler {
|
||||
my ( $self, $observer, $context ) = @_;
|
||||
$self->{scheduler_observer} = {
|
||||
|
@ -73,6 +73,20 @@ our $SCHEDULER_COMMANDS = {
|
||||
QUERY_TASK_REPLY => 10,
|
||||
};
|
||||
|
||||
our $STEPPER_COMMANDS = {
|
||||
STEPPER_CONFIG => 0,
|
||||
STEPPER_STEP => 1,
|
||||
};
|
||||
|
||||
our $ENCODER_COMMANDS = {
|
||||
ENCODER_ATTACH => 0,
|
||||
ENCODER_REPORT_POSITION => 1,
|
||||
ENCODER_REPORT_POSITIONS => 2,
|
||||
ENCODER_RESET_POSITION => 3,
|
||||
ENCODER_REPORT_AUTO => 4,
|
||||
ENCODER_DETACH => 5,
|
||||
};
|
||||
|
||||
our $MODENAMES = {
|
||||
0 => 'INPUT',
|
||||
1 => 'OUTPUT',
|
||||
@ -82,6 +96,8 @@ our $MODENAMES = {
|
||||
5 => 'SHIFT',
|
||||
6 => 'I2C',
|
||||
7 => 'ONEWIRE',
|
||||
8 => 'STEPPER',
|
||||
9 => 'ENCODER',
|
||||
};
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@ -289,6 +305,16 @@ sub sysex_parse {
|
||||
$return_data = $self->handle_scheduler_response($sysex_data);
|
||||
last;
|
||||
};
|
||||
|
||||
$command == $protocol_commands->{STEPPER_DATA} and do {
|
||||
#TODO implement and call handle_stepper_response
|
||||
last;
|
||||
};
|
||||
|
||||
$command == $protocol_commands->{ENCODER_DATA} and do {
|
||||
$return_data = $self->handle_encoder_response($sysex_data);
|
||||
last;
|
||||
};
|
||||
|
||||
$command == $protocol_commands->{RESERVED_COMMAND} and do {
|
||||
$return_data = $sysex_data;
|
||||
@ -841,6 +867,75 @@ sub handle_scheduler_response {
|
||||
}
|
||||
}
|
||||
|
||||
#TODO packet_stepper_config
|
||||
sub packet_stepper_config {
|
||||
my ( $self ) = @_;
|
||||
my $packet = $self->packet_sysex_command('STEPPER_DATA', $STEPPER_COMMANDS->{STEPPER_CONFIG});
|
||||
}
|
||||
|
||||
#TODO packet_stepper_step
|
||||
sub packet_stepper_step {
|
||||
my ( $self ) = @_;
|
||||
my $packet = $self->packet_sysex_command('STEPPER_DATA', $STEPPER_COMMANDS->{STEPPER_STEP});
|
||||
}
|
||||
|
||||
sub packet_encoder_attach {
|
||||
my ( $self,$encoderNum, $pinA, $pinB ) = @_;
|
||||
my $packet = $self->packet_sysex_command('ENCODER_DATA', $ENCODER_COMMANDS->{ENCODER_ATTACH}, $encoderNum, $pinA, $pinB);
|
||||
return $packet;
|
||||
}
|
||||
|
||||
sub packet_encoder_report_position {
|
||||
my ( $self,$encoderNum ) = @_;
|
||||
my $packet = $self->packet_sysex_command('ENCODER_DATA', $ENCODER_COMMANDS->{ENCODER_REPORT_POSITION}, $encoderNum);
|
||||
return $packet;
|
||||
}
|
||||
|
||||
sub packet_encoder_report_positions {
|
||||
my ( $self ) = @_;
|
||||
my $packet = $self->packet_sysex_command('ENCODER_DATA', $ENCODER_COMMANDS->{ENCODER_REPORT_POSITIONS});
|
||||
return $packet;
|
||||
}
|
||||
|
||||
sub packet_encoder_reset_position {
|
||||
my ( $self,$encoderNum ) = @_;
|
||||
my $packet = $self->packet_sysex_command('ENCODER_DATA', $ENCODER_COMMANDS->{ENCODER_RESET_POSITION}, $encoderNum);
|
||||
return $packet;
|
||||
}
|
||||
|
||||
sub packet_encoder_report_auto {
|
||||
my ( $self,$arg ) = @_; #TODO clarify encoder_report_auto $arg
|
||||
my $packet = $self->packet_sysex_command('ENCODER_DATA', $ENCODER_COMMANDS->{ENCODER_REPORT_AUTO}, $arg);
|
||||
return $packet;
|
||||
}
|
||||
|
||||
sub packet_encoder_detach {
|
||||
my ( $self,$encoderNum ) = @_;
|
||||
my $packet = $self->packet_sysex_command('ENCODER_DATA', $ENCODER_COMMANDS->{ENCODER_DETACH}, $encoderNum);
|
||||
return $packet;
|
||||
}
|
||||
|
||||
sub handle_encoder_response {
|
||||
my ( $self, $sysex_data ) = @_;
|
||||
|
||||
my @retval = ();
|
||||
|
||||
while (@$sysex_data) {
|
||||
|
||||
my $command = shift @$sysex_data;
|
||||
my $direction = ($command & 0x40) >> 6;
|
||||
my $encoderNum = $command & 0x3f;
|
||||
my $value = shift14bit($sysex_data) + (shift14bit($sysex_data) << 14);
|
||||
|
||||
push @retval,{
|
||||
encoderNum => $encoderNum,
|
||||
value => $direction ? -1 * $value : $value,
|
||||
};
|
||||
};
|
||||
|
||||
return \@retval;
|
||||
}
|
||||
|
||||
|
||||
sub shift14bit {
|
||||
my $data = shift;
|
||||
|
Loading…
x
Reference in New Issue
Block a user