pixel_pi 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 08cca7dba9a29b50641d0408dcbe81a1f5c86e7e
4
- data.tar.gz: 7aaf72769a673bac2c41d23111fbec22658b0c73
3
+ metadata.gz: 1c158234b67ccd01d55b48cf274c5ccb437ae77a
4
+ data.tar.gz: 5125b6c0d47381ca23ba8fc942ac73d22f9f3bbb
5
5
  SHA512:
6
- metadata.gz: 50a6c2996d7421024e4c657cc17936b7ee28da810fb6820fbb94199200d1e3025e9899c3338adb29bb40fa827acdc6fe419f2f3f9878e62949932d2761cfaf64
7
- data.tar.gz: b9e70d44aeb4e8e7332f3d04f7321e0f3922c1253fb52f7afcea9deb4d004d1803df44b536de3759a33dbfbcdd837ba0870d5a37cd66d989695bbf2f6a743603
6
+ metadata.gz: d010f3d8e722cb39aea7cd13cb78e92621628014799899bb08def77a0b0e1333dcf88362aa797f88ccdf2949b6d524f80bf23fa3302951e875e974fbf0e7a80b
7
+ data.tar.gz: acdac849b6517a354918be99681e360592a8edb77ca18a77bc741aba66008c56b42a62a760500a9026f6bd41c7d6d1a7794d5085765e3a39fee56637ef8129e0
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
+ *.gem
1
2
  tmp
@@ -54,11 +54,11 @@ module StrandTest
54
54
  spacing = opts.fetch(:spacing, 3)
55
55
 
56
56
  iterations.times do
57
- spacing.times do |jj|
58
- (0...self.length).step(spacing) { |ii| self[ii+jj] = color }
57
+ spacing.times do |sp|
58
+ self.clear
59
+ (sp...self.length).step(spacing) { |ii| self[ii] = color }
59
60
  self.show
60
61
  sleep(wait_ms / 1000.0)
61
- (0...self.length).step(spacing) { |ii| self[ii+jj] = 0 }
62
62
  end
63
63
  end
64
64
 
@@ -71,6 +71,7 @@ module StrandTest
71
71
  #
72
72
  # Returns a 24-bit RGB color value.
73
73
  def wheel( pos )
74
+ pos = pos & 0xff
74
75
  if pos < 85
75
76
  return PixelPi::Color(pos * 3, 255 - pos * 3, 0)
76
77
  elsif pos < 170
@@ -94,7 +95,7 @@ module StrandTest
94
95
  iterations = opts.fetch(:iterations, 1)
95
96
 
96
97
  (0...256*iterations).each do |jj|
97
- self.length.times { |ii| self[ii] = wheel((ii+jj) & 0xff) }
98
+ self.fill { |ii| wheel(ii+jj) }
98
99
  self.show
99
100
  sleep(wait_ms / 1000.0)
100
101
  end
@@ -114,7 +115,7 @@ module StrandTest
114
115
  iterations = opts.fetch(:iterations, 5)
115
116
 
116
117
  (0...256*iterations).each do |jj|
117
- self.length.times { |ii| self[ii] = wheel(((ii * 256 / self.length) + jj) & 0xff) }
118
+ self.fill { |ii| wheel((ii * 256 / self.length) + jj) }
118
119
  self.show
119
120
  sleep(wait_ms / 1000.0)
120
121
  end
@@ -135,10 +136,10 @@ module StrandTest
135
136
 
136
137
  256.times do |jj|
137
138
  spacing.times do |sp|
138
- (0...self.length).step(spacing) { |ii| self[ii+sp] = wheel((ii+jj) % 255) }
139
+ self.clear
140
+ (sp...self.length).step(spacing) { |ii| self[ii] = wheel((ii+jj) % 255) }
139
141
  self.show
140
142
  sleep(wait_ms / 1000.0)
141
- (0...self.length).step(spacing) { |ii| self[ii+sp] = 0 }
142
143
  end
143
144
  end
144
145
 
@@ -158,10 +159,10 @@ strip = PixelPi::Leds.new \
158
159
  strip.extend StrandTest
159
160
 
