@@ -19,10 +19,18 @@ with 'Reflex::Role::Streaming' => {
19
19
cb_closed => make_terminal_emitter(on_closed => " closed" ),
20
20
};
21
21
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
+
22
29
has buffer => ( isa => ' Str' , is => ' rw' , default => ' ' );
23
30
24
31
# 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' );
26
34
27
35
{
28
36
package Firmata::Pin ;
@@ -39,6 +47,12 @@ has pins => (
39
47
default => sub { [] },
40
48
);
41
49
50
+ sub on_handle_error {
51
+ my ($self , $arg ) = @_ ;
52
+ use YAML;
53
+ warn YAML::Dump($arg );
54
+ }
55
+
42
56
before put_handle => sub {
43
57
my ($self , $message ) = @_ ;
44
58
print " --> " , $self -> hexify($message ), " \n " ;
@@ -136,23 +150,49 @@ sub on_handle_data {
136
150
137
151
if ($buffer =~ s / ^\xF9 (..)// s ) {
138
152
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 );
140
162
next ;
141
163
}
142
164
143
165
# SysEx? Ogods!
144
166
145
167
if ($buffer =~ s / ^\xF0\x79 (..)(.*?)\xF7 // s ) {
146
168
my ($maj , $min ) = unpack (" CC" , $1 );
169
+ my $new_string = $self -> firmata_string_parse($2 );
147
170
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
+ }
156
196
157
197
next ;
158
198
}
@@ -161,12 +201,14 @@ sub on_handle_data {
161
201
162
202
if ($buffer =~ s / ^\xF0\x71 (.*?)\xF7 // s ) {
163
203
my $string = $self -> firmata_string_parse($1 );
204
+ if (0) {
164
205
$self -> emit(
165
206
event => " string" ,
166
207
args => {
167
208
string => $string ,
168
209
},
169
210
);
211
+ }
170
212
next ;
171
213
}
172
214
@@ -213,9 +255,10 @@ sub on_handle_data {
213
255
# with emits/observes traits and all. Problem is, we need to
214
256
# build those attributes at runtime after the object has been
215
257
# running for a little while.
258
+
216
259
$self -> emit(
217
- event => " capabilities " ,
218
- args => { }, # TODO
260
+ event => " initialized " ,
261
+ args => { }, # TODO - What?!
219
262
);
220
263
221
264
next ;
@@ -233,49 +276,51 @@ sub on_handle_data {
233
276
my $port = ord ($1 ) & 0x0F;
234
277
my ($lsb , $msb ) = unpack " CC" , $2 ;
235
278
my $value = (($msb & 0x7F) << 7) | ($lsb & 0x7F);
236
-
279
+ if (0) {
237
280
$self -> emit(
238
281
event => " analog" ,
239
282
args => {
240
283
pin => $port ,
241
284
value => $value ,
242
285
},
243
286
);
287
+ }
244
288
next ;
245
289
}
246
290
247
291
if ($buffer =~ s / ^([\x90 -\x9F ])(..)// s ) {
248
292
my $port = ord ($1 ) & 0x0F;
249
293
my ($lsb , $msb ) = unpack " CC" , $2 ;
250
294
my $value = (($msb & 0x7F) << 7) | ($lsb & 0x7F);
251
-
295
+ if (0) {
252
296
$self -> emit(
253
297
event => " digital" ,
254
298
args => {
255
299
pin => $port ,
256
300
value => $value ,
257
301
},
258
302
);
303
+ }
259
304
next ;
260
305
}
261
306
262
307
# TODO - These are Firmata commands. Stuff we send to the device.
263
308
# 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
+ # }
271
316
#
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
+ # }
279
324
280
325
last ;
281
326
}
@@ -309,4 +354,37 @@ sub hexify {
309
354
return $data ;
310
355
}
311
356
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
+
312
390
1;
0 commit comments