Node-red-contrib-mcp23017chip

Marry Xmas to all :slight_smile:
I've installed and tried today this mcp23017chip node, but it says:

TypeError: Cannot read property 'setBit' of null

  • How can I debug it further, what could be the problem?
  • Can I see somewhere the source-code of this node?

My guess is:

  • it can only handle the default I2C bus (attached to Raspberry Pi directly) and can not recognise 2th bus (available through an AtTiny85 USB adapter).

kép

Thanks for all hints!

go to the .node-red folder
then fo to the node_modules folder
in there you should see a folder for the node and its's code.

@zenofmud
Thanks :slight_smile: found it here:
/home/openhabian/.node-red/node_modules/node-red-contrib-mcp23017chip


Also found this... :

changing "i2c-bus": "~1.2.2" to "i2c-bus": "~5.2.1" and installing it locally via npm i /path/to/mcp23017chip did the thing. All is working good now

It's at the package.json file 31. line.


Although I'm not sure if this part is a must?
... in the .../.node-red/setting.js file add the line as follows:

functionGlobalContext: {
i2c:require('i2c-bus')
// os:require('os'),
// jfive:require("johnny-five"),
// j5board:require("johnny-five").Board({repl:false})
},

How do I apply changes?

  • enough to restart NR?

edit the file,
apply the change,
save the file,
stop NR,
start NR
test

Thanks :slight_smile:

I've hoped it will be so easy.
But now I have no idea, how to find out, what is the "right bus number"?
i2c-11 is not similar to : "~5.2.1"

:~$ sudo i2cdetect -l
i2c-11  i2c             i2c-tiny-usb at bus 001 device 013      I2C adapter

:~$ sudo i2cdetect -y 11
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
  "dependencies": {
    "i2c-bus": "~5.2.1"
  },

Hmmm... that number seems to be rather the current "NPM i2c-bus modul" 's version number:

Try sudo i2cdetect -y 1

If you look at what you posted

:~$ sudo i2cdetect -l
i2c-11 i2c i2c-tiny-usb at bus 001 device 013 I2C adapter

it shows the bus is 001.

As for "i2c-bus": "~5.2.1"

  • ~version “Approximately equivalent to version” , will update you to all future patch versions, without incrementing the minor version. ~1.2.3 will use releases from 1.2.3 to <1.3.0.

No. You mix USB bus with I2C bus.
For proof, look at 1 line under it:
:~$ sudo i2cdetect -y 11
11 is the bus number of that command.
It is successfully listing both devices under 0x27 and 0x51.

I've already found the problem:

At mcp23017chip.js source file, Line 15:
this.i2c1 = i2cBus.openSync(1);

Currently I'm trying to enhance the component with +1 variable:
this.i2c1 = i2cBus.openSync(this.busNum);

