-
Well, optimizing for speed is often bad for readability. I wouldn't add "+0.5" to the code, just to save the time needed for this extra operation.
And yes, numbers in square brackets are not rounded to an integer. And we all love code like this:>foo={"0.5": "bar", "1": "foo"}; >foo[0.5]; ="bar" >foo[Math.round(1.5)]; ="foo"
Since prepareDisplay is one of the slowest functions: ColorMap has only 8 different values, Temperature has 208 different values - so it might be feasible to pre-compute things and avoid all division and multiplication operations with Temperature in this function - if there's enough RAM available on the ESP32. Anyway, that's much harder than just removing rounding and clamping for TemperatureMap values. Removing 262 function calls will result in a measurable improvement, even for the compiled version.
-
Just looked at the code, and I think there are still options for improvement: All the clamping and rounding for TemperatureMap values can be omitted:
>let foo = new Uint8ClampedArray(3); =new Uint8ClampedArray(3) >foo[0] = -0.5; foo[1] = 1.5; foo[2] = 255.5; =undefined >foo =new Uint8ClampedArray([0, 1, 255])
One day I'll test this code, I think the effect will be nice.
-
-
I don't think it is easy to fix, especially without breaking existing code. Maybe it is possible to change
digitalPulse(csPin, true, [1, 1, 0.03, 0.03, 0.045]);
to
digitalPulse(csPin, false, [1, 0.03, 0.03, 0.045]);
and get the desired pulse, just a a little delay. Then there would be no code change required, just a note in the documentation.
-
The neopixel module for ESP8266 does a dry-run/pre-roll without emitting any pulses. That dry run is necessary to load the machine code from flash into RAM. Without this dry run the timing of the pules representing the first byte won't have proper timing. It might be the same issue in this case. Reference files:
jswrap_neopixel.c, line 220...
jswrap_io.c, line 201...There is no dry-run for ESP8266 in jswrap_io.c, so I would assume it is the same issue. That code is not capable of producing very short pulses accurately in the first run.
-
A simple FET switch might be all thats needed to turn off the juice to the Neopixel hogs or a relay as indicated in post #2 What about using a pin on the Espruino to control a Buck step-up converter that would supply the 5V? hummmmmm . . . .
Neopixel shall be connected with ground first, i.e. a simple FET wouldn't be a good solution. Get a high rail FET, e.g. MIC94060 or something else with an internal charge pump.
-
-
-
-
-
https is not working on 2.04
You have to build your own version, using less jsvars. However no details on how much to reduce the variables. See also: https://github.com/espruino/Espruino/issues/1613
I'll make a custom build, sooner or later, maybe end of this year. (Without the graphics library, without telnet and without ota.). And, if necessary for https, less jsvars.
-
-
I'd say even two motors with 10mA are too much and will drain a CR2032 battery really fast. I'd add a capacitor and a diode in parallel to each motor (over voltage/inverse voltage protection).
However I'd check the motors first, do they have the right speed and power at the planned voltage, or do you need more power/a higher voltage and gears...
-
res.on('data',
is triggered as soon as the first data arrives, not when all data is there. That causes the error, if you replace the lineconsole.log(JSON.parse(data).datetime);
withconsole.log('###');
you'll see that `res.on('data',
is triggered multiple times.
As such you're trying to parse an incomplete JSON string, and the error is normal.
Edit: And it's pure luck that it works in node.js. -
Just add
const LED1 = D2
orconst LED1 = NodeMCU.D4; //(pin2 of ESP8266)
to get the build-in LED blinking.
And actually you don't need the variablesLED1
andon
as you can simply callD2.toggle()
orNodeMCU.D4.toggle()
to toggle the pin D2/build-in LED:setInterval(function() { D2.toggle(); }, 1000);
To stop the blinking call
clearInterval()
. -
If you want to use nodejs modules use nodejs, e.g. on a pc, rpi or opi.
Espruino has limited js/ts compatibility, and runs typically on hardware with very limited memory, and as such most nodejs modules are simply to big to be includes and using non-supported js/ts. Espruino typically uses modules to provide and interface for I2C/1-wire/serial chips, see https://www.espruino.com/modules/
I'm pretty sure it's impossible to use the mentioned module on Espruino. -
-
The leap socket is listening only on the loopback port, to make the socket accessible from the outside execute these commands on Windows (on Linux it's different):
netsh interface ipv4 install netsh interface portproxy add v4tov4 listenport=6437 connectport=6437 connectaddress=127.0.0.1
However, it might be easier to run a local nodejs server on your computer (easier development and debugging). That server would read the leap motion data from the websocket, then interpret it provide a new webpage for the ESP8266 to control the servos directly. Logging and debugging would be much easier this way, and since you need to have the computer running anyway it's basically no extra cost.
-
I guess there is a better way: Do not create new timer every 1000ms, but only once. Just to quote one function:
//get wifi status every second function iw1() { wifi_stat = Wifi.getDetails().status; //set led blink rate if(wifi_stat !== "connected") {led_speed = 100;} else {led_speed=500;} setTimeout(iw1,1000); } iw1();
And how to do it better:
//get wifi status every second function iw1() { wifi_stat = Wifi.getDetails().status; //set led blink rate if(wifi_stat !== "connected") {led_speed = 100;} else {led_speed=500;} } iw1(); setInterval(iw1,1000);
While there is a garbage collection, it might be called too late, or not working properly - I didn't look into it. But if you call setTimeout every 1000ms instead of setInterval once there's a really high chance it'll allocate a new block of memory for a new timer every 1000ms.
The other functions shall be modified accordingly. -
The collection of "0"s and "1"s should only be enabled within the expected window
Why, what's the benefit?
For me setting the watch once is more effective, as it is only done once. The pin can't be used for anything else but a DHT11 sensor anyway.Since multiple sensors can be on a single line
No. That is impossible. Or did I miss something?
-
Nice rewrite, I really like it. Maybe you could
- add
pinMode(self.pin, 'input_pullup');
tofunction DHT11(pin)
before setting the watch. In my opinion not having this is the reason that the first bit is zero in the first run, and one in the consecutive runs that you observed (line 15). - replace
self.d += 0 | (t.time - t.lastTime > 0.00005);
withself.d += Number(t.time - t.lastTime > 0.00005);
(line 19). - remove
pinMode(self.pin);
(line 40). The signal should be pulled all time, line 39 is sufficient. - Remove the 10 consecutive measurements, already done.
- fix
// Two first bytes are header ...
tobits
(line 63). - add
err: false
in the callback for a successful measurement (line 79). - change to
temp: undefined, rh: undefined
in the callback for a failed measurement (line 89). Because -1 is a valid temperature it's not an optimal return value for a failed measurement, and also not good for further processing (you can store -1 for temp and rh in a database, if you don't test) - Test t, tf, rh, rhf to be numbers before calling parseFloat. If self.d is less than 42 bits the parseInt will eventually return "NaN", so I would suggest to test the length of self.d in line 63.
5, 6, 7 and 8:
setTimeout(function() { let error = true; let temp = undefined; let relh = undefined; if (self.d.length === 42) { //Only if we got 42 bits // Two first bits are header. First bit is 0 on first, 1 on consecutive. Second bit is always 1. let h = self.d.substr(1,1); // Header, always "1" - we'll include this in checksum test let rh = parseInt(self.d.substr(2,8),2); // Relative humidity let rhf = parseInt(self.d.substr(10,8),2); // Relative humidity fraction let t = parseInt(self.d.substr(18,8),2); // Temperature let tf = parseInt(self.d.substr(26,8),2); // Temperature fraction let csum = parseInt(self.d.substr(34,8),2); // Checksum // Calculate checksum let cks = rh + rhf + t + tf; // Check checksum: // - It is not zero (temp and humidity exactly zero?) // - Sum all data, compare last byte to checksum byte if (h == "1" && cks && ((cks & 0xFF) == csum)) { error = false; temp = parseFloat(t + "." + tf); relh = parseFloat(rh + "." + rhf); } } // Callback cb({ err: error, raw: self.d, temp: temp, rh: relh }); }, 30);
I did't try the code not having a DHT11, watch out for typos and other errors. But I guess you'll get the idea and catch them.
Anyway, you write the module so do what you need. Others can adjust the code to their needs, as it is now much cleaner and easier to understand compared to the original module. - add
-
You should set the pin mode in the connect function to
pinMode(ht.pin, 'input_pullup');
, to avoid random signals to be received.And you could replace a code of code as follows, mainly for better comments, from
... digitalWrite(ht.pin, 0); pinMode(ht.pin,"output"); // force pin state to output // raise pulse after 1ms setTimeout(function() { pinMode(ht.pin, 'input_pullup'); pinMode(ht.pin); }, 20); // stop looking after 50ms ...
to
... //pull signal to ground for 20 ms to request data from DHT11 pinMode(ht.pin,"output"); digitalWrite(ht.pin, 0); setTimeout(function() { pinMode(ht.pin, 'input_pullup'); }, 20); //parse the received data after 50ms ...
-
Looks good, just a lil' bit hacked (
var _this = this;
and latervar ht = this;
). I'd keep it the same variable in both lines - I like to use "var self = this;" as it works without underscore.Maybe a disconnect function would be nice, to remove the watch when no longer needed. But memory is limited, and I don't think that anyone would ever use it. Unless trying to connect different devices to the same pin, which would be a bad design, better using I2C instead.
Your Adruino code looks complicated, and I'm not sure if it's correct, or if you're overwriting the variable IncomingString in the while loop.
The sample code for serial input from https://www.javatpoint.com/arduino-serial-available:
I'd suggest to remove the while and the true/false in your code, and change it according to the sample code.