Dansk Elektronik Forum

Generel Elektronik => Arduino & Lign. => Emne startet af: DanFr efter September 23, 2022, 13:54:24

Titel: Gennnemsnit temp.
Indlæg af: DanFr efter September 23, 2022, 13:54:24
Hej.
Jeg har lavet en lille kodning i Arduino som skal styre nogle relæ'er alt efter hvor temperaturen er på min DS18B20 temperatur sensor.
Der SKAL være et relæ trukket hele tiden, så jeg har selvfølgelig lidt problemer med at relæ'erne står og danser frem og tilbage, og det er ikke rigtig godt, jeg kan selvfølgelig give den en høj Delay time, så er det knapt så voldsomt. Skal lige siges at det er en ude temperatur jeg måler

Jeg har læst lidt om at finde gennemsnit forskellige steder, men jeg forstår det ikke rigtigt, jeg er meget ny i denne verden, så måske der var en herinde der kunne hjælpe, Hvis jeg bare kunne få rette mit Sketch, så skal jeg skam nok sidde og nørde med det for at finde ud af hvordan og hvorfor.. Tænker hvis der feks kunne laves 10 målinger og så giver den en gennemsnit værdi, ved ikke om det kan laves så jeg selv kan vælge om der skal være 1 eller 15 sek mellem de 10 målinger? Har lidt svære ved at se mig ud af det.
Den kodning jeg har lavet kan med garanti laves på en helt anden og forenklet måde, men viser jo bare hvor ny jeg er i det. Men kom gerne med input.

Mvh Dan

#include <OneWire.h>
#include <DallasTemperature.h>

float Temp1 = 22.0;
float Temp2 = 24.0;
float Temp3 = 26.0;
float Temp4 = 28.0;
float Temp5 = 30.0;
float Temp6 = 32.0;
float Temp7 = 29.0;
float Temp8 = 30.0;   
float Temp9 = 31.0;

#define ONE_WIRE_BUS 2
#define K101 3
#define K102 4
#define K103 5
#define K104 6
#define K105 7
#define K106 8
#define K107 9
#define K108 10

 
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
 
void setup(void)
{
  Serial.begin(9600);
  pinMode(K101, OUTPUT);
  pinMode(K102, OUTPUT);
  pinMode(K103, OUTPUT);
  pinMode(K104, OUTPUT);
  pinMode(K105, OUTPUT);
  pinMode(K106, OUTPUT);
  pinMode(K107, OUTPUT);
  pinMode(K108, OUTPUT);
   

  sensors.begin();
}
 
void loop(void)
{
  sensors.requestTemperatures();
  float current_temp = sensors.getTempCByIndex(0);
 
  Serial.print("Ude Temperatur: ");
  Serial.println(current_temp);

 
if(current_temp < Temp1)
  {
    digitalWrite(K101, HIGH);
    digitalWrite(K102, LOW);
    digitalWrite(K103, LOW);
    digitalWrite(K104, LOW);
    digitalWrite(K105, LOW);
    digitalWrite(K106, LOW);
   
  }
  if(current_temp >= Temp1)
  {
    digitalWrite(K101, LOW);
    digitalWrite(K102, HIGH);
    digitalWrite(K103, LOW);
    digitalWrite(K104, LOW);
    digitalWrite(K105, LOW);
    digitalWrite(K106, LOW);
   
   }
   if(current_temp >= Temp2)
  {
    digitalWrite(K101, LOW);
    digitalWrite(K102, LOW);
    digitalWrite(K103, HIGH);
    digitalWrite(K104, LOW);
    digitalWrite(K105, LOW);
    digitalWrite(K106, LOW);
   
   }
    if(current_temp >= Temp3)
  {
    digitalWrite(K101, LOW);
    digitalWrite(K102, LOW);
    digitalWrite(K103, LOW);
    digitalWrite(K104, HIGH);
    digitalWrite(K105, LOW);
    digitalWrite(K106, LOW);
     
   }
   if(current_temp >= Temp4)
  {
    digitalWrite(K101, LOW);
    digitalWrite(K102, LOW);
    digitalWrite(K103, LOW);
    digitalWrite(K104, LOW);
    digitalWrite(K105, HIGH);
    digitalWrite(K106, LOW);
     
   }
   if(current_temp >= Temp5)
  {
    digitalWrite(K101, LOW);
    digitalWrite(K102, LOW);
    digitalWrite(K103, LOW);
    digitalWrite(K104, LOW);
    digitalWrite(K105, LOW);
    digitalWrite(K106, HIGH);
     
   } 
   
   
    delay(2000);
  }
Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 23, 2022, 15:58:56
Hej
Du kan sagtens lave noget gennemsnit, men tror ikke det vil hjælpe dig her. Jeg kender DS18B20 og de giver en meget stabil udlæsning. I stedet skal du bruge hysteresis. Desuden tænder og slukker du faktisk udgangene en masser gange. Det går bare så hurtigt at du ikke opdager det  ;). Du skal i stedet overveje at bruge noget "if else". Der er mange måder at gøre det på, men jeg har prøvet lave lidt ændringer i dit kode. Vil ikke garantere at det virker, da jeg ikke har testet det:
#include <OneWire.h>
#include <DallasTemperature.h>

