-
-
Although I'm too late for this little "contest" I would still like to document my most recent Espruino project (a small "lava lamp" replacement, see
the current "work-in-progress" onGitHub) for my students - just to give them an idea how they could publish their own projects (which are likely based on Maker Unos which is why I won't qualify for a free Espruino anyway).My question is: am I allowed to use images and diagrams from the Espruino web site in my documentation and - if so - how should I "cite" them?(an answer is no longer necessary, I just finished the write-up) -
-
I can't predict when people will no longer be able to use HTTP. What I am observing is that Google Chrome is raising the bar continuously, e.g., by introducing concepts like "Content Security Policies" or disallowing self-signed certificates etc.
If you start with the preparations to migrate to HTTPS soon enough you won't have to worry about the time it will take and will instead be prepared for the final switch.
-
Hello Gordon,
I assumed s.th. like that and did not expect you to answer too soon. Just take the time to need to ship all Bangles (I'm waiting for two of them myself), then take a breath or two, so that your family does not forget how you look like and then, perhaps, look at the bugs we found.
With greetings from Germany,
Andreas Rozek
-
-
-
-
-
which device are you using? your code still crashes for me even without Neopixel-specific calls (which you may - and perhaps should - leave enabled as they do not expect any feedback but, effectively, just send pulses to pin B15)
Amendment: moving outer variables into the three main functions (as you suggested) also already hangs up my code.
Personally, I'd recommend to "diff" the code generated for the working and the non-working versions of my source for the original Espruino and look at the changes as s.th. really weird must be going on...
-
In the mean time, I got
computeHeating
to compile as well by not directly assigning toTemperatureMap
, but first to an auxiliary variableaux
and thenTemperatureMap[i] = aux
I tried the same trick with
computeDiffusion
but failed. And compilingcomputeHeating
did not have any noticeable effect on performance - thus, I reverted my changes again.Amendment: I tried over two dozens of variants for
computeDiffusion
- even silly ones like byte lookups from aUint8ClampedArray
with the values 0...255 - but all of them failed.My current impression is that success is nothing but good luck and depends on side effects of compilation (such as overwriting memory areas because of invalid length calculations or similar)
Amendment #2: wow, indeed, success is pure luck! After all my experiments I tried to upload my working example again - and failed because I had also changed
Math.random
torandom
in the mean time. After reverting that change, the example started working again.Which means: simply adding
let random = Math.random
and replacing all (four) calls ofMath.random
byrandom
broke a working program!Hopefully, this information may help Gordon et al. finding the reason for this weird compiler bug!
Technical details:
- I'm using an original Espruino (Rev 1.3b) with an HC-05 attached and running Espruino 2v10
- the board is connected by USB, programming is done using the Web IDE configured without minification, without mangling and without pretokenization (because I once thought, that could cause problems as well)
- my Neopixel 16x16 matrix is attached to pin B15
- I can send you both versions of my code - the working and the failing one
- I'm using an original Espruino (Rev 1.3b) with an HC-05 attached and running Espruino 2v10
-
S.th. which might be worth adding to https://www.espruino.com/Compilation: trying to assign
null
to a variable causes a compiler error message[ COMPILER MESSAGE ] : Error: Unknown literal type object
-
I always send my code directly to the attached device - thus, I never touch (nor even see) the compiled code.
And, indeed, trying to compile
computeDiffusion
orcomputeHeating
breaks everything - sometimes even immediately after uploading (although I don't really start my code - except for those initialization lines)This sounds as if s.th. gets overwritten during upload.
-
Hello Gordon,
I just noticed that the forum still uses HTTP rather than HTTPS - which may make it difficult to use modern browsers in the near future.
Since
espruino.com
already uses HTTPS, it should not be difficult to get a certificate (just addforum.espruino.com
as an "alternative subject name".What remains may a configuration change of port 80 to 443 and to load certificate and private key in your forum software.
From then on, you should not have to care about browser security restrictions for quite a while, I'd guess.
With greetings from Germany,
Andreas Rozek
-
What about writing a own library for this?
https://github.com/espruino/Espruino/blob/master/libs/README.md
well, I've chosen Espruino in order to avoid having to code in C/C++!
-
-
This is my final code (for an original Espruino, with a 16x16 Neopixel LED matrix wired to pin B15) - just for the case that you want to play with it:
let Neopixel = require("neopixel"); let rounded = Math.round; let clamped = E.clip; let max = Math.max; let DisplaySize = 16*16; let Display = new Uint8ClampedArray(DisplaySize*3); let PixelOffset = new Int16Array(256); for (let i = 0; i < 16; i++) { for (let j = 0; j < 16; j++) { let Index = i*16 + j; if (i % 2 === 0) { PixelOffset[Index] = Index*3; } else { PixelOffset[Index] = (i*16 + 15 - j)*3; } } } let normalized = new Uint8ClampedArray(16*16); for (let i = 0; i < 256; i++) { normalized[i] = ( i === 0 ? 0 : rounded(1 + 256/4*(i/256)*(i/256)) ); } let TemperatureMap = new Uint8ClampedArray(DisplaySize); for (let i = 0; i < 256; i++) { TemperatureMap[i] = 0; } let ColorMap = new Array(16); for (let i = 0; i < 16; i++) { ColorMap[i] = E.HSBtoRGB(i/16, 1, 1, true); } /**** computeDiffusion ****/ function computeDiffusion () { let i = 0, j = 0, k = 0; for (i = 15; i > 0; i--) { // intensity diffusion for upper rows k = i*16; TemperatureMap[k] = rounded(( 6*TemperatureMap[k] + 2*TemperatureMap[k-16] + TemperatureMap[k-15] )/9); for (j = 1; j < 15; j++) { k++; TemperatureMap[k] = rounded(( 6*TemperatureMap[k] + TemperatureMap[k-17] + 2*TemperatureMap[k-16] + TemperatureMap[k-15] )/10); } k++; TemperatureMap[k] = rounded(( 6*TemperatureMap[k] + TemperatureMap[k-17] + 2*TemperatureMap[k-16] )/9); } } /**** computeHeating ****/ let HeatX = rounded(16*Math.random()); // where to insert new heat let HeatCount = rounded(12*Math.random()); // how long to heat there function computeHeating () { HeatCount -= 1; if (HeatCount < 0) { // heat around HeatX, cool elsewhere HeatX = rounded(16*Math.random()); HeatCount = rounded(12*Math.random()); } let i, l = HeatX-4; for (i = 0/*, l = HeatX-4*/; i < l; i++) { TemperatureMap[i] = clamped(TemperatureMap[i] - 8, 0,255); } i = HeatX-4; i++; if (i >= 0) { TemperatureMap[i] = clamped(TemperatureMap[i] + 1, 0,255); } i++; if (i >= 0) { TemperatureMap[i] = clamped(TemperatureMap[i] + 3, 0,255); } i++; if (i >= 0) { TemperatureMap[i] = clamped(TemperatureMap[i] + 4, 0,255); } i++; TemperatureMap[i] = clamped(TemperatureMap[i] + 5, 0,255); i++; if (i < 16) { TemperatureMap[i] = clamped(TemperatureMap[i] + 4, 0,255); } i++; if (i < 16) { TemperatureMap[i] = clamped(TemperatureMap[i] + 3, 0,255); } i++; if (i < 16) { TemperatureMap[i] = clamped(TemperatureMap[i] + 1, 0,255); } i++; for (i = i; i < 16; i++) { TemperatureMap[i] = clamped(TemperatureMap[i] - 8, 0,255); } } /**** prepare display ****/ let normalizedRGB = new Uint8ClampedArray(3); function prepareDisplay () { "compiled"; for (let i = 0; i < 16; i++) { // row-wise let RowStart = i*16; let RowEnd = RowStart + 15; let k = RowStart; for (let j = 0/*, k = RowStart*/; j < 16; j++/*, k++*/) { // column-wise let RGB = ColorMap[j]; let Temperature = TemperatureMap[k]; if (Temperature < 16) { Temperature = 0; } else { Temperature = max(48,Temperature)/256; } normalizedRGB[0] = normalized[rounded(RGB[1]*Temperature)]; normalizedRGB[1] = normalized[rounded(RGB[0]*Temperature)]; normalizedRGB[2] = normalized[rounded(RGB[2]*Temperature)]; Display.set(normalizedRGB, PixelOffset[k]); k++; } } } /**** handleNextFrame ****/ function handleNextFrame () { computeDiffusion(); computeHeating(); prepareDisplay(); /**** show display ****/ Neopixel.write(B15,Display); /**** wait for next frame and proceed ****/ setTimeout(handleNextFrame,10); } /**** start automatically ****/ setTimeout(handleNextFrame,1000); // give Espruino some time to start up
-
There is s.th. terribly going wrong with "compiled" code:
I just restructured my source into several functions which I can individually "compile" or not - and I did not start the program automatically, giving me the chance to simply "reset" the board after a hang-up. Additionally, this allows me to invoke individual functions after flashing (or reset)
But now the board even hangs itself up after calling an uncompiled function - without ever calling a compiled function before!
Just for the records: the program runs fine (albeit slowly) without compilation!
Amendment: meanwhile, I found a combination of optimizations (e.g.,
Math.round
->rounded
) and compilation of a single, small function that does not hang up my Espruino and runs fast enough to live with. Taking into account how much time it took to find that (kind of) "solution" I have to stop here.While the performance increases of compilation are impressive, I still can't really recommend going that way as it seems completely unclear how one can get compiled code running - it may work or it may not, but a recipe cannot be given...
-
Ok, I have to give up for today.
My impression is that "compilation" of functions has some important (and perhaps undocumented) limitations I do not know yet.
@Gordon should we limit compiled functions to computations only? Can they access local variables in their lexical context? Or should we pass any such variables as invocation parameters? Can compiled functions handle
Uint8ClampedArray
properly? (i.e., incl. clamping?) -
damn...it's not my day...
it seemed to work once but now it does no longer.
I'm currently working with the original Espruino:
- after uploading the code into flash, the device hangs itself up
- trying to reconnect does not report the board type, regardless of reset or power cycling
- after reflashing the firmware (which works), connection over Web Serial works as intended - until I upload my source into flash again
S.th. seems to be terribly wrong right now...
Amendment: my code works fine - albeit slowly - even after uploading into flash as long as I do not compile - as soon as "compiled" is added, the Espruino hangs itself up, does no longer properly connect via Web Serial and I'll have to reflash the firmware in order to "unbrick" it.
2nd amendment:
Neopixel.write(B15,Display);
seems to crash compiled code - for whatever reason. If I comment it out, I may upload to flash and the code will run fine (but, of course, it will be useless)3rd amendment: by "compiling" the actual computations only and moving everything else into an uncompiled function, I was able to avoid the hang ups and the code still runs fast enough - but
Neopixel.write(B15,Display);
has no effect any more (perhaps, becauseDisplay
wasn't updated properly by the compiled function) - after uploading the code into flash, the device hangs itself up
-
-
Which device did you use for testing? Both my MDBT42Q and my original Espruino run out of memory with compiled code (and minification does not help)...and my Espruino Pico hangs itself up after transmitting the code - Espruino does not like me today (perhaps, I should not have mentioned the RasPi pico?)
-
-
Just to let you know:
- thank you very much for your effort
- I'm currently trying to update my source code accordingly, but the BT connection no longer works reliably: I can't even transfer the source any longer (and my original Espruino does not have enough memory...and my ESP32 does not support compilation...)
I'll post my results here as soon as I have some....
- thank you very much for your effort
I just finished the documentation of a little project I made for my wife with which I wanted to replace a real lava lamp with s.th. less dangerous and dirty (just imagine the mess if a real lava lamp falls to the ground and breaks...)
After some experiments, I decided to use an Espruino microcontroller to drive a 16x16 matrix of WS2812 LEDs.
You will find the complete write-up on GitHub, the project itself has also been mentioned on Thingiverse