update perl-firmata, new module FRM_SERVO

git-svn-id: https://fhem.svn.sourceforge.net/svnroot/fhem/trunk/fhem@2627 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
ntruchsess
2013-02-02 11:50:06 +00:00
parent 348a258f7c
commit 5e2b528f44
9 changed files with 285 additions and 99 deletions

View File

@@ -220,16 +220,14 @@ 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
ONEWIRE_REQUEST => 0x73, # send an OneWire read/write/reset/select/skip/search request
ONEWIRE_REPLY => 0x7D, # reply to a OneWire read/search request
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_REQUEST => 0x7B, # send a createtask/deletetask/addtotask/schedule/querytasks/querytask request to the scheduler
SCHEDULER_REPLY => 0x7C, # a reply to a querytasks/querytask-request from the scheduler
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

View File

@@ -26,6 +26,9 @@ use Device::Firmata::Base
# To track internal status
analog_pins => [],
analog_resolutions => {},
pwm_resolutions => {},
servo_resolutions => {},
ports => [],
pins => {},
pin_modes => {},
@@ -167,7 +170,7 @@ sub messages_handle {
# Handle analog pin messages
$command eq 'ANALOG_MESSAGE' and do {
my $pin_number = $message->{command} & 0x0f;
my $pin_value = ( $data->[0] | ( $data->[1] << 7 ) ) / 1023;
my $pin_value = ( $data->[0] | ( $data->[1] << 7 ) );
if (defined $self->{metadata}{analog_mappings}) {
$pin_number = $self->{metadata}{analog_mappings}{$pin_number};
}
@@ -247,6 +250,9 @@ sub sysex_handle {
my @analogpins;
my @inputpins;
my @outputpins;
my @pwmpins;
my @servopins;
my @shiftpins;
my @i2cpins;
my @onewirepins;
foreach my $pin (keys %$capabilities) {
@@ -259,6 +265,18 @@ sub sysex_handle {
}
if ($capabilities->{$pin}->{PIN_ANALOG+0}) {
push @analogpins, $pin;
$self->{metadata}{analog_resolutions}{$pin} = $capabilities->{$pin}->{PIN_ANALOG+0}->{resolution};
}
if ($capabilities->{$pin}->{PIN_PWM+0}) {
push @pwmpins, $pin;
$self->{metadata}{pwm_resolutions}{$pin} = $capabilities->{$pin}->{PIN_PWM+0}->{resolution};
}
if ($capabilities->{$pin}->{PIN_SERVO+0}) {
push @analogpins, $pin;
$self->{metadata}{servo_resolutions}{$pin} = $capabilities->{$pin}->{PIN_SERVO+0}->{resolution};
}
if ($capabilities->{$pin}->{PIN_SHIFT+0}) {
push @shiftpins, $pin;
}
if ($capabilities->{$pin}->{PIN_I2C+0}) {
push @i2cpins, $pin;
@@ -271,6 +289,9 @@ sub sysex_handle {
$self->{metadata}{input_pins} = \@inputpins;
$self->{metadata}{output_pins} = \@outputpins;
$self->{metadata}{analog_pins} = \@analogpins;
$self->{metadata}{pwm_pins} = \@pwmpins;
$self->{metadata}{servo_pins} = \@servopins;
$self->{metadata}{shift_pins} = \@shiftpins;
$self->{metadata}{i2c_pins} = \@i2cpins;
$self->{metadata}{onewire_pins} = \@onewirepins;
last;
@@ -300,7 +321,7 @@ sub sysex_handle {
last;
};
$sysex_message->{command_str} eq 'ONEWIRE_REPLY' and do {
$sysex_message->{command_str} eq 'ONEWIRE_DATA' and do {
my $pin = $data->{pin};
my $observer = $self->{onewire_observer}[$pin];
if (defined $observer) {
@@ -309,7 +330,7 @@ sub sysex_handle {
last;
};
$sysex_message->{command_str} eq 'SCHEDULER_REPLY' and do {
$sysex_message->{command_str} eq 'SCHEDULER_DATA' and do {
my $observer = $self->{scheduler_observer};
if (defined $observer) {
$observer->{method}( $data, $observer->{context} );
@@ -572,6 +593,18 @@ sub i2c_config {
return $self->{io}->data_write($self->{protocol}->packet_i2c_config($delay,@data));
}
sub servo_write {
my ( $self, $pin, $value ) = @_;
return undef unless $self->is_configured_mode($pin,PIN_SERVO);
return analog_write( $self, $pin, $value );
}
sub servo_config {
my ( $self, $pin, $args ) = @_;
return undef unless $self->is_configured_mode($pin,PIN_SERVO);
return $self->{io}->data_write($self->{protocol}->packet_servo_config_request($pin,$args));
}
sub scheduler_create_task {
my $self = shift;
my $id=-1;

View File

@@ -296,13 +296,13 @@ sub sysex_parse {
last;
};
$command == $protocol_commands->{ONEWIRE_REPLY} and do {
$command == $protocol_commands->{ONEWIRE_DATA} and do {
$return_data = $self->handle_onewire_reply($sysex_data);
last;
};
$command == $protocol_commands->{SCHEDULER_REPLY} and do {
$return_data = $self->handle_scheduler_reply($sysex_data);
$command == $protocol_commands->{SCHEDULER_DATA} and do {
$return_data = $self->handle_scheduler_response($sysex_data);
last;
};
@@ -657,15 +657,15 @@ sub packet_i2c_config {
# * 7 END_SYSEX (0xF7)
# */
sub packet_servo_config {
sub packet_servo_config_request {
my ( $self, $data ) = @_;
my ( $self, $pin, $data ) = @_;
my $min_pulse = $data->{min_pulse};
my $max_pulse = $data->{max_pulse};
return $self->packet_sysex_command( SERVO_CONFIG,
$data->{pin} & 0x7f,
$pin & 0x7f,
$min_pulse & 0x7f,
$min_pulse >> 7,
$max_pulse & 0x7f,
@@ -693,17 +693,17 @@ sub packet_servo_config {
sub packet_onewire_search_request {
my ( $self, $pin ) = @_;
return $self->packet_sysex_command( ONEWIRE_REQUEST,$ONE_WIRE_COMMANDS->{SEARCH_REQUEST},$pin);
return $self->packet_sysex_command( ONEWIRE_DATA,$ONE_WIRE_COMMANDS->{SEARCH_REQUEST},$pin);
};
sub packet_onewire_search_alarms_request {
my ( $self, $pin ) = @_;
return $self->packet_sysex_command( ONEWIRE_REQUEST,$ONE_WIRE_COMMANDS->{SEARCH_ALARMS_REQUEST},$pin);
return $self->packet_sysex_command( ONEWIRE_DATA,$ONE_WIRE_COMMANDS->{SEARCH_ALARMS_REQUEST},$pin);
};
sub packet_onewire_config_request {
my ( $self, $pin, $power ) = @_;
return $self->packet_sysex_command( ONEWIRE_REQUEST, $ONE_WIRE_COMMANDS->{CONFIG_REQUEST},$pin,
return $self->packet_sysex_command( ONEWIRE_DATA, $ONE_WIRE_COMMANDS->{CONFIG_REQUEST},$pin,
( defined $power ) ? $power : 1
);
};
@@ -748,7 +748,7 @@ sub packet_onewire_request {
my $writeBytes=$args->{write};
push @data,@$writeBytes;
}
return $self->packet_sysex_command( ONEWIRE_REQUEST, $subcommand, $pin, pack_as_7bit(@data));
return $self->packet_sysex_command( ONEWIRE_DATA, $subcommand, $pin, pack_as_7bit(@data));
};
sub handle_onewire_reply {
@@ -797,49 +797,49 @@ sub handle_onewire_reply {
sub packet_create_task {
my ($self,$id,$len) = @_;
my $packet = $self->packet_sysex_command('SCHEDULER_REQUEST', $SCHEDULER_COMMANDS->{CREATE_FIRMATA_TASK}, $id, $len & 0x7F, $len>>7);
my $packet = $self->packet_sysex_command('SCHEDULER_DATA', $SCHEDULER_COMMANDS->{CREATE_FIRMATA_TASK}, $id, $len & 0x7F, $len>>7);
return $packet;
}
sub packet_delete_task {
my ($self,$id) = @_;
return $self->packet_sysex_command('SCHEDULER_REQUEST', $SCHEDULER_COMMANDS->{DELETE_FIRMATA_TASK}, $id);
return $self->packet_sysex_command('SCHEDULER_DATA', $SCHEDULER_COMMANDS->{DELETE_FIRMATA_TASK}, $id);
}
sub packet_add_to_task {
my ($self,$id,@data) = @_;
my $packet = $self->packet_sysex_command('SCHEDULER_REQUEST', $SCHEDULER_COMMANDS->{ADD_TO_FIRMATA_TASK}, $id, pack_as_7bit(@data));
my $packet = $self->packet_sysex_command('SCHEDULER_DATA', $SCHEDULER_COMMANDS->{ADD_TO_FIRMATA_TASK}, $id, pack_as_7bit(@data));
return $packet;
}
sub packet_delay_task {
my ($self,$time_ms) = @_;
my $packet = $self->packet_sysex_command('SCHEDULER_REQUEST', $SCHEDULER_COMMANDS->{DELAY_FIRMATA_TASK}, pack_as_7bit($time_ms & 0xFF, ($time_ms & 0xFF00)>>8, ($time_ms & 0xFF0000)>>16,($time_ms & 0xFF000000)>>24));
my $packet = $self->packet_sysex_command('SCHEDULER_DATA', $SCHEDULER_COMMANDS->{DELAY_FIRMATA_TASK}, pack_as_7bit($time_ms & 0xFF, ($time_ms & 0xFF00)>>8, ($time_ms & 0xFF0000)>>16,($time_ms & 0xFF000000)>>24));
return $packet;
}
sub packet_schedule_task {
my ($self,$id,$time_ms) = @_;
my $packet = $self->packet_sysex_command('SCHEDULER_REQUEST', $SCHEDULER_COMMANDS->{SCHEDULE_FIRMATA_TASK}, $id, pack_as_7bit($time_ms & 0xFF, ($time_ms & 0xFF00)>>8, ($time_ms & 0xFF0000)>>16,($time_ms & 0xFF000000)>>24));
my $packet = $self->packet_sysex_command('SCHEDULER_DATA', $SCHEDULER_COMMANDS->{SCHEDULE_FIRMATA_TASK}, $id, pack_as_7bit($time_ms & 0xFF, ($time_ms & 0xFF00)>>8, ($time_ms & 0xFF0000)>>16,($time_ms & 0xFF000000)>>24));
return $packet;
}
sub packet_query_all_tasks {
my $self = shift;
return $self->packet_sysex_command('SCHEDULER_REQUEST', $SCHEDULER_COMMANDS->{QUERY_ALL_FIRMATA_TASKS});
return $self->packet_sysex_command('SCHEDULER_DATA', $SCHEDULER_COMMANDS->{QUERY_ALL_FIRMATA_TASKS});
}
sub packet_query_task {
my ($self,$id) = @_;
return $self->packet_sysex_command('SCHEDULER_REQUEST', $SCHEDULER_COMMANDS->{QUERY_FIRMATA_TASK},$id);
return $self->packet_sysex_command('SCHEDULER_DATA', $SCHEDULER_COMMANDS->{QUERY_FIRMATA_TASK},$id);
}
sub packet_reset_scheduler {
my $self = shift;
return $self->packet_sysex_command('SCHEDULER_REQUEST', $SCHEDULER_COMMANDS->{RESET_FIRMATA_TASKS});
return $self->packet_sysex_command('SCHEDULER_DATA', $SCHEDULER_COMMANDS->{RESET_FIRMATA_TASKS});
}
sub handle_scheduler_reply {
sub handle_scheduler_response {
my ( $self, $sysex_data ) = @_;
my $command = shift @$sysex_data;