Netgalleria / arska-node

Smart power manager for optimized solar power usage as well as greenest and cheapest energy purchase
GNU General Public License v3.0
24 stars 1 forks source link

Possibility to have gpio outputs inverted #13

Closed joe-ave closed 1 year ago

joe-ave commented 1 year ago

Hello, looking thru the schematics of many of the relayboards with optoisolaters available for arduino/esp/rpi etc. most of them need a low pulldown signal to activate the relay. So maybe there should be an option of some kind that the output could be inverted?

//Jonas

Olli69 commented 1 year ago

Tack för idén, Jonas! I just try to figure out the case. Maybe you could give an example of a board model/setup, please? Maybe, at least in some cases, you could also invert the result by wiring? I mean if there are out both NO "normally open" and NC "normally closed" (which are reverse) in the relay, you just select the right terminal to get the correct result?

Inverting the output would of course be quite simple in the program logic. But additional parameters in the channel configuration would always make the user interface a bit more complex - something we try to avoid if easily possible.

Olli

joe-ave commented 1 year ago

Hi Olli!,

9277b82e552fc8d5b16d3de2996d1f47ef1d7272

Borrowed picture from https://forum.arduino.cc/t/4-channel-relay-board/268035/4

Most of them seem to have this type of setup, the channels have common vcc and to activate the relay the input needs to be pulled low. And yes the easy way is to connect the function to to a NC contact instead but the failsafe position ( if the ESP is powered off for instance and the outputs will be sort of floating ) would be constant on and that might cause trouble dependent on what you are controlling. Maybee you could just have a new output type, like "Relay inverted" the you do not need additional parameters and/or checkboxes. //Jonas

Olli69 commented 1 year ago

Hi Jonas, So let me know if I have understood it right:

State chart

# Description Channel state Normal NO Normal NC Inverted NO Inverted NC
1 ESP power off / failure ? open (a) closed (a) open (b) closed (b)
2 Channel down DOWN open (a) closed (a) closed open
3 Channel up UP closed open open (b) closed (b)

In case of ESP32 failure:

joe-ave commented 1 year ago

Hello Olli,

the main thing is that I want the relay that I am controlling to be energized when the channel in Arska indicates up and is green, most external relayboards seem to use a low signal to energize the coil but some a high signal.

I tried "Target State" set to "DOWN" but then it seems like the channel allways indicates "Down" and never turns (high) on regardless of how the rules are set, tried with "P diff to avg 24h".

I think the "GPIO user-defined, inverted" is the way to go to solve this, you do however need to consider how you initialize the outputs so that they are set high (if inverted!) before they are set as outputs, in the Arduino enviroment I do something like this in setup:

define Relay_1 38

void RelaySetup (){ digitalWrite (Relay_1, HIGH); pinMode (Relay_1, OUTPUT); } This is to prevent the relay from going "click-click" at startup since outputs are set low by default when pinMode are set, otherwise they are low until the code a few ms later tells them to be high. And instead of "HIGH" you could point to a bool that you previously read from eeprom (also in setup) that holds the "GPIO user-defined" type. //Jonas

Olli69 commented 1 year ago

Hi Jonas, Thanks! Now I (finally, hopefully, 😃) got your point about external relay boards. I have been thinking about how to make setups failsafe (defined state if ESP32 or ESP32 power supply is down) in various cases. Generally, I'm focusing mainly on boards with integrated relays to keep the basic setup simple (no soldering, etc. needed in basic cases). But of cause, it is good to have a working solution for external relay boards too and it seems to be analog with potential-free/dry contact case as you mentioned.

About that "Target State set to DOWN" thing you mentioned, A few points about rule conditions - hopefully, these will explain the case - please let me know if not:

