-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4547c71
commit 7f72890
Showing
2 changed files
with
133 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright 2018 Dan Jacques. All rights reserved. | ||
// Use of this source code is governed under the MIT License | ||
// that can be found in the LICENSE file. | ||
|
||
package main | ||
|
||
import ( | ||
"github.com/danjacques/gopushpixels/demo/colorphase" | ||
) | ||
|
||
func main() { | ||
colorphase.Main() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// Copyright 2018 Dan Jacques. All rights reserved. | ||
// Use of this source code is governed under the MIT License | ||
// that can be found in the LICENSE file. | ||
|
||
package colorphase | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
"log" | ||
"time" | ||
|
||
"github.com/danjacques/gopushpixels/device" | ||
"github.com/danjacques/gopushpixels/discovery" | ||
"github.com/danjacques/gopushpixels/pixel" | ||
) | ||
|
||
var ( | ||
fps = flag.Int("fps", 30, "FPS that colors will be cycled.") | ||
) | ||
|
||
// Main is the main entry point. | ||
func Main() { | ||
flag.Parse() | ||
|
||
// Calculate sleep interval from FPS. | ||
sleepInterval := time.Second / (time.Second * time.Duration(*fps)) | ||
|
||
// Start discovery. | ||
var l discovery.Listener | ||
conn, err := discovery.DefaultListenerConn().ListenMulticastUDP4() | ||
if err != nil { | ||
log.Fatalf("Couldn't listen for discovery packets: %s", err) | ||
} | ||
defer conn.Close() | ||
if err := l.Start(conn); err != nil { | ||
log.Fatalf("Couldn't start discovery listener: %s", err) | ||
} | ||
|
||
var reg discovery.Registry | ||
c := context.Background() | ||
for { | ||
dh, err := l.Accept(c) | ||
if err != nil { | ||
log.Fatalf("Error listening for discovery packets: %s", err) | ||
} | ||
if d, isNew := reg.Observe(dh); isNew { | ||
go cycleColors(d, sleepInterval) | ||
} | ||
} | ||
} | ||
|
||
func cycleColors(d device.D, sleepInterval time.Duration) { | ||
log.Printf("Cycling on device: %s", d.ID()) | ||
|
||
sender, err := d.Sender() | ||
if err != nil { | ||
log.Printf("Could't create sender for device %q: %s", d.ID(), err) | ||
return | ||
} | ||
defer sender.Close() | ||
|
||
// Create a mutable state for the device. | ||
var m device.Mutable | ||
m.Initialize(d.DiscoveryHeaders()) | ||
|
||
var c cycler | ||
for { | ||
// Cycle colors. | ||
// | ||
// First, shift all pixels towards the end. | ||
next := c.Next() | ||
for s := 0; s < m.NumStrips(); s++ { | ||
for i := m.PixelsPerStrip() - 1; i > 0; i-- { | ||
m.SetPixel(s, i, m.GetPixel(s, i-1)) | ||
} | ||
m.SetPixel(s, 0, next) | ||
} | ||
|
||
// Send any update packets. | ||
if pkt := m.SyncPacket(); pkt != nil { | ||
if err := sender.SendPacket(pkt); err != nil { | ||
log.Printf("Couldn't send packet to device %q: %s", d.ID(), err) | ||
return | ||
} | ||
} | ||
|
||
time.Sleep(sleepInterval) | ||
} | ||
} | ||
|
||
type cycler struct { | ||
r, g, b int | ||
offset int | ||
} | ||
|
||
func (c *cycler) Next() (p pixel.P) { | ||
var v *int | ||
var pos *byte | ||
switch c.offset { | ||
case 0: | ||
v, pos = &c.r, &p.Red | ||
case 1: | ||
v, pos = &c.g, &p.Green | ||
case 2: | ||
v, pos = &c.b, &p.Blue | ||
} | ||
|
||
*v++ | ||
switch { | ||
case *v > 0x1FF: | ||
*v, *pos = 0, 0 | ||
c.offset = ((c.offset + 1) % 3) | ||
case *v > 0xFF: | ||
*pos = 0xFF - byte(*v) | ||
default: | ||
*pos = byte(*v) | ||
} | ||
return | ||
} |