160
161
  trap("SIGINT") do
161
- strip.clear
162
- strip.close # not explicitly needed - the finalizer will gracefully shutdown
163
- exit # the PWM channel and release the DMA memory
164
- end
162
+ strip.clear.show # turn off all the LEDs
163
+ strip.close # close is not explicitly needed - the finalizer will
164
+ exit # gracefully shutdown the PWM channel and release the
165
+ end # DMA memory
165
166
 
166
167
  STDOUT.puts "Press Ctrl-C to quit."
167
168
 
@@ -3,6 +3,10 @@
3
3
 
4
4
  #define RGB2COLOR(r,g,b) ((((r) & 0xff) << 16) | (((g) & 0xff) << 8) | ((b) & 0xff))
5
5
 
6
+ #ifndef MIN
7
+ #define MIN(a,b) (((a)<(b))?(a):(b))
8
+ #endif
9
+
6
10
  VALUE mPixelPi;
7
11
  VALUE cLeds;
8
12
  VALUE ePixelPiError;
@@ -69,9 +73,9 @@ pp_leds_struct( VALUE self )
69
73
  static int
70
74
  pp_rgb_to_color( VALUE red, VALUE green, VALUE blue )
71
75
  {
72
- int r = NUM2INT(red);
73
- int g = NUM2INT(green);
74
- int b = NUM2INT(blue);
76
+ int r = FIX2INT(red);
77
+ int g = FIX2INT(green);
78
+ int b = FIX2INT(blue);
75
79
  return RGB2COLOR(r, g, b);
76
80
  }
77
81
 
@@ -110,7 +114,7 @@ pp_leds_initialize( int argc, VALUE* argv, VALUE self )
110
114
 
111
115
  /* get the number of pixels */