I tested with ESP32/LilyGo with integrated optoisolated relay modules following code and pinMode did not seem (no "click") set output LOW (if set HIGH before restart). Could it be caused by a difference between Arduino/ESP32, individual board design/random, depends on gpio (settings)... . Requires some further investigation to avoid that "inversed click-click" after the boot/init (if it issue with ESP32). Maybe that extra digitalWrite (pin, HIGH); for inversed in the init. Currently up/down status is not updated to eeprom after channel state change (only after settings change), to avoid memory wear-out caused by frequent writes. So currently, Arska does not know gpio states just after a reboot.

  // testing pinMode in beginning of setup() 
  Serial.println("pinMode OUTPUT, sleep 10");
  pinMode(5, OUTPUT);
  delay(10000);
  Serial.println("digitalWrite HIGH, sleep 10");
  digitalWrite(5, HIGH);
  delay(10000);
  Serial.println("restart");
  ESP.restart();
joe-ave commented 1 year ago

Hello Olli,

thanks for the advice about "Target State set to DOWN"!, with that workaround the rules works during normal operation but it´s just a little confusing when you look at it as the channel will indicate down when rule 1 is fulfilled and the external relay will activate, and rule 2 will indicate up and the external relay is deactivated when rule 1 is not fulfilled.

However, if I the rules are set so that rule 2 is up that puts the gpio high to have the external relay deactivated and then restart the board with the reset button the external relay will go on/off after approx. 22 seconds, when the wifi has been connected, duration maybe 0,5 second.

It happens right after the wifi is connected, probably when this line is printed on the serial: set_state, channel: 0, on: 0 , off: 1665320235, utilization: 0.000000

and the turns high and deactivates the external relay when this lines is printed 0,5 sec later: channel_idx 0, condition_idx 1 matches, channel wanna_be_up: false set_relays rise_count: 1, drop_count: 0 Switching ch 0 (16) from 0 .-> 1 set_state, channel: 0, on: 0 , off: 0, utilization: 0.000000 1665255436

You will probably not see this with the internal relayboards that use an active 1 to activate the relays.

//Jonas

Olli69 commented 1 year ago

Hi Jonas, Do you think the new type "GPIO inversed" would solve what you wrote in the comment? I have implemented the first versions of it, but haven't had yet time to test it.

Olli

joe-ave commented 1 year ago

Hello Olli,

it should solve the confusing down/up workaround, and if the inverted gpio’s are initialized high the ”click/click” behaviour should go away during startup.

//Jonas

joe-ave commented 1 year ago

Hello Olli,

on my local version I did this:

high before initialized

and

inverse of output

, this solved the issues for me so the relays don´t go "click-click" during startup and the rules work normaly. I needed to write to the output first before pinmode was set, otherwise the relay led would blink for a brief moment, not long enough to energize the relay though.

You could probably create a new "set_channel_relay_inv" and "set_gpio_pinmode_output_inv" that do this and is called instead if "GPIO inversed" is selected. But you probably already did something like this in your test version?

//Jonas

Olli69 commented 1 year ago

Hi Jonas, I will still check that once more, but when I tested with the piece of code in my earlier comment, the line did stay HIGH after pinMode(x, OUTPUT). I just wonder if we do something differently or could there be differences between our boards?

Anyway, pinMode is needed only once per gpio, but now it is called before every digitalWrite. Maybe removing excessive calls to pinMode helps.

I just pushed latest version (not well tested) to devel branch. It makes pinMode call only in init.

Olli

joe-ave commented 1 year ago

Hello Olli,

I poked in your latest 0.92-RC3 from the install page and it seems to work!, you can however see a brief blink ( not enough to energize the relay ) a couple of seconds after powerup. Besides that the logic rules seems to work when "GPIO, inversed" is tested with my setup!

//Jonas

Edit: I found this also: https://community.particle.io/t/can-i-not-call-digitalwrite-before-pinmode/49920, maybe digitalwritefast should be used?

//Jonas

Olli69 commented 1 year ago

Hi Jonas! Sounds good! I moved relay init (setting to default channel down) to the beginning of setup(), so it goes to the failsafe mode even though there would be problems with the wifi - there you probably saw the blinks.

Thanks for the link. There seem to be ...fast versions for AVR environments but I couldn't find them for ESP32. I could not see blinks on my test board with test led and no change in the relay. Maybe the capacitance of the connected relays slows down the change - and normally there is some kind of relay connected. But let's see if this (blink) could cause problems in some future setups - then there is probably a possibility to fix it with software or hardware (capacitor?).

Olli