-
It also seems like up until the this crash happens, the network responses take longer and longer until the crash. I'm keeping a running average, f.e.
let ws = new WebSocket("ws://192.168.43.247/my_websocket", "protocolOne"); let lastTime = performance.now() let timesCount = 0 let totalTime = 0 let averageTime = 0 ws.addEventListener('message', ({data}) => { timesCount++ const thisTime = performance.now() const elapsed = thisTime - lastTime totalTime += elapsed averageTime = totalTime / timesCount lastTime = thisTime mpuData = parseEspruinoJson(data) }); ws.addEventListener('open', () => { ws.send("Hello to Espruino!"); }) setInterval(() => console.log('avg time:', averageTime), 2000)
and at first the average is about 38 ms for the time between responses, and by the time it crashes the running average is around 50 ms. It increases steadily the whole time.
-
I'm not sure if this has anything to do with it, but I'm getting a bunch of errors in the Espruino console:
_____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |_____|___| _|_| |___|_|_|_|___| |_| http://espruino.com 1v91 Copyright 2016 G.Williams > =undefined IP: 192.168.43.247 { "connect": function (a,c) {return new b(a,c)} } [WS] "Hello to Espruino!" Uncaught InternalError: Timeout on I2C Read Receive at line 1 col 66 ...is.i2c.readFrom(this.addr,6);a=c[0]<<8|c[1];var b=c[2]<<8|c[... ^ in function "readSXYZ" called from line 1 col 17 this.readSXYZ(67) ^ in function "getRotation" called from line 1 col 36 ...is;return this.getRotation().map(function(c){return c/a.gyro... ^ in function "getDegreesPerSecond" called from line 5 col 51 ...n: mpu.getDegreesPerSecond(), // returns gyro array in degre... ^ in function called from system ERROR: Out of Memory! Execution Interrupted Execution Interrupted Execution Interrupted Execution Interrupted Uncaught InternalError: Timeout on I2C Read Receive at line 1 col 66 ...is.i2c.readFrom(this.addr,6);a=c[0]<<8|c[1];var b=c[2]<<8|c[... ^ in function "readSXYZ" called from line 1 col 17 this.readSXYZ(59) ^ in function "getAcceleration" called from line 1 col 40 ...eturn this.getAcceleration().map(function(c){return c/a.acc_... ^ in function "getGravity" called from line 3 col 46 ...celeration: mpu.getGravity(), // returns acceleration array... ^ in function called from system Execution Interrupted Execution Interrupted Execution Interrupted Execution Interrupted Execution Interrupted Execution Interrupted ERROR: Ctrl-C while processing interval - removing it. Execution Interrupted during event processing. at line 1 col 66 ...is.i2c.readFrom(this.addr,6);a=c[0]<<8|c[1];var b=in function "getRotation" called from line 1 col 36 ...is;return this.getRotation().in function "getDegrees" called fromin function called from system >
-
Sometimes I receive the following error in Chrome when it is receiving websocket messages directly from Espruino WiFi:
WebSocket connection to 'ws://192.168.43.247/my_websocket' failed: Could not decode a text frame as UTF-8.
I'm using the
ws
module for Espruino. Maybe there's something in that module that causes the websocket response to be invalid?What I'm trying to do in practice is read values from the
MPU6050
module, and send them through the websocket connection. Something like:var server = require('ws').createServer(function() {}); server.listen(80); server.on("websocket", function(ws) { ws.on('message', function(msg) { print("[WS] "+JSON.stringify(msg)); }); const mpu = getMPU(); setInterval(function() { let result = { acceleration: mpu.getGravity(), // returns acceleration array in G's rotation: mpu.getDegreesPerSecond(), // returns gyro array in degrees/s } result = JSON.stringify(result) ws.send(result); }, 16.666); });
Where
getMPU()
just return an MPU instance as per the MPU6050 docs, connected over I2C.So I have that
setInterval
loop that just continuously sends values over the websocket. The client code in Chrome does the following:let mpuData = { acceleration: [0,0,0], rotation: [0,0,0], } let ws = new WebSocket("ws://192.168.43.247/my_websocket", "protocolOne"); ws.addEventListener('message', ({data}) => { mpuData = parseEspruinoJson(data) }); ws.addEventListener('open', () => { ws.send("Hello to Espruino!"); }) setInterval(() => console.log('data:', mpuData), 2000) // ... requestAnimationFrame loop uses mpuData for graphics ...
Eventually, after a minute or two, I might get that error, and the connection breaks.
-
Is this normal?
I have been playing with the MPU6050, but I've noticed that the
mpu.getRotation()
values, etc, fluctuate a lot even if the accelerometer is completely still. Is this expected?Maybe the
getRotation()
values represent a small delta, so they fluctuate from vibrations and/or imprecision?I haven't figured out how to normalize the value from the four functions in the doc into yaw/pitch/roll, maybe that will be more stable?
(I'm completely new to this stuff, so I have no idea, yet!)
-
Alright, so I'm trying it with actual values from the accelerometer, but that really slows it down. For example:
function getMPU() { I2C1.setup({scl:B6,sda:B7, bitrate: 100000}); var MPU6050 = require("MPU6050"); console.log(MPU6050); var mpu = MPU6050.connect(I2C1); return mpu } function connectToWifi(wifiName, options) { var resolve, reject var promise = new Promise(function(res, rej) {resolve = res; reject = rej}) var wifi = require("EspruinoWiFi"); wifi.connect(wifiName, options, function(err) { if (err) reject(err); resolve(); }); return promise } function getIP() { const wifi = require("EspruinoWiFi"); wifi.getIP(function(err, info) { if (err) { console.log('Wifi connection failed, trying again in a sec...') setTimeout(getIP, 1000) } console.log('IP:', info.ip) }); } connectToWifi("starlancer", { password : "Next stop: Mars." }) .then(function() { getIP(); var server = require('ws').createServer(function() {}); server.listen(80); server.on("websocket", function(ws) { ws.on('message', function(msg) { print("[WS] "+JSON.stringify(msg)); }); const mpu = getMPU(); setInterval(function() { let result = { acceleration: mpu.getAcceleration(), // returns an [x,y,z] array with raw accl. data gravity: mpu.getGravity(), // returns acceleration array in G's rotation: mpu.getRotation(), // returns an [x,y,z] array with raw gyro data degreesPerSecond: mpu.getDegreesPerSecond(), // returns gyro array in degrees/s } result = JSON.stringify(result) ws.send(result); }, 16.666); }); }); function onInit() { console.log('Espruino started!'); }
And the browser just does something like
let mpuData = {...defaults}; let ws = new WebSocket("ws://192.168.43.247/my_websocket", "protocolOne"); ws.addEventListener('message', ({data}) => { mpuData = parseEspruinoJson(data) }); // ... use mpuData in requestAnimationFrame loop ...
The rendering in my animation loop is slow now that I'm sending actual MPU data.
Also after a short while I start to see some out-of-memory output until it crashes:
_____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |_____|___| _|_| |___|_|_|_|___| |_| http://espruino.com 1v91 Copyright 2016 G.Williams > =undefined IP: 192.168.43.247 { "connect": function (a,c) {return new b(a,c)} } [WS] "Hello to Espruino!" ERROR: Out of Memory! Execution Interrupted Execution Interrupted Execution Interrupted Execution Interrupted Execution Interrupted Execution Interrupted Execution Interrupted Uncaught InternalError: Timeout on I2C Read Receive at line 1 col 66 ...is.i2c.readFrom(this.addr,6);a=c[0]<<8|c[1];var b=c[2]<<8|c[... ^ in function "readSXYZ" called from line 1 col 17 this.readSXYZ(59) ^ in function "getAcceleration" called from line 2 col 51 ...ation: mpu.getAcceleration(), // returns an [x,y,z] array wi... ^ in function called from system
It seems like trying to read MPU and send over socket every
16.666
ms is too much. Is that right?What might be the best way to do this to get values as fast as possible and not crash it? Maybe I need to be able to somehow detect how many network request and/or MPU requests are queued, and not request faster than is possible, somehow?
-
-
-
-
-
Thanks for the tips @Gordon. I gave websockets a try on Espruino Wifi, like the following, and it seems to work at a reasonable rate that could be used for animation, however every few seconds or so the incoming values on the UI seems to pause for a very noticeable while. Could it be GC on Espruino? Maybe there's some way to smooth it out?
By values, I meant that Chrome console shows a counter for every time the same thing is logged. So this counter increments, it isn't really a value sent from Espruino, but the counter pauses every short while, which could cause "jank". I wonder if it is possible to fix that.
function getMPU() { I2C1.setup({scl:B6,sda:B7, bitrate: 100000}); var MPU6050 = require("MPU6050"); console.log(MPU6050); var mpu = MPU6050.connect(I2C1); return mpu } function connectToWifi(wifiName, options) { var resolve, reject var promise = new Promise(function(res, rej) {resolve = res; reject = rej}) var wifi = require("EspruinoWiFi"); wifi.connect(wifiName, options, function(err) { if (err) reject(err); resolve(); }); return promise } connectToWifi("starlancer", { password : "Next stop: Mars." }) .then(function() { const mpu = getMPU(); const wifi = require("EspruinoWiFi"); wifi.getIP(function(err, info) { if (err) throw err console.log('IP:', info.ip) }); var page = '<html><body><script>var ws;setTimeout(function(){'; page += 'ws = new WebSocket("ws://" + location.host + "/my_websocket", "protocolOne");'; page += 'console.log("host", location.host);'; // <--------------------- this is logged slowly. page += 'ws.onmessage = function (event) { console.log("MSG:"+event.data); };'; page += 'setTimeout(function() { ws.send("Hello to Espruino!"); }, 1000);'; page += '},1000);</script></body></html>'; function onPageRequest(req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.end(page); } var server = require('ws').createServer(onPageRequest); server.listen(8000); server.on("websocket", function(ws) { ws.on('message',function(msg) { print("[WS] "+JSON.stringify(msg)); }); setInterval(function() {ws.send("Hello from Espruino!");}, 42); }); }); function onInit() { console.log('Espruino started!'); }
Thanks for all the help! I am loving to learn, but I have a long ways to go.
-
Continuing from https://github.com/espruino/EspruinoDocs/issues/367#issuecomment-306120068,
I tried the
"falling"
edge suggestion, but the behavior seems the same, the HTTP server never responds, and I never see the------ dmpYawPitchRoll
output in Espruino console.Here's the code I'm trying:
function getMPU() { I2C1.setup({scl:B6,sda:B7, bitrate: 100000}); var MPU6050 = require("MPU6050"); console.log(MPU6050); var mpu = MPU6050.connect(I2C1); return mpu } function connectToWifi(wifiName, options) { var resolve, reject var promise = new Promise(function(res, rej) {resolve = res; reject = rej}) var wifi = require("EspruinoWiFi"); wifi.connect(wifiName, options, function(err) { if (err) reject(err); resolve(); }); return promise } connectToWifi("wifi", { password : "password" }) .then(function() { const mpu = getMPU(); const dmp = require('MPU6050_DMP').create(mpu, 3); const http = require("http"); let dmpYawPitchRoll = null // This loop locks up the espruino: https://github.com/espruino/EspruinoDocs/issues/367 function dmpLoop() { const dmpData = dmp.getData() if (dmpData !== undefined) { //console.log( dmpYawPitchRoll = dmp.getYawPitchRoll(dmpData) //) } } setWatch(dmpLoop, B5, { repeat:true, edge:'falling' }); http.createServer(function (req, res) { res.writeHead(200); let result = { acceleration: mpu.getAcceleration(), // returns an [x,y,z] array with raw accl. data gravity: mpu.getGravity(), // returns acceleration array in G's rotation: mpu.getRotation(), // returns an [x,y,z] array with raw gyro data degreesPerSecond: mpu.getDegreesPerSecond(), // returns gyro array in degrees/s } result = JSON.stringify(result) res.end(result); // This never fires, HTTP response is never sent to computer console.log(' ------ dmpYawPitchRoll:', dmpYawPitchRoll) }).listen(80); const wifi = require("EspruinoWiFi"); wifi.getIP(function(err, info) { if (err) throw err console.log('IP:', info.ip) }); }); function onInit() { console.log('Espruino started!'); }
Making an HTTP request from the computer to Espruino doesn't work. If you uncomment the
console.log
calls, thesetWatch
loop is working, and I will see that output repeatedly in console. -
I'm not sure why you're not getting a response from .get('http://192.168.0.5:3000' though - did it just happen the once, or does it happen multiple times? Do you see the request appearing on your server at all?
That didn't seem to work at all on the Espruino end, but I didn't check if the server received anything.
However, now I'm connecting from computer to Espruino. What I'm currently doing is the browser sends a websocket request to the local Meteor server (simply calling an RPC method defined on the server, not needing to know Meteor's DDP websocket API), then the server does a
GET
on the Espruino chip, and the Espruino sends back accelerometer/gyro data.It takes 120 to 200 milliseconds for the server to receive a response back from the Espruino. This includes the time it takes for Espruino to request data from the MPU6050 module. So it's not really ideal for realtime visuals. I haven't timed how long the MPU6050 request takes yet.
At first I tried the browser's new
fetch()
API, but it would not work due to this problem: https://bugs.chromium.org/p/chromium/issues/detail?id=728953So instead of making direct HTTP requests from the browser I am going through the local Meteor server which obviously will take longer.
Do you know if the Espruino WiFi is capable of replying with data over WiFi at a speed closer to something usable with a graphical application? If not, maybe can you recommend a chip that is easy to install Espruino firmware on, so that it can be faster (and just as easy to connect to in Web IDE)?
-
I know the IP of my computer, but when I try
require("http").get('http://192.168.0.5:3000', function(res) { res.on('data', function(d) { console.log("--->"+d); }); }).on('error', function(e) { console.log(' --- ERROR: ', e) });
it shows the error
--- ERROR: { "code": -15, "message": "no response" }
But I can access
http://192.168.0.5:3000
on my desktop browser.Any thoughts on why Espruino might not be able to access it?
EDIT: hmm, I can access the Espruino if I know it's IP:
┌─[00:41:15/localhost/chronos/.../src/trusktr+trusktr.io] └─╼ ping 192.168.0.8 PING 192.168.0.8 (192.168.0.8) 56(84) bytes of data. 64 bytes from 192.168.0.8: icmp_seq=1 ttl=255 time=15.1 ms 64 bytes from 192.168.0.8: icmp_seq=2 ttl=255 time=35.6 ms 64 bytes from 192.168.0.8: icmp_seq=3 ttl=255 time=61.1 ms
Is there a way to make Espruino's IP static?
-
-
-
@allObjects I see the
ws
module for example, but how do I make the connection without knowing IP addresses? -
-
I'd like to connect Espruino WiFi to my computer over WiFi so that I can send data from (f.e. accelerometer data) from Espruino to the computer without a wired connection.
I could easily set up website and communicate through it, but that would be too slow.
When both devices are connected to a router, I am thinking to have the computer scan the network for IPs and send a request to each one, then Espruino will reply when the computer hits its IP and then the computer can know which one is Espruino.
Is there a better way? Maybe I can pre-configure the IPs and just hard code them? Any tips on how to do it?
Maybe it is possible to do it directly from computer to Espruino with Espruino is a WiFi AP? Would that work and be better?
-
are you really at the development stage and will be writing code for the near future?
Yep, am aiming to have something finished by June 30th for 3DWebFest. That's a good idea, I think I will get that power regulator! And yeah, plugging in a cell phone battery sounds nice, so it can last long. Thanks for the tips!
I only need the device to run for 3 to 5 minutes during the show. :D
-
@Gordon Thanks! That helped a lot.
The battery I pictured above has that same (JST PHR2) connector, and says 3.6v. Would that one work then?
when fully charged the 3.6v NiMh battery could be a little over 3.6v.
If the battery is fully charged (and is above 3.6v), could that break (burn) the espruino? Should I get a voltmeter to check before wiring it up?
Battery: https://www.adafruit.com/product/328
If I get that battery, would the white JST PHR2 connector fit onto the GND/VUSB pins directly?
As for the separate power supply option, which does sound best based on what you describe,
Battery Black -> Espruino GND -> LM3671 GND
Would I need to fork the black wire to two wires (like a snake tongue) and connect to both pins, one on each board?
LM3671 3V -> Espruino 3.3v
Just to confirm, this is to the 3.3v pin (which the schematic calls "3.3v output"), NOT the VUSB pin?
-
Happy soldering:)
@ClearMemory041063 thanks! Looking forward to it, these will be my first soldering projects. :D Thanks for the tips. I'll be back once the chip arrives in the mail (and after I've tried to solder something).
-
@allObjects Hey, thanks for your helpful intent, but its still advanced for me. You mentioned the Pico, but I'm using the WiFi. Does that make a difference?
You are perfectly fine to connect this battery directly to the 3.3V because its highest voltage and worst case is below the maximum ratings.
Does the 3.3v pin go inside the red or the black side of the connector? And what about the extra wire (if I connect to red, the black is left over)?
-
-
Hmm, WebRTC sounds like it would be a great way to, for example, stream sensor values to a client (f.e. accelerometer from Espruino to Chrome tab).
Do you guys have WebRTC running in Espruino?