float Temp1 = 22.0;
float Temp2 = 24.0;
float Temp3 = 26.0;
float Temp4 = 28.0;
float Temp5 = 30.0;
float Temp6 = 32.0;
float Temp7 = 29.0;
float Temp8 = 30.0;   
float Temp9 = 31.0;

#define ONE_WIRE_BUS 2
#define K101 3
#define K102 4
#define K103 5
#define K104 6
#define K105 7
#define K106 8
#define K107 9
#define K108 10

// Buffer til opbevaring af værdier mens de behandles
bool K101_buffer = 0;
bool K102_buffer = 0;
bool K103_buffer = 0;
bool K104_buffer = 0;
bool K105_buffer = 0;
bool K106_buffer = 0;

//Værdi der bruges til beregninger:
float current_temp = 0;
float temp_hys = 0.2;//Hysteresis. Prøv at google det. Så står relæerne ikke og danser.

 
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
 
void setup(void)
{
  Serial.begin(9600);
  pinMode(K101, OUTPUT);
  pinMode(K102, OUTPUT);
  pinMode(K103, OUTPUT);
  pinMode(K104, OUTPUT);
  pinMode(K105, OUTPUT);
  pinMode(K106, OUTPUT);
  pinMode(K107, OUTPUT);
  pinMode(K108, OUTPUT);
   

  sensors.begin();
}
 
void loop(void)
{
  sensors.requestTemperatures();
  float current_temp_unhandled = sensors.getTempCByIndex(0);

  Serial.print("Ude Temperatur: ");
  Serial.println(current_temp_unhandled);

    //Bestemmer om temperaturen skal opdateres. Sikre at relæet ikke danser.
    //ABS() tager længden af værdien 10-> 10 og -10 -> 10. Altså fjerner minus fortegn..
    if(abs(current_temp_unhandled-current_temp)>temp_hys){
        current_temp = current_temp_unhandled;
    }else{
        Serial.println("Ingen opdatering af temperatur");
    }
 

    //I udgangspunktet skal de alle være slukket
    K101_buffer = 0;
    K102_buffer = 0;
    K103_buffer = 0;
    K104_buffer = 0;
    K105_buffer = 0;
    K106_buffer = 0;
 

  if(current_temp >= Temp5)
  {
      K106_buffer = 1;
    /*digitalWrite(K101, LOW);
    digitalWrite(K102, HIGH);
    digitalWrite(K103, LOW);
    digitalWrite(K104, LOW);
    digitalWrite(K105, LOW);
    digitalWrite(K106, LOW);*/
   
   }
   else if(current_temp >= Temp4)
  {
      K105_buffer = 1;
    /*digitalWrite(K101, LOW);
    digitalWrite(K102, LOW);
    digitalWrite(K103, HIGH);
    digitalWrite(K104, LOW);
    digitalWrite(K105, LOW);
    digitalWrite(K106, LOW);*/
   
   }
    else if(current_temp >= Temp3)
  {
    K104_buffer = 1;
     
   }
   else if(current_temp >= Temp2)
  {
    K103_buffer = 1;
     
   }
   else if(current_temp >= Temp1)
  {
    K102_buffer = 1;
     
   }else {
       K101_buffer = 1;
   }

   //Sender buffer til pins
   digitalWrite(K101, K101_buffer);
    digitalWrite(K102, K102_buffer);
    digitalWrite(K103, K103_buffer);
    digitalWrite(K104, K104_buffer);
    digitalWrite(K105, K105_buffer);
    digitalWrite(K106, K106_buffer);
   
   
    delay(2000);
  }
Titel: Sv: Gennnemsnit temp.
Indlæg af: Icecap efter September 23, 2022, 20:13:22
Løsningen ser jeg som en grænse + X som ska opnås - men det er grænsen - X som gælder på returen.
Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 23, 2022, 20:57:09
Som svar til Icecap:
Denne funktionalitet fås ved at bruge abs().
Følgende to udsagn vil give det samme:
abs(current_temp_unhandled-current_temp)>temp_hys

abs(current_temp-current_temp_unhandled)>temp_hys

Altså det virker både ved faldende og stigende værdier i forhold til udgangspunktet.
Lige netop den funktionalitet er jo hvad man er interesseret i med en hysterese. Overstående vil kun være sandt hvis den nye værdi variere for meget fra den gamle.
Ny værdi: current_temp_unhandled
Gammel værdi: current_temp
Hysterese: temp_hys

Håber det giver mening

Titel: Sv: Gennnemsnit temp.
Indlæg af: DanFr efter September 24, 2022, 09:31:13
Hej dany8303

Tak for svar, giver meget god mening det du forklare og har lavet, umiddelbart virker det også, synes bare der er noget som ikke passer med mine setpunkter, leger lige lidt med det.
Den ABS værdi du skriver om med -10- hvor har du gemt den henne, den kan ikke lige gennemskue, og hvad den skal bruges til.

Det med den føler DALLAS DS18B20, ser jeg ikke som så stabil som du skriver, den hopper rund med 0,5 til 1 hel grad. og det er alle 4 jeg har prøvet at sætte på(kun en af gangen) prøvet med kort/langt kabelføring osv, det er det samme, føleren ligger pakket ind i en klud, netop så jeg er sikker på at der ikke er pludselige temp udsving. ) Og det skulle være en original DALLAS og ikke en fra Kina.
Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 24, 2022, 09:43:14
Hej Dan

ABS() med 10 var bare et eksempel. Desuden mener jeg også at Dallas biblioteket til Arduino har indbygget CRC kontrol. Det gør at fejlaflæsning ikke skulle kunne opstå i selve kablet til sensoren.

Her er nogle af de udlæsninger som mine sensorer laver. Det er også DS18B20, dog direkte fra Kina. Dem jeg har fået virker ganske fornuftigt.
https://dannerelv.dk/radi/28ae3856b513c6a/2022/266.vlog (https://dannerelv.dk/radi/28ae3856b513c6a/2022/266.vlog)
Titel: Sv: Gennnemsnit temp.
Indlæg af: DanFr efter September 24, 2022, 10:54:25
Hej dani8303
Her har du min udlæsning med 2 sek delay (Føleren sidder ikke ude..!)

Ude Temperatur: 20.44
Ingen opdatering af temperatur
Ude Temperatur: 20.37
Ude Temperatur: 21.12  >> hop på 0,75gr
Ude Temperatur: 21.06
Ingen opdatering af temperatur
Ude Temperatur: 21.00
Ingen opdatering af temperatur
Ude Temperatur: 21.06
Ingen opdatering af temperatur
Ude Temperatur: 21.00
Ingen opdatering af temperatur
Ude Temperatur: 21.00
Ingen opdatering af temperatur
Ude Temperatur: 21.19
Ingen opdatering af temperatur
Ude Temperatur: 20.62  >> drop på 0,57gr og tilbage igen
Ingen opdatering af temperatur
Ude Temperatur: 21.19
Ingen opdatering af temperatur
Ude Temperatur: 21.12
Ingen opdatering af temperatur
Ude Temperatur: 21.19
Ingen opdatering af temperatur
Ude Temperatur: 21.00
Ingen opdatering af temperatur
Ude Temperatur: 20.44  >> drop på 0,68gr
Ude Temperatur: 21.12
Ude Temperatur: 21.06
Ingen opdatering af temperatur
Ude Temperatur: 21.00

Synes det er meget når den ligger på et bord og er pakket ind i et viskestykke, der skulle temperaturen være meget stabil. Nogen ide om hvad det kan være? For det hjælper jo også til at de relæ'er vil stå og danse..
Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 24, 2022, 13:29:36
Hej Dan

Min umiddelbare mistanke er det bibliotek du bruger til DS18b20 vælger der kun skal bruges 9bit opløsning. Herved fås der hurtigere målinger, men også med større udsving. I din kode kan du dog regne gennemsnit, hvorved det nok undgås. Her er et eksempel på hvordan det kan gøres, dog ikke testet:
#include <OneWire.h>
#include <DallasTemperature.h>

float Temp1 = 22.0;
float Temp2 = 24.0;
float Temp3 = 26.0;
float Temp4 = 28.0;
float Temp5 = 30.0;
float Temp6 = 32.0;
float Temp7 = 29.0;
float Temp8 = 30.0;   
float Temp9 = 31.0;

#define ONE_WIRE_BUS 2
#define K101 3
#define K102 4
#define K103 5
#define K104 6
#define K105 7
#define K106 8
#define K107 9
#define K108 10

// Buffer til opbevaring af værdier mens de behandles
bool K101_buffer = 0;
bool K102_buffer = 0;
bool K103_buffer = 0;
bool K104_buffer = 0;
bool K105_buffer = 0;
bool K106_buffer = 0;

//Værdi der bruges til beregninger:
float current_temp = 0;
float temp_hys = 0.2;//Hysteresis. Prøv at google det. Så står relæerne ikke og danser.

//Bruges til gennemsnit
float temp_avg_sum = 0;//Summen der bruges til beregning af gennemsnit
int temp_avg_runs = 0;//Antal beregninger der indgår i gennemsnittet
int Number_of_runs = 10;//Hvor mange målinger der skal udgøre en gennemsnitsberegning

 
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
 
void setup(void)
{
  Serial.begin(9600);
  pinMode(K101, OUTPUT);
  pinMode(K102, OUTPUT);
  pinMode(K103, OUTPUT);
  pinMode(K104, OUTPUT);
  pinMode(K105, OUTPUT);
  pinMode(K106, OUTPUT);
  pinMode(K107, OUTPUT);
  pinMode(K108, OUTPUT);
   

  sensors.begin();
}
 
void loop(void)
{
  if(temp_avg_runs<Number_of_runs){
    sensors.requestTemperatures();
    float current_temp_unhandled += sensors.getTempCByIndex(0);
    temp_avg_sum += current_temp_unhandled;//Lægger den nye måling til den summerede værdi.
    temp_avg_runs++; //Der er blevet tilføjet endnu en måling til den summerede værdi.
    Serial.print("Ude Temperatur: ");
    Serial.println(current_temp_unhandled);
  }else{//Der er nu foretaget nok målinger til at beregne et gennemsnit.

    float temp_avg_unhandled = temp_avg_sum / temp_avg_runs;//Beregner gennemsnit. Summerede værdi delt med antal målinger
    temp_avg_sum = 0;//Nulstiller, så der tages nye målinger næste gang loop køres
    temp_avg_runs = 0;
    //Bestemmer om temperaturen skal opdateres. Sikre at relæet ikke danser.
    //ABS() tager længden af værdien 10-> 10 og -10 -> 10. Altså fjerner minus fortegn..
    if(abs(temp_avg_unhandled-current_temp)>temp_hys){
      current_temp = temp_avg_unhandled;
    }else{
      Serial.println("Ingen opdatering af temperatur");
    }
 

    //I udgangspunktet skal de alle være slukket
    K101_buffer = 0;
    K102_buffer = 0;
    K103_buffer = 0;
    K104_buffer = 0;
    K105_buffer = 0;
    K106_buffer = 0;
 

    if(current_temp >= Temp5)
    {
      K106_buffer = 1;
    }
    else if(current_temp >= Temp4)
    {
      K105_buffer = 1;
    }
    else if(current_temp >= Temp3)
    {
      K104_buffer = 1;
    }
    else if(current_temp >= Temp2)
    {
      K103_buffer = 1;
    }
    else if(current_temp >= Temp1)
    {
      K102_buffer = 1;
    }else {
      K101_buffer = 1;
    }

    //Sender buffer til pins
    digitalWrite(K101, K101_buffer);
    digitalWrite(K102, K102_buffer);
    digitalWrite(K103, K103_buffer);
    digitalWrite(K104, K104_buffer);
    digitalWrite(K105, K105_buffer);
    digitalWrite(K106, K106_buffer);
  }
 
   
   
   
    delay(200);//Sat ned fra 2s til 0,2s, da antal målinger til gennemsnit er 10, hvorved relæerne opdateres med samme hastighed.
  }
Titel: Sv: Gennnemsnit temp.
Indlæg af: DanFr efter September 24, 2022, 14:33:49
Ser spændende ud, det må jeg lige teste og sætte mig ind i et STORT lærestadie.
Stort tak

Du siger det bibliotek jeg bruger, hmm findes der flere slags, skriver man det selv hvis man er hardcore ??

P.S. den kommer med en fejl, kan ikke lige se mig ud af hvad der mangler?
Arduino: 1.8.16 (Windows 10), Board: "Arduino Uno"

C:\Users\dan74\Documents\Arduino\Test_med_GNS\Test_med_GNS.ino: In function 'void loop()':

Test_med_GNS:67:34: error: expected initializer before '+=' token

     float current_temp_unhandled += sensors.getTempCByIndex(0);

                                  ^~

Test_med_GNS:68:21: error: 'current_temp_unhandled' was not declared in this scope

     temp_avg_sum += current_temp_unhandled;//Lægger den nye måling til den summerede værdi.

                     ^~~~~~~~~~~~~~~~~~~~~~

C:\Users\dan74\Documents\Arduino\Test_med_GNS\Test_med_GNS.ino:68:21: note: suggested alternative: 'current_temp'

     temp_avg_sum += current_temp_unhandled;//Lægger den nye måling til den summerede værdi.

                     ^~~~~~~~~~~~~~~~~~~~~~

                     current_temp

exit status 1

expected initializer before '+=' token



This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 24, 2022, 16:24:24
Tror jeg ved hvad fejlen er. Det var ikke meningen der skulle stå += i den linje. Kun =.
Prøv det her:
#include <OneWire.h>
#include <DallasTemperature.h>

float Temp1 = 22.0;
float Temp2 = 24.0;
float Temp3 = 26.0;
float Temp4 = 28.0;
float Temp5 = 30.0;
float Temp6 = 32.0;
float Temp7 = 29.0;
float Temp8 = 30.0;   
float Temp9 = 31.0;

#define ONE_WIRE_BUS 2
#define K101 3
#define K102 4
#define K103 5
#define K104 6
#define K105 7
#define K106 8
#define K107 9
#define K108 10

// Buffer til opbevaring af værdier mens de behandles
bool K101_buffer = 0;
bool K102_buffer = 0;
bool K103_buffer = 0;
bool K104_buffer = 0;
bool K105_buffer = 0;
bool K106_buffer = 0;

//Værdi der bruges til beregninger:
float current_temp = 0;
float temp_hys = 0.2;//Hysteresis. Prøv at google det. Så står relæerne ikke og danser.

//Bruges til gennemsnit
float temp_avg_sum = 0;//Summen der bruges til beregning af gennemsnit
int temp_avg_runs = 0;//Antal beregninger der indgår i gennemsnittet
int Number_of_runs = 10;//Hvor mange målinger der skal udgøre en gennemsnitsberegning

 
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
 
void setup(void)
{
  Serial.begin(9600);
  pinMode(K101, OUTPUT);
  pinMode(K102, OUTPUT);
  pinMode(K103, OUTPUT);
  pinMode(K104, OUTPUT);
  pinMode(K105, OUTPUT);
  pinMode(K106, OUTPUT);
  pinMode(K107, OUTPUT);
  pinMode(K108, OUTPUT);
   

  sensors.begin();
}
 
void loop(void)
{
  if(temp_avg_runs<Number_of_runs){
    sensors.requestTemperatures();
    float current_temp_unhandled = sensors.getTempCByIndex(0);
    temp_avg_sum += current_temp_unhandled;//Lægger den nye måling til den summerede værdi.
    temp_avg_runs++; //Der er blevet tilføjet endnu en måling til den summerede værdi.
    Serial.print("Ude Temperatur: ");
    Serial.println(current_temp_unhandled);
  }else{//Der er nu foretaget nok målinger til at beregne et gennemsnit.

    float temp_avg_unhandled = temp_avg_sum / temp_avg_runs;//Beregner gennemsnit. Summerede værdi delt med antal målinger
    temp_avg_sum = 0;//Nulstiller, så der tages nye målinger næste gang loop køres
    temp_avg_runs = 0;
    //Bestemmer om temperaturen skal opdateres. Sikre at relæet ikke danser.
    //ABS() tager længden af værdien 10-> 10 og -10 -> 10. Altså fjerner minus fortegn..
    if(abs(temp_avg_unhandled-current_temp)>temp_hys){
      current_temp = temp_avg_unhandled;
    }else{
      Serial.println("Ingen opdatering af temperatur");
    }
 

    //I udgangspunktet skal de alle være slukket
    K101_buffer = 0;
    K102_buffer = 0;
    K103_buffer = 0;
    K104_buffer = 0;
    K105_buffer = 0;
    K106_buffer = 0;
 

    if(current_temp >= Temp5)
    {
      K106_buffer = 1;
    }
    else if(current_temp >= Temp4)
    {
      K105_buffer = 1;
    }
    else if(current_temp >= Temp3)
    {
      K104_buffer = 1;
    }
    else if(current_temp >= Temp2)
    {
      K103_buffer = 1;
    }
    else if(current_temp >= Temp1)
    {
      K102_buffer = 1;
    }else {
      K101_buffer = 1;
    }

    //Sender buffer til pins
    digitalWrite(K101, K101_buffer);
    digitalWrite(K102, K102_buffer);
    digitalWrite(K103, K103_buffer);
    digitalWrite(K104, K104_buffer);
    digitalWrite(K105, K105_buffer);
    digitalWrite(K106, K106_buffer);
  }
 
   
   
   
    delay(200);//Sat ned fra 2s til 0,2s, da antal målinger til gennemsnit er 10, hvorved relæerne opdateres med samme hastighed.
  }
Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 24, 2022, 16:50:35
Jeg har haft brugt det her bibliotek:
https://github.com/PaulStoffregen/OneWire

Dog en ældre version. Virker fint på både almindelig arduino(atmega328) og ESP8266.
Titel: Sv: Gennnemsnit temp.
Indlæg af: DanFr efter September 25, 2022, 09:36:17
Hej dani8303

