Heizbett, arduino geregelt mit Rotary Controller und OLED

Hi Alle,
ich plane eine Vorrichtung zur chemischen Glättung von 3D Druckteilen (FDM aus PLA, ABS).
Dazu brauche ich ein Behältnis, in dem ich Lösemittel auf bestimmte Temperaturen erwärmen kann.
Ich möchte dafür ein Heizbett verwenden, mit dem Rotary Encoder die Zieltemperatur einstellen und am OLED die Ziel- und Isttempetatur anzeigen.
Ich traue es mir zu, die nötigen Codeschnipsel zusammen zu tragen. Aber:
Bevor ich loslege, wollte ich euer Feedback einholen, ob ich etwas übersehen habe oder der Plan aus irgendeinem Grund nicht funktionieren könnte.
Ich habe diese HauptBauteile im
Visier:

arduino nano ( mit 9V batterie)
KY040 rotary encoder
0,9“ OLED
12V 120W Heizbett mit Temp Sensor
12V Netzteil
IRFZ44N MOSFET 49A 55V

Freue mich über eure Kommentare, danke im Voraus,
p

Vergiss die 9V-Batterie. Da Du für die Heizung sowieso ein leistungsfähiges 12V-Netzteil (>= 10 A) brauchst, kannst Du den Nano auch über einen StepDown (auf 9, 7,5 oder 5V) daraus versorgen.

Gruß Tommy

Hallo
Ich würde noch einen Notausschalter vorsehen.

Damit du dein Projekt auch funktionsfähig zusammen bekommst, benötigst du noch eine Lochrasterplatine und geeignetes Kleinmaterial wie Buchsenleisten und Stiftleisten um die jeweiligen Module auf der Platine steckbar zu befestigen.

Vielleicht noch einen Treiber für den IRFZ44?
Der wird mit den 5V vom Nano nicht ganz zufrieden sein.
10-12V sollten es für vollständiges Durchsteuern schon sein...

mfg

Oder gleich einen LogikLevelMosfewt nehmen, z.B. IRLZ44N

Gruß Tommy

OK, ihr seid'S super, danke für eure Inputs.

@Tommy56 und f91w: Ich hab irgendwo einmal aufgeschnappt, dass eine separate Stromquelle vom Heizbett das Messergebnis des Temperatursensors verbessert, hab's aber eh nicht ganz verstanden warum das so sein soll, also danke, werde das mit einem Stepdownmodul machen.

Zum MOSFET: Hab mich kurz eingelesen: Scheint doch nicht so trivial zu sein, wie ich mir das mit dem MOSFET vorgestellt habe. Auf amzn gibts so Treibermodule mit DUAL MOSFETs, so etwas werde ich wohl anschaffen. Die lassen direkt mit dem GPIO des Ardiuno steuern. Die gibts auch mit ausreichend Reserve für mein 120W Heizbett.

Notausschalter werde ich überlegen, vielleicht reicht auch einfach ein gut zugänglicher Hauptschalter vor dem Netzteil.

Kleinteile - habe ich vergessen zu erwähnen - habe ich genug herumliegen. Aber danke für die Erinnerung!

Schau bei den MOSFET-Modulen genau, was für ein Typ da drauf ist. Wenn es kein LogikLevelTyp ist, wird der Dir ohne Zusatzbeschaltung thermisch abrauchen, wenn Du den direkt vom Arduino aus ansteuerst, weil er nicht komplett durchsteuert.

Gruß Tommy

Darf ich hier ein amzn-link posten?
Na egal:
Es ist zweimal ein D4184 BE7B6G verbaut.
Folgenden ich glaube relevanten Wert hab ich herausgefunden:
GATE-Source Threshold Voltage: 1,2-2,5V
In der Beschreibung steht, dasdass mit dem Arduino direkt geht und in den Rezensionen hat jemand ein ähnliches Heizbett, wie ich es einplane, damit betrieben.

Ok, der ist geeignet.

Gruß Tommy

Hi,
ich hatte endlich Zeit, den Sketch zusammen zu basteln.
Ich habe das, wie angekündigt, nur zusammengetragen, das Rad musste ja nicht neu erfunden werden :wink:

