Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flip/Flop or slow pulse output while relay is in ON state. #2081

Closed
davebuk opened this issue Dec 22, 2019 · 11 comments · Fixed by #2170
Closed

Flip/Flop or slow pulse output while relay is in ON state. #2081

davebuk opened this issue Dec 22, 2019 · 11 comments · Fixed by #2170
Labels
enhancement New feature or request

Comments

@davebuk
Copy link
Contributor

davebuk commented Dec 22, 2019

I have an D1 mini device connected to a buzzer on one of the GPIOs.

Is there a way to have the GPIO pulse or flip/flop with a set duty cycle, say 1 second on, 1 second off while the 'RELAY/GPIO' state is ON?

I currently use a rule in openHAB to switch the GPIO output ON/OFF so the buzzer pulses, but it would be nice to just set the device to ON and the D1 mini do the pulsing.

@davebuk davebuk added the enhancement New feature or request label Dec 22, 2019
@davebuk davebuk changed the title Flip/Flop or slow pulse output while relay in in ON state. Flip/Flop or slow pulse output while relay is in ON state. Dec 22, 2019
@mcspr
Copy link
Collaborator

mcspr commented Dec 24, 2019

So I wonder how this will fit with an existing timers.

We do have a "pulse once" action, where after defining a "normal" status it will toggle the relay back after a specified time. API call can change the pulse time, but not the required status, because it is always based on the current one.
But it will switch the status every pulse...

When relay is turned on it's status goes through a bunch of checks and ends up here:
https://github.com/xoseperez/espurna/blob/dev/code/espurna/relay.ino#L297-L313
Staying with the default relay provider for real GPIOs, basic digital signal <-> status is used for RELAY_TYPE_NORMAL, RELAY_TYPE_INVERSE. RELAY_TYPE_LATCHED has an additional reset pin that will be toggled temporarily for RELAY_LATCHING_PULSE ms.

So maybe there could be a new RELAY_TYPE_PULSE that does periodically switch the status that the function above receives. Pulse time configuration can even be reused to avoid adding yet another setting

@mcspr
Copy link
Collaborator

mcspr commented Dec 25, 2019

Pulse time configuration can even be reused to avoid adding yet another setting

Scratch that. I got the same idea with flood timers and having a sort-of temporary lock for relays to hold them after switching, but it got real entangled having the same settings in different modes. No reason pulse action should not work for such relay type.

@davebuk
Copy link
Contributor Author

davebuk commented Dec 25, 2019

I presume the BUZZER option of Tasmota https://github.com/arendst/Tasmota/wiki/Buzzer would be sort of what I'm looking for? The ON/OFF state of the plused state wouldn't need to be output to mqtt etc. just the fact that the output is selected as ON or OFF.

Would it be easier to add it as some sort of light mode rather than a relay?

@mcspr
Copy link
Collaborator

mcspr commented Dec 25, 2019

Buzzer does it's thing only once, and I think it is only available as "buzzer" command? We can do that too and add cli & api command to schedule such action, but relay would not be used as an abstraction, we would just need a GPIO pin number to use. For mqtt, <root>/buzz/14 with some message describing the pattern to buzz GPIO14

What I though about is to use relay (aka our general ON OFF switch abstraction) as a trigger and continuously do some pattern with the timer. For example, use something like "100,1,200,0" for configuration, which is translated to 100msec wait, digital write 1, 200msec wait, write 0, repeat

@davebuk
Copy link
Contributor Author

davebuk commented Dec 25, 2019

Looks like a good option. Is there a load on the ESP CPU to say hold that timer for 1 second on, 1 second off? From other computer coding I've had experience with, wait timers seem to use processing power or cycles. Would there be a theoretical max 'wait' time?

To be really fancy, could the timer be adjusted by an mqtt command? E.g. openHAB would send mqtt command to switch on timer output with "500,1,500,0" then later send "200,1,200,0" as a quicker pulse? This may require the option to define up to say 5 wait sequences and enable them using <root>/buzz/14/set/1.....5 etc

@mcspr
Copy link
Collaborator

mcspr commented Dec 26, 2019

SDK continuously calls loop() function, in which we store timestamp of the last action and probe that the current time − last timestamp is ≥ the timeout we want.
ref:

if (_system_send_heartbeat || (millis() - last_hbeat > _heartbeat_interval * 1000)) {
#endif
last_hbeat = millis();
heartbeat();
_system_send_heartbeat = false;
}

