-
• #2
At this moment I do not have an Espruino board at hand to make a comparison of free space after reset and after requiring the module. I assume the modulle that is pulled from the Web is the minified version... http://www.espruino.com/modules/BMP085.min.js.
I pulled the code, did some formatting, and you might shrink it a bit more by dropping some of the debug stuff... also some shortening of member (value/function property) names can help.
function d(a){ this.i2c=a; this.BME280_ADDRESS=118; this.debug=!1; 96==this.read8(208)&&this.debug&&console.log("This chip is BME280"); this.writeReg(242,1); this.writeReg(244,39); this.writeReg(245,160); this.readCoefficients() } d.prototype.concatU8=function(a,b){ var c=new Uint8Array(a.length+b.length); c.set(a); c.set(b,a.length); return c }; d.prototype.convS16=function(a,b){ var c=(a<<8)+b; c&32768&&(c=-(c-1^65535)); return c }; d.prototype.writeReg=function(a,b){ this.i2c.writeTo(this.BME280_ADDRESS,[a,b]) }; d.prototype.read8=function(a){ this.i2c.writeTo(this.BME280_ADDRESS,a); return this.i2c.readFrom(this.BME280_ADDRESS,1)[0] }; d.prototype.readCoefficients=function(){ this.i2c.writeTo(this.BME280_ADDRESS,136); var a=this.i2c.readFrom(this.BME280_ADDRESS,24); this.i2c.writeTo(this.BME280_ADDRESS,161); a=this.concatU8(a,this.i2c.readFrom(this.BME280_ADDRESS,1)); this.i2c.writeTo(this.BME280_ADDRESS,225); a=this.concatU8(a,this.i2c.readFrom(this.BME280_ADDRESS,7)); this.dig_T1=a[1]<<8|a[0]; this.dig_T2=this.convS16(a[3],a[2]); this.dig_T3=this.convS16(a[5],a[4]); this.dig_P1=a[7]<<8|a[6]; this.dig_P2=this.convS16(a[9],a[8]); this.dig_P3=this.convS16(a[11],a[10]); this.dig_P4=this.convS16(a[13],a[12]); this.dig_P5=this.convS16(a[15],a[14]); this.dig_P6=this.convS16(a[17],a[16]); this.dig_P7=this.convS16(a[19],a[18]); this.dig_P8=this.convS16(a[21],a[20]); this.dig_P9=this.convS16(a[23],a[22]); this.dig_H1=a[24]; this.dig_H2=this.convS16(a[26],a[25]); this.dig_H3=a[27]; this.dig_H4=a[28]<<4|15&a[29]; this.dig_H5=a[30]<<4|a[29]>>4&15; this.dig_H6=a[31] }; d.prototype.readRawData=function(){this.i2c.writeTo(this.BME280_ADDRESS,247); var a=this.i2c.readFrom(this.BME280_ADDRESS,8); this.debug&&(console.log("d0: "+a[0]),console.log("d1: "+a[1]) ,console.log("d2: "+a[2]),console.log("d3: "+a[3]) ,console.log("d4: "+a[4]),console.log("d5: "+a[5]) ,console.log("d6: "+a[6]),console.log("d7: "+a[7])); this.pres_raw=a[0]<<12|a[1]<<4|a[2]>>4; this.temp_raw=a[3]<<12|a[4]<<4|a[5]>>4; this.hum_raw=a[6]<<8|a[7] }; d.prototype.calibration_T=function(a){ var b; b=(a/16384-this.dig_T1/1024)*this.dig_T2; a=(a/131072-this.dig_T1/8192)*(a/131072-this.dig_T1/8192)*this.dig_T3; this.t_fine=b+a; return(b+a)/5120*100 }; d.prototype.calibration_P=function(a){ this.debug&&(console.log("T1: "+this.dig_T1),console.log("T2: "+this.dig_T2) ,console.log("T3: "+this.dig_T3),console.log("H1: "+this.dig_H1) ,console.log("H2: "+this.dig_H2),console.log("H3: "+this.dig_H3) ,console.log("H4: "+this.dig_H4),console.log("H5: "+this.dig_H5) ,console.log("H6: "+this.dig_H6),console.log("P1: "+this.dig_P1) ,console.log("P2: "+this.dig_P2),console.log("P3: "+this.dig_P3) ,console.log("P4: "+this.dig_P4),console.log("P5: "+this.dig_P5) ,console.log("P6: "+this.dig_P6),console.log("P7: "+this.dig_P7) ,console.log("P8: "+this.dig_P8),console.log("P9: "+this.dig_P9)); var b,c; b=this.t_fine/2-64E3; c=b*b*this.dig_P6/32768; c+=b*this.dig_P5*2; c=c/4+65536*this.dig_P4; b=(this.dig_P3*b*b/524288+this.dig_P2*b)/524288; b=(1+b/32768)*this.dig_P1; if(0===b)return 0; a=6250*(1048576-a-c/4096)/b; b=this.dig_P9*a*a/2147483648; c=a*this.dig_P8/32768; return a+=(b+c+this.dig_P7)/16 }; d.prototype.calibration_H=function(a){var b; b=this.t_fine-76800; b=((a<<14)-(this.dig_H4<<20)-this.dig_H5*b+16384>>15) *((((b*this.dig_H6>>10)*((b*this.dig_H3>>11)+32768)>>10)+2097152)*this.dig_H2+8192>>14); b-=((b>>15)*(b>>15)>>7)*this.dig_H1>>4; b=0>b?0:b; return(419430400<b?419430400:b)>>12 }; exports.connect=function(a){return new d(a)}
Here is what I manually did to it:
var d=function(a){ this.i2c=a; this.addr=118; this.wR(242,1); this.wR(244,39); this.wR(245,160); this.rCs() },p=d.prototype; p.ccU8=function(a,b){ var c=new Uint8Array(a.length+b.length); c.set(a); c.set(b,a.length); return c }; p.cS16=function(a,b){ var c=(a<<8)+b; c&32768&&(c=-(c-1^65535)); return c }; p.wR=function(a,b){ this.i2c.writeTo(this.addr,[a,b]) }; p.r8=function(a){ this.i2c.writeTo(this.addr,a); return this.i2c.readFrom(this.addr,1)[0] }; p.rCs=function(){ this.i2c.writeTo(this.addr,136); var a=this.i2c.readFrom(this.addr,24); this.i2c.writeTo(this.addr,161); a=this.ccU8(a,this.i2c.readFrom(this.addr,1)); this.i2c.writeTo(this.addr,225); a=this.ccU8(a,this.i2c.readFrom(this.addr,7)); this.dT1=a[1]<<8|a[0]; this.dT2=this.cS16(a[3],a[2]); this.dT3=this.cS16(a[5],a[4]); this.dP1=a[7]<<8|a[6]; this.dP2=this.cS16(a[9],a[8]); this.dP3=this.cS16(a[11],a[10]); this.dP4=this.cS16(a[13],a[12]); this.dP5=this.cS16(a[15],a[14]); this.dP6=this.cS16(a[17],a[16]); this.dP7=this.cS16(a[19],a[18]); this.dP8=this.cS16(a[21],a[20]); this.dP9=this.cS16(a[23],a[22]); this.dH1=a[24]; this.dH2=this.cS16(a[26],a[25]); this.dH3=a[27]; this.dH4=a[28]<<4|15&a[29]; this.dH5=a[30]<<4|a[29]>>4&15; this.dH6=a[31] }; p.rRaw=function(){ this.i2c.writeTo(this.addr,247); var a=this.i2c.readFrom(this.addr,8); this.pres_raw=a[0]<<12|a[1]<<4|a[2]>>4; this.temp_raw=a[3]<<12|a[4]<<4|a[5]>>4; this.hum_raw=a[6]<<8|a[7] }; p.calT=function(a){ var b=(a/16384-this.dT1/1024)*this.dT2; a=(a/131072-this.dT1/8192)*(a/131072-this.dT1/8192)*this.dT3; this.t_fine=b+a; return(b+a)/5120*100 }; p.calP=function(a){ var b=this.t_fine/2-64E3,c=b*b*this.dP6/32768; c+=b*this.dP5*2; c=c/4+65536*this.dP4; b=(this.dP3*b*b/524288+this.dP2*b)/524288; b=(1+b/32768)*this.dP1; if(0===b)return 0; a=6250*(1048576-a-c/4096)/b; b=this.dP9*a*a/2147483648; c=a*this.dP8/32768; return a+=(b+c+this.dP7)/16 }; p.calH=function(a){ var b=this.t_fine-76800; b=((a<<14)-(this.dH4<<20)-this.dH5*b+16384>>15) *((((b*this.dH6>>10)*((b*this.dH3>>11)+32768)>>10)+2097152)*this.dH2+8192>>14); b-=((b>>15)*(b>>15)>>7)*this.dH1>>4; b=0>b?0:b; return(419430400<b?419430400:b)>>12 }; exports.connect=function(a){return new d(a)}
And the attached file is the above code with tabs and new lines removed. I hope I did not mess with essentials... of course, it is a 'different' module... but constraints justify many means...
...reduction by 1374 bytes down to 2255 bytes... yes, looking at the code, it creates quite a lot of things...
1 Attachment
-
• #3
It gets minified. After loading it "only" uses ~420 JSvars, but during loading the string itself makes it all blow up.
The upload is:Modules.addCached("BMP085","function c(b,a){this.i2c=b;this.oss=\"undefined\"!==typeof a?a:3;if(3<this.oss||0>this.oss)this.oss=3;var d=this.read8(208);if(85!=d)return console.log(\"Bad ID of: \"+d),null;this.readCoefficients()}c.prototype.read16=function(b){this.i2c.writeTo(119,b);b=this.i2c.readFrom(119,2);return b[0]<<8|b[1]};c.prototype.readS16=function(b){this.i2c.writeTo(119,b);b=this.i2c.readFrom(119,2);b=b[0]<<8|b[1];return 32767<=b?b-65536:b};c.prototype.read8=function(b){this.i2c.writeTo(119,b);return this.i2c.readFrom(119,\n1)[0]};c.prototype.readCoefficients=function(){this.ac1=this.readS16(170);this.ac2=this.readS16(172);this.ac3=this.readS16(174);this.ac4=this.read16(176);this.ac5=this.read16(178);this.ac6=this.read16(180);this.b1=this.readS16(182);this.b2=this.readS16(184);this.mb=this.readS16(186);this.mc=this.readS16(188);this.md=this.readS16(190)};c.prototype.readRawTemperature=function(b){this.i2c.writeTo(119,[244,46]);var a=this;setTimeout(function(){b(a.read16(246))},5)};c.prototype.readRawPressure=function(b){this.i2c.writeTo(119,\n[244,52+(this.oss<<6)]);var a,d=this;switch(this.oss){case 0:a=5;break;case 1:a=8;break;case 2:a=14;break;case 3:a=26}setTimeout(function(){var a=d.read8(246),c=d.read8(247),e=d.read8(248);b((a<<16)+(c<<8)+e>>8-d.oss)},a)};c.prototype.getTemperature=function(b){var a=this;this.readRawTemperature(function(d){d=Math.round((d-a.ac6)*a.ac5/32768);var c=Math.round(2048*a.mc/(d+a.md));b((d+c+8)/160)})};c.prototype.getPressure=function(b){var a=this;this.readRawTemperature(function(c){a.readRawPressure(function(f){var g=\nMath.round((c-a.ac6)*a.ac5/32768),g=g+Math.round(2048*a.mc/(g+a.md)),e=g-4E3;f=Math.round((f-((4*a.ac1+(a.b2*(e*e>>12)>>11)+(a.ac2*e>>11)<<a.oss)+2>>2))/(a.ac4*(((a.ac3*e>>13)+(a.b1*(e*e>>12)>>16)+2>>2)+32768)>>15)*(5E4>>a.oss))<<1;b({pressure:f+(((f>>8)*(f>>8)*3038>>16)+(-7357*f>>16)+3791>>4),temperature:(g+8)/160})})})};c.prototype.getAltitude=function(b,a){return 44330*(1-Math.pow(b/a,1/5.255))};c.prototype.getSeaLevel=function(b,a){return b/Math.pow(1-a/44330,5.255)};exports.connect=function(b,\na){return new c(b,a)}");
-
• #4
I was not aware of the fact that the debug stuff is dropped automatically... so the savings are not that much as I calculated. I'm also not sure if we are talking about exactly the same module, because there is some code I cannot find in.... NEVER MIND... pulled something else to work on than BMP085... ~~~{:(
-
• #5
BMP085.min.js formatted:
function c(b,a){ this.i2c=b; this.oss="undefined"!==typeof a?a:3; if(3<this.oss||0>this.oss)this.oss=3; var d=this.read8(208); if(85!=d)return console.log("Bad ID of: "+d),null; this.readCoefficients() } c.prototype.read16=function(b){ this.i2c.writeTo(119,b); b=this.i2c.readFrom(119,2); return b[0]<<8|b[1] }; c.prototype.readS16=function(b){ this.i2c.writeTo(119,b); b=this.i2c.readFrom(119,2); b=b[0]<<8|b[1]; return 32767<=b?b-65536:b }; c.prototype.read8=function(b){ this.i2c.writeTo(119,b); return this.i2c.readFrom(119, 1)[0] }; c.prototype.readCoefficients=function(){ this.ac1=this.readS16(170); this.ac2=this.readS16(172); this.ac3=this.readS16(174); this.ac4=this.read16(176); this.ac5=this.read16(178); this.ac6=this.read16(180); this.b1=this.readS16(182); this.b2=this.readS16(184); this.mb=this.readS16(186); this.mc=this.readS16(188); this.md=this.readS16(190) }; c.prototype.readRawTemperature=function(b){ this.i2c.writeTo(119,[244,46]); var a=this; setTimeout(function(){ b(a.read16(246))},5) }; c.prototype.readRawPressure=function(b){ this.i2c.writeTo(119,[244,52+(this.oss<<6)]); var a,d=this; switch(this.oss){ case 0:a=5; break; case 1:a=8; break; case 2:a=14; break; case 3:a=26 } setTimeout(function(){ var a=d.read8(246),c=d.read8(247),e=d.read8(248); b((a<<16)+(c<<8)+e>>8-d.oss) },a) }; c.prototype.getTemperature=function(b){ var a=this; this.readRawTemperature(function(d){ d=Math.round((d-a.ac6)*a.ac5/32768); var c=Math.round(2048*a.mc/(d+a.md)); b((d+c+8)/160)}) }; c.prototype.getPressure=function(b){ var a=this; this.readRawTemperature(function(c){ a.readRawPressure(function(f){ var g=Math.round((c-a.ac6)*a.ac5/32768),g=g+Math.round(2048*a.mc/(g+a.md)),e=g-4E3; f=Math.round((f-((4*a.ac1+(a.b2*(e*e>>12)>>11)+(a.ac2*e>>11)<<a.oss)+2>>2)) /(a.ac4*(((a.ac3*e>>13)+(a.b1*(e*e>>12)>>16)+2>>2)+32768)>>15)*(5E4>>a.oss))<<1; b({pressure:f+(((f>>8)*(f>>8)*3038>>16)+(-7357*f>>16)+3791>>4),temperature:(g+8)/160}) }) }) }; c.prototype.getAltitude=function(b,a){ return 44330*(1-Math.pow(b/a,1/5.255)) }; c.prototype.getSeaLevel=function(b,a){ return b/Math.pow(1-a/44330,5.255) }; exports.connect=function(b,a){return new c(b,a)}
There is not much you can do about...
I just wonder what the nested inline runtime function creation does to memory consumption...
-
• #6
Hmm - interesting that the initial string itself makes it blow up.
No sure what to suggest - I imagine that the 12 byte JsVars mean it's not quite as efficient at storing data in the normal, extendable String format
-
• #7
Do the 12-byte JSvars not support the extendable string format?
-
• #8
Oh, they do - but as each var needs a pointer and flags, the efficiency goes down.
- On 16 byte vars, you've got 12 bytes of data in a StringExt
- On 12 byte vars, you've only got 8 bytes of data
Potentially the extra 2 bits for
lastChild
could maybe go intoflags
saving you 1 byte and letting you use 9/12 bytes for a StringExt, but it's not huge. - On 16 byte vars, you've got 12 bytes of data in a StringExt
I'm trying to load the BMP085 module onto an esp8266 with 800 JSvars and I'm getting an our of memory error when the IDE loads the module:
I have 760 free JSvars after a reset:
Does it make sense that this is not enough for this small module? Are there any tricks I could employ?