Funktioniert soweit, ein paar Kleinigkeiten sind noch nervig:

  1. Jede Änderung am OLED erfordert ein clear(), dadurch flackert das Display bei jeder Bedienung des Rotary encoders.
  2. Der Taster des Rotary encoder spricht nur ca. jedes zweite bis dritte mal an

Trotzdem würd ich euch gern den Code zeigen, und fragen, ob euch etwas ganz negativ auffällt.
Freue mich über jedes Feedback!

/* This sketch controls a heatbed using a 2 point regulator and a fan motor in two speeds. 
 *  A rotary encoder is used to set the target temperature and the fan speed. 
 */
 
#include <U8g2lib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Encoder.h>

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); //initialize OLED


#define ONE_WIRE_BUS 5  // Temperatur data wire is plugged into port 5 on the Arduino
OneWire oneWire(ONE_WIRE_BUS);  // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature. 

// SETUP Pins
const int CLK = 2;      // Definition of Rotary pins. Use interrupt pins! Connect CLK to D2, DT to D3.
const int DT = 3;
const int SW = 4;       // Connect switch to Pin D4.

const int HEATBED = 7; // Define output pin for heating bed
const int MOTOR = 9; // Define output pin for ventilation motor: Use pin for PWM, analogWrite()

// SETUP variables
long oldPos = -999;  // Definition of "old" position for rotary encoder
int target; // target temperature
int hyst = 2; // set total tolerance for target temperature 

int motorstate = 0; //set motor to initial state 0 (OFF). motorstate 1 will be 50%, motorstate 2 100% fanspeed.

Encoder TempControl(DT,CLK);  // create new encoder

void u8g2_prepare() //Setup OLED display
{
  u8g2.setFont(u8g2_font_6x12_mf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}

void setup(void) {

  // Start up the libraries
  sensors.begin();
  u8g2.begin();
  
  u8g2_prepare();
  Serial.begin(9600);
  
  pinMode(SW, INPUT_PULLUP);
  pinMode(MOTOR, OUTPUT);
  pinMode(HEATBED, OUTPUT);
}

void loop(void) {
  
// 1. GET CURRENT TEMPERATURE
sensors.requestTemperatures();  // Send the command to get temperatures

float current = sensors.getTempCByIndex(0); // Use the function ByIndex to get the temperature from the first sensor.

if(current != DEVICE_DISCONNECTED_C)  // Check if reading was successful
  {
    u8g2.setCursor(50, 27); //show current temp on OLED
    u8g2.setFont(u8g2_font_inb16_mf);
    u8g2.print(current);
    Serial.print("Current: ");
    Serial.println(current);
  } 
else
  {
    u8g2.setCursor(50, 27);
    u8g2.setFont(u8g2_font_6x12_mf);
    u8g2.print("Error");
    Serial.println("Error");
  }

// 2. ADJUST TARGET TEMPERATURE

long newPos = TempControl.read()/4;  // Divide by 4 because rotary controller outputs values in steps of 4
newPos = newPos + 20; //Set initial target temp to room temperature

if (newPos != oldPos)  //Check for change of rotary controller
{
  u8g2.clear(); // clear Display, i didn't find any way to clear only a single string
  oldPos = newPos;
}

target = newPos; // assign rotary position to target temperature variable

// 3. Compare temperatures and control heatbed

float upperlimit = target + hyst/2;
float lowerlimit = target - hyst/2;

Serial.print("Upperlimit: ");
Serial.println(upperlimit);
Serial.print("Lowerlimit: ");
Serial.println(lowerlimit);

if (current < lowerlimit) {
  digitalWrite(HEATBED, HIGH);
}
if (current > upperlimit) {
  digitalWrite(HEATBED, LOW);
}
Serial.print("Heatbed: ");
Serial.println(digitalRead(HEATBED));

// 4. ADJUST FAN SPEED IN 2 STEPS

if (digitalRead(SW) == LOW) {
  u8g2.clear(); // clear Display;
  if (motorstate < 2) {
    motorstate++;
  }
  else {
    motorstate = 0;
  }
}

if (motorstate == 0){
  analogWrite(MOTOR, 0);
  Serial.println("MOTOR OFF");
}
else if (motorstate == 1) {
  u8g2.drawRBox(52, 54, 35, 8, 1);
  u8g2.sendBuffer();
  analogWrite(MOTOR, 127);
  Serial.println("MOTOR 50%");
}
else {
  u8g2.drawRBox(52, 54, 70, 8, 1);
  u8g2.sendBuffer();
  analogWrite(MOTOR, 255);
  Serial.println("MOTOR 100%");
}

// 5. Write info on OLED
  u8g2.setCursor(50, 0);
  u8g2.setFont(u8g2_font_inb16_mf);
  u8g2.print(newPos); // write current position on OLED
  u8g2.setFont(u8g2_font_6x12_mf);
  u8g2.setCursor(0, 0);
  u8g2.print("TARGET:");
  u8g2.setCursor(0, 27);
  u8g2.print("CURRENT:");
  u8g2.setCursor(0, 52);
  u8g2.print("MOTOR:");
  u8g2.drawRFrame(50, 52, 74, 12, 3);
  u8g2.sendBuffer();
  delay(100);
  
}

EDIT: Achja, und hier ein Foto vom "UI":

Falsch. Du solltest nur das neu schreiben, was sich geändert hat. Entweder zum Löschen den Bereich mit einem Rechteck in Hintergrundfarbe überschreiben oder den alten Text in Hintergrundfarbe ausgeben.

Gruß Tommy

Hallo,
nimm mal das delay raus , und mach das mit millis() eventuell bekommst Du dann jeden Tasterdruck mit.
Heinz

Hi, danke für die Tips!
Das clear() bin jetzt los, soweit alles gut.
Nur den Taster krieg ich nicht hin, hab jetzt sowas probiert:
Komischerweise ist der Taster unbetätigt auf HIGH, gedrückt liefert er LOW...

/* This sketch controls a heatbed using a 2 point regulator and a fan motor in two speeds. 
 *  A rotary encoder is used to set the target temperature and the fan speed. 
 */
 
#include <U8g2lib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Encoder.h>

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); //initialize OLED


