Skip to content

Commit 57b4e32

Browse files
committed
Do more with the device's advertised capabilities.
1 parent f9ce8be commit 57b4e32

File tree

2 files changed

+111
-32
lines changed

2 files changed

+111
-32
lines changed

Firmata.pm

+106-28
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,18 @@ with 'Reflex::Role::Streaming' => {
1919
cb_closed => make_terminal_emitter(on_closed => "closed"),
2020
};
2121

22+
has init_wait => ( isa => 'Num', is => 'rw', default => 10 );
23+
has init_wait_autostart => ( isa => 'Bool', is => 'ro', default => 0 );
24+
with 'Reflex::Role::Timeout' => {
25+
att_delay => 'init_wait',
26+
att_auto_start => 'init_wait_autostart',
27+
};
28+
2229
has buffer => ( isa => 'Str', is => 'rw', default => '' );
2330

2431
# Whee.
25-
emits protocol_version => ( is => 'rw', isa => 'Num', default => 0 );
32+
emits protocol_version => ( is => 'rw', isa => 'Num' );
33+
emits protocol_string => ( is => 'rw', isa => 'Str' );
2634

2735
{
2836
package Firmata::Pin;
@@ -39,6 +47,12 @@ has pins => (
3947
default => sub { [] },
4048
);
4149

50+
sub on_handle_error {
51+
my ($self, $arg) = @_;
52+
use YAML;
53+
warn YAML::Dump($arg);
54+
}
55+
4256
before put_handle => sub {
4357
my ($self, $message) = @_;
4458
print "--> ", $self->hexify($message), "\n";
@@ -136,23 +150,49 @@ sub on_handle_data {
136150

137151
if ($buffer =~ s/^\xF9(..)//s) {
138152
my ($maj, $min) = unpack("CC", $1);
139-
$self->protocol_version("$maj.$min");
153+
my $new_version = "$maj.$min";
154+
155+
my $old_version = $self->protocol_version();
156+
if (defined $old_version) {
157+
next if $old_version == $new_version;
158+
warn "Version changed from $old_version to $new_version";
159+
}
160+
161+
$self->protocol_version($new_version);
140162
next;
141163
}
142164

143165
# SysEx? Ogods!
144166

145167
if ($buffer =~ s/^\xF0\x79(..)(.*?)\xF7//s) {
146168
my ($maj, $min) = unpack("CC", $1);
169+
my $new_string = $self->firmata_string_parse($2);
147170

148-
my $string = $self->firmata_string_parse($2);
149-
$self->emit(
150-
event => "version",
151-
args => {
152-
version => "$maj.$min",
153-
firmware => $string,
154-
},
155-
);
171+
my $new_version = "$maj.$min";
172+
173+
my $old_version = $self->protocol_version();
174+
if (defined $old_version) {
175+
unless ($old_version == $new_version) {
176+
warn "Version changed from $old_version to $new_version";
177+
$self->protocol_version($new_version);
178+
}
179+
}
180+
else {
181+
# This one's silent.
182+
$self->protocol_version($new_version);
183+
}
184+
185+
my $old_string = $self->protocol_string();
186+
if (defined $old_string) {
187+
unless ($old_string eq $new_string) {
188+
warn "Version string changed from '$old_string' to '$new_string'";
189+
$self->protocol_string($new_string);
190+
}
191+
}
192+
else {
193+
# This one's silent.
194+
$self->protocol_string($new_string);
195+
}
156196

157197
next;
158198
}
@@ -161,12 +201,14 @@ sub on_handle_data {
161201

162202
if ($buffer =~ s/^\xF0\x71(.*?)\xF7//s) {
163203
my $string = $self->firmata_string_parse($1);
204+
if (0) {
164205
$self->emit(
165206
event => "string",
166207
args => {
167208
string => $string,
168209
},
169210
);
211+
}
170212
next;
171213
}
172214

@@ -213,9 +255,10 @@ sub on_handle_data {
213255
# with emits/observes traits and all. Problem is, we need to
214256
# build those attributes at runtime after the object has been
215257
# running for a little while.
258+
216259
$self->emit(
217-
event => "capabilities",
218-
args => { }, # TODO
260+
event => "initialized",
261+
args => { }, # TODO - What?!
219262
);
220263

221264
next;
@@ -233,49 +276,51 @@ sub on_handle_data {
233276
my $port = ord($1) & 0x0F;
234277
my ($lsb, $msb) = unpack "CC", $2;
235278
my $value = (($msb & 0x7F) << 7) | ($lsb & 0x7F);
236-
279+
if (0) {
237280
$self->emit(
238281
event => "analog",
239282
args => {
240283
pin => $port,
241284
value => $value,
242285
},
243286
);
287+
}
244288
next;
245289
}
246290

247291
if ($buffer =~ s/^([\x90-\x9F])(..)//s) {
248292
my $port = ord($1) & 0x0F;
249293
my ($lsb, $msb) = unpack "CC", $2;
250294
my $value = (($msb & 0x7F) << 7) | ($lsb & 0x7F);
251-
295+
if (0) {
252296
$self->emit(
253297
event => "digital",
254298
args => {
255299
pin => $port,
256300
value => $value,
257301
},
258302
);
303+
}
259304
next;
260305
}
261306

262307
# TODO - These are Firmata commands. Stuff we send to the device.
263308
# TODO - We could handle these if we wanted to emulate a device.
264-
# if ($buffer =~ s/^([\xC0-\xCF])(..)//s) {
265-
# my $port = ord($1) & 0x0F;
266-
# my ($lsb, $msb) = unpack "CC", $2;
267-
# my $value = $lsb & 0x01;
268-
# print "<-- a($port) set $value\n";
269-
# next;
270-
# }
309+
# if ($buffer =~ s/^([\xC0-\xCF])(..)//s) {
310+
# my $port = ord($1) & 0x0F;
311+
# my ($lsb, $msb) = unpack "CC", $2;
312+
# my $value = $lsb & 0x01;
313+
# print "<-- a($port) set $value\n";
314+
# next;
315+
# }
271316
#
272-
# if ($buffer =~ s/^([\xD0-\xDF])(..)//s) {
273-
# my $port = ord($1) & 0x0F;
274-
# my ($lsb, $msb) = unpack "CC", $2;
275-
# my $value = $lsb & 0x01;
276-
# print "<-- d($port) set $value\n";
277-
# next;
278-
# }
317+
# if ($buffer =~ s/^([\xD0-\xDF])(..)//s) {
318+
# my $port = ord($1) & 0x0F;
319+
# my ($lsb, $msb) = unpack "CC", $2;
320+
# my $value = $lsb & 0x01;
321+
# print "<-- d($port) set $value\n";
322+
# next;
323+
# }
279324

280325
last;
281326
}
@@ -309,4 +354,37 @@ sub hexify {
309354
return $data;
310355
}
311356

357+
sub on_init_wait_done {
358+
my ($self, $timeout) = @_;
359+
$self->put_handle("\xFF");
360+
$self->emit(event => "has_reset");
361+
}
362+
363+
sub initialize_from_device {
364+
my $self = shift;
365+
366+
ATTEMPT: while (1) {
367+
warn "attempt";
368+
369+
# Wait for a protocol string.
370+
$self->start_init_wait();
371+
my $e = $self->next('protocol_string', 'has_reset');
372+
next ATTEMPT if $e->{name} eq 'has_reset';
373+
$self->stop_init_wait();
374+
375+
# Request capabilities.
376+
$self->put_handle("\xF0\x6B\xF7");
377+
378+
# Wait for initialization.
379+
$self->start_init_wait();
380+
$self->next('initialized', 'has_reset');
381+
next ATTEMPT if $e->{name} eq 'has_reset';
382+
$self->stop_init_wait();
383+
384+
last ATTEMPT;
385+
}
386+
387+
$self->stop_init_wait();
388+
}
389+
312390
1;

test.pl

+5-4
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,16 @@
5858
#$device->digital_report(0, 1);
5959

6060
# Pins 12 and 13 are digital output.
61-
$device->digital_out(12);
62-
$device->digital_out(13);
61+
#$device->digital_out(12);
62+
#$device->digital_out(13);
6363

6464
# Read digital input on pin 7.
6565
# Wire one of pins 12 or 13 to pin 7, and watch it register input
6666
# as that port lights up.
6767

68-
$device->digital_in(7);
69-
$device->digital_report(0, 1 << 6);
68+
$device->digital_in($_) for 0..15;
69+
$device->digital_report(0, 0x7f);
70+
$device->digital_report(1, 0x7f);
7071

7172
# Some silly sample rate.
7273
# It may only be for analog?

0 commit comments

Comments
 (0)