# Node-red-contrib-mcp23017chip

**URL:** <https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999>\
**Category:** General\
**Created:** [25 December 2020 08:30 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999 "2020-12-25T08:30:32Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [4 January 2021 09:45 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/61 "2021-01-04T09:45:41Z")

</div>

> [@PizzaProgram](#):
>
> I have already resistors between all ports, but still, when NR started \>\> ALL relays turned on!

That should not happen. The default for the ports is to be inputs on power up so they will start open circuit and the the relays should not turn on (assuming they pull down to switch on). The standard gpio Out node has an option to initialise it high or low on startup, so assuming that is set to High then again the relays should not turn on. It is then down the the flows to make sure they don't accidentally set it low when node-red starts. You should not need external pull up on an output.

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [4 January 2021 09:45 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/62 "2021-01-04T09:45:44Z")

</div>

# OFF

The main problem was a "}" sign placed to a wrong position. It exluded the entire timer function from the main one.

> [@Steve-Mcl](#):
>
> Are you using an IDE that you can step debug?

Currently I'm still using lot's of `console.log()` functions.  
I'm still trying to figure out, how to remote debug with VS2017 (Win7) to a RPi (debian) running NR.  
But That's [an other topic...](https://discourse.nodered.org/t/development-tools/35938/21)

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [4 January 2021 10:02 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/63 "2021-01-04T10:02:02Z")

</div>

If I could encourage you, it would be to switch to vscode. Remote debug to PI is quite simple with that. If I get a chance later, I'll point you to the post I used (but there is a lot of pages on this for vscode if you search on Google)

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [4 January 2021 10:06 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/64 "2021-01-04T10:06:02Z")

</div>

> [@Colin](#):
>
> The default for the ports is to be inputs on power up so they will start open circuit and the the relays should not turn on

I don't understand it either. ☹  
By default (POR/RST value)

- GPIOA + GPIOB = 0x00 + 0x00 = 00000000
- Yes, it's set to input. 0xFF = 11111111
- pullup is turned OFF. = 00000000

Still, I can **turn OFF** all ports only with this command now:

```
// OUTPUT 111111111111111
if (msg.topic === 'all1'){
	const aBus = i2c.openSync(chip.busNum);
    aBus.writeByteSync(chip.address, 0x14, 0xFF);	//Set output A
	aBus.writeByteSync(chip.address, 0x15, 0xFF);	//Set output B
    aBus.closeSync();
}

```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [4 January 2021 10:31 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/65 "2021-01-04T10:31:24Z")

</div>

Do you mean that with them configured as inputs the pin is pulling low?  
What external components have got connected to the output?

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [4 January 2021 11:54 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/66 "2021-01-04T11:54:32Z")

</div>

Someone with more micro-electrical knowledge draw me this pic. _(Paid him for advice.)_

 ![Raspberry-Pi_opto-in_relay-out_en](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/3/938e07620183deed8ee275740378c9783d9b39a7.jpeg)

I think the 4.7k Ohm input resistors are not necessary between the opto-couplers and the IO chip, if I activate the built-in pull-up resistors.

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [4 January 2021 13:47 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/67 "2021-01-04T13:47:26Z")

</div>

Is this a Pi? You mustn't pull a pi gpio pin up to 5V, only to 3.3, and as you said you don't need it on outputs anyway, in fact in this application you should not have one at all. If you have pulled up to 5v through a 2.2k you may have blown the pin up, if not the pi itself.

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [4 January 2021 22:41 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/68 "2021-01-04T22:41:46Z")

</div>

The code is starting to feel safe now. No more NR crash, pin states are showing well:

 ![kép](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/5/95b7210b75d86eeaf50c7a2b32c9da9a7f12a935.png)  
Also if wrong Bus number is set. (See nice red "! Error" text...)

* * *

But there is still something wrong with bit masking, when I try to turn on/off:

```auto
let ip1 = 0x00;
if (bitNum < 8) { // first read current state of bank
	ip1 = _aBus.readByteSync(_addr, 0x12);
} else {
	ip1 = _aBus.readByteSync(_addr, 0x13);
}
if (newState) {
	ip1 = ip1 | 1 << bitNum;
} else {
	ip1 = ip1 & ~(1 << bitNum);
}
if (bitNum < 8) {
	_aBus.writeByteSync(_addr, 0x14, ip1 & 0xFF);	//Set output A
} else {
	_aBus.writeByteSync(_addr, 0x15, (ip1 >> 8) & 0xFF);	//Set output B
}

```

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [5 January 2021 09:19 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/69 "2021-01-05T09:19:11Z")

</div>

@Colin No. It's not a Pi.  
MCP23017 (i2c bus, 5V). Driving it through an AtTiny85 USB adapter with i2c-tiny-usb firmware.  
Tried Arduino Nano before that. (USB bus, 5V).

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [5 January 2021 09:20 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/70 "2021-01-05T09:20:48Z")

</div>

> [@PizzaProgram](#):
>
> But there is still something wrong with bit masking

Found the error:

```auto
	if (bitNum < 8) {
		ip1 = _aBus.readByteSync(_addr, 0x12);
	} else {
		ip1 = _aBus.readByteSync(_addr, 0x13);
		ip1 = (ip1 << 8); // <<< that was missing !
	}

```

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [5 January 2021 09:36 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/71 "2021-01-05T09:36:56Z")

</div>

I tend to use a set of functions that help me avoid typos...

```auto
//Get bit
function getBit(number, bitPosition) {
  return (number & (1 << bitPosition)) === 0 ? 0 : 1;
}

//Set Bit
function setBit(number, bitPosition) {
  return number | (1 << bitPosition);
}

//Clear Bit
function clearBit(number, bitPosition) {
  const mask = ~(1 << bitPosition);
  return number & mask;
}

//Update Bit
function updateBit(number, bitPosition, bitValue) {
  const bitValueNormalized = bitValue ? 1 : 0;
  const clearMask = ~(1 << bitPosition);
  return (number & clearMask) | (bitValueNormalized << bitPosition);
}

```

e.g...

```auto
let readVal = 0, writeVal = 0;
let writeByte = 0x14, readByte = 0x12, bit = bitNum;
if (bitNum >= 8) {
    writeByte = 0x15;
    readByte = 0x13
    bit = bitNum - 8;
}

readVal = _aBus.readByteSync(_addr, readByte); //read the value
writeVal = updateBit(readVal, bit, newState); //set/reset the bit
_aBus.writeByteSync(_addr, writeByte, writeVal & 0xFF); //write back new value

```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [5 January 2021 12:25 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/72 "2021-01-05T12:25:06Z")

</div>

> [@PizzaProgram](#):
>
> No. It's not a Pi.

You said earlier in the thread:

> [@PizzaProgram](#):
>
> Also, I had exactly the same problem with "node-red-contrib-gpio" / Firmata using Arduino Nano boards.  
> That's why I've started to modify this node

The reference to node-red-contrib-gpio node having the same problem led me astray apparently.

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [6 January 2021 19:50 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/73 "2021-01-06T19:50:21Z")

</div>

# Help to make Help ...

I still could not release the finished code, because wanted to add help to it.  
But nothing is shown.

This is the code I've added to the .html file:

```auto
<script type="text/x-red" data-help-name="mcp23017ouput">
	<p>MCP23017 has 16 pins (0-15). Can be individually selected as in or out.</p>
	<p> The message to the output requires a payload. If the <code>msg.payload</code> =true or =1 then it turns on</p>
	<p> Topic (and any other parts) are ignored</p>
	<p> Before each output command, the node reads the current value and sets only the changed bit.</p>
	<p> </p>
	<h3>Invert</h3>
	<p> The "invert" checkbox forcing to send the opposite command to the chip, but still showing 1 = true = On. </p>
	<p> </p>
	<h3>Errors</h3>
	<p> If any error occure, red sign is shown with "!Error" text under the Node.</p>
	<p> Possibilities are: wrong Bus or Address.</p>
	<p> </p>

	<h3>History of changes</h3>
	<h4> 2020-12-31 (by László Szakmári www.pizzaprogram.hu)</h4>
	<ul>
		<li>
			<strong><span style="color:#c0392b">!!! IMPORTANT CHANGE:</span></strong><br />
			&nbsp;-- [x] Inverse is now affecting Output too !<br />
			&nbsp;(Some relay boards are functioning &quot;the opposite way&quot;, turning ON if pin is Low.)
		</li>
		<li>
			Fixed NR crash: Added Error handling (try - catch) for each i2c bus operation.<br />
			&nbsp; Each operation has own value to report proper error text. (Bus opening failed ... etc)<br />
			&nbsp; (But execution time increased from 8ms to 12ms on Raspberri 4)
		</li>
		<li>
			Changed Bus open/close behaviour. Separate open before/after each read/write operation block.<br />
			&nbsp; (This way no more non-stop opened bus &gt; no more NodeRed crash if unexpected disconnect.)
		</li>
		<li>Fixed 16pin array initialization (16x null)</li>
		<li>Added multiple/same pin initialization error handling. (Highlander: &quot;There Can Be Only One&quot; :-D )</li>
		<li>Added lots of comments and constants to mcp23017chip.js file (like IOCON, IODIR_A, etc...)</li>
		<li>Changed icon to a chip-like one. (font-awesome/fa-ticket)</li>
		<li>Faster initialisation: if set to output &gt;&gt; skips pullup &amp; invert writes.</li>
		<li>Prevents the input-timer to run if the previous function is still running.</li>
		<li>4 states of a node: On=green&nbsp;&nbsp; Off=grey&nbsp;&nbsp; Uninitialised=yellow&nbsp;&nbsp; Error=red</li>
	</ul>
	<p> </p>
	<h4> 2020-11-xx fix for run under NR </h4>
</script>

```

![kép](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/7/672ac404a9270a899fb29a654ea117806b89a162.png)

What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [6 January 2021 20:04 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/74 "2021-01-06T20:04:57Z")

</div>

Presumably the name matches the node exactly?

Generally we don’t add a change list to the help as it doesn’t help use of the node. That is better off in the readme.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [6 January 2021 22:47 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/75 "2021-01-06T22:47:42Z")

</div>

Assuming you are modifying the [this](https://github.com/willhey/mcp23017chip/blob/afd65660bd3bc000500d9e47d2bcbe39e5a595ea/mcp23017chip/mcp23017chip.js#L122) shouldn't `data-help-name="mcp23017ouput"` be `data-help-name="mcp23017ouputNode"`?

Also, if you change `type="text/x-red"` to `type="text/html"` you will probably get syntax highlighting in your editor (you certainly do in vscode)

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [7 January 2021 09:36 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/76 "2021-01-07T09:36:35Z")

</div>

> [@dceejay](#):
>
> Presumably the name matches the node exactly?

You were right!  
`data-help-name="mcp23017ouput">` \>\> `ouTput`  
_(The only good thing of fixing other peoples mistakes is: you can blame them, not yourself! 😆 )_

> [@dceejay](#):
>
> Generally we don’t add a change list to the help as it doesn’t help use of the node. That is better off in the readme.

Do you know the way, how to include a separate file inside the package and point with a link from the help? I couldn't figure out.

> [@Steve-Mcl](#):
>
> Also, if you change `type="text/x-red"` to `type="text/html"` you will probably get syntax highlighting in your editor (you certainly do in vscode)

Great tip! Thanks 🙂

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [7 January 2021 09:46 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/77 "2021-01-07T09:46:53Z")

</div>

> [@PizzaProgram](#):
>
> Do you know the way, how to include a separate file inside the package and point with a link from the help? I couldn't figure out.

There is no way to do this without a lot of unnecessary work.

If you want to link to something, link to its page on [flows.nodered.org](http://flows.nodered.org) where the full readme will be displayed.

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [6 March 2021 14:01 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/78 "2021-03-06T14:01:17Z")

</div>

After investing 100++ working hours to fix most of the problems, I've uploaded the finished code to github 7 weeks ago.

- many enhancement,
- no more NodeRed server crash, etc.  
See full list of changes here:  
[GitHub - PizzaProgram/mcp23017chip: Node-red mcp23017chip](https://github.com/PizzaProgram/mcp23017chip#change-log-2021-01-11-y-m-d)

# Created a [Pull request](https://github.com/willhey/mcp23017chip/pull/11/commits/fb76a620ae297aecd72abef1fde2d64df39e38cd) on Jan.16, but nothing happened.

I'm still not even added to the project, as a contributor.

> [@willhey](#):
>
> As for Node-red-contrib-mcp23017chip, I would be happy to accept a pull request (I will need a little coaching on GitHub & NPM)

Well, so much to promises...

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [6 March 2021 17:40 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/81 "2021-03-06T17:40:35Z")

</div>

Give it a few days, add a comment on the PR asking if/when he'll get a moment to review/accept your PR & if you get no joy, consider releasing your fork as a new npm package.

Hold off as long as you can as having multiple versions in the flow library can be equally confusing and problematic.

---

<div class="post-metadata">

**Author:** ![PizzaProgram](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pizzaprogram/32/19431_2.png) [@PizzaProgram](https://discourse.nodered.org/u/PizzaProgram)\
**Post date:** [6 March 2021 17:55 UTC](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999/82 "2021-03-06T17:55:23Z")

</div>

\< OFF \>  
OK, thanks for the encouraging words! I'll wait a few weeks longer than.

> [@Steve-Mcl](#):
>
> multiple versions in the flow library can be equally confusing and problematic.

Exactly! And also the old ones won't get auto-updated. That's why I didn't released by myself.  
I hoped I'll have +1 free month more during winter, so I can create a WHOLE new flow-friendly version of MCP23017 + scanner + PCF8574 All-in-one package.  
But RL kicked in, had too many work lately.

[Previous page](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999.md?page=3)

[Next page](https://discourse.nodered.org/t/node-red-contrib-mcp23017chip/37999.md?page=5)