112
116
  if (TYPE(length) == T_FIXNUM) {
113
- ledstring->channel[0].count = NUM2INT(length);
117
+ ledstring->channel[0].count = FIX2INT(length);
114
118
  if (ledstring->channel[0].count < 0) {
115
119
  rb_raise( rb_eArgError, "length cannot be negative: %d", ledstring->channel[0].count );
116
120
  }
@@ -120,7 +124,7 @@ pp_leds_initialize( int argc, VALUE* argv, VALUE self )
120
124
 
121
125
  /* get the GPIO number */
122
126
  if (TYPE(gpio) == T_FIXNUM) {
123
- ledstring->channel[0].gpionum = NUM2INT(gpio);
127
+ ledstring->channel[0].gpionum = FIX2INT(gpio);
124
128
  if (ledstring->channel[0].gpionum < 0) {
125
129
  rb_raise( rb_eArgError, "GPIO cannot be negative: %d", ledstring->channel[0].gpionum );
126
130
  }
@@ -135,7 +139,7 @@ pp_leds_initialize( int argc, VALUE* argv, VALUE self )
135
139
  tmp = rb_hash_lookup( opts, sym_dma );
136
140
  if (!NIL_P(tmp)) {
137
141
  if (TYPE(tmp) == T_FIXNUM) {
138
- ledstring->dmanum = NUM2INT(tmp);
142
+ ledstring->dmanum = FIX2INT(tmp);
139
143
  if (ledstring->dmanum < 0) {
140
144
  rb_raise( rb_eArgError, "DMA channel cannot be negative: %d", ledstring->dmanum );
141
145
  }
@@ -148,7 +152,7 @@ pp_leds_initialize( int argc, VALUE* argv, VALUE self )
148
152
  tmp = rb_hash_lookup( opts, sym_frequency );
149
153
  if (!NIL_P(tmp)) {
150
154
  if (TYPE(tmp) == T_FIXNUM) {
151
- ledstring->freq = NUM2UINT(tmp);
155
+ ledstring->freq = FIX2UINT(tmp);
152
156
  } else {
153
157
  rb_raise( rb_eTypeError, "frequency must be a number: %s", rb_obj_classname(tmp) );
154
158
  }
@@ -158,7 +162,7 @@ pp_leds_initialize( int argc, VALUE* argv, VALUE self )
158
162
  tmp = rb_hash_lookup( opts, sym_brightness );
159
163
  if (!NIL_P(tmp)) {
160
164
  if (TYPE(tmp) == T_FIXNUM) {
161
- ledstring->channel[0].brightness = (NUM2UINT(tmp) & 0xff);
165
+ ledstring->channel[0].brightness = (FIX2UINT(tmp) & 0xff);
162
166
  if (ledstring->channel[0].brightness < 0) {
163
167
  rb_raise( rb_eArgError, "brightness cannot be negative: %d", ledstring->channel[0].brightness );
164
168
  }
@@ -273,7 +277,7 @@ static VALUE
273
277
  pp_leds_brightness_set( VALUE self, VALUE brightness )
274
278
  {
275
279
  ws2811_t *ledstring = pp_leds_struct( self );
276
- ledstring->channel[0].brightness = (NUM2UINT(brightness) & 0xff);
280
+ ledstring->channel[0].brightness = (FIX2UINT(brightness) & 0xff);
277
281
  return brightness;
278
282
  }
279
283
 
@@ -308,24 +312,23 @@ pp_leds_clear( VALUE self )
308
312
  {
309
313
  ws2811_t *ledstring = pp_leds_struct( self );
310
314
  ws2811_channel_t channel = ledstring->channel[0];
311
- int ii, resp;
315
+ int ii;
312
316
 
313
317
  for (ii=0; ii<channel.count; ii++) {
314
318
  channel.leds[ii] = 0;
315
319
  }
316
320
 
317
- resp = ws2811_render( ledstring );
318
- if (resp < 0) {
319
- rb_raise( rb_eRuntimeError, "PixelPi::Leds failed to render: %d", resp );
320
- }
321
-
322
321
  return self;
323
322
  }
324
323
 
325
324
  /* call-seq:
326
325
  * close
327
326
  *
328
- * FIXME
327
+ * Shutdown the NeoPixels connected to the DMA / PWM channel. After this method
328
+ * the current PixelPi::Leds instance will no longer be usable; a new instance
329
+ * will need to be created. This method is automatically invoked when the
330
+ * instance is deallcoated by the Ruby garbage collector. It does not need to be
331
+ * explicitly invoked.
329
332
  *
330
333
  * Returns `nil`.
331
334
  */
@@ -350,7 +353,7 @@ pp_leds_get_pixel_color( VALUE self, VALUE num )
350
353
  ws2811_t *ledstring = pp_leds_struct( self );
351
354
  ws2811_channel_t channel = ledstring->channel[0];
352
355
 
353
- int n = NUM2INT(num);
356
+ int n = FIX2INT(num);
354
357
  if (n < 0 || n >= channel.count) {
355
358
  rb_raise( rb_eIndexError, "index %d is outside of LED range: 0...%d", n, channel.count-1 );
356
359
  }
@@ -372,9 +375,9 @@ pp_leds_set_pixel_color( VALUE self, VALUE num, VALUE color )
372
375
  ws2811_t *ledstring = pp_leds_struct( self );
373
376
  ws2811_channel_t channel = ledstring->channel[0];
374
377
 
375
- int n = NUM2INT(num);
378
+ int n = FIX2INT(num);
376
379
  if (n >= 0 && n < channel.count) {
377
- channel.leds[n] = NUM2INT(color);
380
+ channel.leds[n] = FIX2UINT(color);
378
381
  }
379
382
  return self;
380
383
  }
@@ -415,6 +418,204 @@ pp_leds_set_pixel_color2( int argc, VALUE* argv, VALUE self )
415
418
  return self;
416
419
  }
417
420
 
421
+ /* call-seq:
422
+ * to_a
423
+ *
424
+ * Takes the current list of 24-bit RGB values stored in the LED strings and
425
+ * returns them as an Array. These colors might not be actively displayed; it
426
+ * all depends if `show` has been called on the PixelPi::Leds instance.
427
+ *
428
+ * Returns an Array of 24-bit RGB values.
429
+ */
430
+ static VALUE
431
+ pp_leds_to_a( VALUE self )
432
+ {
433
+ ws2811_t *ledstring = pp_leds_struct( self );
434
+ ws2811_channel_t channel = ledstring->channel[0];
435
+ int ii;
436
+ VALUE ary;
437
+
438
+ ary = rb_ary_new2( channel.count );
439
+ for (ii=0; ii<channel.count; ii++) {
440
+ rb_ary_push( ary, INT2NUM(channel.leds[ii]) );
441
+ }
442
+
443
+ return ary;
444
+ }
445
+
446
+ /* call-seq:
447
+ * replace( ary )
448
+ *
449
+ * Replace the LED colors with the 24-bit RGB color values found in the `ary`.
450
+ * If the `ary` is longer than the LED string then the extra color values will
451
+ * be ignored. If the `ary` is shorter than the LED string then only the LEDS
452
+ * up to `ary.length` will be changed.
453
+ *
454
+ * You must call `show` for the new colors to be displayed.
455
+ *
456
+ * Returns this PixelPi::Leds instance.
457
+ */
458
+ static VALUE
459
+ pp_leds_replace( VALUE self, VALUE ary )
460
+ {
461
+ ws2811_t *ledstring = pp_leds_struct( self );
462
+ ws2811_channel_t channel = ledstring->channel[0];
463
+ int ii, min;
464
+
465
+ Check_Type( ary, T_ARRAY );
466
+ min = MIN(channel.count, RARRAY_LEN(ary));
467
+
468
+ for (ii=0; ii<min; ii++) {
469
+ channel.leds[ii] = FIX2UINT(rb_ary_entry( ary, ii ));
470
+ }
471
+
472
+ return self;
473
+ }
474
+
475
+ static void
476
+ pp_leds_reverse( ws2811_led_t *p1, ws2811_led_t *p2 )
477
+ {
478
+ while (p1 < p2) {
479
+ ws2811_led_t tmp = *p1;
480
+ *p1++ = *p2;
481
+ *p2-- = tmp;
482
+ }
483
+ }
484
+
485
+ /* call-seq:
486
+ * reverse
487
+ *
488
+ * Reverse the order of the LED colors.
489
+ *
490
+ * Returns this PixelPi::Leds instance.
491
+ */
492
+ static VALUE
493
+ pp_leds_reverse_m( VALUE self )
494
+ {
495
+ ws2811_t *ledstring = pp_leds_struct( self );
496
+ ws2811_channel_t channel = ledstring->channel[0];
497
+ ws2811_led_t *ptr = channel.leds;
498
+ int len = channel.count;
499
+
500
+ if (--len > 0) pp_leds_reverse( ptr, ptr + len );
501
+
502
+ return self;
503
+ }
504
+
505
+ /* call-seq:
506
+ * rotate( count = 1 )
507
+ *
508
+ * Rotates the LED colors in place so that the color at `count` comes first. If
509
+ * `count` is negative then it rotates in the opposite direction, starting from
510
+ * the end of the LEDs where -1 is the last LED.
511
+ *
512
+ * Returns this PixelPi::Leds instance.
513
+ */
514
+ static VALUE
515
+ pp_leds_rotate( int argc, VALUE* argv, VALUE self )
516
+ {
517
+ ws2811_t *ledstring = pp_leds_struct( self );
518
+ ws2811_channel_t channel = ledstring->channel[0];
519
+ int cnt = 1;
520
+
521
+ switch (argc) {
522
+ case 1: cnt = FIX2INT(argv[0]);
523
+ case 0: break;
524
+ default: rb_scan_args( argc, argv, "01", NULL );
525
+ }
526
+
527
+ if (cnt != 0) {
528
+ ws2811_led_t *ptr = channel.leds;
529
+ int len = channel.count;
530
+ cnt = (cnt < 0) ? (len - (~cnt % len) - 1) : (cnt % len);
531
+
532
+ if (len > 0 && cnt > 0) {
533
+ --len;
534
+ if (cnt < len) pp_leds_reverse( ptr + cnt, ptr + len );
535
+ if (--cnt > 0) pp_leds_reverse( ptr, ptr + cnt );
536
+ if (len > 0) pp_leds_reverse( ptr, ptr + len );
537
+ }
538
+ }
539
+
540
+ return self;
541
+ }
542
+
543
+ /* call-seq:
544
+ * fill( color )
545
+ * fill( color, start [, length] )
546
+ * fill( color, range )
547
+ * fill { |index| block }
548
+ * fill( start [, length] ) { |index| block }
549
+ * fill( range ) { |index| block }
550
+ *
551
+ * Set the selected LEDs to the given `color`. The `color` msut be given as a
552
+ * 24-bit RGB value. You can also supply a block that receives an LED index and
553
+ * returns a 24-bit RGB color.
554
+ *
555
+ * Examples:
556
+ * leds.fill( 0x00FF00 )
557
+ * leds.fill( 0xFF0000, 2, 2 )
558
+ * leds.fill( 0x0000FF, (4...8) )
559
+ * leds.fill { |i| 256 << i }
560
+ *
561
+ * Returns this PixelPi::Leds instance.
562
+ */
563
+ static VALUE
564
+ pp_leds_fill( int argc, VALUE* argv, VALUE self )
565
+ {
566
+ ws2811_t *ledstring = pp_leds_struct( self );
567
+ ws2811_channel_t channel = ledstring->channel[0];
568
+ ws2811_led_t color = 0;
569
+
570
+ VALUE item, arg1, arg2, v;
571
+ long ii, beg = 0, end = 0, len = 0;
572
+ int block_p = 0;
573
+
574
+ if (rb_block_given_p()) {
575
+ block_p = 1;
576
+ rb_scan_args( argc, argv, "02", &arg1, &arg2 );
577
+ argc += 1;
578
+ } else {
579
+ rb_scan_args( argc, argv, "12", &item, &arg1, &arg2 );
580
+ color = FIX2UINT(item);
581
+ }
582
+
583
+ switch (argc) {
584
+ case 1:
585
+ beg = 0;
586
+ len = channel.count;
587
+ break;
588
+ case 2:
589
+ if (rb_range_beg_len(arg1, &beg, &len, channel.count, 1)) {
590
+ break;
591
+ }
592
+ /* fall through */
593
+ case 3:
594
+ beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
595
+ if (beg < 0) {
596
+ beg = channel.count + beg;
597
+ if (beg < 0) beg = 0;
598
+ }
599
+ len = NIL_P(arg2) ? channel.count - beg : NUM2LONG(arg2);
600
+ break;
601
+ }
602
+
603
+ if (len < 0) return self;
604
+
605
+ end = beg + len;
606
+ end = MIN((long) channel.count, end);
607
+
608
+ for (ii=beg; ii<end; ii++) {
609
+ if (block_p) {
610
+ v = rb_yield(INT2NUM(ii));
611
+ color = FIX2UINT(v);
612
+ }
613
+ channel.leds[ii] = color;
614
+ }
615
+
616
+ return self;
617
+ }
618
+
418
619
  /* call-seq:
419
620
  * PixelPi::Color(red, green, blue) #=> 24-bit color
420
621
  *
@@ -456,6 +657,11 @@ void Init_leds( )
456
657
  rb_define_method( cLeds, "[]", pp_leds_get_pixel_color, 1 );
457
658
  rb_define_method( cLeds, "[]=", pp_leds_set_pixel_color, 2 );
458
659
  rb_define_method( cLeds, "set_pixel", pp_leds_set_pixel_color2, -1 );
660
+ rb_define_method( cLeds, "to_a", pp_leds_to_a, 0 );
661
+ rb_define_method( cLeds, "replace", pp_leds_replace, 1 );
662
+ rb_define_method( cLeds, "reverse", pp_leds_reverse_m, 0 );
663
+ rb_define_method( cLeds, "rotate", pp_leds_rotate, -1 );
664
+ rb_define_method( cLeds, "fill", pp_leds_fill, -1 );
459
665
 
460
666
  rb_define_module_function( mPixelPi, "Color", pp_color, 3 );
461
667
 
@@ -1,3 +1,3 @@
1
1
  module PixelPi
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pixel_pi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Pease
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-21 00:00:00.000000000 Z
11
+ date: 2014-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler