PID Regler legt One Wire Bus lahm

Hallo zusammen,

bin seit einiger Zeit schon stiller Mitleser hier im Forum und nun ist es zum ersten Mal soweit, dass meine Frage nicht bereits von jemanden gestellt wurde(oder ich sie einfach nicht gefunden habe :slight_smile: )

Seit einigen Stunden bin ich am gr√ľbeln und suchen aus welchem Grund mein PID Regler einen davon unabh√§ngigen Temperatursensor(DS18B20) derart st√∂rt, dass der R√ľckgabewert zwischen 0-65¬įC springt.

Der Regler bekommt seinen Input von einem Lux-Sensor(BH1750) und der Output geht auf einen PWM-Ausgang.

Sobald ich den Regler auskommentiere funktioniert der Sensor.

Eine Verk√ľrzung der Samplerate bringt leider auch keine Verbesserung.

Hat jemand schon Erfahrung mit dieser Art Problem?

Besten Dank f√ľr eure Hilfe,

Gr√ľ√üe Reini

Wenn Du uns dann noch Deinen Sketch (in Codetags), Deinen Schaltplan und Links zu Deinen Libs mitteilst, könnte jemand sich damit beschäftigen.
Welchen Arduino benutzt Du?

Gruß Tommy

Wie sollen wir dir helfen, wenn wir deinen Sketch nicht kennen.

Poste den in Code-Tags, dann können wir evtl. deinen Fehler finden.

Solange du alles geheim h√§ltst, m√ľssen wir raten und das willst du sicher nicht.

Ok, ich dachte es gibt vielleicht eine andere Ursache als den Code und wollte mal einfach so fragen :slight_smile:

Hab mal die Codeschnipsel zusammengefasst welche mein Problem betreffen.

Verwendet wird akuell ein Mega, hab das gleiche Problem auch mit einem UNO.

Schaltplan werde ich morgen nachreichen :wink:

Hoffe soweit gen√ľgt das mal :wink:

Danke

#include <Wire.h> // I2C
#include <LiquidCrystal_I2C.h>  //Display
#include <LCDMenuLib2.h>¬† //Men√ľ
#include <DS1302.h>   //RealTimeClock  
#include <EEPROM.h>    //Eeprom
#include <Encoder.h>¬† //Clickencoder Men√ľverwaltung
#include <TimerOne.h> //Interrupt
#include <ClickEncoder.h> //Clickencoder Werteverstellung
#include <OneWire.h> //1-Draht Sensoren
#include <DallasTemperature.h>  //Temperatursensor DS18B20
#include <ErriezBH1750.h> //Luxsensor BH1750
#include <PID_v1.h> //PID Regler
#include <Adafruit_MCP4725.h> // DAC MCP4725


OneWire  tempsens(4);  // on pin 4 (a 4.7K resistor is necessary) Temperatursensor

// *********************************************************************
// Lux Sensor
// *********************************************************************
uint16_t luxInnen;
uint16_t luxAussen;


// *********************************************************************
// Temperatur Sensor
// *********************************************************************
int set_barnOffset = EEPROM.get(21, set_barnOffset);   // den Wert aus EEPROM lesen

// *********************************************************************
// PID Regler
// *********************************************************************
const int PIN_OUTPUT = 5; //PWM LED Pin
double Setpoint, Input, Output;
double Kp=1, Ki=0.2, Kd=0.05; //Reglerfaktoren
double dblLuxInnen;
// *********************************************************************
// Objects
// *********************************************************************
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
DS1302 rtc(8, 12, 10);  // (RST,DAT,CLK) Creation of the Real Time Clock Object
ClickEncoder *encoder;      // Dreh-Enkoder mit Klickbutton
BH1750 HelligkeitInnen(LOW); // ADDR line LOW/open:  I2C address 0x23 (0x46 including R/W bit) [default]
BH1750 HelligkeitAussen(HIGH); // ADDR line HIGH:      I2C address 0x5C (0xB8 including R/W bit)
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); //PID Regler
Adafruit_MCP4725 dac; //DAC




void setup()
{
  Serial.begin(9600);          
  Wire.begin(); // Initialize I2C bus
  lcd.init(); //LCD initialisieren
  lcd.backlight(); //LCD Licht EIN
  
// Lux Sensor * * * * *
HelligkeitInnen.begin(ModeContinuous, ResolutionHigh); // Initialize sensor in continues mode, high 0.5 lx resolution
HelligkeitAussen.begin(ModeContinuous, ResolutionHigh); // Initialize sensor in continues mode, high 0.5 lx resolution
HelligkeitInnen.startConversion(); // Start conversion
HelligkeitAussen.startConversion();// Start conversion



//***************************PID***************************

 //initialize the variables we're linked to
  Input = double(luxInnen/2);
  Setpoint = 80;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  pinMode(PIN_OUTPUT, OUTPUT);
  myPID.SetSampleTime(110);    //Sample Time Regler   



//DAC * * * * * * * * * * * * * * * * * 
dac.begin(0x62); // For Adafruit MCP4725A1 the address is 0x62 (default) or 0x63 (ADDR pin tied to VCC)






void loop()
{
 //PID
  
  dblLuxInnen = double(luxInnen);

  Input = dblLuxInnen/2;
  

  double gap = abs(Setpoint-Input); //distance away from setpoint
 
    
   myPID.SetTunings(Kp, Ki, Kd);
 

   myPID.Compute();
   
   analogWrite(PIN_OUTPUT, Output);

   //PID ENDE


¬†  //DAC - Digital Analog Converter 0-10VDC ANM.: *25 Skalierungsfaktor f√ľr Ausgangsspannung, false: Wert nicht in EEPROM speichern
   dac.setVoltage((uint16_t(Output)*25), false);
  


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Lux Sensor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    if (HelligkeitInnen.isConversionCompleted()) // Wait for completion (blocking busy-wait delay)
    {        
        luxInnen = HelligkeitInnen.read(); // Read light
    }


    if (HelligkeitAussen.isConversionCompleted()) // Wait for completion (blocking busy-wait delay)
    {       
        luxAussen = HelligkeitAussen.read(); // Read light
    }
    


}





// *********************************************************************
void mFunc_temp_barn(uint8_t param)
// *********************************************************************
{
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;
¬† unsigned long barnmillis; //Hilfsvariable f√ľr Tempsens delay
  unsigned long delaytime = 1200;  //Zeit in Millisekunden Tempsens delay
  bool flag_barndelay = LOW;
  
  if(LCDML.FUNC_setup())          // ****** SETUP *********
  { 
    
LCDML.FUNC_disableScreensaver();

barnmillis = millis();
    
  LCDML.FUNC_setLoopInterval(100);  // starts a trigger event for the loop function every 100 milliseconds
  lcd.setCursor(2, 1);                
  lcd.print("Temperatur Stall");        
  lcd.setCursor(6, 2);                
  lcd.print(celsius);   // aktuelle Temperatur
  lcd.setCursor(12, 2);                
¬† lcd.write(223);¬† ¬† ¬†  //223 ¬į-Symbol¬† ¬† ANM.:HD44780U Hitachi char library 
  lcd.setCursor(13, 2);
  lcd.print("C");        
 
  encoder = new ClickEncoder(enc_PinA, enc_PinB, enc_PinC, enc_Step); // den Dreh-Enkoder initialisieren
    Timer1.initialize(1000);                      // den Interrupt-Timer fuer den Dreh-Enkoder initialisieren
    Timer1.attachInterrupt(timerIsr);             // und die Interrupt-Funktion festlegen

  
  
  }

  if(LCDML.FUNC_loop())           // ****** LOOP *********
  {    
ClickEncoder::Button b = encoder->getButton();     // den Button-Status abfragen
    
if ( !tempsens.search(addr)) {
    tempsens.reset_search();
    return;
    }
  
  // the first ROM byte indicates which chip
  switch (addr[0])
  {
    case 0x10:
      type_s = 1;
      break;
    case 0x28:
      type_s = 0;
      break;
    case 0x22:
      type_s = 0;
      break;
    default:
      return;
  } 

  tempsens.reset();
  tempsens.select(addr);
  tempsens.write(0x44, 1);        // start conversion, with parasite power on at the end


  if(millis() > delaytime + barnmillis)     
            { 
            barnmillis = millis();
            flag_barndelay = HIGH;  
            }
 
 
 if(flag_barndelay == HIGH)
 { 
  present = tempsens.reset();
  tempsens.select(addr);    
  tempsens.write(0xBE);         // Read Scratchpad


  for ( i = 0; i < 9; i++) // we need 9 bytes
  {           
    data[i] = tempsens.read();
  }
  
 flag_barndelay = LOW;
 
  
  int16_t raw = (data[1] << 8) | data[0];
  
  if (type_s) 
  {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } 
  else 
  {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  
  celsius = ((float)raw / 16.0)+float(set_barnOffset);
 }
  Serial.println(celsius);
  lcd.setCursor(6, 2);                
  lcd.print(celsius);   // aktuelle Temperatur  
  
  if (b != ClickEncoder::Open) 
           {
              switch (b) 
             {                                 // und entsprechend darauf reagieren
                 case ClickEncoder::Clicked:   // Button wurde einmal angeklickt                  

                  LCDML.FUNC_goBackToMenu();
                  break;
             }   
           }  
  
  }
}

Hab mal die Codeschnipsel zusammengefasst welche mein Problem betreffen.

Hast Du kontrolliert ob der Fehler damit auftaucht.
Gr√ľ√üe Uwe

uwefed:
Hast Du kontrolliert ob der Fehler damit auftaucht.
Gr√ľ√üe Uwe

Hallo, das ist schwer zu sagen, da meine ganze Displayverwaltung in dem Ausschnitt nicht dabei ist.

Mein Code ist auf mehrere Tabs aufgeteilt und mein Gedanke war, dass es nicht √ľbersichtlich ist wenn ich alle Tabs kopiere.

Im ganzen Code werden alle Funktionen nur durch Display Auswahl ausgef√ľhrt.

Ausgenommen die Lichtmessung und der dazugehörige PID Regler.

Prinzipiell ist es richtig das nichts unnötiges uns zu geben. Andererseits sollte der Sketch den Fehler schon aufweisen damit wir ihn findne können.
gr√ľ√üe Uwe

(deleted)

Ok, ich dachte es gibt vielleicht eine andere Ursache als den Code und wollte mal einfach so fragen :slight_smile:

Hab mal die Codeschnipsel zusammengefasst welche mein Problem betreffen.

Verwendet wird akuell ein Mega, hab das gleiche Problem auch mit einem UNO.

Schaltplan werde ich morgen nachreichen :wink:

Hoffe soweit gen√ľgt das mal :wink:

Nein leider √ľberhaupt nicht.
Dein Code ist so nicht lesbar - ok, kann man selber machen, wenn man den in die IDE kopiert.
ABER:
Da fehlt schon die schliessende Klammer zwischen setup() und loop().
Den Sensor fragst Du nur ab, wenn Du im Menu bist.

if (LCDML.FUNC_loop())          // ****** LOOP *********
   {

Wenn Du nur einen DS18B20 nutzt, schmeiss doch den Rest aus dem Examplecode raus.

Das geht besser :wink:

Guten Morgen, Mahlzeit liebe Leute!

Danke f√ľr die bisherigen R√ľckmeldungen.

Da aufgrund meiner etwas durchwachsenen Codeschnipsel einige nicht so erfreut waren, habe ich mein gesamtes Projekt inklusive Schaltplan in *.pdf mal bei GitHub hochgeladen.

https://github.com/BeezLoisbert/Huehnerstall_22_3_2020

liebe Gr√ľ√üe,
Reini