#define ONE_WIRE_BUS 5                // Temperatur data wire is plugged into port 5 on the Arduino
OneWire oneWire(ONE_WIRE_BUS);        // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature. 

// SETUP Pins
const int CLK = 2;     // Definition of Rotary pins. Use interrupt pins! Connect CLK to D2, DT to D3.
const int DT = 3;
const int SW = 4;      // Connect switch to Pin D4.

const int HEATBED = 7; // Define output pin for heating bed
const int MOTOR = 9;   // Define output pin for ventilation motor: Use pin for PWM, analogWrite()

// SETUP variables
long oldPos = -999;  // Definition of "old" position for rotary encoder
int target;          // target temperature
int hyst = 2;        // set total tolerance for target temperature 

int buttonState = HIGH;     // this variable tracks the state of the button, low if not pressed, High if pressed
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers
int motorstate = 0;         // set motor to initial state 0 (OFF). motorstate 1 will be 50%, motorstate 2 100% fanspeed.

Encoder TempControl(DT,CLK);  // create new encoder

void u8g2_prepare()           //Setup OLED display
{
  u8g2.setFont(u8g2_font_6x12_mf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}

void setup(void) {

  // Start up the libraries
  sensors.begin();
  u8g2.begin();
  
  u8g2_prepare();
  Serial.begin(9600);
  
  pinMode(SW, INPUT);
  pinMode(MOTOR, OUTPUT);
  pinMode(HEATBED, OUTPUT);
}

void loop(void) {
  
// 1. GET CURRENT TEMPERATURE
sensors.requestTemperatures();  // Send the command to get temperatures

float current = sensors.getTempCByIndex(0); // Use the function ByIndex to get the temperature from the first sensor.

if(current != DEVICE_DISCONNECTED_C)  // Check if reading was successful
  {
    u8g2.setCursor(50, 27); //show current temp on OLED
    u8g2.setFont(u8g2_font_inb16_mf);
    u8g2.print(current);
    Serial.print("Current: ");
    Serial.println(current);
  } 
else
  {
    u8g2.setCursor(50, 27);
    u8g2.setFont(u8g2_font_6x12_mf);
    u8g2.print("Error");
    Serial.println("Error");
  }

// 2. ADJUST TARGET TEMPERATURE

long newPos = TempControl.read()/4;  // Divide by 4 because rotary controller outputs values in steps of 4
newPos = newPos + 20; //Set initial target temp to room temperature

if (newPos != oldPos)  //Check for change of rotary controller
{
  u8g2.setDrawColor(0); // clear area of target temperature on OLED
  u8g2.drawBox(50, 0, 70, 20);
  oldPos = newPos;
}

target = newPos; // assign rotary position to target temperature variable

// 3. Compare temperatures and control heatbed

float upperlimit = target + hyst/2;
float lowerlimit = target - hyst/2;

Serial.print("Upperlimit: ");
Serial.println(upperlimit);
Serial.print("Lowerlimit: ");
Serial.println(lowerlimit);

if (current < lowerlimit) {
  digitalWrite(HEATBED, HIGH);
}
if (current > upperlimit) {
  digitalWrite(HEATBED, LOW);
}
Serial.print("Heatbed: ");
Serial.println(digitalRead(HEATBED));

// 4. ADJUST FAN SPEED IN 2 STEPS

//sample the state of the button - is it pressed or not?
buttonState = digitalRead(SW);

//filter out any noise by setting a time buffer
if ( (millis() - lastDebounceTime) > debounceDelay) {
  if (buttonState == LOW) {
    if (motorstate < 2) {
    motorstate++;
    }
    else {
    motorstate = 0;
    }
    lastDebounceTime = millis(); //set the current time
  }
}//close if(time buffer)


if (motorstate == 0){
  u8g2.setDrawColor(0);
  u8g2.drawRBox(52, 54, 70, 8, 1);
  analogWrite(MOTOR, 0);
  Serial.println("MOTOR OFF");
}
else if (motorstate == 1) {
  u8g2.setDrawColor(0);
  u8g2.drawRBox(52, 54, 70, 8, 1);
  u8g2.setDrawColor(1);
  u8g2.drawRBox(52, 54, 35, 8, 1);
  u8g2.sendBuffer();
  analogWrite(MOTOR, 127);
  Serial.println("MOTOR 50%");
}
else {
  u8g2.setDrawColor(0);
  u8g2.drawRBox(52, 54, 70, 8, 1);
  u8g2.setDrawColor(1);
  u8g2.drawRBox(52, 54, 70, 8, 1);
  u8g2.sendBuffer();
  analogWrite(MOTOR, 255);
  Serial.println("MOTOR 100%");
}

// 5. Write info on OLED
  u8g2.setDrawColor(1);
  u8g2.setCursor(50, 0);
  u8g2.setFont(u8g2_font_inb16_mf);
  u8g2.print(target); // write current target temperature on OLED
  u8g2.setFont(u8g2_font_6x12_mf);
  u8g2.setCursor(0, 0);
  u8g2.print("TARGET:");
  u8g2.setCursor(0, 27);
  u8g2.print("CURRENT:");
  u8g2.setCursor(0, 52);
  u8g2.print("MOTOR:");
  u8g2.drawRFrame(50, 52, 74, 12, 3);
  u8g2.sendBuffer();  
}

Hallo,
dann schreibe Dir doch mal einen Testsketch bei dem Du nur den Taster abfragst und den dann auf eine LED legst. zusätzlich auf einen Zähler , immer nur einen hochzählen mit jedem drücken.
Heinz

EDIT:
Es ist merkwürdig: Bei einem einfachen Test wie von dir vorgeschlagen funktioniert alles perfekt. Habe den Taster jetzt auch entprellt mit Bounce2. ABER:
Sobald ich das in meinem Sketch umsetze, spricht der Taster nur an, wenn ich ihn länger drücke (ca. 1 sec). Und auch nur, wenn etwas Zeit zwischen den einzelnen Tastendrücken ist, auch ca. 1 sec. Hat jemand noch eine Idee dazu? Es wirkt als ob eine Pause im Sketch jegliche EIngabe verhindert...

Hier der aktuelle Stand, noch besser aufgeräumt:

/* This sketch controls a heatbed using a 2 point regulator and a fan motor in two speeds. 
 *  A rotary encoder is used to set the target temperature and the fan speed. 
 */
 
#include <U8g2lib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Encoder.h>
#include <Bounce2.h>

// SETUP Pins
const int CLK = 2;     // Definition of Rotary pins. Use interrupt pins! Connect CLK to D2, DT to D3.
const int DT = 3;
const int SW = 4;      // Connect switch to Pin D4.

const int HEATBED = 7; // Define output pin for heating bed
const int MOTOR = 9;   // Define output pin for ventilation motor: Use pin for PWM, analogWrite()

// SETUP variables
long oldPos = -999;  // Definition of "old" position for rotary encoder
int target;          // target temperature
int hyst = 2;        // set total tolerance for target temperature 

int motorstate = 0;         // set motor to initial state 0 (OFF). motorstate 1 will be 50%, motorstate 2 100% fanspeed.

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); // initialize OLED

