-
I successfully drove NeoPixel matrices using MOSI pin (D13) on my dev board from: https://www.ezsbc.com/index.php/featured-products-list-home-page/wifi01-32.html#.Wo4QjxPwZTY
I'm making a clock with 4 buttons as input. Later I discovered that setWatch currently only works for D12 - D15 (using 1.95). Some pin throw error when I set setWatch (unable to setWatch) and some can be set but once button is pressed I got either crashes or turning on board LED . As I think I'll need D13 for one of the button, I'll need some alternative pin to drive the matrix.
Anybody knows if I can use other pin(s) to drive the matrix? I thought about software SPI but the code I use to write accept direct pin:
neopixel.write(D13, ledbuffer);
Thanks!
-
That does it! Thanks @Gordon! You're the best :)!
-
I see - I think that could work, but I'd have to reassemble my module differently:
00 01 02 03 16 17 18 19 32 33 34 35 07 06 05 04 23 22 21 20 39 38 37 36 08 09 10 11 24 25 26 27 40 41 42 43 15 14 13 12 31 30 29 28 47 46 45 44 //TO 00 01 02 03 07 06 05 04 08 09 10 11 15 14 13 12 16 17 18 19 23 22 21 20 24 25 26 27 31 30 29 28 ...
However, being rotated, I don't think doing
leds.drawString("123")
will draw expectedly something like
/* \\\\\\\\\\\\\\\\\ \\\ 123 \\\ \\\\\\\\\\\\\\\\\ */
but instead will create a rotated version of
///////// // 123 // // // // // // // // // // // /////////
Would work for fillRect or lines I think, but I need to draw text...
Thanks again!
-
Thanks MaBe for the comment.
I modified the H count:
Graphics.createArrayBuffer(4,12,24);
but doesn't work for my 3 plates horizontal with this led array sequence:
00 01 02 03 16 17 18 19 32 33 34 35 07 06 05 04 23 22 21 20 39 38 37 36 08 09 10 11 24 25 26 27 40 41 42 43 15 14 13 12 31 30 29 28 47 46 45 44
-
So I did a manual remapping from the Graphics.buffer to the way my modules are chained:
/* Graphics.buffer (not zigzag): 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 My module chained, three 4x4 modules horizontally: 00 01 02 03 16 17 18 19 32 33 34 35 07 06 05 04 23 22 21 20 39 38 37 36 08 09 10 11 24 25 26 27 40 41 42 43 15 14 13 12 31 30 29 28 47 46 45 44 */
And use this code, with a util function to copy the triplets of RGB per index:
// var neopixel = require("neopixel"); var leds = Graphics.createArrayBuffer(12,4,24,{zigzag:false}); var getTriplet = function(array,index){ index*=3; var result =[array[index],array[index+1],array[index+2]]; return result; }; leds.flip = function() { var rawBuffer = []; rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,0)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,1)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,2)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,3)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,15)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,14)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,13)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,12)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,24)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,25)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,26)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,27)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,39)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,38)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,37)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,36)); // rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,4)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,5)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,6)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,7)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,19)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,18)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,17)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,16)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,28)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,29)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,30)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,31)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,43)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,42)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,41)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,40)); // rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,8)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,9)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,10)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,11)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,23)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,22)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,21)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,20)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,32)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,33)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,34)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,35)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,47)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,46)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,45)); rawBuffer.push.apply(rawBuffer,getTriplet(leds.buffer,44)); neopixel.write(B15, rawBuffer); };
The above does the trick, but all of the array operations slowed down the performance quite a bit... :(
Anybody know any tips on the best way for this kinds of operation?
-
I got a several 4x4 neopixel-compatible modules:
and would like to string several of them horizontally to create a 16x4 matrix. Can the Graphics library work with this configuration?
I know in the RGB123 example you can create an array buffer x*y but wondering if it will work with arbitrary rows and columns since in regard to the wirings of arbitrary modules.
Thanks!
*edit: I need to do 12X4 instead of 16X4
-
@allObjects That's awesome that you made your version! I'm dying to get back to the project, but still can't touch it until next week (if only I can do this all day everyday :)). I'll give it a shot, first reimplementing the interrupt setup and handling with my code to learn, and give your 'module' a try. I'd really be interested in comparing the perf of setInterval with your implementation. I moved to a NodeMCU esp8266 for a fuller build (with 3d printed chassis) - putting Date().ms comparison at the start and the end of my scan routine with setInterva of 50ms gives me ~50ms so no hit, but when I moved to try on ESP32 (for more pins) I get 150ms. Could this be also because of I2C performance difference?
Anyway, thanks so much, will try and report back.
-
-
-
Looking at the datasheet, seems like I need to setup the expander's interrupt pin. How can I do that? Is it by writing via I2C? I'm afraid a lot of these hardware concepts is flying over my head :) Here's how I wire up the expander, espruino, and the matrix (omitting some details such as I2C pullup resistors, power, and gnd):
-
-
-
Thanks for the detailed explanations. Seems like since I have the row and column scanning routines already, the remaining thing to do is set up the interrupt. Will this work like a switch? So if I connect INTA to say B13 on espruino, do I simply setwatch B13 and anytime button is pressed on the matrix an event will fire? Or do I need to set up something between the expander GPIO and the INTA?
Much appreciated!
-
-
I went ahead and tried the interval route, and seemed to have made it work. Possible downside is the interval eating resource for other stuff, but I think I can get away with it by being smart in clearing the interval when input is safely not needed.
My solution:
var i2c = new I2C(); i2c.setup({ scl: B2, sda: B3 }); var address = 0; //this is the address, set by the address pins. // for MCP23017 var port = require("MCP23017").connect(i2c, null, address); //matrix var colPins = [port.A7, port.A6, port.A5, port.A4]; var rowPins = [port.A3, port.A2, port.A1, port.A0]; //set col to low for (var i in colPins) { colPins[i].mode("output"); colPins[i].write(0); } //set row to 1 via pull up for (var j in rowPins) { rowPins[j].mode("input_pullup"); } var col = -1; var row = -1; var lastButton = null; function mapToButton(c, r) { if (c === 3 && r === 3) return ("B1"); if (c === 2 && r === 3) return ("B2"); if (c === 1 && r === 3) return ("B3"); if (c === 0 && r === 3) return ("B4"); if (c === 3 && r === 2) return ("B5"); if (c === 2 && r === 2) return ("B6"); if (c === 1 && r === 2) return ("B7"); if (c === 0 && r === 2) return ("B8"); if (c === 3 && r === 1) return ("B9"); if (c === 2 && r === 1) return ("B10"); if (c === 1 && r === 1) return ("B11"); if (c === 0 && r === 1) return ("B12"); if (c === 3 && r === 0) return ("B13"); if (c === 2 && r === 0) return ("B14"); if (c === 1 && r === 0) return ("B15"); if (c === 0 && r === 0) return ("B16"); } function scanCol() { //set col to low var i, j; for (i in colPins) { colPins[i].mode("output"); colPins[i].write(0); } //set row to 1 via pull up for (j in rowPins) { rowPins[j].mode("input_pullup"); } for (i in rowPins) { if (rowPins[i].read() === 0) { col = i; break; } } } function scanRow() { //set row to low var i, j; for (i in rowPins) { rowPins[i].mode("output"); rowPins[i].write(0); } //set row to 1 via pull up for (j in colPins) { colPins[j].mode("input_pullup"); } for (i in colPins) { if (colPins[i].read() === 0) { row = i; break; } } if (col >= 0 && row >= 0) { var btn = mapToButton(col, row); if (lastButton !== btn) { print(btn); lastButton = btn; } } } setInterval(function () { col = -1; row = -1; scanCol(); if (col >= 0) { scanRow(); } else { lastButton = null; } }, 50);
Would still love to hear if it is possible to use setWatch btw!
-
Thanks for the reply @allObjects - So I did a quick test, hooked up via I2C and instantiated as "port". Tried:
setWatch(function(){print("test")},port.A0,{repeat:true,edge:'both'});
Got an error:
ERROR: Invalid pin
I suspect that the virtual pin is not compatible with the Pin() object the setWatch function expects...
Or, did you meant hooking up setWatch differently?
-
-
-
(consolidating my post under this account, I have 2, user81779 is my other one I'm retiring, sorry if this is causing confusion)
So I did further test and the module seems to be flawed as it does not support R + other color scenario. I used this code:
setInterval(function(){ data[0] = 0b11111111; data[2] = 0b11111111 << i ; data[1] = 0b00000000; data[3] = 0x01 << 0 ; i++; if(i>=8)i=0; SPI1.write(data,A6); },500);
for combining B+G and R+B (video attached). Red did suck the power out of other color diodes. No go with this module :( I'm better off 3d-printing a pixel mask on top of neopixel. Price wise, an 8x8 neopixel matrix clone is pretty good.
Thanks @allObjects for your keen interest and assistance!
-
I bought a cheap RGB123 clone (16x16 WS28xx rgb matrix) and the neopixel lib works with it. My problem is using Graphics lib the display is flipped on this module. I seem to need to mirror the buffer horizontally. I know that Graphics has setRotation to apply rotation before writing to the buffer, is there similar thing for mirroring? Another way could be to clone the buffer and apply matrix transform (is the arrayBuffer a 2D array?) to mirror it and then write the transformed buffer to the LEDs. Thought I'd ask here before researching the buffer transform route...
-
-
require("neopixel");
The neopixel module seems to be not available. I got the "module not found" from the web IDE. I tried hitting http://www.espruino.com/modules/neopixel.js and got 404. Has it been renamed / moved?
Thanks!
-
-
Thanks for the reply @Gordon. Sorry I wasn't clear, I tried to do that but I couldn't understand the keypad.js enough to successfully modify it for ESP8266. I tried to switch all the "input_pulldown" to "input_pullup" and set the rows to low instead of high but no dice. Any hint on how to accomplish this in general? Thanks again!
PS. Kudos & great work with Espruino! made MCU development so accessible to an old JS hack like me :) I bought all 3 variants of the official espruino board, but planning to use NodeMCU boards as "throwaway" project boards.
Thanks! I have all the pins I need now!