OneButton subfunction

Hello,

I´ve got a problem with the OneButton library and using it with subfunctions.
When pushing a button I like to change a variable in a subfunction.
First problem: The value (dFlow) only gives a “?” back. Maybe there is a problem with the snprintf conversion?
Second:The button is not working, is there a problem using two subfunctions?

// Includes ----------------------------------------------------------------------
#include <OneButton.h>

//oled
#define OLED_RST   8
#define OLED_DC    9
#define OLED_CS   10
#define OLED_DATA 11
#define OLED_CLK  13

#include "SSD1306Ascii.h"
#include "SSD1306AsciiSoftSpi.h"
SSD1306AsciiSoftSpi oled;

// Variables ---------------------------------------------------------------------

// Init up button on pin A1 with default high
OneButton buttonUp(A1, false);
// Current flow value
double dFlow=0;

// Subfunctions ------------------------------------------------------------------

/*
  Increases current flow by 0.1 ml/h
  returns increased flow value
*/
int increaseFlow()
{
  // Increase flow
  dFlow += 0.1;
  oled.println("2");
  // return new flow value
  return dFlow;
}

/*
  Attaches ClickHandler to buttonUp
*/
void setButtonUpClickHandler()
{
  // Attach click handler
  buttonUp.attachClick(increaseFlow);

}

/*
  Prints on OLED
*/
void print()
{
  char cFlow[10];
  snprintf(cFlow, 10, "%f", dFlow);
  // Print new flow value
  oled.println(cFlow);
  oled.println("ml/h");

}

void setup()
{
  //oled setup
  oled.begin(&Adafruit128x32, OLED_CS, OLED_DC, OLED_CLK, OLED_DATA, OLED_RST);
  oled.setFont(TimesNewRoman16_bold);
  print();
}

/*
  Checks cyclic for button interactions
  This function runs in a cyclic loop
*/
void loop()
{
  buttonUp.tick();
  delay(10);
}
int increaseFlow()
{
  // Increase flow
  dFlow += 0.1;
  oled.println("2");
  // return new flow value
  return dFlow;
}

Your function modifies a global float, and returns an int.
Why?

And sprintf doesn't by default support float.
Use dtostrf.

True but doesn´t change a thing, also there was an other mistake in this section:

double increaseFlow()
{
  // Increase flow
  dFlow += 0.1;
  print();
  // return new flow value
  return dFlow;
}

complete:

// Includes ----------------------------------------------------------------------
#include <OneButton.h>

//oled
#define OLED_RST   8
#define OLED_DC    9
#define OLED_CS   10
#define OLED_DATA 11
#define OLED_CLK  13

#include "SSD1306Ascii.h"
#include "SSD1306AsciiSoftSpi.h"
SSD1306AsciiSoftSpi oled;

// Variables ---------------------------------------------------------------------

// Init up button on pin A1 with default high
OneButton buttonUp(A1, false);
// Current flow value
double dFlow=0;

// Subfunctions ------------------------------------------------------------------

/*
  Increases current flow by 0.1 ml/h
  returns increased flow value
*/
double increaseFlow()
{
  // Increase flow
  dFlow += 0.1;
  print();
  // return new flow value
  return dFlow;
}

/*
  Attaches ClickHandler to buttonUp
*/
void setButtonUpClickHandler()
{
  // Attach click handler
  buttonUp.attachClick(increaseFlow);

}

/*
  Prints on OLED
*/
void print()
{
  char cFlow[10];
  snprintf(cFlow, 10, "%f", dFlow);
  // Print new flow value
  oled.println(cFlow);
  oled.println("ml/h");

}

void setup()
{
  //oled setup
  oled.begin(&Adafruit128x32, OLED_CS, OLED_DC, OLED_CLK, OLED_DATA, OLED_RST);
  oled.setFont(TimesNewRoman16_bold);
  print();
}

/*
  Checks cyclic for button interactions
  This function runs in a cyclic loop
*/
void loop()
{
  buttonUp.tick();
  delay(10);
}

True but doesn´t change a thing,

What do you mean?
sprintf (and also snprintf) do not support float and the %f template.

  buttonUp.attachClick(increaseFlow);And the returned value goes . . where?

Thank you!!!

Just one more problem. The subfunction is not working correctly do you have any idea?

// Includes ----------------------------------------------------------------------
#include <OneButton.h>

//oled
#define OLED_RST   8
#define OLED_DC    9
#define OLED_CS   10
#define OLED_DATA 11
#define OLED_CLK  13