#define ONE_WIRE_BUS 5                // Temperatur data wire is plugged into port 5 on the Arduino
OneWire oneWire(ONE_WIRE_BUS);        // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature. 

Encoder TempControl(DT,CLK);          // create new encoder
Bounce2::Button mySwitch = Bounce2::Button();

void u8g2_prepare()                    // Setup OLED display
{
  u8g2.setFont(u8g2_font_6x12_mf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}

void setup() {

  sensors.begin();
  u8g2.begin();
  Serial.begin(9600);
  
  u8g2_prepare();
  
  pinMode(SW, INPUT);
  pinMode(MOTOR, OUTPUT);
  pinMode(HEATBED, OUTPUT);
  mySwitch.setPressedState(LOW);
  mySwitch.attach(SW);
  mySwitch.interval(10); // 5ms zum Entprellen
}

void loop() {

// 1. GET CURRENT TEMPERATURE
sensors.requestTemperatures();  // Send the command to get temperatures

float current = sensors.getTempCByIndex(0); // Use the function ByIndex to get the temperature from the first sensor.

if(current != DEVICE_DISCONNECTED_C)  // Check if reading was successful
  {
    u8g2.setCursor(50, 27); //show current temp on OLED
    u8g2.setFont(u8g2_font_inb16_mf);
    u8g2.print(current);
  } 
else
  {
    u8g2.setCursor(50, 27);
    u8g2.setFont(u8g2_font_6x12_mf);
    u8g2.print("Error");
    Serial.println("Error");
  }

// 2. ADJUST TARGET TEMPERATURE

long newPos = TempControl.read()/4;  // Divide by 4 because rotary controller outputs values in steps of 4
newPos = newPos + 20; //Set initial target temp to room temperature

if (newPos != oldPos)  //Check for change of rotary controller
{
  u8g2.setDrawColor(0); // clear area of target temperature on OLED
  u8g2.drawBox(50, 0, 70, 20);
  oldPos = newPos;
}

target = newPos; // assign rotary position to target temperature variable

// 3. Compare temperatures and control heatbed

float upperlimit = target + hyst/2;
float lowerlimit = target - hyst/2;

if (current < lowerlimit) {
  digitalWrite(HEATBED, HIGH);
}
if (current > upperlimit) {
  digitalWrite(HEATBED, LOW);
}

// 4. ADJUST FAN SPEED IN 2 STEPS

mySwitch.update();

if (mySwitch.pressed()) {
    if (motorstate < 2) {
    motorstate++;
    }
    else {
    motorstate = 0;
    }
}

if (motorstate == 0){
  u8g2.setDrawColor(0);
  u8g2.drawRBox(52, 54, 70, 8, 1);
  analogWrite(MOTOR, 0);
  Serial.println("MOTOR OFF");
}
else if (motorstate == 1) {
  u8g2.setDrawColor(0);
  u8g2.drawRBox(52, 54, 70, 8, 1);
  u8g2.setDrawColor(1);
  u8g2.drawRBox(52, 54, 35, 8, 1);
  analogWrite(MOTOR, 127);
  Serial.println("MOTOR 50%");
}
else {
  u8g2.setDrawColor(0);
  u8g2.drawRBox(52, 54, 70, 8, 1);
  u8g2.setDrawColor(1);
  u8g2.drawRBox(52, 54, 70, 8, 1);
  analogWrite(MOTOR, 255);
  Serial.println("MOTOR 100%");
}

// 5. Write info on OLED
  u8g2.setDrawColor(1);
  u8g2.setCursor(50, 0);
  u8g2.setFont(u8g2_font_inb16_mf);
  u8g2.print(target); // write current target temperature on OLED
  u8g2.setFont(u8g2_font_6x12_mf);
  u8g2.setCursor(0, 0);
  u8g2.print("TARGET:");
  u8g2.setCursor(0, 27);
  u8g2.print("CURRENT:");
  u8g2.setCursor(0, 52);
  u8g2.print("MOTOR:");
  u8g2.drawRFrame(50, 52, 74, 12, 3);
  u8g2.sendBuffer();  
}

Hallo,
ich denke es liegt daran wie der Temp Sensor eingelesen wird. Du solltest das nicht ständig machen, alle 2 Sekunden reicht doch, zudem ist das nun so der request wird ausgelöst und dann die Abfrage sofort gemacht. Damit wird gewartet bis die Messung erfolgt und die Daten angekommen sind. Das dauert je nach Auflösung gut eine Sekunde. Wenn es schneller sein soll mußt Du mit der Auflösung runter.
Schau dir das Beispiel "waitforconversation" aus der Dallas Lib an da wird gezeigt wie man das asynchron machen kann dann blockiert das nicht mehr.

Heinz

Servus Heinz,
ja vielen dank für deinen Hinweis. Ich habe das derweil auch empirisch festgestellt, einfach mal den Temperaturmessabschnitt auskommentiert und siehe da!
Hab das jetzt auch irgendwie hingekriegt, hier mein Code in Beta Version (muss das ganze ja noch am Gerät selbst testen ) :slight_smile: :

/* This sketch controls a heatbed using a 2 point regulator and a fan motor in three speeds.
    A rotary encoder is used to set the target temperature and the fan speed.
    Version 0.90
*/

#include <U8g2lib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Encoder.h>
#include <Bounce2.h>

// SETUP Pins
const int CLK = 2;     // Definition of Rotary pins. Use interrupt pins! Connect CLK to D2, DT to D3.
const int DT = 3;
const int SW = 4;      // Connect switch to Pin D4.

const int HEATBED = 7; // Define output pin for heating bed
const int MOTOR = 9;   // Define output pin for ventilation motor: Use pin for PWM, analogWrite()

// SETUP variables
long oldPos = -999;  // Definition of "old" position for rotary encoder
int target;          // target temperature
int hyst = 2;        // set total tolerance for target temperature

const int delayTime = 10000; // get Temperature every 10 seconds
unsigned long previousMillis = 0;

int motorstate = 0;         // set motor to initial state 0 (OFF). motorstate 1 will be 33%, 2 66% and 3 100% fanspeed.

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); // initialize OLED

