-
function getTypedHistString(tdx) { var ret=""; var typen = htypes[tdx]; if (tdx<4){ var tstr="["; for (var i=0;i<48;i++) { tstr=tstr+HISTORY[typen][i].toFixed(1); if (i !=47) { tstr+=","; } } tstr+="]"; return tstr; } else { return JSON.stringify(HISTORY[typen]); } } function processrequest(req, res) { try { var par=url.parse(req.url,true); var q=par.query; var path=par.pathname; path=path.split('/'); path=path[1]; switch(path) { case "status.json": var r='{"lamp":{'; for (var i=0;i<5;i++) { r+='"'+colors.substr(i*4,4)+'":'+STATUS.LEDs[i].toFixed(2); if (i<4) {r+=",";} } r+='},\n"sensors":{"RH":'+STATUS.RH.toFixed(1)+',"Temp":'+STATUS.Temp.toFixed(1)+',"Pressure":'+STATUS.Pressure.toFixed(2)+',"Air Quality":'+STATUS.AirQual.toFixed(2)+'},\n"Light":'+JSON.stringify(STATUS.Light)+'}'; res.writeHead(200,head); res.write(r); res.end(); break; case "history.json": res.writeHead(200,head); var n=0; res.on('drain',function(){ res.write('"'+htypes[n]+'"'); res.write(":"); res.write(getTypedHistString(n++)); if (n==8) {res.end("}");} else {res.write(',\r\n');} }); res.write("{"); break; case "usermsg.cmd": if (query.msg && query.msg.length > 1) { usrmsg=query.msg; MnuS=10; setTimeout("uplcd();",100); res.writeHead(200,head); res.write("{status:\"ok\",message:\""+query.msg+"\"}"); } else { res.writeHead(400,head); res.write("{status:\"error\",error:\"No message supplied\"}"); } res.end(); break; case "lamp.cmd": STATUS.LEDs[0]=q.BLUE===undefined ? 0:E.clip(q.BLUE,0,1); STATUS.LEDs[1]=q.COOL===undefined ? 0:E.clip(q.COOL,0,1); STATUS.LEDs[2]=q.WARM===undefined ? 0:E.clip(q.WARM,0,1); STATUS.LEDs[3]=q.YELL===undefined ? 0:E.clip(q.YELL,0,1); STATUS.LEDs[4]=q.RED===undefined ? 0:E.clip(q.RED,0,1); setTimeout("upled();",100); res.writeHead(200,head); res.write("{status:\"ok\",message:\"lamp state set\"}"); res.end(); break; case "code.run": //This is why I don't expose this board to requests from outside the LAN ;-) if (query.code) { var x=""; try { x=eval(query.code); res.writeHead(200,head); res.write("{status:\"ok\",result:\""+x+"\"}"); } catch (err) { res.writeHead(500,head); res.write("{status:\"error\",error:\""+err.message+"\"}"); } } else { res.writeHead(400,head); res.write("{status:\"error\",error:\"No code supplied.\"}"); } res.end(); break; default: res.writeHead(404,head); res.write("{status:\"error\",error:\"unknown command\"}"); res.end(); } } catch (err){ res.writeHead(500,head); res.write("{status:\"error\",error:\""+err.message+"\"}"); res.end(); } }
Works like a charm!
I was thinking about the object.keys() approach - but I don't want to bite myself in the ass if I later add something to HISTORY object, since my code (as you can see) makes assumptions about which index number corresponds to which kind of data, since I have to do float arrays differently from integer arrays.
-
-
While working with the Wiznet adapter on an Espruino Original Board (well, my clone of it), I noticed that there seemed to be a very low cap on the number of requests that can be serviced by it. After making a few requests, it would simply refuse the connection. But try again a minute or two later, and it would work.
I think this is due to browsers trying to keep the socket open (keep alive) - it seemed to be markedly improved - possibly solved - by adding Connection: close to the http headers. Has anyone else noticed/investigated this issue? Is my diagnosis correct? If so, should it be added to the documentation?
-
AzzyRF is not connected at all, and no serial handlers have been defined for it.
No watches set except on the keypad, which isn't being touched.
So either there's a problem with keypad (though I have no indication that onkey() is being called), or somehow there's an overflow from what it's printing to the USB console (which I didn't think was ever very much data).... -
-
-
HUZZAH!!!!! Thank you!!
htypes=["Temp","RH","Pressure","AirQual","Clear","Red","Green","Blue"]; function writeTypedHistory(res,tdx) { var typen = htypes[tdx]; res.write((tdx === 0) ? '{"' : ',"'); res.write(typen); res.write('":'); res.write(JSON.stringify(HISTORY[typen])); if (++tdx < htypes.length) { setTimeout(writeTypedHistory,200,res,tdx); } else { res.write('}'); res.end(); } } function processrequest(req, res) { try { var par=url.parse(req.url,true); var q=par.query; var path=par.pathname; path=path.split('/'); path=path[1]; switch(path) { case "history.json": res.writeHead(200,head); setTimeout(writeTypedHistory,10,res,0); break; <snip> } } catch (err){ res.writeHead(500,head); res.write("{status:\"error\",error:\""+err.message+"\"}"); res.end(); } }
-
I don't understand what you're suggesting?
HISTORY object contains 8 typed 48 element arrays (representing data every 30 minutes), 4 Float32Arrays and 4 Uint16Arrays. The time data is not retained - I push onto one end and drop the oldest value every time I update it (by looping over the arrays since I can't do push() with a typed array). This works.
The problem is that I need to stringify the whole thing and send it as JSON to the webpage that will display it as a nice neat graph. However, I get out of memory when I do this - in the above, I've commented out all except RH, Temp, and Clear - which works, but then I don't get to have all the data I want.
I've tried breaking it all up into separate documents, but this doesn't work either - still runs out of memory, I think because it's not waiting until everything gets sent before stuffing more into the bufer.It looks like the drain() method is made just for this kind of thing - but I don't know how to use it and there are no examples :-(
-
LDR's and LEDs probably won't be fast enough to sense a ball going by them. Opto switches based on phototransistor/photodiode are much more effective. Or just use pinball rollover switches (depends on how how much of the hardware is "pre-made" for you....)
The display on the scoreboard for each "lane" need not be separate. I'd just use one string of neopixels for the whole thing. Specifically, my first attempt would be to get one of those strings of 50 WS2811 pixels (the ones that look kinda like strings of christmas lights), using the appropriate number of LEDs for each lane. Unlike the "strip", you can move the bulbs around to position them the way you want (it's unclear to me whether you have an existing score-board for a derby game - if you do, you could tuck these lights where the old bulbs went)....
Espruino should be able to handle a large number of players, and probably a bit more naturally than an Arduino would. Both of them would be effective for your task though.
Arduino vs Espruino:
Espruino has faster developent time (JS is easier to write than C, especially in terms of writing sane, readable code that makes sense), especially if you're interfacing with the web, where the painful parts of C become more prominent. The fact that you get a js console that you can execute code on "live" during development is indescribably useful.
On Arduino, "String" is the devil - strings that you can easily concatenate with + exist, but the usage patterns they lead to result in weird memory problems; the alternative is c-strings (null terminated character arrays), and operations on them are, shall we say, less than intuitive - on Espruino, strings are a great data type and are work the way you expect them to without caveats.
Espruino code execution is slow - even though the processor is several times faster than an arduino, the overhead of the interpreter often makes it slower (though it's worth noting that where you can send the Espruino a bunch of data to work on at once, it's fast).
Arduino is cheaper. Code execution is very fast. RAM is very limited, and you need to think much more carefully about how you use resources. C doesn't have a native data type like js objects, and it really hurts if you're coming from a modern language where you're used to that.
My rule of thumb is that if if i'm interacting with the internet (including calls to webservers on a local network), or if the application is difficult to realize without dynamically sized arrays use Espruino. If I'm working at a low level, or have very tightly timing critical things, if the task is very well defined, predictable, and amenable to fixed size arrays, use Arduino.
Many of my larger projects have both of them - for example, I have an Arduino sketch that sends and receives data using those el-cheapo 433mhz transmitter/receivers, and interfaces via serial, and have that talk to an Espruino to act as a Serial <-> RF gateway. In a current project I also have an Arduino (well, arduino-programmed attiny4313) converting serial to the curious parallel interface used for the futaba VFD I'm using - but those serial commands are sent by the Espruino, which provides the web interface, the menu, and all that jazz.
-
-
How do I do this?
I am currently doing this:
res.writeHead(200,head); res.write("{\"Temp\":"); res.write(JSON.stringify(HISTORY.Temp)); res.write(",\r\"RH\":"); res.write(JSON.stringify(HISTORY.RH)); res.write(",\"Pressure\":"); res.write(JSON.stringify(HISTORY.Pressure)); res.write(",\"AirQual\":"); res.write(JSON.stringify(HISTORY.AirQual)); res.write(",\"Clear\":"); res.write(JSON.stringify(HISTORY.Clear)); res.write(",\"Red\":"); res.write(JSON.stringify(HISTORY.Red)); res.write(",\"Green\":"); res.write(JSON.stringify(HISTORY.Green)); res.write(",\"Blue\":"); res.write(JSON.stringify(HISTORY.Blue)); res.write("}");
It doesn't seem any better than just doing res.write(JSON.stringify(HISTORY));
either way, it runs out of memory halfway through (the main reason being that some of the arrays being stringified are floats, so they get printed with a billion decimal places). I see that there's the .drain callback, but I can't find any example about how to use this. How do I keep track of where in the process I am so I know what to stringify next?
Thanks!
-
-
While running code with half a dozen intervals running, the following message was printed:
New interpreter error: FIFO_FULL
How do I determine what caused it, what functionality broke, and how to prevent it from happening again?
This is the code that I'm running:
https://github.com/SpenceKonde/AzzyProjects/blob/master/GraphProject/DeskController/DeskController.js
But i have no watches set, so what could generate this error in this code???It's running on an Espruino Board clone (the one I posted about in projects months ago) with the D-spec chip for the slightly larger RAM. But it should be working like a normal Espruino Board...
I haven't switched to the save on send to run functions from flash yet - but would that even help? It's FIFO not RAM that's filling up.Since I do my own builds, can I make the FIFO bigger? With the D spec part, I should have the ram for it, especially once I switch to do save on send.
I'm a bit concerned, since I still haven't started the code to drive the nixies, monitor RF messages (the heavy lifting gets done by an arduino that takes commands and outputs data via serial, since arduino is very good at that and espruino isn't so great at it), or do the userinterface for manual control via the keypad and VFD display (the latter is also serial, via an attiny4313 helper). And it's getting FIFO overflows when I don't even understand what in there could be stuffing lots of stuff into the FIFO.
Running v2.00 of Espruino.
Note: I can't find any functionality that broke.....
-
"single bus" is NOT the same as OneWire!!!
OneWire is a specific protocol used almost exclusively by Dallas Semiconductor products. The slave devices all have a unique serial number, there's a way to parasite power so you don't need a separate power wire, etc. The Aosong temperature/humidity sensors do not use OneWire, they use their own single wire protocol; calling it a bus is misuse of that term, IMO, as well - "bus" sort of implies that more than two devices can be connected to it - but with no provision for addressing, the single wire protocol that the Aosong sensors use can only ever have two devices connected to it - the sensor, and the controller it talks to (I mean, I guess you could have multiple controllers connected to it, but I still don't think this counts!).
But yeah, it looks like you can talk to that as if it's an AM2302 (aka DHT22) if you ground the SCL pin. An I2C module for those would be nice though - reading the single wire protocol in javascript doesn't play to Espruino's strengths.... Like, it works, but behind the scenes it's generating IIRC 80 callbacks within just a few milliseconds. An I2C module for it wouldn't be hard to write either...
-
I'm trying to upload a block of code to an Espruino (it's my Espruino Board clone, but it's just a clone of the official Espruino with the D-spec part, so this should happen with normal Espruino board as well). Using the IDE, connected via USB - nothing special.
If I upload my code with No Minification, it uploads fine.
If I use the Closure Compiler, it uploads fine.
If I upload my code with Esprima minification, I get a memory error immediately on uploading it, and not all the code gets saved.
Is there any fix or workaround for this? Something that needs to be fixed in the IDE?
My guess is that it's rolling multiple commands (maybe all of them?) into one line, resulting in the Espruino getting this huge blob of code that it can't handle in one "bite"?Espruino Web IDE version showing as 0.70.6.
-
Couple of things - pulse reset low after power on but before trying to communicate with it. Depending on the power up sequence, it can go into a low power shutdown mode in which it doesn't respond to UART on startup.
Make sure you have TX and RX wired correctly. TX of one device goes to RX of the other device.
-
-
So what if all the good stuff is SMD? These boards have SOIC and (T)SSOP outline, and stack with my 2x4 SMD protoboards for even more part options! Someone needs to drill into people's heads that SMD soldering really isn't hard! I'd pick soldering a SOIC package over a DIP one any day, even working by hand... but most hobbyists act like SMD soldering is kryptonite.
-
-
Fritzing is an abomination, and it promotes unclear and misleading forum posts because people inevitably substitute parts, and then post diagrams that show one thing, with footnotes like "That regulator is actually a transistor, and that battery is actually a power supply". Noobs love it over at Arduino forums, but all the people answering the questions detest it - a hand-drawn schematic, photographed with a cellphone, is more effective for communicating a circuit than that awful, no-longer-supported piece of crap.
-
While the interpreter is idle, it checks for intervals, timeouts, and other events, and runs the associated handlers. After such a callback returns, interpreter is back in idle state (until the next callback fires).
So, if you have something slow-ish, that will block callbacks from firing until it's done. The Espruino will queue up callbacks during this time, but that may not be good enough, depending on your application.
This really points to a fundamental difference between what Arduino and Espruino are good at. Espruino makes it so easy to interact with the world via http/etc, write civilized, modern code in a forgiving language, gives you a live interpreter, and generally incredible ease of coding. Anything where you are doing a lot with strings is way easier. But the price of that is that it's pretty slow - there are plenty of things I can do on an 8mhz AVR that the 72mhz stm32 or 160mhz ESP8266 running Espruino just isn't fast enough for, and similarly, things where sub-second timing is critical are often troublesome. I have a few applications where I use an Espruino for the stuff that handles strings, talks to the world, and so on, talking to an AVR dedicated to the timing critical stuff (in my case, dealing with 433mhz OOK RF) over serial.....
For more detailed assessment, post the code you're observing this with and what board (and espruino version) you're using it on, and an example of what it's receiving over serial (the content of the string could be relevant); I find it hard to belive that what you've described would end up messing the timing up by hundreds of ms - but who knows what you're doing when processing the received string, or how your serial handler is written, and so on...
-
-
I agree with @Gordon here - port expanders are much more useful if they all have a consistent API and provided pin objects with read/write/set/reset/mode methods so they worked with the standard functions.
That sort of thing is one of the ways that Espruino is a lot more friendly than Arduino.
On a related note - is there a method of a pin object for analogRead/analogWrite? It doesn't look like there is - maybe there should be? It would be neat for those PWM-capable port expanders, and external ADC chips.... though maybe the complexities and limitations of those parts would make this less useful than it seems at first glance.