-
Agreed - I tend to use brackets too - I can usually only remember that * / comes before + -
I could never remember all this accurately: Operator_Precedence
-
The minifier used by Espruino - Google Closure ( http://closure-compiler.appspot.com/home ) is excellent & I think it makes sense for the IDE to make use of it's API but it is strange at times:
I've just noticed that when I minify the first example above using Simple Optimization but select the "Pretty Print" option the semi-colon isn't removed!
I thought "Pretty Print"only affected white space?
(It still removes the brackets in the second example though.)
-
@Gordon I wasn't suggesting there are many, the interpreter seems extremely "fluent" - I have only come across 3 issues:
The first was when closure decided to insert a labeled statement when I used a break or return within a loop - I can't remember the exact code, but I wouldn't expect labels to be implemented in Espruino and if this does occur it is extremely easy to see within the error message.
The second was as described above - closure identifies that the final semi-colon in a function is superfluous and removes it - Espruino expects a semicolon after a do.. while (and possibly after for loop as @allObjects experienced). The following code is valid but breaks when using simple optimizations
function test(){ var i=0; do{ console.log(i++); } while (i < 10); } test();
The final problem was with brackets being removed by the minifier - the precedence of operators must be evaluated slightly differently by Espruino. This was probably the most difficult to debug because an error wasn't thrown (correct answer is 256 but returns 0 when minified because outer brackets are removed by minifier )
function swap16(val) { return ((val & 0xFF) << 8) | ((val >> 8) & 0xFF) ; } console.log(swap16(1));
I hope this simplified code helps - although minor its the sort of thing that may put beginners off the platform and that would be a pity because it can be extremely enjoyable to work with.
-
-
I have come across something similar to that - its because the minifier identifies that the final semi-colon in a function is superfluous and removes it. The Espruino interpreter chokes if there is no semicolon after a loop (in my case a while loop). I added a "return 1;" statement after the loop and all was fixed. Hope this helps.
-
-
@allObjects I'm new to all this and have been reading up on SPI & sending dummy data in order to read - I found it very confusing but this is what I now understand:
SPI is always dual-direction (even if the data in one direction is sometimes ignored) so if the master expects to receive 24 bits of data from the slave, then it must send out 24 bits to generate all the clocking for the 24 bits sent in the other direction.
Some implementations may provide a "read" SPI function which provides the clocks without you having to specifically supply some "dummy" data to write.
I read that it may be more appropriate to use 0xFF rather than 0x00 for the dummy bytes
since the idle state is usually high - so sending FF is effectively doing nothing (not sure if this is correct?)It may help clear things up a bit (I'm still not 100% clear)
I made use of your getPixel function in my buffered ILI9341 code - I was totally stuck without it - thanks.
-
Thanks Gordon, "Overiding" the functions was just what I needed to make my buffered ILI9341 module backwardly compatible with the existing one.
The module has two additional methods:
setUseBuffer(true/false): If true then use buffering, otherwise use callbacks (default=true)
setMaxBuffer(size): Sets the maximum size of the graphics buffer (number of 16 bit pixels). This defaults to 2000 (i.e. 4kb, similar to the 1bit PCD8544 84*48 display).
The full string is generally written in one go but if the maxBufferSize will be exceeded it is written one character at a time (It may make more sense to have the maxBufferSize in KB).
The buffer is only used during the drawing process but you may wish to lower it if memory is an issue. (NOTE If set too low, a single character in a large font could exceed maxBufferSize, I suppose I should really revert to non-buffered mode if this arises)
I've attached the module (DL_ILI9341.js) and a simple demo comparing buffered with unbuffered.
Hopefully anyone with one of the displays will find it useful - The demo takes 7.6 seconds unbuffered and 1.7 seconds when using buffering. Just set the appropriate pins in onInit().
-
Firstly the good news: Great to see setTime & ArrayBufferView.sort now working. Thanks.
Now for the bad news: I have some code to test the performance of my buffered ILI9341 module (simply multiple drawStrings).
Using the existing ILI9341 module the test was taking 7.5 seconds, 1.8 seconds with the buffered version. Since upgrading to 1v71 the tests now take 10.5 and 2.1 seconds respectively.
I didn't believe the difference so went back to 1v70 and the timings reverted to 7.5 & 1.8 seconds. (I use getTime() before & after the tests to calculate timings)
All I can think of is that SPI is running slower for some reason - any ideas?
-
Great idea - that would obviously work for setFontBitmap too. I'll have to think about the custom fonts - if I "override" setCustomFont in a similar way maybe I could trap setFont8x12 etc. (its really cool the way custom fonts are implemented - I was impressed)
Although I've programmed for years (vb, delphi, c# ...) I'm new to javascript (very basic knowledge before getting my Espruino - learning a lot)
-
@Gordon : I implemented your suggestions at the weekend and am really pleased with the results: Drawing text takes 1/4 of the time taken by the stock ILI9341 module and the colours are now correct - thanks.
I have re-factored my module to make is easier to use but have one question:
Is is possible to get details of the current font from a Graphics object (e.g. is it Bitmap/ Vector/ Custom, vector font size/custom font bitmap etc)? I'm sure this is held within the object but just not surfaced (maybe there a way to access it?).
Without these details I need the user to set the font via a new method: setFont(nameOrSize). This sets the font of the LCD object (using eval to call the setFontNxN() method for custom fonts). I then save the nameOrSize parameter to use when setting the font of my internal buffer Graphics object.
@allObjects : You are 100% correct about memory - even one character in a large font can use a lot of ram. I have taken this into consideration and the connect method now takes an additional parameter: maxBufferSize. If the string requires a buffer larger than this (based on width/height) I draw the characters individually (an individual character can still cause this to be exceeded - if the font is very large).
I will post the code later when fully completed (maybe someone could review the code and if OK add it to the modules library - its a really nice display, just a bit slow at present)
-
Thanks - that sounds perfect! I'll try it out this evening and may write a completely new ILI9341 module which is backwardly compatible with the existing one but doesn't use any callbacks.
Setting the background colour could be an issue but I could query the display to get the existing background (probably just one pixel needed assuming the background was from a simple fillRect).
The SPI speed should be the only bottleneck now - clear() takes a second or so but then that is 320 * 240 * 16 = 1,228,800 bits!!
An option when initialising Graphics would definitely be cleaner (some day!) but your suggested method should have very little impact on performance.
-
Hi
I got a 2.2" 240*320 ILI9341 controlled display and have been really pleased with it (considering its low price) but the current ILI9341 module uses a Graphics Callback to display every pixel which is a bit too slow.
I have implemented a new method in the Controller module:
LCD.drawStringBuffered(str, x, y, fontSize, r, g, b)
This creates a buffer for the string being drawn then sends it to the display all at once. It is working (much faster than pixel by pixel) but I am having issues with the colour (wrong colours being displayed). I think it is something to do with the endianness of the 16bit colour data.
The current module uses the following code when writing 16 bit values (e.g. pixel colour) to the SPI:
spi.write(c>>8,c);
Could this be achieved by changing modifying the spi setup to use an order of 'lsb'. (I did try this but nothing was displayed!)
Anyway I'm pleased with how the screen performs & can work around the invalid colors but it would be great if I could get it functioning correctly. My method is as follows:
LCD.drawStringBuffered = function(str, x, y, fontSize, r, g, b){ //Create a dummy Graphics object to get size of string in fontSize var g = Graphics.createArrayBuffer(1, 1, 1); g.setFontVector(fontSize); var width = g.stringWidth(str) var height = fontSize * 1.3; // this works but not sure how height is related to size for vector font var x2 = x + width-1; var y2 = y + height-1; //now the width/height is known actual Graghics object can be created g = Graphics.createArrayBuffer(width, height, 16); g.setFontVector(fontSize); g.setColor(r, g, b); g.drawString(str,0,0); //write buffer to spi ce.reset(); spi.write(0x2A,dc); spi.write(x>>8,x,x2>>8,x2); spi.write(0x2B,dc); spi.write(y>>8,y,y2>>8,y2); spi.write(0x2C,dc); spi.write(g.buffer); ce.set(); //I tried shifting the buffer by 8 bits - some colors correct but others lost //offsetBuffer = new Uint8Array(g.buffer, 1); //spi.write(offsetBuffer); }
-
It looks like really good quality equipment - I'd be tempted to try controlling one of these radiator valves as part of my current heating controller project:
http://www.maplin.co.uk/p/lightwaverf-radiator-valve-n81qjThere is so much out there I sometimes wonder why I bother trying to develop my own controllers but I suppose that isn't the point!!
-
-
I am currently using the Clock module so no real inconvenience if setTime() is F4 specific.
I just tried it because in your response to an earlier message stated that
1v71 will have some changes so that it remembers the current time after a hard reset ".
I was wondering how this would work (since the current time is held within a Clock object) - I then noticed setTime() and thought I would try it.
Thanks.
-
I'm having a problem using setDate() and there appears to be a bug. Here's some simplified code to try:
var x=0; setInterval(function(){digitalWrite(LED1,x); x=!x;}, 500); console.log(getTime()); //setTime(1000); console.log(getTime());
This works as expected - the red LED flashed every 500ms.
Now uncomment the setTime(1000) and try again - the Time is not set and the interval stops working!
I need to power Espruino off/on to get timer functions working again - not even a reset() helps.
-
Yes - that is exactly what I was planning to do.
Numerous simple services exist e.g.
http://www.timeapi.org/utc/now
Or
http://currentmillis.com/api/millis-since-unix-epoch.phpThis should be easily integrated using http.get() see:
-
Espruino has a real time clock which accurately records the elapsed time since the device was started (powered up). This can be retrieved in ms using getTime().
There is also a Date class which handles dates & times (calendar, years, months, days, hours, mins etc.)
These are tied together using the Clock class to manage the current date/time. An instance of this class needs to be instantiated/initialised every time the device is restarted as shown below:
var Clock = require("clock").Clock; var clk=new Clock(2014,4,15,23,45,0,0); // Initialise with specific date var clk=new Clock("Jun 23, 2014 12:18:02"); // ... or Initialise with specific date
You can then retrieve the current date/time as follows:
var currentDatetime = clk.getDate();
See http://www.espruino.com/Reference#Date , http://www.espruino.com/clock and http://www.espruino.com/Clocks for more details.
-
-
I have refactored some code to save memory using Typed Arrays and have come in to a problem which I have managed to replicate using the following code:
x=new Uint32Array([30474260, 124846100, 219217940, 313589780, 407961620, 502333460, 596705300, 33423370, 127795210, 222167050, 316538890, 410910730, 505282570, 599654410, 49152018, 143523858, 237895698, 332267538, 426639378, 521011218, 615383058, 53084170, 147456010, 241827850, 336199690, 430571530, 524943370, 619315210, 64880661, 159252501, 253624341, 347996181, 442368021, 536739861, 631111701, 86507535, 180879375, 275251215, 369623055, 463994895, 558366735, 652738575]); console.log(x); x.sort(function(a, b){return (a - b);}); console.log(x);
I get the following Output for the second console.log (the first is as expected):
new Uint32Array([30474260, 33423370, 49152018, 124846100, 53084170, 124846100, 124846100, 64880661, 124846100, 86507535, 124846100, 143523858, 147456010, 237895698, 407961620, 407961620, 241827850, 407961620, 336199690, 407961620, 407961620, 127795210, 407961620, 159252501, 407961620, 253624341, 410910730, 316538890, 410910730, 180879375, 410910730, 410910730, 410910730, 442368021, 442368021, 410910730, 442368021, 369623055, 410910730, 0, 410910730, 0])
As you can see its a bit of a mess - some values missing, others repeated.
I haven't exceeded the maximum value for a Uint32 ( 4,294,967,295).
Any ideas?
-
Would Socket Support enable the SMTP protocol to be implemented? It would be great if simple emails could be sent when the Espruino encountered certain conditions/errors.
I was thinking of implementing a simple REST API on another web server which Espruino could call using HTTP to send emails but it would be great if this could be done without the need for another web server to relay the message.
(Maybe this could be done currently without socket support?)
-
I would like to get one of the 400*240 displays but I assume the graphics buffer will take 12KB RAM.
http://www.makerdyne.com/blog/selecting-a-microcontroller-to-use-with-memory-lcds/
I noticed that the current flip() function seems to write 1 line of pixels at a time to the display (i.e. linebuffer rather than frame buffer approach?)
http://www.espruino.com/modules/MemoryLCD.js
Could I use a smaller graphics buffer to build & send one row of text at a time? (the display would "remember" the rest of what had been previously displayed)
e.g. if I was displaying 12 rows of text the buffer would only need to be 1KB. I would write one row at a time as needed.
I would obviously need to customise the MemoryLCD module.
I don't want to purchase one of these and then discover that I can't use it because of memory limitations.
-
Sounds good - I'm currently at work but will definitely try it later this evening.