Very cool thank you Alan :-)

On Sat, Jul 12, 2025 at 12:57 AM Alan C. Assis <acas...@gmail.com> wrote:
>
> Hi Tomek,
>
> I agree with you, but in this first "incarnation" it will support only two
> actions, but people are invited to improve it later.
>
> Notice that I used INPUT_SBUTTON, so the "Dual Action" is just a Kconfig
> message, easy to change. :-)
>
> Now my idea is just to add the improvements that Michał Łyszczek added in
> the review and add a debouncing, because after more tests I discovered that
> sometimes it was returning invalid key press.
>
> The driver itself is very simple, less than 300 LoC, so I hope everybody
> can understand how it works.
>
> BR,
>
> Alan
>
> On Fri, Jul 11, 2025 at 7:39 PM Tomek CEDRO <to...@cedro.info> wrote:
>
> > Very cool thanks Alan! :-)
> >
> > I think there may be more actions with one button:
> > 1. single click.
> > 2. double click.
> > 3. triple click.
> > 4. short press.
> > 5. long press.
> > etc
> >
> > So it is not only dual action button, there may be more actions :-)
> >
> > It would be great if the driver could return event code or have return
> > codes configurable (build time?) on selected actions. That would make
> > things really versatile :-)
> >
> > Thanks :-)
> > Tomek
> >
> >
> > On Fri, Jul 11, 2025 at 11:26 PM Alan C. Assis <acas...@gmail.com> wrote:
> > >
> > > Hi Everyone,
> > >
> > > The driver is done: https://github.com/apache/nuttx/pull/16714
> > >
> > > I started using drivers/input/spq10kbd.c as reference, but then I
> > realized
> > > that there was already a keyboard_upper.c that I could use to send key
> > > events/strokes.
> > >
> > > After that the driver was easier to implement than I thought initially.
> > >
> > > BR,
> > >
> > > Alan
> > >
> > > On Wed, Jul 9, 2025 at 10:16 AM Alan C. Assis <acas...@gmail.com> wrote:
> > >
> > > > Hi Everyone,
> > > >
> > > > Some years ago a customer asked me to develop a project with NuttX for
> > > > this board that used a small OLED display and a single button.
> > > > That button should be used to navigate in the menu, as a side note:
> > > > initially he suggested: quick press and release will work as a ENTER
> > and
> > > > long press will work as TAB (move to other option),
> > > > but while testing the application I released the was faster if quick
> > press
> > > > work as TAB and long press as enter.
> > > >
> > > > This video implements the same idea on a ESP32-Devkit board that also
> > has
> > > > only a single button: https://www.youtube.com/shorts/vfQLW-a2JhA
> > > >
> > > > The daemon that detect the button and define the type of input is
> > > > something like this:
> > > >
> > > >   /* Define the notifications events */
> > > >
> > > >   btnevents.bn_press   = supported;
> > > >   btnevents.bn_release = supported;
> > > >
> > > >   btnevents.bn_event.sigev_notify = SIGEV_SIGNAL;
> > > >   btnevents.bn_event.sigev_signo  = CONFIG_INPUT_BUTTONS_SIGNO;
> > > >
> > > >   /* Register to receive a signal when buttons are pressed/released */
> > > >
> > > >   ret = ioctl(fd, BTNIOC_REGISTER,
> > > >               (unsigned long)((uintptr_t)&btnevents));
> > > >   if (ret < 0)
> > > >     {
> > > >       int errcode = errno;
> > > >       printf("button_daemon: ERROR: ioctl(BTNIOC_SUPPORTED) failed:
> > %d\n",
> > > >              errcode);
> > > >       goto errout_with_fd;
> > > >     }
> > > >
> > > >   /* Ignore the default signal action */
> > > >
> > > >   signal(CONFIG_INPUT_BUTTONS_SIGNO, SIG_IGN);
> > > >
> > > >   /* Now loop forever, waiting BUTTONs events */
> > > >
> > > >   for (; ; )
> > > >     {
> > > >       struct siginfo value;
> > > >       sigset_t set;
> > > >
> > > >       bool timeout;
> > > >       int nbytes;
> > > >
> > > >       /* Wait for a signal */
> > > >
> > > >       sigemptyset(&set);
> > > >       sigaddset(&set, CONFIG_INPUT_BUTTONS_SIGNO);
> > > >       ret = sigwaitinfo(&set, &value);
> > > >       if (ret < 0)
> > > >         {
> > > >           int errcode = errno;
> > > >           printf("ERROR: sigwaitinfo() failed: %d\n", errcode);
> > > >           goto errout_with_fd;
> > > >         }
> > > >
> > > >       sample = (btn_buttonset_t)value.si_value.sival_int;
> > > >
> > > >       if (sample & 0x01)
> > > >         {
> > > >           /* Button pressed, start measuring time */
> > > >
> > > >           clock_gettime(CLOCK_REALTIME, &start);
> > > >         }
> > > >       else
> > > >         {
> > > >           /* Button released, calculate the elapsed time */
> > > >
> > > >           clock_gettime(CLOCK_REALTIME, &curr);
> > > >
> > > >           elapsed.tv_sec  = curr.tv_sec - start.tv_sec;
> > > >           if (curr.tv_nsec >= start.tv_nsec)
> > > >             {
> > > >               elapsed.tv_nsec = curr.tv_nsec - start.tv_nsec;
> > > >             }
> > > >           else
> > > >             {
> > > >               unsigned long borrow = 1000000000 - start.tv_nsec;
> > > >               elapsed.tv_sec--;
> > > >               elapsed.tv_nsec = curr.tv_nsec + borrow;
> > > >             }
> > > >
> > > >  unsigned long ftime = (elapsed.tv_sec * 1000000000) + elapsed.tv_nsec;
> > > >
> > > >  /*printf("Elapsed miliseconds = %d\n", ftime / 1000000);*/
> > > >  if (ftime < 500000000)
> > > >             {
> > > >               input_event(INPUT_TAB);
> > > >             }
> > > >  else
> > > >             {
> > > >               input_event(INPUT_ENTER);
> > > >             }
> > > >         }
> > > >
> > > >       /* Make sure that everything is displayed */
> > > >
> > > >       fflush(stdout);
> > > >
> > > >       usleep(1000);
> > > >     }
> > > >
> > > > But today while taking a shower and thinking about other subjects that
> > > > fact came to mind and I asked myself: how to develop that thing in a
> > more
> > > > standard way to avoid the "kludge" above? (in fact it is not kludge,
> > but we
> > > > can improve, right?)
> > > >
> > > > So, I realized it would be nice to have a kind of "action button"
> > driver
> > > > that generates this kind of event (detecting long press and short
> > press)
> > > > automatically returning INPUT_ENTER or INPUT_TAB.
> > > >
> > > > In fact the driver will be more similar to djoystick.c than the
> > ordinary
> > > > buttons driver itself (for simplicity).
> > > >
> > > > Please let me know if someone already implemented something similar or
> > > > other suggestions before I implement it.
> > > >
> > > > BR,
> > > >
> > > > Alan
> > > >
> >
> >
> >
> > --
> > CeDeROM, SQ7MHZ, http://www.tomek.cedro.info
> >



-- 
CeDeROM, SQ7MHZ, http://www.tomek.cedro.info

Reply via email to