OneButton sehr langsam

Hallo Leute,

wie ich die Google Suche auch drehe und wende, ich komme leider auf keinen grünen Zweig.
Darum wende ich mich nun an euch, in der Hoffnung auf Hilfe.

Ich kämpfe momentan mit der OneButton Library.
Über zwei Taster (Sollwert auf und ab) wird die Solltemperatur eingestellt.
Bei einmaligem drücken eines Tasters (cklick), soll der Sollwert um 0,1°C auf bzw. ab springen.
Bei gedrücktem Taster (longpress) springt der sollwert in 1°C Schritten auf und ab.

Das funktioniert soweit auch, nur die Klickfunktion ist extrem langsam.
Es dauert ca. 2 Sekunden bis sich der sollwert von z.B. 20.00°C auf 20.10°C ändert.
Man könnte natürlich auch damit leben... aber mir gefällt es nicht.

Bin für jede Hilfe dankbar! =)

Hier mein Code

#include <PID_v1.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <OneButton.h>

#define output_pwm_h  6                                              // pwm output heating
#define output_pwm_c  5                                              // pwm output cooling
#define ONE_WIRE_BUS 7                                               // Define the OneWire bus (DS18b20) to pin 7
#define output_fan_cool 8
#define output_fan_cool_heatsink 9
#define output_fan_heat 10

/*******************************************************************
/ Connecting OneButton io's                                        *
/******************************************************************/

OneButton buttonset_up(12, true);                                     // setpoint "up" to pin 12
OneButton buttonset_down(11, true);                                   // setpoint "down" to pin 11

/*******************************************************************
/ Set the LCD address to 0x27 for a 16 chars and 2 line display    *
/******************************************************************/

LiquidCrystal_I2C lcd(0x27, 16, 2);                 

/*******************************************************************
/ Connect Temperature Sensor to OneWire bus                        *
/******************************************************************/
                 
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

/*******************************************************************
/Define Variables we'll be connecting to                           *
/******************************************************************/

double Setpoint=22, Input, Output_h, Output_c;

/*******************************************************************
* Specify the links and initial tuning parameters                  *
/******************************************************************/

double Kph=2, Kih=5, Kdh=1;                                          // heating
double Kpc=2, Kic=6, Kdc=1;                                          // cooling

PID myPID_h(&Input, &Output_h, &Setpoint, Kph, Kih, Kdh, DIRECT);    // heating
PID myPID_c(&Input, &Output_c, &Setpoint, Kpc, Kic, Kdc, REVERSE);   // cooling

//==================================================================================================================//

void setup()
{
  
/*******************************************************************
* Set default output state                                  *
/******************************************************************/

digitalWrite(output_fan_cool,LOW);
digitalWrite(output_fan_cool_heatsink,LOW);
digitalWrite(output_fan_heat,LOW);

/******************************************************************
/ turn the PID on                                                 *
/*****************************************************************/

myPID_h.SetMode(AUTOMATIC);                                          // heating
myPID_c.SetMode(AUTOMATIC);                                          // cooling

sensors.begin();     
lcd.begin();
lcd.backlight();
lcd.print("PID control");  
lcd.setCursor(0,1);         
lcd.print("v 1.0");     
delay(3000);
lcd.clear();
lcd.print("ph:2 ih:5 dh:1");  
lcd.setCursor(0,1);         
lcd.print("pc:2 ic:6 dc:1");
delay(4000);

//Serial.begin(9600);                                                // uncomment for debugging in serial monitor 

lcd.clear();

// link the button 1 functions.
  buttonset_up.attachClick(clickup);
  buttonset_up.attachDuringLongPress(longPressup);

// link the button 2 functions.
  buttonset_down.attachClick(clickdown);
  buttonset_down.attachDuringLongPress(longPressdown);
  

}


void loop()
{

/******************************************************************
/ keep watching the ObeButtonpush buttons                         *
/*****************************************************************/

buttonset_up.tick();
buttonset_down.tick();

/******************************************************************
/ read sensor input                                               *
/*****************************************************************/

sensors.requestTemperatures();
float temperature = sensors.getTempCByIndex(0);

/******************************************************************
/ Display sensor input on LCD                                     *
/*****************************************************************/

lcd.setCursor(0, 0);
lcd.print("Ist :");
lcd.setCursor(6, 0);
lcd.print(sensors.getTempCByIndex(0));
lcd.print("\337C");

/******************************************************************
/ Display setpoint on LCD                                         *
/*****************************************************************/

lcd.setCursor(0,1);
lcd.print("Soll:");
lcd.setCursor(6,1);
lcd.print(Setpoint);
lcd.print("\337C");

/******************************************************************
/ get controller output (pwm)                                     *
/*****************************************************************/

Input = temperature;
myPID_h.Compute();                                                  // heating controller
analogWrite(output_pwm_h, Output_h);

myPID_c.Compute();                                                  // cooling controller
analogWrite(output_pwm_c, Output_c);

/******************************************************************
/ fan controller                                                  *
/*****************************************************************/

if (Output_c > 0) digitalWrite(output_fan_cool, HIGH);
else digitalWrite(output_fan_cool, LOW);

if (Output_h > 0) digitalWrite(output_fan_heat, HIGH);
else digitalWrite(output_fan_heat, LOW);

/******************************************************************
/ Display setpoint and act. temperature on serial monitor         *
/ (uncomment for debugging in serial monitor)                     *
/*****************************************************************/
/*
Serial.print("Soll: ");
Serial.print(Setpoint);
Serial.println("°C");
Serial.print("Ist : ");
Serial.print(temperature);
Serial.println("°C");
Serial.print("y_h : ");
Serial.println(Output_h);
Serial.print("y_c : ");
Serial.println(Output_c);
Serial.println("");
Serial.println("===================");
Serial.println("");
*/
}


