Require-ing BME680 library is broken on Pixl.JS?

Posted on
  • Hi!

    Tried to interface to a BME680 , but fails a rather strange way. Tried to use the example, but

    var bme = require("BME680").connectI2C(i2c);

    Errors at the .connectI2C part: Function connectI2C not found!

    If I just require in the module, like this

    var bme = require("BME680");

    I should be able to use it "on the left side", right? But can't, there is no connectI2c or connectSPI or BME680 properties on the bme variable.

    It does work if I require a DHT22. The connect function can be called from the REPL side.

    Hardware: Pixl.Js, 2v00; the BME680 is connected thru I2C on A4 and A5. (on a pimoroni breakout board)

    I2C and the module seems to work OK: Reading the module's JS code, found that there is a module Id, and I could read that Id without any problems.

    The upload of the code does take a couple of seconds, there are no errors. Looked at the module's JS code, and should work. Or at least should do something, but does nothing. As if nothing is exported...
    Anybody has any idea what might be the problem?


  • See no issue with the module: in both -­s and­in.js - module files, I see the functions as part of the exported and by require retuned object exports... ...weird.

    I assume you got all the details right, down to possible typos and internet connected...

    The modules is kind of a kitchen sink... it provides access to the connectXYZ functions as well as to the class - speaking in oo terms - or in js: constructor function.

    Just upload from the IDE on the right side / from the edit pane this code:

    var bmeMod = require("BME680");

    In console - on the left side you can then play around line by line with:

    var BME680 = bmeMod.BME680;
    var bme1 = bmeMod.connectI2C(...);
    var bme2 = new (bmeMod.BME680)(...);
    var bme3 = new BME680(...);

    I hope this will help debug the issue...

  • Thanks for the input! Really weird, tried almost exactly what you recommend before posting, but no luck.
    A screenshot is attached of the code + the REPL result to show exactly what I tried to do.
    But no luck. Looks like the require-d BME680 is just an empty object (look at the print-ed result and the autocomplete result just at the top of the highlight.

    I did import the DHT module only to verify that require does work. And it does work: dht.connect is indeed a function. but the BME680 is empty???

    1 Attachment

    • 2018-12-28 14_01_03-Espruino Web IDE.png
  • So, just manually copy-pasted the module's code, renamed exports to bmeManual, and uploaded to the Pixl.JS. And it works, and the measured values feel realistic (see the screenshot).

    Edit: it does work both with the minified and non-minified code if I just copy-paste it. But doesn't work with require-ing the code. Don't know what's going on...

    1 Attachment

    • 2018-12-28 14_16_47-Espruino Web IDE.png
  • This behavior is indeed weird...

    What raised some suspicion that require() / IDE uploader does not do what it is supposed to do is the error message I see in one of the screen shots... I do not know where it comes from, but if upload is not going straight and untouched, things are out of whack...

    To go closer to require() / IDE uploader context, take a look at this conversation about Module development. It describes how the module cache can be loaded. It goes similar to your approach, but requires less meddling with the source code. You just plug it in, unminified or minified.

  • Hm, I'm using BME680 without issue....
    Code is here - of course, you can have fun picking out the BME680 stuff from the rest of that mess:­cts/blob/master/GraphProject/DeskControl­ler/DeskController.js

    My hardware is (essentially) an Espruino board - only with the RDT instead of RCT chip, and adjustments to board def to tell it about the extra ram and flash.

  • Thanks for the answers, I think something is wrong with the Pixl.JS!

    If I "send" this single line of code var bmeMod = require("BME680"); from the IDE, it does work on the Espruino Wifi, but does the aforementioned weirdness on the Pixl.JS

    The Pixl.JS prints New interpreter error: LOW_MEMORY,MEMORY, and memory usage is different:
    Calling process.memory() on the Pixl.js prints 2378 free, 122 usage.
    Calling process.memory() on the Espruino wifi prints 6203 free, 945 usage.

    Both running 2v00.
    On the same machine, tried a couple of times, and the Pixl.JS works fine otherwise: the BME 860 works, if I directly upload the whole module code...

  • @AkosLukacs, let me fire up my Pixl and see what it does. I do not have a BME680, but that should through an exception way beyond successful upload.

  • ...same issue for me...

    This is the code I'm uploading:

    var bme680, bme680Mod = require("BME680");
    function onInit() {
      bme680 = bme680Mod.connectI2C();

    This is what the load shows upon clicking the Upload button:

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
     2v00 (c) 2018 G.Williams
    >New interpreter error: LOW_MEMORY,MEMORY
    Uncaught Error: Function "connectI2C" not found!
     at line 1 col 20
    bme680 = bme680Mod.connectI2C();
    in function called from system

    Screenshot attached below shows the whole story, from connect thru the failure.

    The actual error - New Interpreter error... - happens at the end of the upload.

    Will do a few other tests.

    1 Attachment

    • BME680pixleUploadIssueV200.png
  • Testing on a PICO same code... and get expected output:

    Since I do not pass an I2C argument, actually none, I get what I deserve... but clearly, .connectI2c() got invoked... and when trying to write to I2C - variable a in minified code - it fails.

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
     2v00 (c) 2018 G.Williams
    Uncaught Error: Cannot read property 'writeTo' of undefined
     at line 1 col 2
    a.writeTo(b,c);return a.readFrom(b,d)
    in function "r" called from line 1 col 72
    ...;if(this.r(a.CHIP_ID_ADDR,1)!=a.CHIP_­ID)throw Error("BME680 ...
    in function "e" called from line 2 col 5
    in function "connectI2C" called from line 1 col 31
    bme680 = bme680Mod.connectI2C();
    in function called from system

    I suspect/conclude, that something upon reception when Pixl is writing the module to the Modules cache, it fails.

    1 Attachment

    • BME680UploadConnectI2C_PICO.png
  • Last, and 'giving up' test is uploading the following code:

    `function f(b,a,c){if(b<a||b>c)......write(b&127,c­,d)})}`);

    The multi-line string in the single back tick quotes is the minified code from and seems to be just too much for Pixl to handle on reception. Pixl starts to create the cache entry - you can find it w/ Modules.getCached() in the console - but the entry is incomplete... actually empty:

    >var m = require("BME680");
    ={  }
    ={  }

    There is too much node.js like stuff going on... (...things held floating...)

    This module was written a bit too Arduino-ish... where the crunch work happens at compile time in the IDE and BEFFORE upload to the board... and not what happens in ESPRUINO: NOT much in the IDE except finding nested require, all crunching ON the BOARD, AFTER the upload.

    Pixl has obviously not enough memory - my uneducated assumption - to do that heavy lifting. PICO can do it.

    You are NOT out of luck... just up for some significant work.

    Rewriting the Module would need some significant work... and absence of regression tests makes it worse. My approach of rewriting would be a base module containing the 'class'/constructor BME680 w/ the Constants - C - and making C accessible via the 'class'/constructor BME680. Subsequent uploads and extensions of this 'class'/constructor function would add the sensor areas as desired and reference the Constants C always via the 'class'/constructor BME680. Also, some name shortening and more JS like programming have to be applied...

    I know that there is a way to allow constants to be folded in, so they are not around anymore with these long names. Using one and the same constant definition in all the Main and Sub
    modules can tidy up the runtime code even more.

    May be @Gordon has a better answer...

    1 Attachment

    • BME680pixleUploadIssueV200_2.png
  • Thanks a lot @allObjects for confirming it!

    One thing: the module code does work on the Pixl.JS!
    If I just copy-paste the whole module code "on the right hand side", without require-ing it, it can display all the measurements on the LCD too without any problem.
    Had it running with 1 second refresh for a couple of hours, without any problems.

    I suspect the issue is indeed with the require part, so yes, @Gordon will have some fun puzzle after he comes back from his holiday :)

  • ...this is due how the Espruino JavaScript interpreter works: every time a JavaScript expression completes - in level 0 - on upload, it is executed and the source string is released and interpretation resources are freed up for next expression. ...just a reasonable guess.

    The way I emulated the upload is what actually happens on upload, which is not in level 0, where as @AkosLukacs did it, it is in level 0. In other words, it is a way to overcome temp memory issues... this is another reason why @Gordon's Espruino JavaScript interpreter interprets from source and not from some byte code to deliver this high-level environment in a memory resource constraint setting, as all the power-frugal mc are.

  • @allObjects Thank you for the explanation, I guess now I understand the why as well!

  • Ok, so the issue here is really the New interpreter error: LOW_MEMORY,MEMORY message that appears while uploading. This is something you definitely shouldn't ignore - when you get the MEMORY error it means the interpreter totally ran out of memory and had to stop execution, so stuff got lost. LOW_MEMORY itself is just a warning that you hit before MEMORY.

    Basically the BME680 module is big - 10k minified - and the default upload method uploads as a string, which them has to be parsed (using another 10k) and then executed (using another 10k).

    The easy fix for this is actually just to turn on Modules uploaded as functions (BETA) in the Web IDE settings (which allows for a much more efficient upload). Once that's done everything will work fine - I think this is something that I'll turn on by default in the next version of the IDE.

    Other option is also change the options so that everything is uploaded direct to flash (which will save a bunch of memory). OR... you could save the BME680 module to storage as a string (named something else like _BME680) and then it'll be in the Pixl forever and you won't have to re-upload it each time.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Require-ing BME680 library is broken on Pixl.JS?

Posted by Avatar for AkosLukacs @AkosLukacs