Node-red-mcu-plugin v1.0: Integrating Node-RED MCU Edition into the Node-RED editor

The plot thickens. In that same function,

image

if I have a breakpoint on line 47 done?.(); then it hits it on start, steps through to line 48 and will then run ok. If I don't have the break on line 47 then it logs the IP address at line 44 but never gets to line 48. So something odd is going on with done. Possibly a race condition with when it is initialised. It doesn't get to line 52 either.

This part of the code is quite new; there might be some regressions we didn't consider thoroughly enough.

To dig even a bit deeper, you could check if the legacy code crashes either:

Change esp @ line 36 to something else, like x-esp-x, to cover it from the compiler & re-run a build of your flow.
You may find this file in .node-red/node_modules/@ralphwetzel/node-red-mcu-plugin/node-red-mcu.

In any case, you should prepare an issue in the node-red-mcu repo.

In testing node-red-contrib-n2n I am getting the error module dgram not found So I am assuming that we cannot do UDP at this time?

node-red-contrib-n2n has a number of dependencies that are not javascript core:

Without having checked the details further: This looks like a node that needs to be refactored for MCU...

I changed the manifest as suggested and rebuilt, but the behaviour was the same.
[Edit] In fact, on repeating this and doing a clean rebuild I find the problem is not seen with the legacy code.

Issue raised ESP8266 target crashing on startup after connecting to wifi Ā· Issue #83 Ā· phoddie/node-red-mcu Ā· GitHub

Why do I never learn? Life is so much easier if one waits for stuff to stabilise before leaping in. Easier but less fun :slight_smile:

1 Like

Well... the most fun you have doing things no-one else did before.
That's where we are currently...
Thank you for helping us making things better :+1:

Indeed.

A correction to my earlier comment that using the legacy code did not change the problem. I think I must not have done a clean build, because now that I repeat that test I find that the problem is not present in the legacy code. So I do now have a workaround that will allow me to continue while the problem is investigated further.

1 Like

I have reverted the change to the manifest file, but have removed the wifi credentials so that the crash on startup is avoided, and have found another problem.

With the slightly more complex flow below (which requires node-red-contrib-pid) a few seconds after startup I get
Panic /home/colinl/esp/esp8266-2.3.0/cores/esp8266/core_esp8266_main.cpp:131 loop_task
and a stack trace and restart.

Without the Function node Clear all except payload I do not see the problem. Note that are no messages flowing round that part of the flow as it is not necessary to click the Inject node into the PID node in order to make it crash.