/******************************************************************
/ Get user input for setpoints                                    *
/*****************************************************************/

void clickup() {
   Setpoint+=0.1;
} 

void longPressup() {
  Setpoint++;
} 

void clickdown() {
  Setpoint-=0.1;
} 

void longPressdown() {
  Setpoint--;
}

Du beschreibst in jedem loop-Durchlauf dein LCD komplett neu. Das ist ziemlich ineffektiv und kostet viel Zeit.
Du solltest die Festtexte nur einmal schreiben ( im Setup ) und die Variablen nur dann, wenn sie sich auch tatsächlich geändert haben.

Hi

Ich verstehe Dich nicht.
Wenn man zwischen kurzem und langem Tastendruck unterscheiden will, kann man den Kurzen erst beim Lösen der Taste erkennen - oder den Langen, wenn die Zeit für den Langen um ist.

MfG

Hallo,

MicroBahner:
Du beschreibst in jedem loop-Durchlauf dein LCD komplett neu. Das ist ziemlich ineffektiv und kostet viel Zeit.
Du solltest die Festtexte nur einmal schreiben ( im Setup ) und die Variablen nur dann, wenn sie sich auch tatsächlich geändert haben.

Danke für den Tipp, das werde ich gleich so umsetzen!

postmaster-ino:
Wenn man zwischen kurzem und langem Tastendruck unterscheiden will, kann man den Kurzen erst beim Lösen der Taste erkennen - oder den Langen, wenn die Zeit für den Langen um ist.

Ok, dann habe ich wohl das Beispiel "TwoButtons" der OneButton Library falsch verstanden.

Ich dachte die beiden Funtionen

// This function will be called when the button1 was pressed 1 time (and no 2. button press followed).
void click1() {
  Serial.println("Button 1 click.");
} // click1

und

// This function will be called often, while the button1 is pressed for a long time.
void longPress1() {
  Serial.println("Button 1 longPress...");
} // longPress1

werten das ganze aus. Zumindest wird es im Serial Monitor so dargestellt, wenn ich nur das Beispiel lade.
Wie versteht ihr das?

Danke und liebe Grüße!

Versuch's erst mal mit einfacheren Projekten. Die von Dir angegebenen Funktionen werten nichts aus, sie geben lediglich bei jedem Aufruf den fest einprogrammierten Text aus.

DrDiettrich:
Die von Dir angegebenen Funktionen werten nichts aus, sie geben lediglich bei jedem Aufruf den fest einprogrammierten Text aus.

Kommt drauf an, was man unter 'werten das Ganze aus' versteht. Wenn es darum geht, die Bedienung der Taster auszuwerten, und die unterschiedlichen Arten des Drückens zu erkennen, dann ist das schon so. Wobei die eigentlich Auswertung in der 'tick' Methode gemacht wird, und dann je nach Ergebnis die eine oder die andere Funktion aufgerufen wird. Die 'tick' Methode ist aber darauf angewiesen, dass sie häufig genug aufgerufen wird.

Hallo zusammen!

Danke für die Rückmeldungen!

DrDiettrich:
Versuch's erst mal mit einfacheren Projekten.

Ich gebe zu dass meine "Programmierkünste" eher schlecht als recht sind, deshalb orientiere ich mich an den Beispielcodes und versuche das ganze mit Hilfe von Google und dem stöbern in diversen Foren, an meine Ansprüche anzupassen. Bei den ein oder anderen Feinheiten wirds dann eben spannend. Aber soweit funktiniert mein code ja. =)

DrDiettrich:
Die von Dir angegebenen Funktionen werten nichts aus, sie geben lediglich bei jedem Aufruf den fest einprogrammierten Text aus.

Ja, im Beispielprojekt ist das so.

In Meinem Projekt werden mit

OneButton buttonset_up(12, true);
OneButton buttonset_down(11, true);

die beiden Taster definiert (12 Sollwert + und 11 Sollwert -), mit

buttonset_up.attachClick(clickup);
buttonset_up.attachDuringLongPress(longPressup);
buttonset_down.attachClick(clickdown);
buttonset_down.attachDuringLongPress(longPressdown);

werden die Funktionen "Click" und "LongPress" verlinkt.
Mit

buttonset_up.tick();
buttonset_down.tick();

wird in der Loop überprüft was die Taster machen und dementsprechend werden die Funktionen

void clickup() {
Setpoint+=0.1;
}

void longPressup() {
Setpoint++;
}

void clickdown() {
Setpoint-=0.1;
}

void longPressdown() {
Setpoint--;
}

aufgerufen und der Sollwert geändert. So interpretiere ich den Beispielcode der OneButton Library.

Oder könnte es sein dass die PID Regler die Loop derart bremsen, was dann zu dieser Verzögerung bei
button.tick(); führt?

LG

Oder könnte es sein dass die PID Regler die Loop derart bremsen

Nein.

PID::Compute() wartet nicht, sondern arbeitet zyklisch nach dem WithoutDelay Prinzip.

Aber das requestTemperatures() ...

Schau mal nach setWaitForConversion

Hallo Michael,

michael_x:
Schau mal nach setWaitForConversion

Ich danke dir!!! :grinning:
Das war der entscheidende Hinweis. Nun funktioniert es so wie ich das haben will!

Vielen Dank an alle und bleibt gesund!
LG