weird strings produced

Posted on
  • Hi,
    I'm using my heltec esp32 as simple temperature monitoring device:

    1. via setInterval I sample my one wire sensors and generate strings (influx line format) that I push into array. Sampling is done every 300ms
    2. again via setInterval I push the collected strings to influx via http post. This happens every 5 secs.

    What's weird is that every 10-15 minutes I get error from influx because I'm sending corrupt strings. The errors are small — here & there one character is wrong.

    Also, the device works for few hours and then stops sending data. Haven't been able to catch this moment and see tho logs yet.

    How stable/dependable is espruino? Can I rely on it to control heaters and pumps (planned next step)?

  • How stable/dependable is espruino?

    Espruino is super stable on original Espruino devices!

    ESP32 implementation is incomplete and not as reliable, so there is still room for improfement.

    If you like to share your code with the forum, members might give you some advise / hints.

    Do you have an idea why your device stops sending, like running out of vars, sockets or 3v3 power issues etc.....

  • so, I left it connected via tcp and this is what seems relevant:

    ERROR: Ctrl-C while processing interval - removing it.
    Execution Interrupted during event processing.
    New interpreter error: CALLBACK,MEMORY
    ERROR: Ctrl-C while processing interval - removing it.
    Execution Interrupted during event processing.

    I get some exceptions in the http put ("Uncaught InternalError: Unable to create socket" included) but it looks like both setInterval handlers are cancelled? the one reading temperature did not throw visible exceptions.

  • "Uncaught InternalError: Unable to create socket"

    might be your coding or a bug in ESP32 implementation.

  • every request is sent to fixed url. only the payload string varies. not sure where the bug could be

  • Sat 2021.05.08

    re 'again via setInterval I push the collected strings'
    re 'Also, the device works for few hours and then stops sending data'

    New interpreter error: CALLBACK,MEMORY

    Hi @gdanov , what techniques are being used to check memory? There really isn't enough here to make a definitve response. The above however, leads me to believe that memory is being gobbled up. It is quite possible that a setInterval is buried inside a repetative loop, or something of the sort, from which then, Espruino is being blocked from perfofming the necessary garbage collection.

    Has process.memory() been viewed to determine usage as time moves along? Please post before, during and after.

    'but it looks like both setInterval handlers are cancelled?'

    Is the trailing question mark indicating a guess here, was a check actually done?

    If it hasn't been discovered yet, these commands entered into L-Hand WebIDE console will reveal the state of memory.

    console.log(global["\xFF"].timers); //nice, less info
    trace(global["\xFF"].timers); //full info

    As @MaBe pointed out in post #2 it'll be much easier to assist with the actual code. Please post.

  • Hi, you wrote you sample sensors every 300ms, unless the sensor is in some liquid or glued/bolted to something you measure, you create significant self heating (assuming it's a DS18B20 or similar). And IIRC unless you reduce the default resolution, sampling multiple sensors won't finish in 300ms.

    And since you got CALLBACK,MEMORY errors as well, there might be a memory leak somewhere. Happens to everyone, I usually display or send free memory as well, so I can spot if there is any memory leak. Can you post your code? Just remove passwords :)

    The probably too fast sampling rate can lead to a memory leak, because you try to start a new measurement cycle while the first is still in progress. If that's the case, simply measuring slower could solve your problem (and reduce errors due to sensor self heating).

    You can add some debug prints to your to the beginning and end of measurement with process.memory().free to confirm that measurements don't overlap?

  • Thanks a lot for the feedback.
    I'm using DS18B20 and I knew the resolution/conversion time relationship. I use 9 or 10 bit resolution and I read registers then request new resolution without waiting in order to keep the event loop free.
    How much self-heating do you think I'm causing? It's measuring temperatures in the 90-110 range and couple degrees offset (as long as it's constant) is not an issue.

  • Thanks for the debugging hints. I knew none of this. Where should I look for more debugging hints?

    setInterval is called once from the main context. These are my timers in normal situation:

      { time: 140550, interval: 300000,
        callback: function (undefined) { ... }
      { time: 1342468, interval: 3000000,
        callback: function (undefined) { ... }

    this is memory (again under normal conditions)

    { free: 1563, usage: 737, total: 2300, history: 23,
      gc: 538, gctime: 2.717, blocksize: 16 }

    I'll definitelly incorporate your and @AkosLukacs hints into the error handling and debugging when it crashes again.

  • re: 'Where should I look for more debugging hints?'
    re: 'I knew none of this. '

    Hi @gdanov As an enduser like yourself, I've watched the Espruino site grow over the last five years. I started with absolutely no experience with microcontrollers, and gained my knowledge by just helping others through the forum, demonstrating how to 'turn over the rocks' to learn the idiosyncrasies. Surprisingly, all the info is there and well laid out. With the wealth of tutorials and user examples, the site is expansive and complete.

    The easiest and most obvious is to start with any Espruino page and from the menu find the 'Quick Start' info pages. >> Menu >> Documentation >> Quick Start

    or >> Menu >> Support >> Getting Started

    Traversing the forum section is another place to pick up all these hints. A few years back, I created a summary page with the best links in it, and can be found at the top of the 'Tutorials' forum section.


    Open the cream colored pinned top-most 'Writing an effective forum post' and find the heading: 'in addition have these excellent pages been reviewed' found a third the way down the page.

    As a suggestion, keep asking questions, then search out the solution. As I mentioned, most can be found with a small amount of digging.

    Keep turning those rocks over . . . .

  • 'setInterval is called once from the main context'

    What method is being used to end or remove each defined interval?

    From that statement, I'd only expect one timer to show active, but two(five) are shown in the response in post #9

    'this is memory (again under normal conditions)'

    There appears to be plenty available. re: free

    Again, as the others and I have requested, best to post some code, so as not to guess here!

  • Thanks, once again!

    I had two major problems:

    • the infamous brownout detector. Solved with capacitor
    • total mess w.r.t. dev process and flashing code. Spent good deal of time on the "saving code..." page but still not 100% confident I'm doing it right. I obviously had hot mess of setInterval handlers.

    It's big progress because now the probe works for hours without any issues.

  • Mon 2021.05.10

    from post #12
    'Spent good deal of time'
    'but still not 100% confident I'm doing it right'
    'had hot mess of setInterval handlers'

    Here on day three now, it is discovered that it was coding to start with, and not the false assumption:

    from post #1 'How stable/dependable is espruino? Can I rely on it'

    Heck, when I first posted here, I couldn't even spell 'Espruino' let alone write a code block. That was five years ago. Myself and even the others that posted here to assist your endevour, also suggested posting that code to speed things up. @MaBe helped me four years ago, staying with me to the wee hours solving a WiFi mystery in 'sta' mode, and @AkosLukacs having a different take on a rounding issue assisted in finding the suitable solution to that issue. Even @Gordon has spent countless hours assisting us all, creating well laid out tutorial examples, along with excellent resolution explanations. But to get to that point, was the need to upload my code.

    But for some reason, several still find getting going, or navigating the site somewhat of a struggle. This is where I'm asking if you could help us with a few words.

    'Thanks, once again!'

    I'm glad that detail assisted to resolve your issue, as the forum here does generously assist grattis those within the Espruino community.

    And for that @gdanov , I am personally asking for some 'quid pro quo' content to assist us in providing better documentation. As a fair offset, would you please explain the reluctance to have just uploaded some code from the beginning?

    Maybe it's as simple as you are working on the next Elon Musk SpaceX project and want to keep it under wraps, or maybe you are creating a full tutorial to demo your results here to the Espruino community. Although I shouldn't speak for the others, I'm sure from their contribution efforts here, that as do I, would like to learn this simple response.

    Thank you gdanov for an explanation,


  • Hi,
    I'm software professional with very big experience. I know when my code is crap and I know how to learn new stuff. This is why I may appear stubborn, but I really know best how to approach new stuff.

    Uploading my messy experimental code without explaining my workflow would've wasted other ppl's time. You and the community missed nothing, I guarantee you that.

    I'm sorry but I don't really understand what's your request to me. As for my question re stability — It's fair question, in some respects the esp32 port is not complete so I had to know what to expect. I am also very suspicious of the heltec board.

    As a good citizen I always like to help when I can. This is why after asking a question I do my best to follow up, as you can see above.

    So, one more follow-up: the biggest challenge and source of grief for me was the combination of how save() works and how the web ide works. Let me elaborate:

    • Clojure is my favorite environment and espruino's REPL is the closest I've ever seen to clojure's REPL. As usual similarity can hide very subtle traps and this happened here
    • espruiono's save() and boot process is unlike anything I've ever used. It took me one evening of experimenting to finally grasp how the different pieces fit together. The "saving code..." page has it very well laid out, but I needed some practice to really grok it. This page must be front & central, it's extremely important information. The difference when code is evaluated and when global state is restored is key
    • I quickly ditched the web ide to use my emacs + espruino cli. This is, I beleive another trap — the very powerful save & boot capabilities gave me lots of rope to hang myself. Also, using the espruino cli requires you understand what you're doing (which I did not). The web ide has pretty straightforward flow, but "graduating" to espruino cli is deceivingly simple (and wrong in my case)

  • Sun 2021.05.16

    I waited a few days to see what the others might comment, especially regarding the ESP32 port, but it appears their interest was more to get you up and running as their requests were waiting for uploaded code in order to respond, and mine was more to understand in order to improve on the documentation process in addition.

    re: 'source of grief' . . . 'how save() works'

    Had you seen this invaluable companion link: Quick Start - Proper way to call init() on start up

    Again, Thank you @gdanov for your well explained response which should provide insight to those documenting.

  • @gdanov,

    I'm not surprised about your experience with Espruino and even more with Espruino on board not supported by @Gordon. Espruino is different from most of the IoT environment, as JS interpreter different from common implementations, as a system it is different, and also from memory management.

    Esprino as an integrated system of software AND hardware, it comes from its structure closest to a Commodore PET... There is no separation or layering like found in the simplest PCs where there is a BIOS, usually in an (EP)ROM, OS, usually loaded, some monitor and command / system application to system-talk to the OS, and make it load and run applications - applications that are written in a what-ever language and then transformed - compiled - for the particular OS / platform, NOR is is like all the other IoT that have usually only a boot loader - if at all - that allows to upload and store ready-made, all libs included, application into some EPROM, and then fire the load and run of the application.

    With Espruino, it is like it was with the Commodore PET, which is characterized as a BASIC stand-alone system, where the installed language interpreter comes up on power on, and the language includes the monitoring and basic system operation, such as receive a program into memory, save it on a device, load and run if from a storage device, etc. For some back filling you may look at this post simple explanation how to save code that Espruino run on start? and also the conversation it is part of.

    I do this Espruino thing for a while now, and can tell you that Esprino works extremely reliable on the supported platforms... and if there is something, @Gordon is on top of it. In the past, @Gordon was also looking at the other HW - non-Espruino board - but the number of supported Espruino environment has grown as well as the unsupported ones, so that @Gorden had to focus on and give priority to the environments that provide, because - after all - Espruino is open and free.

    As a side note: as much as great experience is helpful, it can make blind or at least biased.

  • espruiono's save() and boot process is unlike anything I've ever used. It took me one evening of experimenting to finally grasp how the different pieces fit together. The "saving code..." page has it very well laid out, but I needed some practice to really grok it. This page must be front & central, it's extremely important information. The difference when code is evaluated and when global state is restored is key

    There can be different opinions about save(), mine would be - forget that it exists :-)
    It is magic that makes things simple in simple cases but may bite you later in unexpected ways so I'd go with plain boot script setting up everything at boot time with no save()d state at all. See also­329685/

  • +1
    Wanted to write something similar, but was too lazy :D

  • Thanks. I've been re-thinking how to structure the code I intend to do (modules included) and am moving in the direction where very little state will be persisted via save(), if any.

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

weird strings produced

Posted by Avatar for gdanov @gdanov