#include "SSD1306Ascii.h"
#include "SSD1306AsciiSoftSpi.h"
SSD1306AsciiSoftSpi oled;

// Variables ---------------------------------------------------------------------

// Init up button on pin A1 with default high
OneButton buttonUp(A1, false);
// Current flow value
double dFlow=0;

// Subfunctions ------------------------------------------------------------------

/*
  Increases current flow by 0.1 ml/h
  returns increased flow value
*/
double increaseFlow()
{
  dFlow += 0.1; // Increase flow
  print();
  return dFlow; // return new flow value
}

/*
  Attaches ClickHandler to buttonUp
*/
//double setButtonUpClickHandler()
//{
//  // Attach click handler
//  
//  return dFlow;
//
//}

/*
  Prints on OLED
*/
void print()
{
  char cFlow[10];
  dtostrf( dFlow, 10, 2, cFlow );
  // Print new flow value
  oled.clear();
  oled.println(cFlow);
  oled.println("ml/h");

}

void setup()
{
  //oled setup
  oled.begin(&Adafruit128x32, OLED_CS, OLED_DC, OLED_CLK, OLED_DATA, OLED_RST);
  oled.setFont(TimesNewRoman16_bold);
  print();
  buttonUp.attachClick(increaseFlow);
}

/*
  Checks cyclic for button interactions
  This function runs in a cyclic loop
*/
void loop()
{
  buttonUp.tick();
  delay(10);
}
  buttonUp.attachClick(increaseFlow);

Does the attachClick() function expect a pointer to a function that returns a double? That would seem highly unusual.

Post a link to the OneButton library.

That's the library I'm using:

r8beta:
That's the library I'm using:

GitHub - mathertel/OneButton: An Arduino library for using a single button for multiple purpose input.

The library has a function declaration:

 void attachClick(callbackFunction newFunction);

The type of argument is callbackFunction, which is a type defined like so:

 typedef void (*callbackFunction)(void);

What this means is that attachClick takes a pointer to a function that takes no arguments and returns no value.

Why are you insisting on trying to pass it a pointer to a function that is NOT the kind it expects?

The subfunction is not working correctly do you have any idea

what does it mean? what behavior do you see?

When I click the button nothing happens. But wiring is correct, I checked this with the sample code.

When I click the button nothing happens.

Have you changed the function to have the proper signature?

I’ve tried this code

#include <OneButton.h>
OneButton buttonUp(A1, true);
double dFlow = 0;

void increaseFlow()
{
  dFlow += 0.1; // Increase flow
  print();
}

void print()
{
  char cFlow[10];
  dtostrf( dFlow, 10, 2, cFlow );
  Serial.print(cFlow);
  Serial.println("\tml/h");
}

void setup()
{
  Serial.begin(115200);
  print();
  buttonUp.attachClick(increaseFlow);
}

void loop()
{
  buttonUp.tick();
  delay(10);
}

which is derived from yours but does not use the OLED, just the serial console and when I click on the button connected to A1 (I changed to activate the pull-up so the wiring needs to be A1 <–> BUTTON <–> GND) then when I click on the button seems things to work

[sub][color=blue]      0.00	ml/h
      0.10	ml/h
      0.20	ml/h
      0.30	ml/h
      0.40	ml/h
      0.50	ml/h
      0.60	ml/h
      0.70	ml/h
      0.80	ml/h
      0.90	ml/h
      1.00	ml/h
      1.10	ml/h
[/color][/sub]

Notice the string format though… (hint)

Thank you guys! Now it´s working fine!

r8beta:
Thank you guys! Now it´s working fine!

So, what did you have to change in your code/hardware? The function signature? The wiring?

I did what you and J-M-L said. I made the attachClick Function void.

Also there was an other problem with the dtostrf function. I used the wrong buffer and width size. It now looks like this:

 char cFlow[10];
  dtostrf( dFlow, 8, 2, cFlow );

r8beta:
Also there was an other problem with the dtostrf function. I used the wrong buffer and width size. It now looks like this:

 char cFlow[10];

dtostrf( dFlow, 8, 2, cFlow );

good catch, that's what I meant with

Notice the string format though... (hint)

:slight_smile:

Having the wrong signature for the function does just create a warning

warning: invalid conversion from 'double ()()' to 'callbackFunction {aka void ()()}' [-fpermissive]
buttonUp.attachClick(increaseFlow);

but that does not prevent the thing to work given how the library uses the call back (does not care about any return value as it's supposed to be void)