[{"id":"f92bb64b93bfc46e","type":"tab","label":"mcu test","disabled":false,"info":"","env":[],"_mcu":{"mcu":true}},{"id":"a74a29ab51318a3a","type":"inject","z":"f92bb64b93bfc46e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"5","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","_mcu":{"mcu":true},"x":230,"y":640,"wires":[["9db682e1f6a487a8"]]},{"id":"9db682e1f6a487a8","type":"debug","z":"f92bb64b93bfc46e","name":"debug 80","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","_mcu":{"mcu":true},"x":430,"y":700,"wires":[]},{"id":"6d9adcf8cdc36b27","type":"debug","z":"f92bb64b93bfc46e","name":"debug 81","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","_mcu":{"mcu":true},"x":480,"y":480,"wires":[]},{"id":"ed0d63aad317e829","type":"inject","z":"f92bb64b93bfc46e","name":"","props":[{"p":"payload"}],"repeat":"2","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","_mcu":{"mcu":true},"x":130,"y":560,"wires":[["a83bf3122efb505c"]]},{"id":"7180d313e18f3785","type":"debug","z":"f92bb64b93bfc46e","name":"debug 82","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","_mcu":{"mcu":true},"x":540,"y":260,"wires":[]},{"id":"32dcd5abbb576d04","type":"rpi-gpio out","z":"f92bb64b93bfc46e","name":"","pin":"2","set":"","level":"0","freq":"","out":"out","bcm":true,"_mcu":{"mcu":true},"x":490,"y":560,"wires":[]},{"id":"e0f56ffc112362dd","type":"inject","z":"f92bb64b93bfc46e","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"18","payloadType":"num","_mcu":{"mcu":true},"x":110,"y":380,"wires":[["df5467ac0d967bce"]]},{"id":"a83bf3122efb505c","type":"trigger","z":"f92bb64b93bfc46e","name":"","op1":"0","op2":"1","op1type":"num","op2type":"num","duration":"500","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"_mcu":{"mcu":true},"x":320,"y":560,"wires":[["6d9adcf8cdc36b27","32dcd5abbb576d04"]]},{"id":"df5467ac0d967bce","type":"PID","z":"f92bb64b93bfc46e","name":"","setpoint":"20","pb":"10","ti":9999,"td":0,"integral_default":0.5,"smooth_factor":3,"max_interval":600,"enable":1,"disabled_op":0,"_mcu":{"mcu":true},"x":320,"y":260,"wires":[["7180d313e18f3785","11aa7984bd220a60"]]},{"id":"0a44cdba4c3f6a65","type":"debug","z":"f92bb64b93bfc46e","name":"debug 85","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","_mcu":{"mcu":true},"x":900,"y":100,"wires":[]},{"id":"ed8f10ab0af4f273","type":"function","z":"f92bb64b93bfc46e","name":"Clear all except payload","func":"var msg2 = {payload: msg.payload};\nreturn msg2;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"_mcu":{"mcu":true},"x":490,"y":180,"wires":[["089ab65425de3b7f"]]},{"id":"11aa7984bd220a60","type":"range","z":"f92bb64b93bfc46e","minin":"0","maxin":"1","minout":"0","maxout":"100","action":"scale","round":false,"property":"payload","name":"","_mcu":{"mcu":true},"x":110,"y":100,"wires":[["30f17f9179c047a4"]]},{"id":"30f17f9179c047a4","type":"function","z":"f92bb64b93bfc46e","name":"2 msg transport delay","func":"// stores messages in a fifo until the specified number have been received, \n// then releases them as new messages are received.\n// during the filling phase the earliest message is passed on each time \n// a message is received, but it is also left in the fifo\nvar fifoMaxLength = 2;\nvar fifo = context.get('fifo') || [];\n// push the new message onto the top of the array, messages are shifted down and\n// drop off the front\nvar length = fifo.push(msg);  // returns new length\nif (length > fifoMaxLength) {\n    newMsg = fifo.shift();\n} else {\n    // not full yet, make a copy of the msg and pass it on\n    var newMsg = JSON.parse(JSON.stringify(fifo[0]));\n}\ncontext.set('fifo', fifo);\nreturn newMsg;","outputs":1,"noerr":0,"_mcu":{"mcu":true},"x":300,"y":100,"wires":[["84f7bc28dcd8c7bf"]]},{"id":"84f7bc28dcd8c7bf","type":"function","z":"f92bb64b93bfc46e","name":"10 sec RC","func":"// Applies a simple RC low pass filter to incoming payload values\nvar tc = 10*1000;       // time constant in milliseconds\n\nvar lastValue = context.get('lastValue');\nif (typeof lastValue == \"undefined\") lastValue = msg.payload;\nvar lastTime = context.get('lastTime') || null;\nvar now = new Date().getTime();\nvar currentValue = msg.payload;\nif (lastTime === null) {\n    // first time through\n    newValue = currentValue;\n} else {\n    var dt = now - lastTime;\n    var newValue;\n    \n    if (dt > 0) {\n        var dtotc = dt / tc;\n        newValue = lastValue * (1 - dtotc) + currentValue * dtotc;\n    } else {\n        // no time has elapsed leave output the same as last time\n        newValue = lastValue;\n    }\n}\ncontext.set('lastValue', newValue);\ncontext.set('lastTime', now);\n\nmsg.payload = newValue;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"_mcu":{"mcu":true},"x":490,"y":100,"wires":[["ed8f10ab0af4f273"]]},{"id":"089ab65425de3b7f","type":"debug","z":"f92bb64b93bfc46e","name":"debug 86","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","_mcu":{"mcu":true},"x":700,"y":120,"wires":[]}]

A couple of possibly helpful comments on the UI.

  1. For me it would be better if the Build button were present on both the Config and Console tabs, so that the console is visible after clicking build.

  2. Clean might be better as an option on the build dropdown, rather than having to switch from All to Clean and then back to All again. Instead one would click on the build dropdown, select Clean, wait till that had completed, then click Build. I know that one does not normally have to Clean, but there are times when that is necessary.

Thank you for these proposals!

While I understand the idea, there's the issue that you might have several build configurations defined - whereas there's only one console window...

That's a good idea! I'll add an option Build clean... there...

I had not realised you could do that, but I see you are right. That does complicate matters.

If it runs out of memory at run time is there a particular error that will see?

Not always. Continuously verifying the memory pointers is impacting performance & thus, as I understood, disabled. It may happen that the MCU just restarts. I've seen yet as well situations where "Memory full" was thrown...

xsbug is very helpful if you have the impression you're hitting limits. On the instruments panel, check how chunks, slots, stack & keys behave.

My experience: Give the garbage collector ticks to do it's job - and you can do almost whatever operation you like to perform. I'm using lengthy Promise chains to interrogate a sensor bus ... running smoothly for days.

Do you know what the panic message from the problem I posted earlier means? I looked at the code, but there isn't anything helpful in the comments.

Sorry, no.

FYI, I noticed that if I wish to restart or stop node-red that it waits for about a minute for the xsbug to timeout. As soon as I close xsbug then the node-red command finishes immediately.

On what platform (macOs, Linux, Windows) are you experiencing this?

Ubuntu 20

Back on this issue, have you been following it on github? I have run the flow in the node-red-mcu environment standalone and the problem is not seen in that case, so there must be some significant difference between running it via the plugin vs standalone. Have you any ideas what that might be?

Yes.

There are some details that could make a difference - they shouldn't, but perhaps they do. To further investigate, would you please zip the environment (as generated by the plugin) that creates the issue & the other one that runs ok? Then either open an(other) issue @ the plugins repo - or just send me the archives.
I'm really curious what that will reveal...