mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-13 17:26:34 +00:00
lib/Device/Firmata: bump driver vesion to 0.63 (Forum #81815)
git-svn-id: https://svn.fhem.de/fhem/trunk@15744 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
b99a628149
commit
119c9a3885
@ -8,18 +8,18 @@ use Device::Firmata::Base
|
||||
ISA => 'Device::Firmata::Base',
|
||||
FIRMATA_ATTRIBS => {
|
||||
};
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Device::Firmata - Perl interface to Firmata for the arduino platform.
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.59
|
||||
Version 0.63
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = '0.59';
|
||||
our $VERSION = '0.63';
|
||||
our $DEBUG = 0;
|
||||
|
||||
|
||||
@ -58,34 +58,32 @@ sub open {
|
||||
# --------------------------------------------------
|
||||
# Establish a connection to Arduino via the serial port
|
||||
#
|
||||
my ( $self, $serial_port, $opts ) = @_;
|
||||
my ( $self, $serial_port, $opts ) = @_;
|
||||
|
||||
# We're going to try and create the device connection first...
|
||||
my $package = "Device::Firmata::Platform";
|
||||
eval "require $package";
|
||||
my $serialio = "Device::Firmata::IO::SerialIO";
|
||||
eval "require $serialio";
|
||||
|
||||
my $io = $serialio->open( $serial_port, $opts );
|
||||
my $platform = $package->attach( $io, $opts ) or die "Could not connect to Firmata Server";
|
||||
my $package = "Device::Firmata::Platform";
|
||||
eval "require $package";
|
||||
my $serialio = "Device::Firmata::IO::SerialIO";
|
||||
eval "require $serialio";
|
||||
|
||||
my $io = $serialio->open( $serial_port, $opts );
|
||||
my $platform = $package->attach( $io, $opts ) or die "Could not connect to Firmata Server";
|
||||
|
||||
# Figure out what platform we're running on
|
||||
$platform->probe;
|
||||
|
||||
return $platform;
|
||||
$platform->probe;
|
||||
return $platform;
|
||||
}
|
||||
|
||||
sub listen {
|
||||
# --------------------------------------------------
|
||||
# Listen on socket and wait for Arduino to establish a connection
|
||||
#
|
||||
my ( $pkg, $ip, $port, $opts ) = @_;
|
||||
my ( $pkg, $ip, $port, $opts ) = @_;
|
||||
|
||||
my $netio = "Device::Firmata::IO::NetIO";
|
||||
eval "require $netio";
|
||||
|
||||
return $netio->listen( $ip, $port, $opts ) or die "Could not bind to socket";
|
||||
|
||||
my $netio = "Device::Firmata::IO::NetIO";
|
||||
eval "require $netio";
|
||||
|
||||
return $netio->listen( $ip, $port, $opts ) || die "Could not bind to socket";
|
||||
}
|
||||
|
||||
1;
|
||||
|
59
fhem/FHEM/lib/Device/Firmata/Changes
Normal file
59
fhem/FHEM/lib/Device/Firmata/Changes
Normal file
@ -0,0 +1,59 @@
|
||||
Revision history for Device-Firmata
|
||||
|
||||
0.63 2016.03.19 - Jens Beyer
|
||||
supported protocol version detection modified (Protocol)
|
||||
|
||||
0.62 2016.02.22 - Jens Beyer
|
||||
added software serial support (Platform, Protocol)
|
||||
|
||||
0.61 2016.01.09 - Jens Beyer
|
||||
added serial pin support (Platform, Protocol, Constants)
|
||||
added protocol version query (Platform)
|
||||
fixed messages_handle: REPORT_VERSION returns protocol version (Platform)
|
||||
added method get_max_compatible_protocol_version (Protocol)
|
||||
|
||||
0.60 2014.06.28 - Norbert Truchsess
|
||||
Fixed formating of Firmata.pm as Windows line-endings break automatic install from CPAN
|
||||
|
||||
0.59 2014.06.26 - Norbert Truchsess
|
||||
Fix a bug in the parser incorrectly skipping single 0x30 bytes
|
||||
|
||||
0.58 2014.06.26 - Yanick Champoux
|
||||
cosmetic change to POD for CPAN
|
||||
|
||||
0.57 2014.06.12 - Norbert Truchsess
|
||||
Fixed building dist for cpan
|
||||
|
||||
0.56 2014.06.04 - Norbert Truchsess
|
||||
add generic method sysex_send to Platform.pl
|
||||
|
||||
0.55 2014.04.17 - Norbert Truchsess
|
||||
fix digital-input message interference with output pins on same port
|
||||
|
||||
0.54 2014.03.04 - Norbert Truchsess
|
||||
add stepper-motor protocol
|
||||
|
||||
0.53 2014.03.03 - Norbert Truchsess
|
||||
add rotary-encoder protocol
|
||||
|
||||
0.52 2013.11.22 - Norbert Truchsess
|
||||
add Firmata over Ethernet
|
||||
|
||||
0.51 2013.09.10/23:00 - Brett Carroll
|
||||
Changed IO.pm to use Win32::SerialPort instead of Win32::Serialport on Windows platforms
|
||||
Norbert Truchsess: fix handle onewire in capability-response
|
||||
|
||||
0.50 2012.12.13-2013.08.11 - Norbert Truchsess
|
||||
adding all missing protocol-features (1-Wire, I2C, Servo ...)
|
||||
adding observers for all suitable protocols
|
||||
|
||||
Valdas Kondrotas: various bugfixes and enhancements.
|
||||
|
||||
2011.03.23 - Chris Fedde
|
||||
reorganizing as CPAN ready module
|
||||
|
||||
2011.02.16 Aki Mimoto
|
||||
implementig all protocol basics and releasing Device::Firmata on Github
|
||||
|
||||
2010.08.31 Aki Mimoto
|
||||
start of development
|
@ -29,6 +29,7 @@ use constant (
|
||||
PIN_ONEWIRE => 7,
|
||||
PIN_STEPPER => 8,
|
||||
PIN_ENCODER => 9,
|
||||
PIN_SERIAL => 10,
|
||||
PIN_LOW => 0,
|
||||
PIN_HIGH => 1,
|
||||
}
|
||||
@ -260,6 +261,8 @@ use constant (
|
||||
|
||||
# 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).
|
||||
SERIAL_DATA => 0x60, # serial port config/write/read/close/flush/listen request and read reply
|
||||
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
|
||||
@ -291,6 +294,8 @@ use constant (
|
||||
I2C => 0x06, # pin included in I2C setup
|
||||
ONEWIRE => 0x07, # pin configured for 1-Wire commuication
|
||||
STEPPER => 0x08, # pin configured for stepper motor
|
||||
SERIAL => 0x0A, # pin configured for serial port
|
||||
|
||||
# Deprecated entries
|
||||
deprecated => [
|
||||
qw( FIRMATA_STRING SYSEX_I2C_REQUEST SYSEX_I2C_REPLY SYSEX_SAMPLING_INTERVAL )
|
||||
@ -315,6 +320,7 @@ use constant (
|
||||
|
||||
# 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).
|
||||
SERIAL_DATA => 0x60, # serial port config/write/read/close/flush/listen request and read reply
|
||||
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
|
||||
@ -348,14 +354,14 @@ use constant (
|
||||
ONEWIRE => 0x07, # pin configured for 1-Wire commuication
|
||||
STEPPER => 0x08, # pin configured for stepper motor
|
||||
ENCODER => 0x09, # pin configured for rotary-encoders
|
||||
|
||||
SERIAL => 0x0A, # pin configured for serial port
|
||||
|
||||
# Deprecated entries
|
||||
deprecated => [
|
||||
qw( FIRMATA_STRING SYSEX_I2C_REQUEST SYSEX_I2C_REPLY SYSEX_SAMPLING_INTERVAL )
|
||||
],
|
||||
|
||||
}, # /Constants for Version 2.6
|
||||
}, # /Constants for Version 2.6
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -30,6 +30,7 @@ use Device::Firmata::Base
|
||||
servo_resolutions => {},
|
||||
stepper_resolutions => {},
|
||||
encoder_resolutions => {},
|
||||
serial_resolutions => {},
|
||||
ports => [],
|
||||
input_ports => [],
|
||||
pins => {},
|
||||
@ -44,6 +45,7 @@ use Device::Firmata::Base
|
||||
onewire_observer => [],
|
||||
stepper_observer => [],
|
||||
encoder_observer => [],
|
||||
serial_observer => [],
|
||||
scheduler_observer => undef,
|
||||
string_observer => undef,
|
||||
|
||||
@ -93,6 +95,7 @@ sub detach {
|
||||
$self->{onewire_observer} = [];
|
||||
$self->{stepper_observer} = [];
|
||||
$self->{encoder_observer} = [];
|
||||
$self->{serial_observer} = [];
|
||||
$self->{scheduler_observer} = undef;
|
||||
$self->{tasks} = [];
|
||||
$self->{metadata} = {};
|
||||
@ -119,6 +122,7 @@ sub system_reset {
|
||||
$self->{onewire_observer} = [];
|
||||
$self->{stepper_observer} = [];
|
||||
$self->{encoder_observer} = [];
|
||||
$self->{serial_observer} = [];
|
||||
$self->{scheduler_observer} = undef;
|
||||
$self->{tasks} = [];
|
||||
$self->{metadata} = {};
|
||||
@ -186,7 +190,7 @@ sub messages_handle {
|
||||
|
||||
# Handle metadata information
|
||||
$command eq 'REPORT_VERSION' and do {
|
||||
$self->{metadata}{firmware_version} = sprintf "V_%i_%02i",
|
||||
$self->{metadata}{protocol_version} = sprintf "V_%i_%02i",
|
||||
@$data;
|
||||
last;
|
||||
};
|
||||
@ -251,6 +255,7 @@ sub sysex_handle {
|
||||
my @onewirepins;
|
||||
my @stepperpins;
|
||||
my @encoderpins;
|
||||
my @serialpins;
|
||||
|
||||
foreach my $pin (keys %$capabilities) {
|
||||
if (defined $capabilities->{$pin}) {
|
||||
@ -289,6 +294,10 @@ sub sysex_handle {
|
||||
push @encoderpins, $pin;
|
||||
$self->{metadata}{encoder_resolutions}{$pin} = $capabilities->{$pin}->{PIN_ENCODER+0}->{resolution};
|
||||
}
|
||||
if ($capabilities->{$pin}->{PIN_SERIAL+0}) {
|
||||
push @serialpins, $pin;
|
||||
$self->{metadata}{serial_resolutions}{$pin} = $capabilities->{$pin}->{PIN_SERIAL+0}->{resolution};
|
||||
}
|
||||
}
|
||||
}
|
||||
$self->{metadata}{input_pins} = \@inputpins;
|
||||
@ -301,6 +310,7 @@ sub sysex_handle {
|
||||
$self->{metadata}{onewire_pins} = \@onewirepins;
|
||||
$self->{metadata}{stepper_pins} = \@stepperpins;
|
||||
$self->{metadata}{encoder_pins} = \@encoderpins;
|
||||
$self->{metadata}{serial_pins} = \@serialpins;
|
||||
last;
|
||||
};
|
||||
|
||||
@ -373,6 +383,15 @@ sub sysex_handle {
|
||||
};
|
||||
last;
|
||||
};
|
||||
|
||||
$sysex_message->{command_str} eq 'SERIAL_DATA' and do {
|
||||
my $serialPort = $data->{port};
|
||||
my $observer = $self->{serial_observer}[$serialPort];
|
||||
if (defined $observer) {
|
||||
$observer->{method}( $data, $observer->{context} );
|
||||
}
|
||||
last;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,14 +411,16 @@ sub probe {
|
||||
my ($self) = @_;
|
||||
$self->{metadata}{firmware} = '';
|
||||
$self->{metadata}{firmware_version} = '';
|
||||
$self->{metadata}{protocol_version} = '';
|
||||
|
||||
# Wait for 5 seconds only
|
||||
my $end_tics = time + 5;
|
||||
$self->firmware_version_query();
|
||||
$self->protocol_version_query();
|
||||
while ( $end_tics >= time ) {
|
||||
select( undef, undef, undef, 0.2 ); # wait for response
|
||||
if ( $self->poll && $self->{metadata}{firmware} && $self->{metadata}{firmware_version} ) {
|
||||
$self->{protocol}->{protocol_version} = $self->{metadata}{firmware_version};
|
||||
select( undef, undef, undef, 0.2 ); # wait for responses
|
||||
if ( $self->poll && $self->{metadata}{firmware} && $self->{metadata}{firmware_version} && $self->{metadata}{protocol_version} ) {
|
||||
$self->{protocol}->{protocol_version} = $self->{protocol}->get_max_supported_protocol_version($self->{metadata}{protocol_version});
|
||||
if ( $self->{metadata}{capabilities} ) {
|
||||
if ( $self->{metadata}{analog_mappings} ) {
|
||||
return 1;
|
||||
@ -409,8 +430,10 @@ sub probe {
|
||||
} else {
|
||||
$self->capability_query();
|
||||
}
|
||||
} else {
|
||||
$self->firmware_version_query() unless $end_tics - 2 >= time; # version query on last 2 sec only
|
||||
} elsif ($end_tics - 2 < time) {
|
||||
# version query on last 2 sec only
|
||||
$self->firmware_version_query();
|
||||
$self->protocol_version_query();
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -540,6 +563,12 @@ pmw_write is an alias for analog_write
|
||||
|
||||
*pwm_write = *analog_write;
|
||||
|
||||
sub protocol_version_query {
|
||||
my $self = shift;
|
||||
my $protocol_version_query_packet = $self->{protocol}->packet_query_version;
|
||||
return $self->{io}->data_write($protocol_version_query_packet);
|
||||
}
|
||||
|
||||
sub firmware_version_query {
|
||||
my $self = shift;
|
||||
my $firmware_version_query_packet = $self->{protocol}->packet_query_firmware;
|
||||
@ -831,6 +860,29 @@ sub encoder_detach {
|
||||
return $self->{io}->data_write($self->{protocol}->packet_encoder_detach( $encoderNum ));
|
||||
}
|
||||
|
||||
sub serial_write {
|
||||
my ( $self, $port, @data ) = @_;
|
||||
return $self->{io}->data_write($self->{protocol}->packet_serial_write( $port, @data ));
|
||||
}
|
||||
|
||||
sub serial_read {
|
||||
my ( $self, $port, $numbytes ) = @_;
|
||||
if ($port >= 8) {
|
||||
$self->{io}->data_write($self->{protocol}->packet_serial_listen( $port ));
|
||||
}
|
||||
return $self->{io}->data_write($self->{protocol}->packet_serial_read( $port, 0x00, $numbytes ));
|
||||
}
|
||||
|
||||
sub serial_stopreading {
|
||||
my ( $self, $port) = @_;
|
||||
return $self->{io}->data_write($self->{protocol}->packet_serial_read( $port, 0x01, 0 ));
|
||||
}
|
||||
|
||||
sub serial_config {
|
||||
my ( $self, $port, $baud, $rxPin, $txPin ) = @_;
|
||||
return $self->{io}->data_write($self->{protocol}->packet_serial_config( $port, $baud, $rxPin, $txPin ));
|
||||
}
|
||||
|
||||
=head2 poll
|
||||
|
||||
Call this function every once in a while to
|
||||
@ -921,6 +973,16 @@ sub observe_encoder {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub observe_serial {
|
||||
my ( $self, $port, $observer, $context ) = @_;
|
||||
return undef if (defined $self->{metadata}->{serialpins} && @$self->{metadata}->{serialpins} == 0 );
|
||||
$self->{serial_observer}[$port] = {
|
||||
method => $observer,
|
||||
context => $context,
|
||||
};
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub observe_scheduler {
|
||||
my ( $self, $observer, $context ) = @_;
|
||||
$self->{scheduler_observer} = {
|
||||
|
@ -16,6 +16,7 @@ use constant {
|
||||
MIDI_PARSE_SYSEX => 1,
|
||||
MIDI_START_SYSEX => 0xf0,
|
||||
MIDI_END_SYSEX => 0xf7,
|
||||
MAX_PROTOCOL_VERSION => 'V_2_05', # highest Firmata protocol version currently implemented
|
||||
};
|
||||
|
||||
use Device::Firmata::Constants qw/ :all /;
|
||||
@ -24,7 +25,7 @@ use Device::Firmata::Base
|
||||
FIRMATA_ATTRIBS => {
|
||||
buffer => [],
|
||||
parse_status => MIDI_PARSE_NORMAL,
|
||||
protocol_version => 'V_2_04', # We are starting with the highest protocol
|
||||
protocol_version => MAX_PROTOCOL_VERSION, # We are starting with the highest protocol
|
||||
};
|
||||
|
||||
$MIDI_DATA_SIZES = {
|
||||
@ -93,6 +94,14 @@ our $ENCODER_COMMANDS = {
|
||||
ENCODER_DETACH => 5,
|
||||
};
|
||||
|
||||
our $SERIAL_COMMANDS = {
|
||||
SERIAL_CONFIG => 0x10, # config serial port stetting such as baud rate and pins
|
||||
SERIAL_WRITE => 0x20, # write to serial port
|
||||
SERIAL_READ => 0x30, # read request to serial port
|
||||
SERIAL_REPLY => 0x40, # read reply from serial port
|
||||
SERIAL_LISTEN => 0x70, # start listening on software serial port
|
||||
};
|
||||
|
||||
our $MODENAMES = {
|
||||
0 => 'INPUT',
|
||||
1 => 'OUTPUT',
|
||||
@ -104,6 +113,7 @@ our $MODENAMES = {
|
||||
7 => 'ONEWIRE',
|
||||
8 => 'STEPPER',
|
||||
9 => 'ENCODER',
|
||||
10 => 'SERIAL',
|
||||
};
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@ -322,6 +332,11 @@ sub sysex_parse {
|
||||
last;
|
||||
};
|
||||
|
||||
$command == $protocol_commands->{SERIAL_DATA} and do {
|
||||
$return_data = $self->handle_serial_reply($sysex_data);
|
||||
last;
|
||||
};
|
||||
|
||||
$command == $protocol_commands->{RESERVED_COMMAND} and do {
|
||||
$return_data = $sysex_data;
|
||||
last;
|
||||
@ -421,7 +436,11 @@ sub packet_query_version {
|
||||
}
|
||||
|
||||
sub handle_query_version_response {
|
||||
|
||||
my ( $self, $data ) = @_;
|
||||
return {
|
||||
major_version => shift @$data,
|
||||
minor_version => shift @$data,
|
||||
};
|
||||
}
|
||||
|
||||
sub handle_string_data {
|
||||
@ -1012,6 +1031,138 @@ sub handle_encoder_response {
|
||||
return \@retval;
|
||||
}
|
||||
|
||||
#/* serial config
|
||||
# * -------------------------------
|
||||
# * 0 START_SYSEX (0xF0)
|
||||
# * 1 SERIAL_DATA (0x60) // command byte
|
||||
# * 2 SERIAL_CONFIG (0x10) // OR with port (0x11 = SERIAL_CONFIG | HW_SERIAL1)
|
||||
# * 3 baud (bits 0 - 6)
|
||||
# * 4 baud (bits 7 - 13)
|
||||
# * 5 baud (bits 14 - 20) // need to send 3 bytes for baud even if value is < 14 bits
|
||||
# * 6 rxPin (0-127) [optional] // only set if platform requires RX pin number
|
||||
# * 7 txPin (0-127) [optional] // only set if platform requires TX pin number
|
||||
# * 6|8 END_SYSEX (0xF7)
|
||||
# */
|
||||
|
||||
sub packet_serial_config {
|
||||
my ( $self, $port, $baud, $rxPin, $txPin ) = @_;
|
||||
if (defined($rxPin) && defined($txPin)) {
|
||||
return $self->packet_sysex_command( SERIAL_DATA,
|
||||
$SERIAL_COMMANDS->{SERIAL_CONFIG} | $port,
|
||||
$baud & 0x7f,
|
||||
($baud >> 7) & 0x7f,
|
||||
($baud >> 14) & 0x7f,
|
||||
$rxPin & 0x7f,
|
||||
$txPin & 0x7f
|
||||
);
|
||||
} else {
|
||||
return $self->packet_sysex_command( SERIAL_DATA,
|
||||
$SERIAL_COMMANDS->{SERIAL_CONFIG} | $port,
|
||||
$baud & 0x7f,
|
||||
($baud >> 7) & 0x7f,
|
||||
($baud >> 14) & 0x7f
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#/* serial listen
|
||||
# * -------------------------------
|
||||
# * 0 START_SYSEX (0xF0)
|
||||
# * 1 SERIAL_DATA (0x60) // command byte
|
||||
# * 2 SERIAL_LISTEN (0x70) // OR with port to switch to (0x79 = switch to SW_SERIAL1)
|
||||
# * 3 END_SYSEX (0xF7)
|
||||
# */
|
||||
|
||||
sub packet_serial_listen {
|
||||
my ( $self, $port ) = @_;
|
||||
return $self->packet_sysex_command( SERIAL_DATA,
|
||||
$SERIAL_COMMANDS->{SERIAL_LISTEN} | $port
|
||||
);
|
||||
}
|
||||
|
||||
#/* serial write
|
||||
# * -------------------------------
|
||||
# * 0 START_SYSEX (0xF0)
|
||||
# * 1 SERIAL_DATA (0x60)
|
||||
# * 2 SERIAL_WRITE (0x20) // OR with port (0x21 = SERIAL_WRITE | HW_SERIAL1)
|
||||
# * 3 data 0 (LSB)
|
||||
# * 4 data 0 (MSB)
|
||||
# * 5 data 1 (LSB)
|
||||
# * 6 data 1 (MSB)
|
||||
# * ... // up to max buffer - 5
|
||||
# * n END_SYSEX (0xF7)
|
||||
# */
|
||||
|
||||
sub packet_serial_write {
|
||||
my ( $self, $port, @serialdata ) = @_;
|
||||
|
||||
if (scalar @serialdata) {
|
||||
my @data;
|
||||
push_array_as_two_7bit(\@serialdata,\@data);
|
||||
return $self->packet_sysex_command( SERIAL_DATA,
|
||||
$SERIAL_COMMANDS->{SERIAL_WRITE} | $port,
|
||||
@data
|
||||
);
|
||||
} else {
|
||||
return $self->packet_sysex_command( SERIAL_DATA,
|
||||
$SERIAL_COMMANDS->{SERIAL_WRITE} | $port
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#/* serial read
|
||||
# * -------------------------------
|
||||
# * 0 START_SYSEX (0xF0)
|
||||
# * 1 SERIAL_DATA (0x60)
|
||||
# * 2 SERIAL_READ (0x30) // OR with port (0x31 = SERIAL_READ | HW_SERIAL1)
|
||||
# * 3 SERIAL_READ_MODE (0x00) // 0x00 => read continuously, 0x01 => stop reading
|
||||
# * 4 maxBytesToRead (lsb) // 0x00 for all bytes available [optional]
|
||||
# * 5 maxBytesToRead (msb) // 0x00 for all bytes available [optional]
|
||||
# * 4|6 END_SYSEX (0xF7)
|
||||
# */
|
||||
|
||||
sub packet_serial_read {
|
||||
my ( $self, $port, $command, $maxBytes ) = @_;
|
||||
|
||||
if ($maxBytes > 0) {
|
||||
return $self->packet_sysex_command( SERIAL_DATA,
|
||||
$SERIAL_COMMANDS->{SERIAL_READ} | $port,
|
||||
$command,
|
||||
$maxBytes & 0x7f,
|
||||
($maxBytes >> 7) & 0x7f
|
||||
);
|
||||
} else {
|
||||
return $self->packet_sysex_command( SERIAL_DATA,
|
||||
$SERIAL_COMMANDS->{SERIAL_READ} | $port,
|
||||
$command
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#/* serial reply
|
||||
# * -------------------------------
|
||||
# * 0 START_SYSEX (0xF0)
|
||||
# * 1 SERIAL_DATA (0x60)
|
||||
# * 2 SERIAL_REPLY (0x40) // OR with port (0x41 = SERIAL_REPLY | HW_SERIAL1)
|
||||
# * 3 data 0 (LSB)
|
||||
# * 4 data 0 (MSB)
|
||||
# * 3 data 1 (LSB)
|
||||
# * 4 data 1 (MSB)
|
||||
# * ... // up to max buffer - 5
|
||||
# * n END_SYSEX (0xF7)
|
||||
# */
|
||||
|
||||
sub handle_serial_reply {
|
||||
my ( $self, $sysex_data ) = @_;
|
||||
|
||||
my $command = shift @$sysex_data;
|
||||
my $port = $command & 0xF;
|
||||
my @data = double_7bit_to_array($sysex_data);
|
||||
return {
|
||||
port => $port,
|
||||
data => \@data,
|
||||
};
|
||||
}
|
||||
|
||||
sub shift14bit {
|
||||
my $data = shift;
|
||||
@ -1133,4 +1284,25 @@ sub unpack_from_7bit {
|
||||
return @outdata;
|
||||
}
|
||||
|
||||
=head2 get_max_compatible_protocol_version
|
||||
|
||||
Search list of implemented protocols for identical or next lower version.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_max_supported_protocol_version {
|
||||
my ( $self, $deviceProtcolVersion ) = @_;
|
||||
return "V_2_01" unless (defined($deviceProtcolVersion)); # min. supported protocol version if undefined
|
||||
return $deviceProtcolVersion if (defined($COMMANDS->{$deviceProtcolVersion})); # requested version if known
|
||||
|
||||
my $maxSupportedProtocolVersion = undef;
|
||||
foreach my $protocolVersion (sort keys %{$COMMANDS}) {
|
||||
if ($protocolVersion lt $deviceProtcolVersion) {
|
||||
$maxSupportedProtocolVersion = $protocolVersion; # nearest lower version if not known
|
||||
}
|
||||
}
|
||||
|
||||
return $maxSupportedProtocolVersion;
|
||||
}
|
||||
|
||||
1;
|
||||
|
47
fhem/FHEM/lib/Device/Firmata/README
Normal file
47
fhem/FHEM/lib/Device/Firmata/README
Normal file
@ -0,0 +1,47 @@
|
||||
Device-Firmata
|
||||
|
||||
Device::Firmata - Perl interface to the Firmata protocol for talking to the arduino microcontroler platform. See http://firmata.org/wiki/Main_Page for more details.
|
||||
|
||||
INSTALLATION
|
||||
|
||||
To install this module, run the following commands:
|
||||
|
||||
perl Makefile.PL
|
||||
make
|
||||
make test
|
||||
make install
|
||||
|
||||
SUPPORT AND DOCUMENTATION
|
||||
|
||||
After installing, you can find documentation for this module with the
|
||||
perldoc command.
|
||||
|
||||
perldoc Device::Firmata
|
||||
|
||||
You can also look for information at:
|
||||
|
||||
RT, CPAN's request tracker
|
||||
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Device-Firmata
|
||||
|
||||
AnnoCPAN, Annotated CPAN documentation
|
||||
http://annocpan.org/dist/Device-Firmata
|
||||
|
||||
CPAN Ratings
|
||||
http://cpanratings.perl.org/d/Device-Firmata
|
||||
|
||||
Search CPAN
|
||||
http://search.cpan.org/dist/Device-Firmata/
|
||||
|
||||
|
||||
LICENSE AND COPYRIGHT
|
||||
|
||||
Copyright (C) 2011 amimato
|
||||
Copyright (C) 2012 ntruchsess
|
||||
Copyright (C) 2016 jnsbyr
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of either: the GNU General Public License as published
|
||||
by the Free Software Foundation; or the Artistic License.
|
||||
|
||||
See http://dev.perl.org/licenses/ for more information.
|
||||
|
1
fhem/FHEM/lib/Device/Firmata/license.txt
Normal file
1
fhem/FHEM/lib/Device/Firmata/license.txt
Normal file
@ -0,0 +1 @@
|
||||
perl-firmata is distributed under the same terms as perl itself
|
@ -504,7 +504,7 @@ FHEM/TR064Utils.pm rudolfkoenig Automatisierung
|
||||
FHEM/UConv.pm loredo FHEM Development
|
||||
FHEM/Unit.pm loredo FHEM Development
|
||||
FHEM/YahooWeatherAPI.pm neubert Unterstuetzende Dienste/Wettermodule
|
||||
FHEM/lib/Device/Firmata/* ntruchsess Sonstige Systeme
|
||||
FHEM/lib/Device/Firmata/* jensb Sonstige Systeme
|
||||
FHEM/lib/Device/MySensors/* Hauswart Sonstige Systeme
|
||||
FHEM/lib/MP3/* Reinerlein Multimedia
|
||||
FHEM/lib/Net/MQTT.pod eisler MQTT
|
||||
|
Loading…
x
Reference in New Issue
Block a user