-
@Robin: If it makes sense or not we don't know. Might be doing some multiplexing of pins, due to limited IO pins. The key message is to use setInterval/setTimeout instead of while/for.
-
You don't need state machines for this simple case.
@Robin: Refering to post #1 and #4, to replace WHILE and FOR with setInterval/setTimeout/clearInterval, use this code when the button is pressed (first setWatch function, line 1) instead of WHILE:
yolo = setInterval(function() { //the watch displays the hour display(1, hourFirstDigit); display(2, hourSecondDigit); }, 50); //with 50ms if may flicker
When the button is released (second setWatch function , line 11) call clearInterval(yolo) and allClear(). Then show the minutes again with yolo = setInterval(), and use setTimeout to clear that interval after 300ms with clearInterval(yolo) again insted of FOR.
If the displays flickers at 50ms reduce the interval to maybe 25 or 20ms.
-
-
the problem is, whenever I press/release the button, the piezo speaker
beeps until the LEDs are clearedThat's what you program is supposed to do. There is no multitasking in Javascript, just a single thread. As such, the timer to stop the beep expires while your WHILE loop is running, but the code to stop the beep only gets executed when the CPU is idle. That's the case when the function containing the WHILE loop is finished. (There might be better and technical more accurate explanations.)
In case you need to write
display(1, hourFirstDigit); display(2, hourSecondDigit);
repeatedly then do this using a function. Start the function with
var yolo=setInterval(...)
and stop it withclearInterval(yolo)
. Don't use WHILE or FOR in such cases.Regarding
pretty simple, right?
No, it's not simple. You need two function while one function with 3 lines would do.
-
-
Thanks Gorden. It's a nice function and really fast. Just tried it with a pixel runner left/right.
//runner (left/right) var pin = NodeMCU.D1; pinMode(pin, "output"); var neopixel = require("neopixel"); const leds = 64; const ledsx3 = 3*leds; //array with rgb values as Uint8ClampedArray const base = new Uint8ClampedArray(ledsx3); var show = new Uint8ClampedArray(ledsx3); var dot1 = new Uint8ClampedArray(3); dot1[0] = 128; dot1[1] = 128; dot1[2] = 128; var dot2 = new Uint8ClampedArray(3); dot2[0] = 128; dot2[1] = 0; dot2[2] = 0; var dot3 = new Uint8ClampedArray(3); dot3[0] = 0; dot3[1] = 0; dot3[2] = 128; // //prepare // var prepare = function() { for (var i=0; i<ledsx3; i++) { base[i] = 0; } }; // //animate // var dir1 = 3; var pos1 = 0; var dir2 = -6; var pos2 = leds; var dly3 = 0; var pos3 = 3*Math.round(Math.random()*leds); var start, duration; var animate = function() { start = getTime(); show.set(base); show.set(dot1, pos1); show.set(dot2, pos2); show.set(dot3, pos3); neopixel.write(pin, show); pos1 = pos1 + dir1; if (pos1 >= ledsx3) dir1 = -3; else if (pos1 <= 0) dir1 = 3; //duration of all code above: 0.006s pos2 = pos2 + dir2; if (pos2 >= ledsx3) dir2 = -6; else if (pos2 <= 0) dir2 = 6; //duration of all code above: 0.007s dly3++; if (dly3 === 7) { dly3 = 0; pos3 = 3*Math.round(Math.random()*leds); } duration = getTime()-start; //duration of all code above: 0.008s }; var onInit = function() { setInterval(function() { animate(); }, 10); }; onInit(); //don't save() this line
Execute at your on risk, epilepsy warning.
-
The diodes are a simple hack.
The proper way would be a hot swap controller, e.g. LTC4227 (check the datasheet for allowed voltages and and current consumption). It senses the input voltages of multiples sources and controls a transistor to connect the source with the highest input voltage to the output. -
-
@allObjects: Line 18 doesn't matter as it was just used to get an idea of the execution time simulating some random merging of per-calculated values. I'll use the require(), that's good.
@Gordon: I didn't get what function do you mean using ".set". I'd say setting RGB values at runtime is most likely too slow in most cases.
Having this thread resurrected, I did a quick rainbow implementation.
//rainbow effect const pin = NodeMCU.D5; pinMode(pin, "output"); var neopixel = require("neopixel"); //array with rgb values as Uint8ClampedArray var rgb = []; //length = 255/step = max. number of leds const step = 3; //integer n, use every n-th rainbow color, effect will be n times faster //const leds = 64; //the number of leds, used by the slower version only // //getRainbowColor(position = 0..255) //returns color of rainbow at the position as rgb in a Uint8ClampedArray // var getRainbowColor = function (position) { var rgb = new Uint8ClampedArray(3); if(position < 85) { rgb[0] = position * 3; rgb[1] = 255 - position * 3; rgb[2] = 0; } else if (position < 170) { position -= 85; rgb[0] = 255 - position * 3; rgb[1] = 0; rgb[2] = position * 3; } else { position -= 170; rgb[0] = 0; rgb[1] = position * 3; rgb[2] = 255 - position * 3; } return rgb; }; // //prepare () // //prefill the rgb array var prepare = function() { for (var i=0; i<255; i += step) { rgb.push(getRainbowColor(i)); } }; // //animate // var tmp; var animate = function() { //rgb.push(rgb.shift()); //rotate the rgb array by one value rgb.unshift(rgb.pop()); //rotate the rgb array by one value, a little bit faster neopixel.write(pin, rgb); //faster version //neopixel.write(pin, rgb.slice(1, leds)); //slower version, technically cleaner }; var onInit = function() { prepare(); setInterval(function() { animate();}, 10); //10ms, if using serial/bt/wifi this might too fast }; onInit(); //don't save() this line
If you have any suggestions on how to make the code faster please give me a hint. And if you want it to https://www.espruino.com/WS2811 feel free to copy it.
-
While it's an old thread, starting with the code provided
arr[n++] = (Math.random() * 255) * 0.25;
I tried to optimize, and see what's possible:
const pin = NodeMCU.D5; const leds = 24; const arrl = 24*3; var arr = new Uint8ClampedArray(arrl); var animate = function(){ for(var a = 0; a < arrl ; a++) { //0.01s //no calculation at all //0.06s //arr[a] = Math.random() * 64; //0.071s //arr[a] = Math.random() * 63.75; //0.075s //arr[a] = Math.random() * 255 * 0.25; //0.097s //arr[a] = Math.round(Math.random() * 63.75); //0.100s //arr[a] = Math.floor(Math.random() * 63.75); } require("neopixel").write(pin, arr); };
The duration measured is included in the code sample, and it's obvious that the neopixel write itself is fast, there's no optimization needed. However filling every array index and calling Math functions makes things slow. To avoid this I did the following:
var arr1 = new Uint8ClampedArray(leds); var arr2 = new Uint8ClampedArray(leds); var arr3 = new Uint8ClampedArray(leds); for(var a = 0; a < arrl ; a++) { arr1[a] = Math.random() * 64; arr2[a] = Math.random() * 64; arr3[a] = Math.random() * 64; } for (i=1; i<10; i++) { if (i===1) require("neopixel").write(pin, [].concat(arr1,arr2,arr3)); else if (i===2) require("neopixel").write(pin, [].concat(arr1,arr1,arr1)); else if (i===3) require("neopixel").write(pin, [].concat(arr1,arr3,arr2)); else if (i===4) require("neopixel").write(pin, [].concat(arr3,arr2,arr1)); else if (i===5) require("neopixel").write(pin, [].concat(arr1,arr3,arr1)); else if (i===6) require("neopixel").write(pin, [].concat(arr3,arr2,arr3)); else if (i===7) require("neopixel").write(pin, [].concat(arr3,arr2,arr3)); else if (i===8) require("neopixel").write(pin, [].concat(arr3,arr3,arr2)); else if (i===8) require("neopixel").write(pin, [].concat(arr3,arr2,arr3)); else if (i===9) require("neopixel").write(pin, [].concat(arr3,arr3,arr2)); else require("neopixel").write(pin, [].concat(arr3,arr3,arr3)); }
This code is 10x faster. However you should note that [].concat() returns a standard array with three (or four) UInt8Arrays inside. (concat and splice are not implemented for UInt8Arrays, so you can't use these functions). Running this code with standard arrays more than doubles the execution time. When doing rainbow effects or other smooth animations you would want to use UInt8Arrays as containers for RGB values, and standard arrays for these containers (if you have enough variables and RAM available).
-
I would not implement something like ota.setMode({mode="on|off") because it'll be still insecure if enabled. Signed updates only would be the way to go, but that would require proper key management, that is not comfortable at all - unless it is build into the IDE.
I'll try to remove all ota.h/ota.c references from the code, and re-compile without.Telnet and OTA are nice features for development, that is I have to agree. But they should not go to the wild, unless you want Espruino devices to join Mirai and other botnets. In my opinion they should be disabled in the standard firmware.
-
-
-
I'd start try to use it as compass, before implementing anything else.
The compass on my smartphone (and an so many others, cheap and expensive) is not accurate at all, not moving when turning the smartphone and suddenly jumping back. Maybe it's just overcompensated, or whatever. I wouldn't use my smartphone compass to control volume up and down. Maybe puckjs is better. -
-
Having an open telnet port the default configuration of the esp8266 is insecure: Anyone with access to your network can take control of your all your esp8266 devices, not even needing a password. IoT botnets are a reality for a few years (e.g. Mirai), I just wonder:
-Why is this the default configuration?
-How to disable the telnet port, other than building a custom firmware?maze
-
Regarding the USB power it's not worth implementing anything: I don't think any developer would ever check even if it was implemented.
@larry: Did your write a class module for this chipset? -
I want the sleeping uC to be triggered by the mic interrupt.
https://www.espruino.com/Reference#l_ESP8266_deepSleep says you must pull down the RST pin, i.e. the mic alone will not work, and the clap detector circuit above doesn't work (0V output, with 5V peaks during claps), the signal is inverted.
-
-
@Robin: USB devices must be in low-power mode (max. 100 mA) initially. They can negotiate high-power mode (max. 500 mA for USB2.0), and only then they are allowed to use more power.
For the Pico itself it's not an issue.
But if you want connect additional devices to the Pico and power them by the USB port it might be an issue. While most PCs deliver 500mA per port some PCs and laptops don't. Connecting this sensor would draw slightly above 100mA, so it might damage the USB port (worst case scenario), that's why I asked. -
Does the Pico request 500mA from the USB bus when connected to a PC? And what does it do when it's only allowed to use 100mA?
Anyway, assuming your USB port can provide 500mA that's enough for the Pico (32mA) and the sensor (70mA +/-10mA), no need for an external power supply.
When using multiple power supplies you MUST connect the ground of all power supplies together. Otherwise there might be a measurable voltage difference between the different grounds, e.g. due to power supply design or due to electrostatic charge.
-> Remove all data cables before connecting grounds together, otherwise you might damage your chips.
-
-
@allObject: The two blocks "After n seconds do" and "Every n seconds do" are already there. I'm not sure why you introduced scheduleOnce() and scheduleRepeated(), do you want them as js functions or blocky, and how would they differ from the existing js functions setTimeout/setInterval or the existing blocks?
-
My favorite logic level shifter is the BSS138. With two resistors it works bi-directional, if you use only one resistor it's unidirectional. It doesn't invert the signal.
"bi-directional-logic-level-converter-hookup-guide" will find relevant documentation.