Mysensors "flic-like button"

Hi.
I want to create a smart button.
A hidden button under my kitchen table to control volume of my music.
It is easy to make a button, present it as a binary sensor.

I want the same functionally as a flic button. Single press, doubble press and long press.
One alternative would be to present 3 binary sensors and make the sketch to send different messages depending on how the button is pressed i guess. This would create 3 entities in home assistant for one button.
It will be a lot of keep trackof with multiple buttons.
Is there a way to get Home Assistant to handle this from only one binary sensor?
Like trigger, state “on” for 2 seconds for the long press, but how to not trigger the automation for single press.
And how to make Home Assistant to handle the duble press?

What do yu guys think.

Present it as a S_SCENE_CONTROLLER and send different payloads depending on the type of button presses.

Of course. Obviously the best way to do it.
Thank you.
I will try that as soon as I get the time.

1 Like

@martinhjelmare

I managed to get this working.
I use the Onebutton library.
Found here: https://github.com/mathertel/OneButton
The node send defferent payloads. 1 for single press, 2 for double press and 3 for hold

I changed the button pin to D2 because i want the node to sleep and use interupt.
This i haven’t tried yet but i will try to make it sleep.
Will you please check my sketch?
I don’t even know the basic ground with arduino.
Must learn when i get the time. :slight_smile:
How to add sleep to the sketch?

Put sleep in the loop?
I haven’t defined the D2 pin “the-mysensors-way” right?

/*
Mysensors Smart Button
*/
 
#define MY_DEBUG
#define MY_RADIO_NRF24
#define MY_NODE_ID 99

#include "OneButton.h"
#include <SPI.h>
#include <MySensors.h>

#define SN "MySmartButton"
#define SV "1.0"
#define CHILD_ID 1
// Setup a new OneButton on pin D2.  
OneButton button(2, true);
MyMessage on(CHILD_ID, V_SCENE_ON);

// setup code here, to run once:
void setup() {
  
  // link the doubleclick function to be called on a doubleclick event.   
  button.attachClick(click);
  button.attachDoubleClick(doubleclick);
  button.attachPress(press);

} // setup
  
void presentation()  {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo(SN, SV);
  present(CHILD_ID, S_SCENE_CONTROLLER);
}

int messageA = 1;
int messageB = 2;
int messageC = 3;


void loop() {
  // keep watching the push button:
  button.tick();

  delay(10);
} // loop
// this function will be called when the button was pressed one time
void click() {
send(on.set(messageA));
}
// this function will be called when the button was pressed 2 times in a short timeframe.
void doubleclick() {
send(on.set(messageB));
} // doubleclick
// this function will be called when the button was pressed for about one second
 void press() {
send(on.set(messageC));
 }

I’m not sure that the OneButton library is compatible with sleep. According to the docs OneButton uses millis to measure time passed. millis does not work when sleeping.

I haven’t used that library myself so I can’t say more how that would work. There is probably some solution out there, but maybe not for that library.

Read about sleeping here:

You need to enter the interrupt number for pin 2 and what change mode you want to use and if there should be a timeout on the sleep. Read about interrupts in the arduino reference. There’s a function to get the interrupt number from a pin number.

The sketch looks OK generally, but don’t use delay, use wait or sleep to suspend execution in the loop. wait will process messages in the background. You don’t need that here and should probably use sleep instead to save power.

I think i solved it.
If someone want to try a sleeping mysensors smart button. Version 2.X compatible.
Three functions from one button. Single click, double click and hold.
You will need to install an external library called Onebutton. This is available in the library manager.

/*
  Mysensors Smart Button
*/

#define MY_DEBUG
#define MY_RADIO_NRF24

#include "OneButton.h"
#include <SPI.h>
#include <MySensors.h>

#define SN "MySmartButton"
#define SV "1.0"
#define CHILD_ID 1
#define SLEEP_PIN 2
// Setup a new OneButton on pin D2. true will set pin high (internal pull up), false will set pin low.
OneButton button(2, false);
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
const long interval = 5000;

MyMessage on(CHILD_ID, V_SCENE_ON);

// setup code here, to run once:
void setup() {

  // link the doubleclick function to be called on a doubleclick event.
  button.attachClick(click);
  button.attachDoubleClick(doubleclick);
  button.attachPress(press);

} // setup

void presentation()  {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo(SN, SV);
  present(CHILD_ID, S_SCENE_CONTROLLER);
}

int messageA = 1;
int messageB = 2;
int messageC = 3;


void loop() {
  currentMillis = millis();
  // keep watching the push button:
  button.tick();

  if (currentMillis - previousMillis >= interval) {
    Serial.println("we go sleep");
    previousMillis = currentMillis;
    sleep(SLEEP_PIN - 2, CHANGE, 0);
  }
} // loop
// this function will be called when the button was pressed one time

void click() {
  send(on.set(messageA));
}
// this function will be called when the button was pressed 2 times in a short timeframe.
void doubleclick() {
  send(on.set(messageB));
} // doubleclick
// this function will be called when the button was pressed for about one second
void press() {
  send(on.set(messageC));
}

I haven’t used it yet.
Just tried on a breadboard but it seems ok.

3 Likes

There is a thread here with a more recent sketch, sleeping and reporting battery level.
There is some pictures showing an example with the button installed.
I find it very useful. Using it almost every day. Even the wife likes it :grin:

I am controlling an chromecast audio.
Short press, volume up
Double press, volume set to an pretty low level i often use (could be used as volume down.)
Long press, starts an radiostation if nothing is playing. If something is playing it has an pause/play function.

Can you share your hardware photo with us? I curious about battery, case and overall look, I’m interested in something similar

Look in the first post in the link in my previous post.

Got it :slight_smile: So, in terms of as low as possible battery usage you should definitely go and try to build something on pure atmega instead of whole Arduino. Google for a Mysensors PCB projects like slim node or stamp node. I’ve printed both, but only the first one is soldered and running, rest is waiting :slight_smile: And in terms of coding there is a great project/library called NodeManager. I found this combination as most flexible from all other Mysensors projects found over the internet.

Yes i know.
There are many interesting projects at openhardware.io

It would be nice to have a small node in a nice case with a button.
But there are better alternatives, like xiaomi smart button. The price is so low that it is almost not worth the time it takes to build one.

But for me, that don’t like wifi-only stuff, specially not from china. I will not use xiaomi gateway.

I almost bought Xiaomi on a good price drop, they are way cheaper that making it by yourself, but:

  • while Hass control it locally it still need to be connected to China servers (at least for pairing as far as I know)
  • ZigBee - I prefer to not to add another wireless standard to my current config
  • MySensors stay competitive when you build some kind of multisensor instead of 1 purpose one

Well, that’s at least my point of view