Sidste gang jeg havde min Arduino fremme læste jeg godt noget omkring det bibliotek fra PoulStoffregen.
Altså den løsning med AVG temp fungere jo perfekt, det ser da sådan ud i hvert fald.
Skal lige klippe klister de 2 sidste temperaturer setpunkter ind og fjerne det som ikke bliver brug og tilføje egne noter.
Der er lige 2 ting.

1. >>Jeg har faktisk sat den til 20 målinger med et delay på 1000. Så var det jeg tænkte, for at holde programmet så enkelt som mulig kun det omkring "hys" og "abs" så fjernes, eller hvad tænker du? ( vil selvfølgelig holde "originalen" og lave noter til fremtidig brug)

2. >> ved ikke om det kan lade sig gøre? Men nu kommer den der tekst "Ingen opdatering af temperaturen" Kan den udregnet avg temperatur blive vist og fremhævet, så jeg kan følge med i hvad temp der bliver kigget på  ;D

mvh Dan
Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 25, 2022, 09:59:39
Hej Dan

1.
Ja du kan fjerne det, men gennemsnit løser ikke hele din udfordring. Hvad nu hvis gennemsnit beregnes til 25,99 det ene øjeblik og 26,01 det næste. Herefter så tilbage til 25,99. Når temperaturen står lige på vippen, så vil det stadig kunne give udfordringer, men med 20 målinger og delay 1000, så er sandsynligheden ikke særlig stor. Du kan dog roligt sætte temp_hys længere ned. Eksempelvis 0,05.

2:
Det kan sagtens lade sig gøre. Det synes jeg næsten selv du skal forsøge at ligge ind. Det burde du sagtens kunne finde ud af, ellers så bare skriv.
Titel: Sv: Gennnemsnit temp.
Indlæg af: DanFr efter September 25, 2022, 10:36:55
Ja okay giver meget god mening, jeg sidder jo også bare og påvirker føleren med et fryse element osv. når først den kommer ud, så vil temperaturen ligge meget ens over længere perioder.

Jeg prøver at kigge på det  ;D
Titel: Sv: Gennnemsnit temp.
Indlæg af: DanFr efter September 25, 2022, 12:01:55
Den funktion du har lagt ind med "ingen opdatering af temperaturen" hvad er det den kigger på? Jeg tror det er avg jeg har fået den til at vise, men hænger bare ikke sammen med ingen opdatering af temperaturen

AVG af ude temperatur: 7.65
Ude temperatur: 7.88
Ude temperatur: 7.88
Ude temperatur: 7.88
Ude temperatur: 7.88
Ude temperatur: 7.25
Ingen opdatering af temperatur
AVG af ude temperatur: 7.75
Ude temperatur: 7.19
Ude temperatur: 7.88
Ude temperatur: 7.88
Ude temperatur: 7.88
Ude temperatur: 7.25
Ingen opdatering af temperatur
AVG af ude temperatur: 7.61
Ude temperatur: 7.88
Ude temperatur: 7.31
Ude temperatur: 7.88
Ude temperatur: 7.88
Ude temperatur: 7.88
Ingen opdatering af temperatur
AVG af ude temperatur: 7.76

Ligger lige programmet ind
#include <OneWire.h>
#include <DallasTemperature.h>

float Temp1 = 8.0;
float Temp2 = 9.0;
float Temp3 = 10.0;
float Temp4 = 12.0;
float Temp5 = 13.0;
float Temp6 = 14.0;
float Temp7 = 15.0;
float Temp8 = 30.0;   
float Temp9 = 31.0;

#define ONE_WIRE_BUS 2
#define K101 3
#define K102 4
#define K103 5
#define K104 6
#define K105 7
#define K106 8
#define K107 9
#define K108 10

// Buffer til opbevaring af værdier mens de behandles
bool K101_buffer = 0;
bool K102_buffer = 0;
bool K103_buffer = 0;
bool K104_buffer = 0;
bool K105_buffer = 0;
bool K106_buffer = 0;

//Værdi der bruges til beregninger:
float current_temp = 0;
float temp_hys = 0.2;//Hysteresis. Prøv at google det. Så står relæerne ikke og danser.

//Bruges til gennemsnit
float temp_avg_sum = 0;//Summen der bruges til beregning af gennemsnit
int temp_avg_runs = 0;//Antal beregninger der indgår i gennemsnittet
int Number_of_runs = 5;//Hvor mange målinger der skal udgøre en gennemsnitsberegning

 
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
 
void setup(void)
{
  Serial.begin(9600);
  pinMode(K101, OUTPUT);
  pinMode(K102, OUTPUT);
  pinMode(K103, OUTPUT);
  pinMode(K104, OUTPUT);
  pinMode(K105, OUTPUT);
  pinMode(K106, OUTPUT);
  pinMode(K107, OUTPUT);
  pinMode(K108, OUTPUT);
   

  sensors.begin();
}
 
void loop(void)
{
  if(temp_avg_runs<Number_of_runs){
    sensors.requestTemperatures();
    float current_temp_unhandled = sensors.getTempCByIndex(0);
    temp_avg_sum += current_temp_unhandled;//Lægger den nye måling til den summerede værdi.
    temp_avg_runs++; //Der er blevet tilføjet endnu en måling til den summerede værdi.
    Serial.print("Ude temperatur: ");
    Serial.println(current_temp_unhandled);
  }else{//Der er nu foretaget nok målinger til at beregne et gennemsnit.

    float temp_avg_unhandled = temp_avg_sum / temp_avg_runs;//Beregner gennemsnit. Summerede værdi delt med antal målinger
    temp_avg_sum = 0;//Nulstiller, så der tages nye målinger næste gang loop køres
    temp_avg_runs = 0;
    //Bestemmer om temperaturen skal opdateres. Sikre at relæet ikke danser.
    //ABS() tager længden af værdien 10-> 10 og -10 -> 10. Altså fjerner minus fortegn..
    if(abs(temp_avg_unhandled-current_temp)>temp_hys){
      current_temp = temp_avg_unhandled;
    }else{
      Serial.println("Ingen opdatering af temperatur");
    }
    Serial.print("AVG af ude temperatur: ");
    Serial.println(temp_avg_unhandled);
 

    //I udgangspunktet skal de alle være slukket
    K101_buffer = 0;
    K102_buffer = 0;
    K103_buffer = 0;
    K104_buffer = 0;
    K105_buffer = 0;
    K106_buffer = 0;
 

    if(current_temp < Temp1)
    {
      K101_buffer = 1;
    }
    else if(current_temp < Temp2)
    {
      K102_buffer = 1;
    }
    else if(current_temp < Temp3)
    {
      K103_buffer = 1;
    }
    else if(current_temp < Temp4)
    {
      K104_buffer = 1;
    }
    else if(current_temp < Temp5)
    {
      K105_buffer = 1;
    }
    else if(current_temp < Temp6)
    {
      K106_buffer = 1;
    }else{
      K106_buffer =1;
    }
   
   

    //Sender buffer til pins
    digitalWrite(K101, K101_buffer);
    digitalWrite(K102, K102_buffer);
    digitalWrite(K103, K103_buffer);
    digitalWrite(K104, K104_buffer);
    digitalWrite(K105, K105_buffer);
    digitalWrite(K106, K106_buffer);
  }
 
   
   
   
    delay(200);//Sat ned fra 2s til 0,2s, da antal målinger til gennemsnit er 10, hvorved relæerne opdateres med samme hastighed.




Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 25, 2022, 12:17:33
Haløj Dan

Den kigger på om den nye gennemsnitstemperatur variere for meget fra den tidligere målte, altså overskrider hysteresen. Prøv at udskrive "current_temp" samtidig med. Det er nemlig den relæerne bliver sat efter. Så tror det begynder at give mening 😉.

Hvis "current_temp" er blevet indlæst til 7,65, så skal avg beregnes til minimum 7,86 før at der sker en opdatering. For nedadgående er det 7,44 eller mere den skal variere. Det skyldes netop at hysteresen (temp_hys) er sat til 0,2.

Programmering er rigtigt godt til at sætte de små grå på arbejde😁.
Titel: Sv: Gennnemsnit temp.
Indlæg af: DanFr efter September 25, 2022, 14:42:34
Hej igen..

Ahhh ja det giver menig,  den er da meget rar at have med på serial monitoren også, så kan jeg se hvad der sker. Også fordi det bliver en styring uden display eller lign, så det er den bærebar på hvis jeg skal se eller justere, men skulle i princippet også passe sig selv når først det køre.
Så nu vil jeg finpudse det lidt og få lavet gode noter mens jeg kan huske det.

Måske jeg lige skylder en forklaring på hvad det skal bruges til, og der er nok noget som siger dig et eller andet, fordi vi skrev sammen sidste år med en analog styring af mit fremløb i forhold til ude temp, men jeg er bare ikke dygtig nok, så fandt på noget andet.
Så denne lille styring her, skal forskyde mit 0-10v signal til min shunt, hvert relæ ligger en modstand værdig parallel over 0-10 volt og på den måde snyder jeg den til at vide hvor den er, troede ikke det virkede, men virker faktisk okay.
Der bliver en udgang som ændre setpunktet på brænderen, lidt et sommer og vinter setpunkt, så jeg ikke har så høj temp før shunten når jeg ikke har brug for det i centeralvarmen, 
Og der bliver et relæ som slukker for mit cirkulations pumpe når ude temp, bliver høj nok.

Og det leder mig faktisk til et andet spørgsmål som jeg har glemt alt om.. Hvor store tider kan man arbejde med i Arduino'en.
Fordi jeg kunne godt tænke mig at lave så pumpen bliver masseret jævnligt om sommeren når der ikke er brug for den. 10-15min hver 6 time feks Kan det laves uden ekstra clock mondul eller lign.. Gerne lidt hjælp, har ingen ide om hvor jeg skal starte
Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 25, 2022, 18:59:50
Hej Dan

Så det var hvad det var til.

Angående tider, så kan arduino sagtens håndtere det du efterspørger. Du skal bruge millis(), hvor denne først får overflow efter cirka 50 dage. Her er et eksempel hvor der skrives en linje hver 6 time:
unsigned long lastime = 0;
  unsigned long interval = 1000 * 60 * 60 * 6; //s * min * time * antal timer
  void loop(void){
    if((millis()-lasttime) > interval){
      Serial.println("Der er nu gået 6 timer siden sidst");
      lastime = millis();
    }



  }
Titel: Sv: Gennnemsnit temp.
Indlæg af: DanFr efter September 25, 2022, 19:18:47
Hej..

Yes det er hvad det er til..

Hvad mener du med "overflow efter 50 dage"?

Jeg har siddet lidt i min tømmermænds magt og google'et lidt og var godt kommet frem til at det var noget med millis() der skulle bruges.

Titel: Sv: Gennnemsnit temp.
Indlæg af: DanFr efter September 25, 2022, 19:34:51
Hej igen igen...
Tror faktisk ikke jeg vil lave den timer i koden, men bruge en ekstern cycle timer i stedet. For når først fyrings sæsonen er helt stoppet, så kan jeg tillade mig at slukke for styringen, shunt osv. Pumpen skal cycle konstant så længe der er tændt for hovedafbryderen til fyret 
Titel: Sv: Gennnemsnit temp.
Indlæg af: Icecap efter September 26, 2022, 16:54:24
Arduino har en interrupt som tæller milisekunder. Den er på 32 bit og efter49 dage, 17 timer og 2,788 sekunder ruller den rundt fra 4.294.967.295 til 0.

Hvis man så bruger funktionen "når ms() >= X" og X regnes ud ved "X = ms() + 1000" bliver det prut når man kommer indenfor det sidste sekund.

X skal jo være en 32 bit også og det ovenstående kan betyde at de sidste 999 ms af perioden udløser 999 gange hvor det er rigtigt når der kun skulle være 1.

Den rette <skudsikre> metode er at bruge en timer-interrupt og lade den tælle en variabel ned. Når variablen når nul genlades variablen med værdien for tiden og det som skal ske udføres.

Det kan være en hurtig og enkel funktion og den kan så køres direkte fra interruptrutinen.

Er det en mere kompliceret funktion sætter interruptrutinen et flag og main-loop kan have en "hvis flag er sat: nulstil flag og gør kompliceret rutine".
Titel: Sv: Gennnemsnit temp.
Indlæg af: dani8303 efter September 26, 2022, 17:29:24
Lige en lille sidenote Icecap, så kan det øverste kode du foreslår godt give problemer. Du risikere nemlig at det ikke virker efter de cirka 50 dage. Det er lidt langhåret at forklare, men hvad nu hvis X beregnes til 4.294.967.295. Dermed findes der ikke noget tal større, hvormed koden aldrig vil blive aktiveret igen.

Prøv at læse denne artikel: https://www.norwegiancreations.com/2018/10/arduino-tutorial-avoiding-the-overflow-issue-when-using-millis-and-micros/ (https://www.norwegiancreations.com/2018/10/arduino-tutorial-avoiding-the-overflow-issue-when-using-millis-and-micros/)

Det har jeg nemlig haft fundet ud af på den trælse måde :o.

Og ja der er mange måder at lave det på  ;). Det kode til tidshåndtering jeg sendte tidligere kører dog ganske fortræffeligt. Har det til at kører på flere ESP8266, hvor flere af disse har kørt adskillige måneder uden problemer :D.
Titel: Sv: Gennnemsnit temp.
Indlæg af: Icecap efter September 26, 2022, 22:59:39
Helt enig. Arduino er i min mening færdigtygget børnemad på dåse, ingen smag - men enkel at bruge.

Opbygningen af funktionerne er gjort sådan at det er let at komme i gang men meget svært at faktisk tage sig ud af skidtet.

Men jeg har så også levet af at udvikle løsninger med mikroprocessorer i omkring 40 år så jeg har nok en anden vinkel ind.