Let Unicorn hat draw blocks and part lines

and add some examples
This commit is contained in:
Dave Conway-Jones 2016-03-22 22:42:31 +00:00
parent 3cb42712bc
commit 0651f6fdc0
6 changed files with 155 additions and 135 deletions

View File

@ -29,13 +29,12 @@ png image, or by specifying a single colour using an r,g,b triple.
The brightness can also be set in the configuration. Defaults to 20% so as not
to blind you.
A pixel is set by `msg.payload` with a CSV string `x,y,r,g,b` , where x and y
are 0 to 7, and r, g and b are 0 - 255.
If `x` or `y` are set to `*` then the complete row or column can be set.
Setting both `x` and `y` to `*` fills the background.
Multiple pixels can be specified at once by using `x1,y1,r1,g1,b1,x2,y2,r2,g2,b2,...` etc
A pixel is set by a `payload` containing a CSV string `x,y,r,g,b` .
`x` and `y` can be a single pixel `0` to `7`, a range of pixels, eg `2-5`, or
`*` to indicate the whole line. Multiple pixels strings can also be sent as
`x1,y1,r1,g1,b1,x2,y2,r2,g2,b2,...` .
The background can also be set to a colour by setting `msg.payload` to an r,g,b triple.
The background can also be set to a colour by setting `msg.payload` to an `r,g,b` triple.
Any msg with a `msg.topic` identifies a 'sprite', which can then be moved
independently of the background. A 'sprite' can be a single pixel, or a group of pixels.
@ -46,6 +45,6 @@ Setting `msg.payload` to `DEL` delete any sprites - leaving the background.
Setting `msg.payload` to `CLS` will clear the display to off and delete any sprites.
The overall brightness may be set by setting `msg.payload` to `brightness,nn`, where `nn` is 0 to 100.
The overall brightness may be set by setting `msg.payload` to `brightness,nn`, where `nn` is `0 to 100`.
The rotation may be set by setting `msg.payload` to 'rotate,rr', where 'rr' is 0, 90, 180 or 270.
The rotation may be set by setting `msg.payload` to `rotate,rr`, where `rr` is `0`, `90`, `180` or `270`.

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name" : "node-red-node-pi-unicorn-hat",
"version" : "0.0.7",
"version" : "0.0.8",
"description" : "A Node-RED node to output to a Raspberry Pi Unicorn HAT from Pimorini.",
"dependencies" : {
"pngjs": "2.2.*"

View File

@ -33,18 +33,18 @@
<script type="text/x-red" data-help-name="rpi-unicorn">
<p>Raspberry Pi Unicorn HAT Node</p>
<p>The background of the array can be configured using an 8x8 pixel sized
png image, or by specifying a single colour using an <i>r,g,b</i> triple.</p>
<p>The background colour can also be set by a <code>msg.payload</code> with an <i>r,g,b</i> triple.</p>
<p>A pixel is set by a <code>payload</code> containing a CSV string <i>x,y,r,g,b</i> .
Multiple pixels strings can also be sent as <i>x1,y1,r1,g1,b1,x2,y2,r2,g2,b2,...</i> .
If x or y are set to * then the complete row or column can be set.</p>
png image, or by specifying a single colour using an <code>r,g,b</code> triple.</p>
<p>A pixel is set by a <code>payload</code> containing a CSV string <code>x,y,r,g,b</code> .
<code>x</code> and <code>y</code> can be a single pixel <code>0</code> to <code>7</code>,
a range of pixels, eg <code>2-5</code>, or <code>*</code> to indicate the whole line.
Multiple pixels strings can also be sent as <code>x1,y1,r1,g1,b1,x2,y2,r2,g2,b2,...</code> .</p>
<p>Any msg with a <code>topic</code> identifies a 'sprite', which can then
be moved independently. A 'sprite' can be a single pixel or a group of pixels.</p>
<p>Setting <code>payload</code> to 0 will delete the sprite from the list.</p>
<p>Setting <code>payload</code> to "CLS" will clear the display to off and delete any sprites.</p>
<p>Setting <code>payload</code> to "DEL" will delete any sprites, and leave the background.</p>
<p>The brightness may be set by setting <code>payload</code> to <i>brightness,nn</i> where nn is 0 to 100.</p>
<p>The rotation may be set by setting <code>payload</code> to <i>rotate,rr</i> where rr is 0, 90, 180 or 270.</p>
<p>Setting <code>payload</code> to <code>0</code> will delete the sprite from the list.</p>
<p>Setting <code>payload</code> to <code>CLS</code> will clear the display to off and delete any sprites.</p>
<p>Setting <code>payload</code> to <ode>DEL</ode> will delete any sprites, and leave the background.</p>
<p>The brightness may be set by setting <code>payload</code> to <code>brightness,nn</code> where nn is 0 to 100.</p>
<p>The rotation may be set by setting <code>payload</code> to <code>rotate,rr</code> where rr is 0, 90, 180 or 270.</p>
</script>
<script type="text/javascript">

View File

@ -92,124 +92,128 @@ module.exports = function(RED) {
else { ready = true; }
function inputlistener(msg) {
var a,b,c,d,e;
var s = msg.payload.toUpperCase().split(",");
var doDraw = true;
if (s.length === 1) {
if (s[0] == "CLS") {
//console.log("CLEAR")
pic.fill(0);
node.items = {};
}
if (s[0] == "DEL") {
//console.log("DELETE")
node.items = {};
}
}
else if (s.length === 2) {
if (s[0] === "BRIGHTNESS") {
//console.log("BRIGHTNESS",s[1])
node.child.stdin.write("B"+s[1]+"\n");
}
if (s[0] === "ROTATE") {
//console.log("ROTATE",s[1])
node.child.stdin.write("R"+s[1]+"\n");
}
}
else if (s.length === 3) {
//console.log("BACKGROUND",s)
for (var i=0; i<192; i++) {
pic[i] = s[0];
pic[i+1] = s[1];
pic[i+2] = s[2];
i += 2;
}
}
else if (s.length % 5 === 0) { // handles pixel updates
if (msg.topic) {
node.items[msg.topic] = msg.payload;
}
else {
node.child.stdin.write('P'+msg.payload+'\n');
doDraw = false;
for (a=0; a<s.length; a++) {
//console.log("PIXELS",a);
if ((s[a] === "*") && (s[a+1] === "*")) {
for (c=0; c<192; c++) {
pic[c] = s[a+2];
pic[c+1] = s[a+3];
pic[c+2] = s[a+4];
c += 2;
}
}
else if (s[a] === "*") {
for (d=0; d<8; d++) {
pic[d*3+s[1]*24] = s[a+2];
pic[d*3+s[1]*24+1] = s[a+3];
pic[d*3+s[1]*24+2] = s[a+4];
}
}
else if (s[a+1] === "*") {
for (e=0; e<8; e++) {
pic[s[a]*3+e*24] = s[a+2];
pic[s[a]*3+e*24+1] = s[a+3];
pic[s[a]*3+e*24+2] = s[a+4];
}
}
else {
pic[s[a]*3+s[a+1]*24] = s[a+2];
pic[s[a]*3+s[a+1]*24+1] = s[a+3];
pic[s[a]*3+s[a+1]*24+2] = s[a+4];
}
a += 4;
if (typeof msg.payload === "string") {
var a,b,c,d,e;
msg.payload = msg.payload.replace('"','');
var s = msg.payload.toUpperCase().split(",");
var doDraw = true;
if (s.length === 1) {
if (s[0] == "CLS") {
//console.log("CLEAR")
pic.fill(0);
node.items = {};
}
if (s[0] == "DEL") {
//console.log("DELETE")
node.items = {};
}
}
}
else if (s.length === 192) { // handle complete buffer refresh.
for (var h=0; h<192; h++) {
pic[h] = s[h];
pic[h+1] = s[h+1];
pic[h+2] = s[h+2];
h += 2;
else if (s.length === 2) {
if (s[0] === "BRIGHTNESS") {
//console.log("BRIGHTNESS",s[1])
node.child.stdin.write("B"+s[1]+"\n");
}
if (s[0] === "ROTATE") {
//console.log("ROTATE",s[1])
node.child.stdin.write("R"+s[1]+"\n");
}
}
}
else {
if (node.items.hasOwnProperty(msg.topic)) { delete node.items[msg.topic]; }
}
if (doDraw) {
var pixels = new Buffer(192);
pic.copy(pixels);
for (var p in node.items) {
if (node.items.hasOwnProperty(p)) {
b = node.items[p].split(",");
for (a=0; a<b.length; a++) {
if (b[a] === "*") {
for (d=0; d<8; d++) {
pixels[d*3+b[a+1]*24] = b[a+2];
pixels[d*3+b[a+1]*24+1] = b[a+3];
pixels[d*3+b[a+1]*24+2] = b[a+4];
else if (s.length === 3) {
//console.log("BACKGROUND",s)
for (var i=0; i<192; i++) {
pic[i] = s[0];
pic[i+1] = s[1];
pic[i+2] = s[2];
i += 2;
}
}
else if (s.length % 5 === 0) { // handles pixel updates
if (msg.topic) {
node.items[msg.topic] = msg.payload;
}
else {
node.child.stdin.write('P'+msg.payload+'\n');
doDraw = false;
for (a=0; a<s.length; a++) {
//console.log("PIXELS",a);
if ((s[a] === "*") && (s[a+1] === "*")) {
for (c=0; c<192; c++) {
pic[c] = s[a+2];
pic[c+1] = s[a+3];
pic[c+2] = s[a+4];
c += 2;
}
}
else if (b[a+1] === "*") {
else if (s[a] === "*") {
for (d=0; d<8; d++) {
pic[d*3+s[1]*24] = s[a+2];
pic[d*3+s[1]*24+1] = s[a+3];
pic[d*3+s[1]*24+2] = s[a+4];
}
}
else if (s[a+1] === "*") {
for (e=0; e<8; e++) {
pixels[b[a]*3+e*24] = b[a+2];
pixels[b[a]*3+e*24+1] = b[a+3];
pixels[b[a]*3+e*24+2] = b[a+4];
pic[s[a]*3+e*24] = s[a+2];
pic[s[a]*3+e*24+1] = s[a+3];
pic[s[a]*3+e*24+2] = s[a+4];
}
}
else {
pixels[b[a]*3+b[a+1]*24] = b[a+2];
pixels[b[a]*3+b[a+1]*24+1] = b[a+3];
pixels[b[a]*3+b[a+1]*24+2] = b[a+4];
pic[s[a]*3+s[a+1]*24] = s[a+2];
pic[s[a]*3+s[a+1]*24+1] = s[a+3];
pic[s[a]*3+s[a+1]*24+2] = s[a+4];
}
a += 4;
}
}
}
node.child.stdin.write(pixels);
node.child.stdin.write("\n");
else if (s.length === 192) { // handle complete buffer refresh.
for (var h=0; h<192; h++) {
pic[h] = s[h];
pic[h+1] = s[h+1];
pic[h+2] = s[h+2];
h += 2;
}
}
else {
if (node.items.hasOwnProperty(msg.topic)) { delete node.items[msg.topic]; }
}
if (doDraw) {
var pixels = new Buffer(192);
pic.copy(pixels);
for (var p in node.items) {
if (node.items.hasOwnProperty(p)) {
b = node.items[p].split(",");
for (a=0; a<b.length; a++) {
if (b[a] === "*") {
for (d=0; d<8; d++) {
pixels[d*3+b[a+1]*24] = b[a+2];
pixels[d*3+b[a+1]*24+1] = b[a+3];
pixels[d*3+b[a+1]*24+2] = b[a+4];
}
}
else if (b[a+1] === "*") {
for (e=0; e<8; e++) {
pixels[b[a]*3+e*24] = b[a+2];
pixels[b[a]*3+e*24+1] = b[a+3];
pixels[b[a]*3+e*24+2] = b[a+4];
}
}
else {
pixels[b[a]*3+b[a+1]*24] = b[a+2];
pixels[b[a]*3+b[a+1]*24+1] = b[a+3];
pixels[b[a]*3+b[a+1]*24+2] = b[a+4];
}
a += 4;
}
}
}
node.child.stdin.write(pixels);
node.child.stdin.write("\n");
}
}
else { node.warn("Input not a string"); }
}
node.child = spawn(hatCommand, [node.bright]);

View File

@ -39,19 +39,35 @@ while True:
data = data[1:].strip()
s = data.split(',')
for p in range(0,len(s),5):
j = 1
if (s[p] == "*") and (s[p+1] == "*"):
for i in range(0,8):
for j in range(0,8):
UH.set_pixel(i,j,int(s[p+2]),int(s[p+3]),int(s[p+4]))
elif s[p] == "*":
for i in range(0,8):
UH.set_pixel(i,int(s[p+1]),int(s[p+2]),int(s[p+3]),int(s[p+4]))
elif s[p+1] == "*":
for i in range(0,8):
UH.set_pixel(int(s[p]),i,int(s[p+2]),int(s[p+3]),int(s[p+4]))
else :
UH.set_pixel(int(s[p]),int(s[p+1]),int(s[p+2]),int(s[p+3]),int(s[p+4]))
x1 = 0
x2 = 0
y1 = 0
y2 = 0
if s[p] == "*":
x1 = 0
x2 = 8
elif "-" in s[p]:
x1 = int(s[p].split('-')[0]) % 8
x2 = int(s[p].split('-')[1]) % 8 + 1
if x1 >= x2:
x2,x1 = x1+1,x2-1
else:
x1 = int(s[p])
x2 = int(s[p])+1
if s[p+1] == "*":
y1 = 0
y2 = 8
elif "-" in s[p+1]:
y1 = int(s[p+1].split('-')[0]) % 8
y2 = int(s[p+1].split('-')[1]) % 8 + 1
if y1 >= y2:
y2,y1 = y1+1,y2-1
else:
y1 = int(s[p+1]) % 8
y2 = int(s[p+1]) % 8 + 1
for i in range(x1,x2):
for j in range(y1,y2):
UH.set_pixel(i,j,int(s[p+2]),int(s[p+3]),int(s[p+4]))
else:
q = 0
for p in range(64):