-
-
-
Trying to send a 16KB file from the Espruino to a HTTP client. I've hooked up an SDcard reader to the Espruino and configured it, can successfully read and write data to/from it.
I've tried both the methods mentioned here: http://www.espruino.com/Internet to send data to a HTTP client.
The first, reading the file in its entirety to RAM and then sending to the client, is relatively fast , 4.52 seconds to send 16.1KB.
The second, piping the file directly from the SD card is massively slower. I could understand it being a second or two slower, but 16.1KB takes 21.24 seconds.
I don't believe the SD card interface is the bottleneck, because reading the file to RAM first happens on a page request, so if the SD card took 16.72 seconds to read the file and the remaining 4.52 seconds was just sending the data over http, then the first request would take the same amount of time as the piping request.
Have I found another bug, am I doing something wrong, or am I misunderstanding the limitations of the platform?
-
-
-
-
-
-
-
I also just had to use DFU and opted to go full solder and then clean up afterwards. I just couldn't get the pencil method to work and even when trying to short the pads with wire I struggled to hold the button down as well.
For me I needed DFU mode because the Espruino was just failing to boot at all. The blue light was on faintly but it wasn't showing up in the IDE or anything. It had been fine last night but when I plugged it in this morning, nothing. Everything is fine after the reflash though, so glad that there was a recovery option!
-
Gordon, unfortunately Esprima minification is causing me some real issues, sometimes modules that I want it to load from disk just won't load, then the next time I try to flash they will load, and the time after they will be gone again.
For now I've turned off all minification, but now I've come up against a memory limit while trying to flash.
If I don't require the final module I'm trying to flash, I get the following output:
Erasing Flash...
Writing...................................
Compressed 114368 bytes to 33031
Checking...
Done!
Loading 33031 bytes from flash...which indicates to me I'm using 33kb of flash, well below the 512kb flash or even the 128kb ram that the Espruino WiFi has.
When I require my final module, which has a size on disk of 16kb, I then get
ERROR: Out of Memory!
Uncaught SyntaxError: Got UNFINISHED STRING expected EOF
at line 1 col 15
E.setBootCode("Modules.removeAllCached();\nModules.addCached...but unless my maths is wrong, the 33kb it reports before, + 16kb is only 49kb, still well below 128kb.
I have save-on-send switched on, and I've tried "Modules uploaded as Functions (BETA)" both on and off.
Is there something I'm missing?
-
-
-
-
-
Ah I suppose I had never thought of the simpler case where the Espruino is just in station mode and runs a http server, I was too caught up in my own example. Lets hope that it is just the problem that you have found and there isn't another layered issue when I get back to using the dual-mode.
Thanks very much for looking into the issue. Hopefully you can find a fix soon!
-
-
OK I was trying to keep the example super simple which is why I wasn't responding to the incoming http requests.
Here is a more in-depth example that I can't get to work.
Flow should be like this:
- Connect Espruino to real AP
- Espruino becomes an AP
- Espruino starts HTTP server
- Connect device to Espruino, browse to 192.168.4.1
- Espruino gets http request, then fetches an internet resource via the real AP.
Espruino takes the response from the internet resource and sends it back to the device that made the http request.
const wifi = require("EspruinoWiFi"); const http = require('http'); const startServer = () => { http.createServer(function (req, res) { console.log('got http request'); console.log(req); if (req.url === '/') { res.writeHead(200); getPage((data) => { console.log('got http response'); console.log(data); console.log('send http response back to requester'); res.end(data); }); } }).listen(80); console.log('http server started'); }; const getPage = (callback) => { console.log('get page'); http.get("http://www.pur3.co.uk/hello.txt", function(res) { let data = ''; console.log("Response: ", res); res.on('data', function(d) { data += d; }); res.on('end', () => { console.log('get request ended'); callback(data); }); }); }; wifi.connect('realAP', { password: 'realPW' }, (err) => { if (err) { throw err; } console.log('wifi connected'); wifi.startAP('ourAP', { password: 'ourPW', authMode: 'wpa2', }, (err) => { if (err) { throw err; } console.log('ap started'); startServer(); }); });
- Connect Espruino to real AP
-
Not to complicate matters but I was also seeing similar behaviour when I wired up a second ESP8266 module to my Espruino WiFi and tried to do the same thing by setting one ESP module to be an AP and the other one to be a station. It seems like the
http
module has no way of knowing which "network" to use, and I couldn't find a way of telling it explicitly. -
Alright so I simplified down and the same issue persists.
const wifi = require("EspruinoWiFi"); const http = require('http'); const startServer = () => { http.createServer(function (req, res) { console.log('got http request'); console.log(req); getPage((data) => { console.log('got http response'); console.log(data); }); }).listen(80); console.log('http server started'); }; const getPage = (callback) => { http.get("http://www.pur3.co.uk/hello.txt", function(res) { let data = ''; console.log("Response: ",res); res.on('data', function(d) { data += d; }); res.on('end', () => { callback(data); }); }); }; wifi.connect('realAP', { password: 'realPW' }, (err) => { if (err) { throw err; } console.log('wifi connected'); wifi.startAP('ourAP', { password: 'ourPW', authMode: 'wpa2', }, (err) => { if (err) { throw err; } console.log('ap started'); getPage((data) => { console.log(data); startServer(); }); }); });
When I log the incoming http requests I'm definitely seeing corrupt data so I'm fairly sure the
http.get
is somehow looping back onto the softAP rather than going out via the station."method": "b390b887c80\"",
"url": "\nAccept-Ranges:", -
-
Actually I'm sure its a bug in the http library. If I log the HTTP requests when they arrive, the first one is normal, and then the second one has this to say:
"method": "ntent-Type:",
"url": "text/plain",so it looks like there is some corruption going on where the outgoing http request is getting intercepted by the http server and becoming an incoming http request!
-
Not sure if anyone else has tried this or had any luck, but the ESP8266 in the Espruino Wifi has built in functionality to simultaneously be an AP as well as a station/client.
The functionality isn't exposed in the Espruino libraries, so a little work is required to get it into the right mode, and I feel like I'm almost there, but something isn't quite right and I get the feeling the Espruino http library is to blame.
Try out the following code, and what should be able to happen is that if you connect to the AP that the Espruino makes, and visit http://192.168.4.1 (assuming it gets this IP, which in my testing it usually does), the Espruino should fetch a http resource. However, I seem to get stuck in some sort of loop
got http request
fetching page
got http request
fetching page
got http request
fetching page
got http request
fetching page
got http request
fetching page
Uncaught Error: No free sockets
at line 1 col 278
...row Error("No free sockets");which to me indicates something odd is going on in the http lib.
Does anyone have any ideas?
const wifi = require("EspruinoWiFi"); const startDual = (callback) => { const at = wifi.at; at.cmd('AT+CWMODE=3\r\n', 1000, (cwm) => { if (cwm!="no change" && cwm!="OK" && cwm!="WIFI DISCONNECT") callback("CWMODE failed: "+(cwm?cwm:"Timeout")); else callback(null); }); }; const connect = (_apName, _apKey, callback) => { const apName = JSON.stringify(_apName); const apKey = JSON.stringify(_apKey); const at = wifi.at; at.cmd("AT+CWJAP="+apName+","+apKey+"\r\n", 20000, function cb(d) { if (["WIFI DISCONNECT","WIFI CONNECTED","WIFI GOT IP","+CWJAP:1"].indexOf(d)>=0) { return cb; } if (d!="OK") { setTimeout(callback,0,"WiFi connect failed: "+(d?d:"Timeout")); } else { setTimeout(callback,0,null); } }); }; const becomeAP = (ssid, options, callback) => { const at = wifi.at; options = options||{}; if (!options.password || options.password.length<8) throw new Error("Password must be at least 8 characters"); var enc = options.password?"3":"0"; // wpa2 or open if (options.authMode) { enc={ "open":0, "wpa":2, "wpa2":3, "wpa_wpa2":4 }[options.authMode]; if (enc===undefined) throw new Error("Unknown authMode "+options.authMode); } if (options.channel===undefined) options.channel=5; at.cmd("AT+CWSAP="+JSON.stringify(ssid)+","+JSON.stringify(options.password)+","+options.channel+","+enc+"\r\n", 5000, function(cwm) { if (cwm!="OK") callback("CWSAP failed: "+(cwm?cwm:"Timeout")); else callback(null); }); }; const startServer = () => { var http = require("http"); //start a server http.createServer(function (req, res) { console.log('got http request'); // break context in case something is weird. setTimeout(() => { console.log('fetching page'); // fetch a resource http.get("http://www.pur3.co.uk/hello.txt", function(clientRes) { console.log("Response: ",clientRes); clientRes.on('data', function(d) { console.log("--->"+d); }); }); }, 1000); }).listen(80); }; // Force a scan so that 'at' gets assigned wifi.scan((err, result) => { if (err) { throw err; } startDual((err) => { if (err) { throw err; } // Connect to a real AP connect('apSSID', 'apPass', (err) => { if (err) { throw err; } console.log('wifi connected'); // Become an AP becomeAP('newSSID', { password: 'newPass', authMode: 'wpa2', }, (err) => { if (err) { throw err; } console.log('ap started'); // Fetch some resource to prove we can require("http").get("http://www.pur3.co.uk/hello.txt", function(res) { console.log("Response: ",res); res.on('data', function(d) { console.log("--->"+d); }); res.on('end', () => { // start a http server startServer(); }); }); }); }); }); });
So while I could set a new baud rate, I can't see a way to then tell the Espruino to communicate with the wifi module at that rate, by the look of http://www.espruino.com/modules/EspruinoWiFi.js its fixed to 115200.
Is there any chance you could alter the module so I can pass configuration information for the Wifi module if I want to?