#define ONE_WIRE_BUS 5                // Temperatur data wire is plugged into port 5 on the Arduino
OneWire oneWire(ONE_WIRE_BUS);        // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature.

Encoder TempControl(DT, CLK);         // create new encoder
Bounce2::Button mySwitch = Bounce2::Button();

DeviceAddress Thermometer = { 0x28, 0x76, 0x04, 0x95, 0xF0, 0x01, 0x3C, 0x1F };

void u8g2_prepare()                    // Setup OLED display
{
  u8g2.setFont(u8g2_font_6x12_mf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}

void setup() {

  sensors.begin();
  sensors.setResolution(Thermometer, 4);
  sensors.setWaitForConversion(false);
  u8g2.begin();
  Serial.begin(9600);

  u8g2_prepare();

  pinMode(SW, INPUT);
  pinMode(MOTOR, OUTPUT);
  pinMode(HEATBED, OUTPUT);
  mySwitch.setPressedState(LOW);
  mySwitch.attach(SW);
  mySwitch.interval(5); // 5ms zum Entprellen
}

void loop() {

  // 1. GET CURRENT TEMPERATURE

  if (millis() - previousMillis >= delayTime) {
    previousMillis = millis();
    sensors.requestTemperatures();  // Send the command to get temperatures
  }
  float current = sensors.getTempC(Thermometer); // Use the function ByIndex to get the temperature from the first sensor.


  u8g2.setCursor(50, 27); //show current temp on OLED
  u8g2.setFont(u8g2_font_inb16_mf);
  u8g2.print(current);

  // 2. ADJUST TARGET TEMPERATURE

  long newPos = TempControl.read() / 4; // Divide by 4 because rotary controller outputs values in steps of 4
  newPos = newPos + 20; //Set initial target temp to room temperature

  if (newPos != oldPos)  //Check for change of rotary controller
  {
    u8g2.setDrawColor(0); // clear area of target temperature on OLED
    u8g2.drawBox(50, 0, 70, 20);
    oldPos = newPos;
  }

  target = newPos; // assign rotary position to target temperature variable

  // 3. Compare temperatures and control heatbed

  float upperlimit = target + hyst / 2;
  float lowerlimit = target - hyst / 2;

  if (current < lowerlimit) {
    digitalWrite(HEATBED, HIGH);
  }
  if (current > upperlimit) {
    digitalWrite(HEATBED, LOW);
  }

  // 4. ADJUST FAN SPEED IN 3 STEPS

  mySwitch.update();

  if (mySwitch.pressed()) {
    if (motorstate < 3) {
      motorstate++;
    }
    else {
      motorstate = 0;
    }
  }

  if (motorstate == 0) {
    u8g2.setDrawColor(0);
    u8g2.drawRBox(52, 54, 72, 8, 1);
    analogWrite(MOTOR, 0);
    Serial.println("MOTOR OFF");
  }
  else if (motorstate == 1) {
    u8g2.setDrawColor(1);
    u8g2.drawRBox(52, 54, 24, 8, 1);
    analogWrite(MOTOR, 80);
    Serial.println("MOTOR 33%");
  }
  else if (motorstate == 2) {
    u8g2.setDrawColor(1);
    u8g2.drawRBox(52, 54, 48, 8, 1);
    analogWrite(MOTOR, 160);
    Serial.println("MOTOR 66%");
  }
  else {
    u8g2.setDrawColor(1);
    u8g2.drawRBox(52, 54, 72, 8, 1);
    analogWrite(MOTOR, 240);
    Serial.println("MOTOR 100%");
  }

  // 5. Write info on OLED
  u8g2.setDrawColor(1);
  u8g2.setCursor(50, 0);
  u8g2.setFont(u8g2_font_inb16_mf);
  u8g2.print(target); // write current target temperature on OLED
  u8g2.setFont(u8g2_font_6x12_mf);
  u8g2.setCursor(0, 0);
  u8g2.print("TARGET:");
  u8g2.setCursor(0, 27);
  u8g2.print("CURRENT:");
  u8g2.setCursor(0, 52);
  u8g2.print("MOTOR:");
  u8g2.drawRFrame(50, 52, 76, 12, 3);
  u8g2.sendBuffer();

}

Hallo,
fast !! , nun hast Du allerdings immer dann wenn der Request dran ist eine lange Laufzeit.
Ich hab das Beispiel aus der lib mal ein bisschen umgebaut. Du kannst ja mal versuchsweise die beiden Zeilen waitforConversion auskommentieren um den Unterschied zu sehen.
Heinz

// Basierend auf dem  Beispiel "waitForConversion" aus der DallasTemperatur LIb
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 4
float tempC;
uint32_t altzeit;

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200);
  sensors.begin();
}

void loop() {
  // put your main code here, to run repeatedly:

  if (millis() - altzeit >= 1000) {
    altzeit = millis();
    
    tempC = sensors.getTempCByIndex(0);
    sensors.setWaitForConversion(false);
    sensors.requestTemperatures();
    sensors.setWaitForConversion(true);
    
    Serial.print("Laufzeit ");
    Serial.print(millis()-altzeit); Serial.print('\t');
    Serial.println(tempC);
  }
}

Die Variable float current wird zwar immer gebraucht, das Einlesen sollte aber seltener erfolgen.
Daher muss sie global (oder static) definiert werden.
Am besten als globale Variable einmal in setup() initialisieren und in loop() im delayTime - Zyklus aktualisieren und erst anschließend erneut requestTemperatures() aufrufen.
Die Anzeige muss natürlich auch nicht häufiger laufen als das Messen.