After action completes, we store the timestamp and start again. ON OFF cycle is what LED module does, see the loop function below for each state:
(but this condition does not expect that millis() can overflow at some point)
static unsigned long next = millis();
if (next < millis()) {

millis() returns 32 bit value and can represent up to ~48.5 days

And I totally forgot that LEDs also accept actions through MQTT (see LED_MODE_MQTT). Maybe one could use <root>/led/0/set for that simple ON OFF pattern value (I guess it can even be ON OFF ON OFF etc., just assuming that the first value is ON and drop the proposed ,1 and ,0). Any new received pattern replaces the old one.
Not sure what you mean about sets of actions.

Or, if creating another action / module, it likely needs a better name.

@davebuk
Copy link
Contributor Author

davebuk commented Dec 26, 2019

The specific function I was looking for was the house alarm system I have built using a D1 mini. When the device is either in an arming state or armed and then triggered by a sensor, one of the GPIOs triggers a buzzer module. It currently just lets out a single tone. I use openHAB to send a 1 then 0 on a 1 second gap loop while the device is in one of the states above. My original alarm system beeps quicker the closer it gets to the state where the alarm actually fully triggers and sets off a louder sounder.

I'm not sure how openHAB or other mqtt system could send "500,1,500,0" for a slow pulse, then "200,1,200,0" for a quicker pulse. If the user could define buzzer#0 set option 0-4 etc for different ON/OFF times, mqtt could just send 0, 1, 2, 3, or 4 to enable that buzzer pulse sequence that is preset in espurna. Hope that makes sense?

@mcspr
Copy link
Collaborator

mcspr commented Dec 26, 2019

Would the device itself be able to control the pattern switching then, based on some timing / pattern itself encoding the switch? e.g. we can have 500,500,10,100,100,0 to translate as beep 500ms ON 500ms ON 10 times and switch to infinite 100 100 after that (0 as a magic value to never stop?)

Can rpn rules module be of any use?
If sensor is connected as a DigitalSensor, then we can read it's value through the rule and set some LED / ALARM / BUZZER state to ON. When ON, it will play out the given setting pattern and reset the pin when off.
And config as alarmGPIO0 => 13 & alarmPattern0 => "500,500,10,100,100,0"

@davebuk
Copy link
Contributor Author

davebuk commented Dec 26, 2019

Yes, I the pattern should be in the device configuration. Either by a #define in custom.h or ideally, a variable, user defined option in the webUI, similar to the current switch pulse option or sensor refresh options. These could be: 1st ON time (e.g. 500ms), 1st OFF time (500ms), 1st number of cycles (10 in your example), 2nd ON time (100ms), 2nd OFF time (100ms), 2nd number of cycles (0 for infinite or number of times before trigger is reset).

My D1 mini device is setup using EVENT sensors. You helped me get that working in #1815. openHAB does all the logic and uses the EVENT mqtt trigger (0 changed to 1) from one of the PIRs, but only when openHABs logic is in an 'ARMED' state. While in the 'ARMING' state or 'ARMED and TRIGGERED' state, one espurna switch SWITCH#1 triggers the connected buzzer on GPIO1. This is the GPIO I wanted to pulse ON/OFF to get a pulsed buzzer while SWITCH#1 = ON. When the system is 'DIS-ARMED' SWITCH#1 goes back to OFF and so does the buzzer.

If there is a way to use the new RPN rules to pulse the GPIO ON/OFF while SWITCH#1 = 1 rather than the single tone, thats great.

@mcspr
Copy link
Collaborator

mcspr commented Dec 27, 2019

So can relay aka switch #0 be configured as dummy trigger for alarm activation (alarmSwitch0 => 0)?
When OFF, alarm pattern stops and disables it and any triggers that activate it. When ON, we can trigger the alarm by some means (MQTT, RPN, etc.)

Why I am asking about RPN... Compared with an existing integrations for things like thingspeak, we define a single tspkMagnitude0 => 13 to map some sensor magnitude to the Thingspeak "channel" index. But, we can't exactly filter anything and neither use the same magnitude for multiple indexes.
I guess I can still do both ways of configuration, just wondering if we can hammer RPN here somehow. Maybe it is not required if sensor data is either 0 or 1.

@davebuk
Copy link
Contributor Author

davebuk commented Dec 28, 2019

The D1 mini is configured like this:

#elif defined(WEMOS_D1_MINI_RELAYSHIELD)

    // Info
    #define MANUFACTURER        "WEMOS"
    #define DEVICE              "D1_MINI_RELAYSHIELD"

    #define DEBUG_SERIAL_SUPPORT    0
    
    // Buttons
    // No buttons on the D1 MINI alone, but defining it without adding a button doen't create problems
    #define BUTTON1_PIN          0   // Connect a pushbutton between D3 and GND,
                                     // it's the same as using a Wemos one button shield
    #define BUTTON1_MODE         BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH
    #define BUTTON1_RELAY        1
     
    // Relays
    #define RELAY1_PIN           5  //D1 Sounder relay
    #define RELAY1_TYPE          RELAY_TYPE_NORMAL
    #define RELAY2_PIN           1  //TX Buzzer relay
    #define RELAY2_TYPE          RELAY_TYPE_INVERSE

    // LED
    #define LED1_PIN             2  //D4
    #define LED1_PIN_INVERSE     1

    //Events I/P support
    
    #define EVENTS_SUPPORT       1

    #define EVENTS1_TRIGGER       1
    #define EVENTS1_PIN            3 //RX
    #define EVENTS1_PIN_MODE       INPUT_PULLUP
    #define EVENTS1_INTERRUPT_MODE	CHANGE
    #define EVENTS2_TRIGGER       1   
    #define EVENTS2_PIN           4  //D2
    #define EVENTS2_PIN_MODE      INPUT_PULLUP
    #define EVENTS2_INTERRUPT_MODE	CHANGE
    #define EVENTS3_TRIGGER       1
    #define EVENTS3_PIN           12  //D6
    #define EVENTS3_PIN_MODE      INPUT_PULLUP
    #define EVENTS3_INTERRUPT_MODE	CHANGE
    #define EVENTS4_TRIGGER       1
    #define EVENTS4_PIN           13  //D7
    #define EVENTS4_PIN_MODE      INPUT_PULLUP
    #define EVENTS4_INTERRUPT_MODE	CHANGE    
    #define EVENTS5_TRIGGER       1
    #define EVENTS5_PIN           14  //D5
    #define EVENTS5_PIN_MODE      INPUT_PULLUP
    #define EVENTS5_INTERRUPT_MODE	CHANGE
#endif

openHAB switches RELAY2 via mqtt for the buzzer and RELAY1 for the loud alarm sounder relay. Could a dummy RELAY3 be configured so that using the rules module, while RELAY3 is ON (via openHAB mqtt command) loop 'RELAY2' ON/OFF in some sort of pattern?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants