-
• #1
-
• #2
I keep getting this error, the first part will send 100+ times. and the actual program is this, any ideas?
-
• #3
I cannot see anything wrong in the logic of your code. From what I get is that you fill an array with functions that do different lights. Such a light pattern function is then called every 50ms and you start with pattern with index 0. When you press the button, you increment the index (with modulo, currently commented) and run the new pattern - which you get by invoking next pattern.
...never mind next paragraph (came across your other conversation about A HY Mini-STM32 VCT6 3.2" board... and there LCD is probably defined... the LCD that is part of the board... but you errors with it and that could be the reason all is failing...)...
What is not clear to me is the LCD... I don't see any initialization or so... and do not understand what you want to achieve with it... (btw, you set the color first, before you draw,... drawing the rectangle border first, and then draw a filled rectangle, is that what you want?)
(And btw, cycle is an undeclared global).
To get to the bottom of the story, check each of your pattern function at once...
It is a good practice to put your initiating / starting code into
onInit()
function, so you can make sure that the upload just sets the stuff up (in your case actually fills up the array), but does not right away start to operate on the data/functions.After upload, you then enter in the console
onInit()
and then it begins to run... (if onInit() is too long to type, create a r() - run - function that calls onInit()). You can then also create a s() - stop - function that clears the interval withclearInterval(cycle);
to stop the cycling. -
• #4
LCD
is actually built-in on the HY STM32 boards.I'm not sure I understand what you're doing - for each LED you're completely wiping the screen with fillRect for most patterns - so it's going to be insanely slow and almost certainly not what you want.
If you want to see the lights on the screen, remove all the LCD calls you have, and change
doLights
to:function doLights() { getPattern(); for (var i=0;i<rgb.length;i+=3) { LCD.setColor(rgb[i+0]/256,rgb[i+1]/256,rgb[i+2]/256); LCD.fillRect(i,0,i+2,10); } SPI2.send4bit(rgb, 0b0001, 0b0011); }
Your actual problem is
changePattern()
. It actually works fine until you press the button?For some reason you've actually commented out the code that made it work - so unsurprisingly it's now broken.
function changePattern() { patternNumber = (patternNumber+1); //% patterns.length; getPattern = patterns[patternNumber]; }
should be:
function changePattern() { patternNumber = (patternNumber+1) % patterns.length; getPattern = patterns[patternNumber]; }
The percent is a 'modulo' - basically if patternNumber gets bigger than the number of patterns then it rolls over back to 0.
Without it, patternNumber gets bigger, and you try and access something in the patterns array that doesn't exist, which gives you undefined.
Finally, you probably also want to debounce the switch, so use:
setWatch(changePattern, BTN, { repeat: true, edge:'rising', debounce: 50 });
instead of just
setWatch(changePattern, BTN, { repeat: true, edge:'rising' });
-
• #5
/*var sensor = require("HC-SR04").connect(C6,C7,function(dist) { console.log(dist+" cm away"); }); setInterval(function() { sensor.trigger(); // send pulse }, 500); */ SPI2.setup({baud:3200000, mosi:B15}); var rgb = new Uint8Array(50*3); var pos=0; function lightsOff() { clearInterval(cycle); pos++; for (var i=0;i<rgb.length;i+=3) { rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = 0; } SPI2.send4bit(rgb, 0b0001, 0b0011); } var patterns = []; //patterns.push(lightsOff); patterns.push(function() { // Fading white lights LCD.clear(); pos++; for (var i=0;i<rgb.length;i+=3) { var col = (Math.sin(i+pos*0.2)+1) * 127; rgb[i ] = col; rgb[i+1] = col; rgb[i+2] = col; } }); patterns.push(function() { // Red Light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = col; rgb[i+1] = 0; rgb[i+2] = 0; } }); patterns.push(function() { // Green Light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = 0; rgb[i+1] = col; rgb[i+2] = 0; } }); patterns.push(function() { // Blue Light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = col; } }); patterns.push(function() { // Yellow light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = col; rgb[i+1] = col; rgb[i+2] = 0; } }); patterns.push(function() { // Cyan light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = 0; rgb[i+1] = col; rgb[i+2] = col; } }); patterns.push(function() { // Fading colours pos++; for (var i=0;i<rgb.length;i+=3) { rgb[i ] = (1 + Math.sin((i+pos)*0.1324))*127; rgb[i+1] = (1 + Math.sin((i+pos)*0.1654))*127; rgb[i+2] = (1 + Math.sin((i+pos)*0.1)) * 127; } }); patterns.push(function() { // Random blue lights for (var i=0;i<rgb.length;i+=3) { rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = Math.random()*255; } }); var getPattern = patterns[0]; function changePattern() { patternNumber = (patternNumber+1) % patterns.length; getPattern = patterns[patternNumber]; SPI2.send4bit(rgb, 0b0001, 0b0011); } var patternNumber = 0; function changePattern() { patternNumber = (patternNumber+1) % patterns.length; getPattern = patterns[patternNumber]; } setWatch(changePattern, BTN, { repeat: true, edge:'rising', debounce: 50 }); //cycle = setInterval(doLights,50); // this below was ^ function doLights() { getPattern(); for (var i=0;i<rgb.length;i+=3) { LCD.setColor(rgb[i+0]/256,rgb[i+1]/256,rgb[i+2]/256); LCD.fillRect(i,0,i+2,10); } SPI2.send4bit(rgb, 0b0001, 0b0011); }
-
• #6
So this is the new code correct? Shouldn't the screen show what the leds are showing and then the screen isn't showing anything?
-
• #7
You seem to have commented out the line
cycle = setInterval(doLights,50);
I guess it was failing because you moved the definition of
doLights
to be after the command, where it was before? Just put the linecycle = setInterval(doLights,50);
after you defineddoLights
.If you get an error and comment stuff out, can say in the future? It can save a lot of time.
Also, if you want code to show up in the forum properly, you need to highlight it and click the
</> code
button - I've just done that for you above. -
• #8
Now it won't send it, it either gets a 1/4 of the way on the progress bar or 90 and then it becomes un responsive.
-
• #9
any ideas?
-
• #10
Did you change anything else? Did you plug in via the other USB connector this time by mistake?
-
• #11
I think i fixed it, thank you so very much!
-
• #12
If i want to make the size of the box on the lcd what numbers would i need to adjust?
-
• #13
I know how to fix the y2 and that made it taller, any way to make it wider?
-
• #14
Check the references for fillRect(...) and drawRect(...).
-
• #15
But the code has i, I'm not sure how i can change that. Its not that simple of a rect allObjects
-
• #16
@GarrettL, line 143
LCD.fillRect(i,0,i+2,10);
is obviously where it happens... and what it does is drawing 50 bars (rectangles) of 3x10 pixels - 3 pixels wide, 10 pixels heigh.The current setup / code takes advantage of the stepping of 3 and makes it 3 wide... depending on the pixels you have in x-axis, you can make it wider... I assume you have a 240x320 display... I though do not know how you orient it: is x-axis (A) 240 pixels, or (b) 320 pixels... It matters, but not really, because you can calculate it...
I suggest you explore your options with these 3 steps:
1st, replace line 143 with these two lines:
LCD.fillRect(x,y,x+xd,y+yd); x += xi; y += yi;
2nd, insert between line 140 and 141 this line:
var x = 0, y = 0;
3rd, to make everything work, you do some prep work between line 10 and 11 with these lines:
var WX = 240, HY = 320, Orient = "y", xi, yi, xd, yd; if (Orient === "x") { xi = Math.floor(WX / (rgb.length / 3)); yi = 0; xd = xi - 1; yd = 29; } else { xi = 0; yi = Math.floor(HY / (rgb.length / 3)); xd = 29; yd = yi - 1; }
The Constant
Orient
says in which direction - x or y - you want to show the (50) LEDs and is used to calculate how many pixels you can use per LED to fit in one line in - x or y - direction.Enjoy!
-
• #17
I tried the code, and it just shows a bar on the left side and i believe it lost all control of the buttons or what it is showing.
-
• #18
Or it just has a delay of the showing
-
• #19
@GarrettL, what I prepared for you are 2 emulations in html5 and movie clips of them running: your initial code and then the code with my suggestion changes to display the LEDs on the display in maximal size - in either vertical or horizontal orientation . Click RGBLightsEmulation2.html link, play with it, view the source (in the browser). To run it on Espruino, copy the portion from line 29 through 223 to the Espruino Web IDE, upload it to your board, and run it by entering in the console
lightsOn()
andlightsOff()
, respective.I used emulation to verify the code because I do not have the LED string and didn't want to wire up my SPI connected LCD to Original/Pico/Wifi/Puck Espruino boards (using the LCD over SPI is so slow that it does not allow to have 50ms redraw cycles... :(... ). Furthermore, emulation shows that cross development is easily and quickly to achieve, is very useful, and is fun. Note that I use your Espruino code as is (with a minor fix that has nothing to do with the emulation0)...
You can run the emulations yourself by clicking on the html attachments. You start and stop the lights by clicking on lightsOn() and lightsOff() buttons. These buttons are for convenience and work as if you entered the commands into the Espruino console (or browser debug console). Cycling through your light patterns is done by clicking repeatedly on the BTN button.
The code in html5 with my suggested modifications for displaying the LED string in maximal size - either vertical or horizontal - looks like below and includes the code for Espruino from line 83 thru 223:
<html><!-- RGBLightsEmulation2.html --> <head> <title>RGB Led Project - Help</title> <style> .btn-bar { padding: 0.3em 0 0.3em 0; } .lcd { border: 1em [#AFAFAF](https://forum.espruino.com/search/?q=%23AFAFAF) solid; } </style> </head> <body> <b>RGBLightsEmulation2</b> <!-- hardware emulation / manifestations --> <div class="btn-bar"> <button id="BTN">BTN</button> </div> <div> <canvas id="LCD" width="240px" height="320px" class="lcd"></canvas> </div> <div><!-- console entry conveniences --> <div class="btn-bar"> <button onclick="lightsOn();">lightsOn()</button> <button onclick="lightsOff();">lightsOff()</button> </div> <script> // some html5 helpers var ee_ = { e: function(i) { return document.getElementById(i); } }; </script> <script> // Espruino shim / emulation var Pin = function(id) { this.id = id; this.state = false; this.watch = null; this.connect(); // connect to hardware emulation / manifestation }; Pin.prototype.connect = function() { var hw = ee_.e(this.id), _this = this; if (hw) { hw.addEventListener("mousedown", function() { _this.setState(true ); }); hw.addEventListener("mouseup" , function() { _this.setState(false); }); } }; Pin.prototype.setState = function(state) { state = state && true; if (this.state !== state) { this.state = state; if ( this.watch && ( this.watch.opts.edge === "both" || ( this.state && (this.watch.opts.edge === "rising" )) || (!this.state && (this.watch.opts.edge === "falling")) ) ) { this.watch.fnct(); } } }; var ee_watches = []; function setWatch(fnct, pin, opts) { opts = opts || {}; opts.repeat = ("undefined" === typeof opts.repeat ) ? true : opts.repeat; opts.edge = ("undefined" === typeof opts.edge ) ? "both" : opts.edge; opts.debounce = ("undefined" === typeof opts.debounce) ? 0 : opts.debounce; pin.watch = { fnct: fnct, opts: opts }; } var SPI2 = { setup: function() {} , send4bit: function() {} } var LCD = { dsp: ee_.e("LCD") , clr: "#000000" , clear: function() {} , setColor: function(r,g,b) { // console.log("LCD.setColor(): " + r + "-" + g + "-" + b); var clr = "#"; clr += ("0" + (Math.round(r * 255) & 255).toString(16)).substr(-2); clr += ("0" + (Math.round(g * 255) & 255).toString(16)).substr(-2); clr += ("0" + (Math.round(b * 255) & 255).toString(16)).substr(-2); this.clr = clr; } , fillRect(x1, y1, x2, y2) { // console.log("LCD.fillRect(): " + this.clr + " " + x1 + "@" + y1 + "x" + x2 + "@" + y2); var ctx = this.dsp.getContext("2d"); ctx.fillStyle = this.clr; ctx.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1); } } var BTN = new Pin("BTN"); var B15 = new Pin("B15"); </script> <script> // ---------- Espruino user code ---------- SPI2.setup({baud:3200000, mosi:B15}); var rgb = new Uint8Array(50*3); var WX = 240, HY = 320, Orient = "y", xi, yi, xd, yd; if (Orient === "x") { xi = Math.floor(WX / (rgb.length / 3)); yi = 0; xd = xi - 1; yd = 29; } else { xi = 0; yi = Math.floor(HY / (rgb.length / 3)); xd = 29; yd = yi - 1; } var pos=0; function lightsOff() { cycle = clearInterval(cycle); pos++; for (var i=0;i<rgb.length;i+=3) { rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = 0; } SPI2.send4bit(rgb, 0b0001, 0b0011); } var patterns = []; patterns.push(function() { // Fading white lights // LCD.clear(); // allObjects: this does not belong here pos++; for (var i=0;i<rgb.length;i+=3) { var col = (Math.sin(i+pos*0.2)+1) * 127; rgb[i ] = col; rgb[i+1] = col; rgb[i+2] = col; } }); patterns.push(function() { // Red Light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = col; rgb[i+1] = 0; rgb[i+2] = 0; } }); patterns.push(function() { // Green Light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = 0; rgb[i+1] = col; rgb[i+2] = 0; } }); patterns.push(function() { // Blue Light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = col; } }); patterns.push(function() { // Yellow light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = col; rgb[i+1] = col; rgb[i+2] = 0; } }); patterns.push(function() { // Cyan light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = 0; rgb[i+1] = col; rgb[i+2] = col; } }); patterns.push(function() { // Fading colours pos++; for (var i=0;i<rgb.length;i+=3) { rgb[i ] = (1 + Math.sin((i+pos)*0.1324))*127; rgb[i+1] = (1 + Math.sin((i+pos)*0.1654))*127; rgb[i+2] = (1 + Math.sin((i+pos)*0.1)) * 127; } }); patterns.push(function() { // Random blue lights for (var i=0;i<rgb.length;i+=3) { rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = Math.random()*255; } }); var getPattern = patterns[0]; function changePattern() { patternNumber = (patternNumber+1) % patterns.length; getPattern = patterns[patternNumber]; SPI2.send4bit(rgb, 0b0001, 0b0011); } var patternNumber = 0; function changePattern() { patternNumber = (patternNumber+1) % patterns.length; getPattern = patterns[patternNumber]; // console.log("changePattern(): patternNumber = "+patternNumber); } setWatch(changePattern, BTN, { repeat: true, edge:'rising', debounce: 50 }); // cycle = setInterval(doLights,50); // this below was ^ function doLights() { getPattern(); var x = 0, y = 0; for (var i=0;i<rgb.length;i+=3) { LCD.setColor(rgb[i+0]/256,rgb[i+1]/256,rgb[i+2]/256); LCD.fillRect(x,y,x+xd,y+yd); x += xi; y += yi; } SPI2.send4bit(rgb, 0b0001, 0b0011); } var cycle ; function lightsOn() { if (!cycle) { cycle = setInterval(doLights,50); } } </script> </body> </html>
There are some small change/fix to your code of which commenting the LCD.clear() statement is noteworthy.
5 Attachments
-
• #20
You made this so much more than it needed to be, I have no idea on any of this stuff you're talking about and wanting me to do now. I just wanted the simple fix to enlarge my screen thats it.
-
• #21
The emulators are great but it still doesn't help me with what i need to edit, I'm on here for help because I'm not sure what i need to change that doesn't tell me what i need to change or anything, I understand how the first guy helped me but you completely changed what he did.
-
• #22
...I'm not so sure... I understand more or less what you want to do: show a larger rectangle for each of the LEDs on your display.
In post #16 of this conversation, I gave you some help to modify the code so it shows wider bars for each of the LED. You mentioned then no positive feedback in posts #17 and #18, since I could not test the code as per the instruction, I decided to to that verification,... and it was successful.
Just follow the instructions and copy the lines 89 through 223 - your code with the added lines as instructed in post #16 - and paste them into the editor pane of your Espruino Web IDE, upload them, and enter
lightsOn()
in the console. Then you play with your button that changes the patterns. Finally, you enterlightsOff()
in the console to stop the lights.That's it!
PS: Study the
doLights() {...}
... you will see how it achieves to make rectangle per LED as wide or tall as possible (together with the setup in the if-then-else after your line that showsvar rgb = new Uint8Array(50*3);
. -
• #23
In post #16 it didn't widen the bars though it, it moved them over the the left or only showed one bar!
-
• #24
Can you take a pic of what you see with the unchanged code and share it in the forum?
Your code creates something looking like on the right in the screen shot I attached... assuming the display you have is configured 240 pixels horizontal in the x-axis and 320 pixels vertical in the y-axis with x=0 and y=0 being left-top corner.
You have 50 lights and the code creates a bar of 3 pixels wide for each of the LEDs, which makes 150 pixels... just by co-using the fact that every third byte in the Uint8Array is the begin of a new LED.
My suggested changes take the full width into account - 240 pixels - which makes it possible to have a 4 pixels wide vertical bar for each LED building a large horizontal bar. Furthermore, the suggested changes allow to use the vertical - 320 pixels - which makes it possible to have a 6 pixels high horizontal bar for each LED building a large vertical bar. The changes in the begin use the
Orient
ation information - "x" or "y" axis - and the WX width and HY height to calculate the maximal width or height for each bar given 50 LEDs and 240 or 320 pixels.If this is not what you get, then we are not talking the same language, or may be not the same hardware...
-
• #25
/*var sensor = require("HC-SR04").connect(C6,C7,function(dist) { console.log(dist+" cm away"); }); setInterval(function() { sensor.trigger(); // send pulse }, 500); */ LCD.clear(); SPI2.setup({baud:3200000, mosi:B15}); var rgb = new Uint8Array(50*3); var pos=0; function lightsOff() { clearInterval(cycle); pos++; for (var i=0;i<rgb.length;i+=3) { rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = 0; } SPI2.send4bit(rgb, 0b0001, 0b0011); } var patterns = []; //patterns.push(lightsOff); patterns.push(function() { // Fading white lights pos++; for (var i=0;i<rgb.length;i+=3) { var col = (Math.sin(i+pos*0.2)+1) * 127; rgb[i ] = col; rgb[i+1] = col; rgb[i+2] = col; } }); patterns.push(function() { // Fading Red lights pos++; for (var i=0;i<rgb.length;i+=3) { var col = (Math.sin(i+pos*0.2)+1) * 127; rgb[i ] = col; rgb[i+1] = 0; rgb[i+2] = 0; } }); patterns.push(function() { // Fading Green lights pos++; for (var i=0;i<rgb.length;i+=3) { var col = (Math.sin(i+pos*0.2)+1) * 127; rgb[i ] = 0; rgb[i+1] = col; rgb[i+2] = 0; } }); patterns.push(function() { // Fading Blue lights pos++; for (var i=0;i<rgb.length;i+=3) { var col = (Math.sin(i+pos*0.2)+1) * 127; rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = col; } }); patterns.push(function() { // Low red light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 85; rgb[i ] = col; rgb[i+1] = 0; rgb[i+2] = 0; } }); patterns.push(function() { // Medium red light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 170; rgb[i ] = col; rgb[i+1] = 0; rgb[i+2] = 0; } }); patterns.push(function() { // Full red light 2 pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = col; rgb[i+1] = 0; rgb[i+2] = 0; } }); patterns.push(function() { // low blue light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 85; rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = col; } }); patterns.push(function() { // Med blue light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 170; rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = col; } }); patterns.push(function() { // Full blue light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = col; } }); patterns.push(function() { // low Green light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 85; rgb[i ] = 0; rgb[i+1] = col; rgb[i+2] = 0; } }); patterns.push(function() { // Med Green light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 170; rgb[i ] = 0; rgb[i+1] = col; rgb[i+2] = 0; } }); patterns.push(function() { // Full Green light pos++; for (var i=0;i<rgb.length;i+=3) { var col = 255; rgb[i ] = 0; rgb[i+1] = col; rgb[i+2] = 0; } }); patterns.push(function() { // Fading colours pos++; for (var i=0;i<rgb.length;i+=3) { rgb[i ] = (1 + Math.sin((i+pos)*0.1324)) * 127; rgb[i+1] = (1 + Math.sin((i+pos)*0.1654)) * 127; rgb[i+2] = (1 + Math.sin((i+pos)*0.1)) * 127; } }); patterns.push(function() { // Random White lights for (var i=0;i<rgb.length;i+=3) { rgb[i ] = Math.random()*255; rgb[i+1] = Math.random()*255; rgb[i+2] = Math.random()*255; } }); patterns.push(function() { // Random Red lights for (var i=0;i<rgb.length;i+=3) { rgb[i ] = Math.random()*255; rgb[i+1] = 0; rgb[i+2] = 0; } }); patterns.push(function() { // Random Green lights for (var i=0;i<rgb.length;i+=3) { rgb[i ] = 0; rgb[i+1] = Math.random()*255; rgb[i+2] = 0; } }); patterns.push(function() { // Random Blue lights for (var i=0;i<rgb.length;i+=3) { rgb[i ] = 0; rgb[i+1] = 0; rgb[i+2] = Math.random()*255; } }); var getPattern = patterns[0]; function doLights() { getPattern(); for (var i=0;i<rgb.length;i+=3) { LCD.setColor(rgb[i+0]/256,rgb[i+1]/256,rgb[i+2]/256); LCD.fillRect(i,0,i+2,240); } SPI2.send4bit(rgb, 0b0001, 0b0011); } var patternNumber = 0; function changePattern() { patternNumber = (patternNumber+1) % patterns.length; getPattern = patterns[patternNumber]; } setWatch(changePattern, BTN, { repeat: true, edge:'rising', debounce: 50 }); cycle = setInterval(doLights,50);