(But it's not saving :frowning: )
kép

I suggest you try to contact the author of the node or possibly try one of the other i2c nodes.

@willhey
I've successfully enhanced the component to accept Bus number for each chip.
kép

It can be downloaded from here...


I can see the device on Bus 11, but the node reports back:
Error: Invalid I2C bus number 11

I have now idea what could be wrong. It should work.
Somebody have a look at the code please! :pleading_face:

Are you running as root ? You run i2cdetect as root so I suspect you may need this to match

Good idea to compare, so I've just checked:

[04:09:56] openhabian@OH:~$  i2cdetect -l
i2c-1   i2c             bcm2835 (i2c@7e804000)                  I2C adapter
i2c-11  i2c             i2c-tiny-usb at bus 001 device 008      I2C adapter
[04:10:01] openhabian@OH:~$ i2cdetect -y 11
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Node-RED is running from my: /home/openhabian/.node-red/ directory, so my guess is, it isn't running as root.

What does ls -l /dev/i2c* report ? and also groups when run as your normal user (it should have i2c as one of the groups it is in).
You said you have fixed the node to accept the bus number (good) - but have you checked exactly what it is set to just before it attempts to open the port ? Is in a number etc ?

I've found the problem. (It has nothing to do with user/group/privileges.)

The programmer who wrote the node originally, declared a variable of an 'i2c-bus' instead of 'i2c'.
A bus can not have a "sub-bus".
This is the right way to handle it:

const i2c = global.get('i2c');
const aBus = i2c.open(11, err => {
  if (err) {
    throw err;
  }
...

Here is an example to list the possible/supported functions of an I2C bus:

[{"id":"1d042afc.dc4755","type":"function","z":"34aad6f7.b85c6a","name":"I2C Functionalities scan","func":"'use strict';\n\n// When run, this program will output the same information as the\n// command 'i2cdetect -F 1'\n//const i2c = global.require('i2c');\nconst i2c = global.get('i2c');\nconst BusNumber = 1;\nconst aBus = i2c.open(BusNumber, err => {\n  if (err) {\n    throw err;\n  }\n\n  node.debug('i2c Bus opened successful.');\n  \n  aBus.i2cFuncs((err, i2cFuncs) => {\n    const boolToYesNo = bool => bool ? 'yes' : 'no';\n\n    if (err) {\n      throw err;\n    }\n\n    console.log('Functionalities implemented by /dev/i2c-11:');\n    console.log('I2C                              ' + boolToYesNo(i2cFuncs.i2c));\n    console.log('SMBus Quick Command              ' + boolToYesNo(i2cFuncs.smbusQuick));\n    console.log('SMBus Send Byte                  ' + boolToYesNo(i2cFuncs.smbusSendByte));\n    console.log('SMBus Receive Byte               ' + boolToYesNo(i2cFuncs.smbusReceiveByte));\n    console.log('SMBus Write Byte                 ' + boolToYesNo(i2cFuncs.smbusWriteByte));\n    console.log('SMBus Read Byte                  ' + boolToYesNo(i2cFuncs.smbusReadByte));\n    console.log('SMBus Write Word                 ' + boolToYesNo(i2cFuncs.smbusWriteWord));\n    console.log('SMBus Read Word                  ' + boolToYesNo(i2cFuncs.smbusReadWord));\n    console.log('SMBus Process Call               ' + boolToYesNo(i2cFuncs.smbusProcCall));\n    console.log('SMBus Block Write                ' + boolToYesNo(i2cFuncs.smbusWriteBlock));\n    console.log('SMBus Block Read                 ' + boolToYesNo(i2cFuncs.smbusReadBlock));\n    console.log('SMBus Block Process Call         ' + boolToYesNo(i2cFuncs.smbusBlockProcCall));\n    console.log('SMBus PEC                        ' + boolToYesNo(i2cFuncs.smbusPec));\n    console.log('I2C Block Write                  ' + boolToYesNo(i2cFuncs.smbusWriteI2cBlock));\n    console.log('I2C Block Read                   ' + boolToYesNo(i2cFuncs.smbusReadI2cBlock));\n  });\n});\n\nreturn aBus;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":370,"y":600,"wires":[["6300686f.7c8ca"]]},{"id":"6300686f.7c8ca","type":"debug","z":"34aad6f7.b85c6a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":550,"y":600,"wires":[]},{"id":"351e5767.889d5","type":"inject","z":"34aad6f7.b85c6a","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":180,"y":600,"wires":[["1d042afc.dc4755"]]}]

I've already modified the component, but can not test it yet, because I've changed some version numbers at the package.json file, and since then none of the flows can start.
package.json (1,5 kB)

First I have to learn more about how to configure that file properly to keep backward compatibility (for auto-update?) but show improvements (with version number and description + later maybe I'd also like to add some help-examples).

Well it depends what you intend to do with it... - Ideally contact the original author and ask if he is interested in a pull request - you can find the owner from npm owner ls node-red-contrib-mcp23017chip - as I can't see he has published the source on github directly. If he is interested (as the last update was only a couple of months ago he may well be) - then hopefully he will make the source public and you can create pull request directly on it. You shouldn't need to change the package.json as he should do that as part of releasing the package - but if you did then you would only need to bump the minor version number - eg from 0.1.0 to 0.2.0.

(but it is Xmas so don't expect instant replies etc)

I've contacted him already yesterday. Linked this topic. No answer yet.

Probably because of that. :smiley:

I've decided to re-distribute the finished node myself again.
Maybe even renaming it to node-red-contrib-multi-i2c-mcp23017
to show it's intended to use multiple of it, not just 1 and to help search for "i2c" keyword too.

I find 0.x.y versioning overcomplicated + confusing for beginners. :x:
Also I hate when developers make groundbreaking, data-destroying changes, but increasing only from 2.5.2 to 2.5.3 (Like FirebirdSQL developers did once.)

"1.2 (2020-12-26)" is easier to follow, also in the change history. :white_check_mark:
( "1" is major, ".2" is for minor changes. + an ISO formatted date.)
"1.3 (202y-mm-dd)" << After adding some examples
"2.0 (202y-mm-dd)" << As soon as I add "auto-bus-search" function.
etc...

Please give him a chance to reply first. Having multiple versions of the same node just adds to the confusion. Please don't create yet another node. And if you really have to - then please stick to three level semantic version numbers otherwise things like npm may not cope well and so not detect updates correctly.

3 Likes

If you are publishing to npm then you must use x.y.z pattern for the version string - you have no choice in the matter.

You can add whatever description you want in the readme.

Absolutely. Version strings should follow semantic versioning rules so the nature of a version change is clear. See semver.org for details. But if course that relies on the developer setting the version to follow the rules and mistakes do sometimes get made.

But it's far better to stick to the very well established norms rather than go your own way.

I've just realized, the problem has nothing to do with the package.json file.
Under the Manage Palette there was a hidden error report:
kép

Strange, because that code works fine within a function.