# Tired of christmas lights? how about a ultra-bright, ultra-low-res display with your led strip?

Posted on
• I was in the situation described in the subject, and wired my 25 led strip as an array; I tried uploading an image but couldn't - use your fantasy, it's 5 one way and five the other and so on. I also installed a 10 μF capacitor in parallel with the strip +5v (I read it's a good idea to be sure your power supply doesn't fry the first led when being powered).
If you have a 3d printer you can probably do much better than me, but I don't... so I used duct tape to keep it in place!
Also, I did the error of assuming a cartesian coordinate system, so my 0,0 is bottom left - I could have chosen top left and made my life easier (actually, I believe the docs for Graphics don't say anything about coordinate system, maybe they should?). Anyway, I was able to use the Graphics class to write to my led strip; I was inspired by the Adafruit Neopixel library as well, but didn't really get that nice separation between the strip and the matrix part they have; So here's the code:

``````function QuadStrip(width, height, spi) {
this.spi = spi;
this.spi.setup({baud:3200000});
var really_me = this;
this.width = width;
this.height = height;
this.size = width * height;
this.buffer = new Uint8Array(this.size * 3);
this.flip = function() {
this.spi.send4bit(this.buffer, 0b0001, 0b0011);
};
this.flip();
this.setPixel = function(x, y, c) {
var idx;
// If you wired it from top left, then check for === 0;
// I wired it from bottom left;
if (y % 2 === 1) {
idx = y * height + x;
} else {
idx = y * height + ((width - 1) - x);
}
idx = idx * 3;
really_me.buffer[idx] = (c & 0xff0000) >>> 16;
really_me.buffer[idx+1] = (c & 0x00ff00) >>> 8;
really_me.buffer[idx+2] = c & 0x0000ff;
};

// I only implemented fast clear because it's more common, because it
// gets called on Graphic.clear, and because I'm lazy
// If you need a proper fillRect you'll have to implement it.
this.fillRect = function(x1, y1, x2, y2, c) {
if (x1 === 0 &&
y1 === 0 &&
x2 === (really_me.width - 1) &&
y2 === (really_me.height - 1) &&
really_me.isGray(c)) {
var lum = c & 0x0000ff;
for (var i = 0; i < really_me.size * 3; i++) {
really_me.buffer[i] = lum;
}
} else {
print("Unimplemented.. sorry!");
}
};
this.isGray = function(c) {
var r = (c & 0xff0000) >>> 16;
var g = (c & 0x00ff00) >>> 8;
var b =  c & 0x0000ff;
return ((r == g) && (g == b));
};
}

``````

and you can use it like that:

``````
var strip = new QuadStrip(5,5, SPI1);
var graphic = Graphics.createCallback(5,5,24, strip);

``````

Which is not ideal, but you get an idea.. just a check with a bi-colored cross:

``````
graphic.setColor(0x0000ff);
graphic.drawLine(0,0,4,4);
graphic.setColor(0x220000);
graphic.drawLine(0,4,4,0);
strip.flip();

``````

Ah yes, you have to call flip() to actually send the thing via SPI.. on to something beefier: A tiny, unreadable, scrollable text that could be read from miles away (if it wasn't unreadable) because of display brigtness:

``````
var pos = 0;
var pix = -3;
var text = "HELLO ESPRUINO!";
function showText() {
if (pix > 4) {
pix = -3;
pos ++;
}
if (pos > text.length)
pos = 0;
graphic.clear();
graphic.drawString(text.charAt(pos), pix, 0);
strip.flip();
pix++;
}

setInterval(showText, 50);

``````

So there you go. Does anyone think that would be a good tutorial? if so I may polish it a bit and make it so, by having actual photos, and by fiddling with the code formatting (I can't get it to tab correctly), and also check if it works with other resolutions ( I only checked whith a 25 led strip, arranged as 5x5).

Bye!

• Hi - yes, I think that'd be really good. Even better if you can get some low-res images displayed :)

You may find this helpful: http://www.espruino.com/File+Converter (until 1v56 you'll have to ignore the base64 version though)

If you save an image file as a 5x5 pixel 8 bit RGB RAW file (maybe use ImageMagick and a command like `convert -size 5x5 file1.png output.rgb`) you could then load that file into the above webpage and it'll convert it to a string, which you can then put into the Web IDE and can use `buffer.set(myString)`... Although having said that you'll have to reverse every other row :)

You may also be able to create an 'ArrayBuffer' graphics instance without the callbacks. RGB123 works in pretty much exactly the same way (a zig-zag of WS2811s) so the Graphics library should handle it quite well: http://www.espruino.com/RGB123

• Hi Gordon,
Yes I actually did a small heart pixel by pixel at some point.. but converting something existing sounds convenient too (altrough.. with that resolution.. I don't know..).
Also, thanks for the tip on buffer.set(), I didn't realize I could blit characters into it.. I will certainly find some use for that, like easily implementing fillRect for non-gray colors.

So keep posted for the polished version as tutorial!

bye

Posted by @Loop