Arduino USB > Firmata > I2C > [GPIO PCF8574 + MCP23017 + temp BMP280]

My question is:

  • What is the recommended way to connect multiple I2C boards to Arduino boards to:
    use both Ardu's GPIOs + the I2C expanders too?
  • Is firmata standard suitable for that, or I need to specify the I2C boards at the Arduino IDE, by writing a special C program?
  • What if I use MQTT for all those to be able to use ESP32 or Ethernet modules also?
  • Isn't MQTT too slow for handling "long press" + "Continuous dimming"?

Is there ANY full-example for this?

(I simply can not believe nobody ever used more than 16 IO ports and some I2C sensors plugged in via USB... )

< OFF >
I just wanted to control my house with wired, cheap :money_mouth_face: things...
(Had an expensive HomeControl before, but it's burned by a lightning.)

  • Bought all those things >>>
  • plugged in some Arduino boards via USB into my Raspberry Pi4 >>>
  • connected 8x PCF8574 + some MCP23017 via I2C >>>
  • and thought I just need to click "Discover" in OpenHAB and should work... :face_with_hand_over_mouth:

After 2 :spiral_calendar: month of searching the forums and analysing GitHub projects: here I am ... while still "sitting in the dark" :milky_way:* (literally, since I still can not use any switches and relays... :woozy_face: )*
So I've registered to this forum to ask for help. (YES, I've searched and red ALLLL topics related to "firmata & i2c" :nerd_face: ... except I've missed one?)

The goal is: to handle EVERY GPIO + sensors + rules via NodeRed, and just "push/receive" messages to/from OpenHAB to visualize the controls+values.
< /OFF >

Hi, can’t help you with firmata but with ESPeasy and ESP8266 (esp32 is as cheap but more complex so start with and ESP8266 - 80 MHz isn’t enough?) or even write your own code. Switching relays should not be a big project. Smooth dimming is more a thing with ESPEasy because it’s smallest timer for rules is 1sec. But own firmware can di the job.
I suggest start small and with simple things and ramp up using the experience you made.
Would not go the openhab/node-red path. Done it before abd not worth the effort taking care of two systems at all times where Node-Red can do the job on it’s own.
Just render the smallest project you can think of and start with that and forget smooth dimming for now.
And Yes you are right mqtt isn’t a good choice for sending values in a ordered and well timed way. Better think about sending one command like dimm, value, time and let the microcontroller do the job.
Discovery via mqtt needs homie compatible devices - ESPEasy & Node-RED can do this too. And much more transparent than openHAB as I experienced it a year ago (perhaps it’s better bow). So grab a Wemos D1 mini and start over again

1 Like

Thank you for sharing your experience!
I knew about ESP things, and I do not wish to buy or use any of those. All the forums are full with those, but, as you already stated yourself:

  • not suitable for quick response time.
  1. If I press a button, or start opening a door >> I need light. Immediately. Not 1+ sec later.
  2. Think about safety! Walking in a dark room is everything but recommended. Many bad things can happen within 1 sec...
  3. If a lightning strikes in nearby again > I don't want to drop into the trash everything again because of Wifi things. Shielded wires do not act as antennas.
  4. OpenHAB can handle my Artnet DMX dimmered bulbs and LED-stripes perfectly fine. None of the other system was able do that so quickly and easily. (Tried many of them!)

I understand you want good with your recommendation, but why do you force me into a way that is the opposite I've asked for?

Hi
I understand you are frustrated at not being able to get the information that you want but this is not a general forum for Arduino - it is a Node-RED specific place.

In general, sensors are usually placed around a home and that makes wireless devices more appropriate to communicate back to a central controller running Node-RED which is why ESP devices are generally recommended for such tasks.

Back to the OP - in general I would avoid firmata for all but simple bit banging of io when you want to tie up your PI :slight_smile: You would be better to just write i2c arduino code on the arduino so that it performs the basics of the task you need - and then use the USB serial to send messages to Node-RED - and receive commands - as and when you need to. There are lots of libraries for arduino for specific i2c devices - or just raw commands - but they are all arduino questions not Node-RED.

1 Like

I think you'll need to start with protecting your electrical installation against the lighting. This is quite of job and should not be done cheap way. After that done, it doesn't matter if you install wired or non wired pieces, they will be protected as much you have spent on protection.

Hi, not at all I want to force you into something that you don't like, only some ideas to perhaps solve your problem. You ask a question and you get a answer. Perhaps the answer don`t fit your needs, sorry. But I still have some comments. All only suggestions out of my own experience. Yours might differ

  • You were writing about arduinos and now you mention Artnet DMX. That's a complete other league.
  • I do not see any difference in wireless DMX or Wifi from a security point of view. All runs on the same public frequency band(s).
  • Ligtning problems as @hotNipi suggested probably has to solved in your electrical installation. There is where your KV surge comes from. They are rarely picked up over the air. If so you ... :hushed:
  • Compared to an arduino an ESP is a much more capable solution I have around 20 around my house and I`m happy: (My house was build 1890 with massive brick walls. So rewiring everything down to a switchboard is not an option for me).
  • I never experience a delay of 1sec in my installation. It is more between 25ms and 100ms. (But perhaps because I use professional WiFi-APs , Switch, dedicated Router, Server - All note expensive but selected for best performance - I do not use one of the fit for everything home routers nor a raspberry - but that`s another story.
  • You mentioned MQTT. If this don't suites you, perhaps take a look into websockets. https://www.youtube.com/watch?v=8ISbmQTbjDI 250Hz or even more is possible. I have currently 1137 topics and around 1.200 Messages per minute on my broker (that`s during development, in idle it is around 500). No performance issues at all.
  • Wifi light switches and dimmers I use (mostly of the shelf products flashed with my own firmware) work with immediate response. (automation is only a secondary mission objective). All a matter of design.
  • Same with other "critical" items like pumps, motors (people get killed by automatic garage doors and other motor driven things) or valves (too much water at the wrong place could do harm too). All of mine have a safe fail mode and can be overruled by physical switches. Timers run on the device not in Node-Red. If (why ever) a connection fails or more likely the software is buggy the valve either does what is safe or finish the task.
  • I gone the route of maintaining 2 systems (openHAB & Node-RED) and they work good together. But for many points you mentioned (security, speed, reliability) bringing another player to the game can create another bottleneck. Switch>node-red>openhab>visualize>openhab>node-red>relay? I suggest: switch>relay & >mqtt (with a first short loop feedback by the broker) > Node-Red (with another feedback)>dashboard and back. Perhaps the delay you mention comes form somewhere else.

Sorry If this don`t fit your needs. Sorry for TL;DR

Back to your OP:

  • ESP32 or whatever Yes, this is the way I would go
  • Long press dimming should be done inside the micro controller of your choice. Only send the values to update your visualization. You have the best visualization by your eyes when you press the button standing in the room (or did I understand you wrong again). Finding and opening a app on your phone while you stand in the room finding the correct control ... nice but. A physical wall switch/dimmer is my first choice. And when I switch on my TV/Projector with a good old IR remote control the light dims down. Nice to have but not necessary to work 100%. Or speak to the voice assistant of your choice.

And last but not least: https://create.arduino.cc/projecthub/tarantula3/pcf8574-gpio-extender-with-arduino-and-nodemcu-a8cb00 as @dceejay suggested... think about write your own code.

1 Like

< OFF >
Thank you very very much to all of you for all these tips! :blush: :heartbeat:
It's great to see a vivid forum like this with so many people willing to help. I'm touched.

About the lightning:

  • yes, it came through the are Air! (Did not rain, it stroke in dry into the nearby Fuel-station)
  • in a radius of 1km each house in nearby streets suffered from it somehow. (TVs, fridge, heating, PCs, etc.)
  • weather conditions are getting worth each year.

About protection:

  • I use only professional routers + switches too
  • I have a sinus wave Legrand Niky 1500
  • electrically the house is well grounded.
  • the path of destoyed devices were easy to follow back to everything that worked as antennas. (Wifi-Routers, gate-phone)

About the project:

  • My whole house was already wired into one, central place. And I like it this way.
  • There are more than 100 switches hard wired with shielded cables.
  • There are 2 Tablets on walls + 2PC + 4 phones + 1 media server << all those with nonstop-opened HABpanel
  • So it would make much more sense for me to me, to find a software-solution for my existing setup, rather than change drop everything just because "there are more examples for the ESP design".

< /OFF >

It seems to me: Node-Red is the IDEAL, perfect, multi-functional tool, to do everything in "one place", while showing the whole project visually nicely.
I was very happy when I've found this free software, which can handle ALL of those things listed in the Title.

So I'm still looking for a NodeRed sketch / example how to use devices on I2C bus via Firmata?

Not for myself only, but ALL those people searching for the same things.
(Believe me, I have found hundreds of opened topics during these 2 month about these things without any real answers/solution, except: "go and buy some Sonoff / ESP ... thing".)

That's all what I would like to do! :slight_smile: Everything else would be handled at NodeRed.
(Well, maybe later some temp-sensors, but it's ok, to use ESPs for those. Temperature sensing isn't crucial, switching & dimming is.)

I know, but I would like to handle everything in Node-red. Firmata would have been just a "message-forwarder". Or is that not possible at all?
Do I really have to write C code to Arduino to push/receive I/O data from NR?

Isn't it possible to connect somehow Arduino NODE or the Johnny5 node to >> PCF8574 node ?

OK if you insist then this is the node you need to play with - https://www.npmjs.com/package/node-red-contrib-gpio

1 Like

Hi,
interesting discussion, ideas and experiences!

I don't have much to add, the wired and wireless modes of communication have their advantages and disadvantages.

The Arduino and port expander via I2C works great, but you need to build the code depending on your preferences.
Further communication is via USB.

I was dealing with a PCF8575 (16x I/O port expander).
An Arduino with 4xPCF8575 (total = 64 inputs or outputs) works great.

What I would recommend is to use the interrupt function (from PCF8575 pdf: An interrupt is generated by any rising or falling edge of the port inputs in the input mode.).
The alternative to this is to do polling, but this causes constant activity on the USB and additional CPU load. On the Raspberry Pi 3B, depending on the frequency of polling, the CPU was about 20-35% increased, which is not small.
In my opinion, it is better to use interrupt and the option to call port readings as needed (see trigger below).
With this, in a static situation, there is no USB traffic in practice and therefore no processing.

The PCF8575 I/O operates at 5V and as such can directly control the relays or relays modules.
Care should be taken here to choose the "Trigger LOW" module.
Selecting such a relay module avoids flickering when booting arduino & PCF8575.
Also choosing module with optocouplers avoids the need for additional driver chips as is ULN2803.
Of course, choose the 5V relay module (with this module the trigger is 5V of course).
If you choose a 12V relay module, you will need to redesign the 5V trigger module.

I needed to develop a wire type I/O module, and choosing the Arduino (Nano) and PCF8575 was a winning combination for me.

My working principle (Arduino code) is extremly simple and ideal for Node-RED.

In short:
Eg. to set a port to a specified state. Send command: < A10 >. (without space; can't post like that).
In this case:
A = first group of 8 ports (first bank of PCF8575)
1 = port number,
0 = port state.

chrome_N2VPEG8MmJ


That is all for turn the relay ON or OFF!

To read the port status, it is easiest to install node-red-contrib-PCF8575-extractor (link is in the documentation).
After configuration (just choose which group of inputs to analyze), and on the outputs we have a state for each individual port.
The output states are 1, 0, or E.
1 = status is 1 :smile:
0 = status is 0,
E = Error (PCF8575 did not respond).

chrome_K5Ce62vU4y

chrome_2MPk7xnGgo
That is all, connect/disconnect port to GND and node output will be changed!

Each change on any port sends the state of the entire group (8xport).

It can also be posiible to send a trigger message (manual or at intervals) according to the USB.
The command to send is < T > (without space again).
This command checks all ports and returns statuses, including errors on PCF8575 (if any).

Full documentation is at https://www.tindie.com/products/picotouch/gpios-fromto-serial-usb-module-16-48-ports/

I hope it helps in which direction to go and what logic is used.

P.S. The module described on the link can work as an input or output module (selected by jumper).

Greeting.

2 Likes

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.

Funny. I ran into a similar lightning problem with my house and kinda had the same idea two years ago. Lightning sucks. Had a lot to learn about proper overvoltage protection despite being an electrician. That post is older, but maybe it helps others who go down a similar approach a bit.

At first I wanted to use I2C expanders too, because I needed lots of pins, but due to lack of excess time, I still haven't even started experimenting with those. I ended up just using the Arduino GPIOs. I connected them via USB to a Raspberry PI 2, but also used an USB Lan Cabel Adaptor to connect to one in a remote control box over a 25m long shielded Cat5 network cable.
Then I ran into the connection drop problem described here:

I found a different solution by simply adding one of those cheap 10€ USB-signal amplifiers to it. It's running stable for one and a half years now. (Only works with the amplifier on the PI before the adaptor, not the other end of the cable surprisingly)

My 4 Arduino Mega are running on Firmata, talking to node red trough the nod-red-node-arduino. Btw I'm still using old version 0.0.18 of it, because newer versions including the latest version 0.3.1 don't seem to safely reconnect after a restart when several Arduinos are connected to the PI at once. Occasionally all nodes configured to connect to one Arduino, may connect to the wrong one or not at all at reboot. Same when reimporting saved flows. Don't know why so I stick with the old version working fine. I'm open for better ways, but "never change a running system". I'm actually using over 240 GPIOs (including the RPIs) simultaneously, to do my home automation, to give you an idea.

I've connected all my ordinary installation push buttons (4-ways mostly ~25€ each) throughout the house via standard shielded cat5 network cables to the GPIOs on the one side (using the integrated pullups configured in the node). On the other side, the commons of the push buttons are connected to 1 current limiting resistor (just in case an input becomes an output) connected to RPI ground.

The response time is insanely fast! 2 to 6 on/off massages are sent within 2-4ms on a single push down. You can literally record the bouncing effect of each push button in node red, that's how fast it responds. Crazy! While that's easy to filter out, what's more difficult is the capacitive crosstalk transmission between the wires within the same long cable. When one is pushed, the other buttons(wires) inside the same cable, within the same shield, may go on too, just to go off again after a very short time, only the pushed remains. Increasing the time in a debounce node, beyond that time frame alone, will still results in false button released messages. EM interferences like when several devices turn off under load (blinds ~15-45ms) or again heavy thunderstorm lightning (~60-70ms) were another source of problems. Yes I had to figure that out the hard way and found sulotions. Using Pullup is a necessity. Shielded cables help, they aren't antennas. Long unshielded wires are. Connecting those shields and grounding them may help too. While not placing the relays directly next to the Arduinos maybe might have helped as well, a little subflow after each input node to filter it all trough code solved it for me. Reliably so and heavy thunderstorm proof.

For switching I used 8€ cheap china 5V 8-way relays for Arduinos. They are rated at 10 Amps (wouldn't trust it), enough to switch blinds and LED light bulbs though. Compare that to a 300€ 8-way KNX actor who does nothing but switching either. OK, thats comparison is off a bit. They all worked fine for 2 years now. Let's see how that progresses. To replace a defective would take maybe half an hour. They have onboard optocouplers and flyback diodes on a separated relais circuit onboard (if you connect it right). To have the possibility to use an extra power supply, separated from the RPI (and Arduino) one, just to power the relay circuit alone is nice, because it can't affect the other circuit, due to the electrical isolation between them, like when your switching lots of relays at once. But they have inverse logic, meaning they turn on when GPIO is low or 0 (has negativ (-) potential). Happens during startup and reconnects like during a redeploy! Fair warning: blinds engines may die when up and down relays can switch on at the same time. It all depends on the right relay wiring to prevent that. Raspberry GPIOs don't show that startup turn on behavior with those relays. I just use one of these to cut off relay power until deploy or startup completes.

I handle all the programming in a modular way using subflows, from double-click long-press inputs, to blinds or rolloshutter relay control, to dimming LED Lamps, to talking to RGBW LED Stripe Wi-Fi Contollers by TCP. For each functionality I created its own subflow and now I only have to connect these subflow modules the way I like it, transmitting switch states color information or what have you. I used openhab for hue light control and dashboard at first too. Too complicated for me. But since there are new functional contrib nodes it's all node red now. The colorpicker could be better for lights though.

1 Like

Thank you very very much for the detailed post!
All those information would have had save me 2 month time, but currently I'm almost at the same conclusions too.

  1. I use ONLY shielded alarm cables for buttons. + pullup resistors for all PINs separately.

  2. I have found a solution to Arduino / Firmata boards to startup with ALL OFF ! (protecting blinds tube-motors.) 2 lines of code in the .INO file.

  3. LED 13 startup blinking is still causing me trouble.

  4. Still no solution for identifying automatically which board is on which USB port currently.

  5. The max USB cable standard is 5m (4.5m exactly, but a good quality cable can handle 5m.) To extend more >> you need an ACTIVE USB extender.

  6. Haven't tried any I2C boards attached to the Arduino's A4+A5 PIN. Johnny5 theoretically can handle it, but did not find ANY working example yet.

  7. The Arduino - firmata board reconnection is still a problem too. The only way I've found yet to minimise the problem is to change the DEPLOY button to "Modified nodes only". The other is to "edit the board USB port" and re-deploy.

  8. I'm thinking to drop openhub too and move to NodeRed fully.

More info will come, if I find out more...

Those "long press" / "double press" subflows interest me very much! Please share with us :slight_smile:

1 Like
  1. Wise decision. I just don't get why other people don't also go for the imo straight forward (central wired) way like home automation systems do, when they approach a self-made smart home project. Maybe I'm biased, but most people's idea of smart home seems to be "Wow, I can switch that bulky plug in socket with my phone", or they stick ugly wireless buttons next to their switches for their lights. I don't get it! That kind of esthetics just collides with my womans acceptance factor. If I start such a project, I'd need stuff to be seamlessly integrated and that means wired. Node-Red is sooo powerful for like exactly that and you'd think there are some existing how to do's or examples, but... Sorry for the rant.

  2. I'm really, really interested in these 2 lines of code in that .ino file (firmata sketch?) you mentioned. Please share! Pretty please! That would have spared me many weeks trying to find a solution, before I was like screw it (like literally) and reverted back to that hardware based override I've described.

  3. Yeah... huh... it's... blinking..... ¯_(ツ)_/¯
    I've nothing connected to pin 13, so... no trouble for me. I use it to (make it blink) identify the Arduino to which the nodes are actually connected to, in case It gets wrecked again. Haven't really noticed before that it does that on startup. lol It does look kinda cool! Sorry... it's just such a non-issue for me.

  4. Me neither. But at least they all connect to the right pins on the right one now, every time, like on every reboot. I always have some backup SD-cards in case things don't work again, because reimporting the arduino nodes from whole saved flows never works, or not entirely. I can tell you more if you want to.

  5. Hmm... Guess that explains it! Although, I've tried an active one and it didn't work reliably. Maybe that thing was crap. (and yeah I've plugged that thingy into the socket).

  6. Same. unbelievable somehow. I find markost 's response very interesting. I'm not good at coding though.

  7. Not so much of a problem with the old arduino node version I've mentioned. It works fine on full deploy and everything. As soon as I update --> problem. That's why I still use the old one. Haven't really got the time to try, if I can get the new version to work the same way I succeeded with the old version in the first place, because with so many pins/nodes that's a lot of work. My first attempts failed and why change it when it "works", kinda. hmm....

  8. I still have node red running on openhabian, because of the arduino node problem. I also had that "just click Discover moment" btw. facepalm lmao

Ok, here they are:

But I have to warn you. I never posted any code and all I know about javascript is the little I've learned in like middle school, because I was bored and didn't have friends, or should I say, they were more interested in makeup and stuff than I was. Anyways, my code in those function nodes may look alike that, so if you find mistakes you can keep them.

At first I couldn't get things working so I tried different approaches, which then led to different functionalities. Take a pick! Some don't output on push-down, only on release, which makes them unsuitable for continuous dimming, others however do. They all expect msg.payload true for pushbutton pushed, false for released, output likewise, everything else should pass trough. You can set the time frame for them all globally with a global.awaitRetouch (type number) else its 600 (milliseconds). The inner workings is pretty obvious, so it should be easy to adjust stuff like number of outputs. Have fun!

[{"id":"ba6d3fbf.d68c1","type":"subflow","name":"short long times","info":"","category":"","in":[{"x":140,"y":100,"wires":[{"id":"776fb18.b36efd"}]}],"out":[{"x":660,"y":100,"wires":[{"id":"776fb18.b36efd","port":0}]}],"env":[],"color":"#DDAA99"},{"id":"776fb18.b36efd","type":"function","z":"ba6d3fbf.d68c1","name":"short long times","func":"clearTimeout(context.retouchTimer);\nmsg.timespushed = context.get(\"count\") || 0;\nif(msg.payload) context.set(\"count\", msg.timespushed +=1);\nelse if(msg.timespushed === 0) {\n    msg.longpress = true;\n    msg.timespushed = context.get(\"lastlongpress\");\n    context.set(\"lastlongpress\", 0);\n    return msg;\n}\ncontext.retouchTimer = setTimeout(function() {\n    context.set(\"count\", 0);\n    msg.longpress = msg.payload;\n    if(msg.longpress) context.set(\"lastlongpress\", msg.timespushed);\n    else{\n        msg.payload = true;\n        //node.send(msg);         // send\n        //msg.payload = false;    // short released\n    }\n    node.send(msg, false);\n}, global.get(\"awaitRetouch\") || 600);\n","outputs":1,"noerr":0,"x":400,"y":100,"wires":[[]],"outputLabels":["short"],"icon":"node-red/timer.svg"},{"id":"51c4402.953584","type":"subflow","name":"doubleclick long","info":"","category":"","in":[{"x":160,"y":180,"wires":[{"id":"36f46f30.43663"}]}],"out":[{"x":980,"y":120,"wires":[{"id":"352d3c0d.36ab54","port":0}]},{"x":980,"y":180,"wires":[{"id":"352d3c0d.36ab54","port":1}]},{"x":980,"y":240,"wires":[{"id":"36f46f30.43663","port":1}]}],"env":[],"color":"#DDAA99","outputLabels":["single","double","long press released"]},{"id":"36f46f30.43663","type":"function","z":"51c4402.953584","name":"count","func":"const awaitRetouch = global.get(\"awaitRetouch\") || 600;\nconst now = new Date().getTime();\nif(msg.payload) {\n    context.set(\"touched\", now);\n    flow.set(\"times\", (flow.get(\"times\") || 0) +1);\n    return [{reset: true}, null];   // my finger is on the button\n}else{\n    msg.payload = true;\n    if(now > context.get(\"touched\") + awaitRetouch) {\n        flow.set(\"times\", 0);\n        return [null, msg];     // pushed it looong\n    }else{\n        msg.delay = awaitRetouch;\n        return [msg, null];     // pushed the button\n    }\n}\n","outputs":2,"noerr":0,"x":310,"y":180,"wires":[["86f068be.134d18"],[]]},{"id":"352d3c0d.36ab54","type":"function","z":"51c4402.953584","name":"output","func":"delete msg.delay;\nconst out = flow.get(\"times\") > 1 ? [null, msg] : [msg, null];\nflow.set(\"times\", 0);\nreturn out;\n","outputs":2,"noerr":0,"x":740,"y":180,"wires":[[],[]]},{"id":"86f068be.134d18","type":"delay","z":"51c4402.953584","name":"","pauseType":"delayv","timeout":"600","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":540,"y":180,"wires":[["352d3c0d.36ab54"]]},{"id":"ff5195f9.b5d7e","type":"subflow","name":"multiclick long","info":"","category":"","in":[{"x":140,"y":160,"wires":[{"id":"7c6b1881.f94c8"}]}],"out":[{"x":900,"y":200,"wires":[{"id":"ab365874.0aefc8","port":1}]},{"x":900,"y":280,"wires":[{"id":"ab365874.0aefc8","port":2}]},{"x":900,"y":360,"wires":[{"id":"ab365874.0aefc8","port":3}]},{"x":900,"y":440,"wires":[{"id":"ab365874.0aefc8","port":4}]},{"x":1000,"y":100,"wires":[{"id":"ab365874.0aefc8","port":0}]}],"env":[],"color":"#DDAA99","outputLabels":["single","double","triple","more times","long press"]},{"id":"7c6b1881.f94c8","type":"function","z":"ff5195f9.b5d7e","name":"count","func":"msg.delay = global.get(\"awaitRetouch\") || 600;\nlet times = flow.get(\"times\") || 0;\nif(msg.payload && times < 4) flow.set(\"times\", times +=1);    // if < number of outputs: increment\n// msg.timespushed = times;\nreturn times ? [[{reset: true}, msg], null] : [null, msg];    // if 0 long released\n","outputs":2,"noerr":0,"x":290,"y":160,"wires":[["e120ace8.2c4e8"],["ab365874.0aefc8"]]},{"id":"ab365874.0aefc8","type":"function","z":"ff5195f9.b5d7e","name":"output","func":"const out = [];\nconst index = msg.payload ? 0 : flow.get(\"times\");\nflow.set(\"times\", 0);\nif(index) msg.payload = true;\n// msg.longpress = !index;\ndelete msg.delay;\nout[index] = msg;\nreturn out;\n","outputs":5,"noerr":0,"x":710,"y":180,"wires":[[],[],[],[],[]]},{"id":"e120ace8.2c4e8","type":"delay","z":"ff5195f9.b5d7e","name":"","pauseType":"delayv","timeout":"600","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":500,"y":140,"wires":[["ab365874.0aefc8"]]},{"id":"f4e04705.a4b84","type":"subflow","name":"short or long","info":"","category":"","in":[{"x":140,"y":160,"wires":[{"id":"7091f356.1403e4"}]}],"out":[{"x":480,"y":120,"wires":[{"id":"7091f356.1403e4","port":0}]},{"x":480,"y":200,"wires":[{"id":"7091f356.1403e4","port":1}]}],"env":[],"color":"#DDAA99","outputLabels":["short","long"]},{"id":"7091f356.1403e4","type":"function","z":"f4e04705.a4b84","name":"short or long","func":"const awaitRetouch = global.get(\"awaitRetouch\") || 600;\nconst now = new Date().getTime();\nif(msg.payload) context.set(\"touched\", now);    // no output on touched\nelse{\n    msg.payload = true;\n    if(now > context.get(\"touched\") + awaitRetouch) return [null, msg]  // long\n    else return [msg, null];     // short\n}\n","outputs":2,"noerr":0,"x":290,"y":160,"wires":[[],[]]},{"id":"a574854b.81773","type":"subflow","name":"multicklick multilong","info":"","category":"","in":[{"x":180,"y":320,"wires":[{"id":"33fd466.8f3aaba"}]}],"out":[{"x":720,"y":80,"wires":[{"id":"38b80536.7064ba","port":0}]},{"x":720,"y":140,"wires":[{"id":"38b80536.7064ba","port":1}]},{"x":720,"y":200,"wires":[{"id":"38b80536.7064ba","port":2}]},{"x":720,"y":260,"wires":[{"id":"38b80536.7064ba","port":3}]},{"x":720,"y":380,"wires":[{"id":"38b80536.7064ba","port":4}]},{"x":720,"y":440,"wires":[{"id":"38b80536.7064ba","port":5}]},{"x":720,"y":500,"wires":[{"id":"38b80536.7064ba","port":6}]},{"x":720,"y":560,"wires":[{"id":"38b80536.7064ba","port":7}]}],"env":[],"color":"#DDAA99","outputLabels":["short 1x","short 2x","short 3x","short 4x","long 1x","long 2x","long 3x","long 4x"]},{"id":"33fd466.8f3aaba","type":"function","z":"a574854b.81773","name":"count","func":"clearTimeout(context.retouchTimer);\nif(msg.payload) flow.set(\"count\", (flow.get(\"count\") || 0) +1);\nelse if(flow.get(\"lastlongpress\")) return msg;\ncontext.retouchTimer = setTimeout(function() {\n    node.send(msg, false);\n}, global.get(\"awaitRetouch\") || 600);\n","outputs":1,"noerr":0,"x":310,"y":320,"wires":[["38b80536.7064ba"]],"icon":"node-red/timer.svg"},{"id":"38b80536.7064ba","type":"function","z":"a574854b.81773","name":"output","func":"const maxcount = 4;     // half the outputs, other half long press\nconst count = Math.min(flow.get(\"count\"), maxcount);\nflow.set(\"count\", 0);\nconst out = [];\nconst outputnumber = flow.get(\"lastlongpress\") || (msg.payload ? maxcount + count : count);\nif(outputnumber > maxcount) flow.set(\"lastlongpress\", msg.payload ? outputnumber : 0);\nelse msg.payload = true;\nout[outputnumber -1] = msg;\nreturn out;\n","outputs":8,"noerr":0,"x":490,"y":320,"wires":[[],[],[],[],[],[],[],[]],"icon":"node-red/switch.svg"},{"id":"4a9f2d8.38632d4","type":"subflow:a574854b.81773","z":"cf56d87c.939b8","name":"","env":[],"x":390,"y":620,"wires":[[],[],[],[],[],[],[],[]]},{"id":"350b25bc.d42aca","type":"subflow:f4e04705.a4b84","z":"cf56d87c.939b8","name":"","env":[],"x":370,"y":300,"wires":[[],[]]},{"id":"c7557adb.7fa498","type":"subflow:ff5195f9.b5d7e","z":"cf56d87c.939b8","name":"","env":[],"x":370,"y":480,"wires":[[],[],[],[],[]]},{"id":"153fa4ba.33f123","type":"subflow:51c4402.953584","z":"cf56d87c.939b8","name":"","env":[],"x":380,"y":380,"wires":[[],[],[]]},{"id":"b5b41a3d.c09f1","type":"subflow:ba6d3fbf.d68c1","z":"cf56d87c.939b8","name":"short + long times","env":[],"x":390,"y":760,"wires":[["606f19e5.e2a21"]]},{"id":"606f19e5.e2a21","type":"switch","z":"cf56d87c.939b8","name":"times pushed","property":"timespushed","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"gte","v":"3","vt":"num"}],"checkall":"false","repair":false,"outputs":3,"x":640,"y":760,"wires":[["4a84e4ce.a183e4"],["8faf506e.8d4b8"],["c47662f9.670988"]]},{"id":"4a84e4ce.a183e4","type":"switch","z":"cf56d87c.939b8","name":"long?","property":"longpress","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"false","repair":false,"outputs":2,"x":840,"y":720,"wires":[[],[]]},{"id":"8faf506e.8d4b8","type":"switch","z":"cf56d87c.939b8","name":"long?","property":"longpress","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"false","repair":false,"outputs":2,"x":840,"y":760,"wires":[[],[]]},{"id":"c47662f9.670988","type":"switch","z":"cf56d87c.939b8","name":"long?","property":"longpress","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"false","repair":false,"outputs":2,"x":840,"y":800,"wires":[[],[]]}]

Well, I have a half-good news and a bad one:

  • yes, the .ino file C code works,
  • but only as long as you do not connect to Node-RED.
void setup()
{
  byte pin;
  for (pin = 0; pin < TOTAL_PINS-2; pin++) {
    digitalWrite(pin, HIGH);
  }

So basically if you give it power, if will not turn on anything.
But if I connect to Node-RED, and try to switch 1 PIN "up", =>> ALL pins switch UP too.
It's like the Node is somehow thinks / saves by default, all other pins are HIGH >> and sending ALL those infos with that one order together.
Or maybe the Johnny5 library does.
(I had no time to investigate the JS code, nor J5 C.)

I think a better solution would be to INVERT the LOW / HIGH behaviour completely.


To identify the boards, here is a workaround, if you are willing to sacrafice 3 PINs:

But after facing so many problems, I have decided:

I'm dropping Firmata completely.

Not suitable for industrial usage.

(The developer wrote wrote this line himself.)

Well, Iterating through the pins, to write them all to high at first, was one of the things I've tried before, but thanks anyway.

I think you're onto something here. Seems like it writes all states on every change and if state is undefined it sets pin HIGH or maybe as input with pullup?

That's interesting, maybe there is a "hidden way" to invert it. I was playing around with Jonny5 a bit, but I didn't had enough time to dive real deep into. Was eventually planning to switch to it, but good to know it isn't easy to get it working the way I anticipated.

Another possibility to invert output polarity is on the hardware side of things. There are ICs for that, but then I could just as well make my own I2C board, if there wouldn't be that problem, that I'm not smart enough to get that, to talk to Node-Red.

Thanks for mentioning that workaround, that's something to look into.

I'd say, that applies for almost everything we've been talking about here so far. lol
If I may ask, is there another approach you have in mind?