duinozone.cz - Arduino a Raspberry fórum

Autor Téma: Nastavnie hysterezi na spinanie rele  (Přečteno 5482 krát)

Offline drawtt

  • Bastlíř začátečník
  • *
  • Příspěvků: 48
Nastavnie hysterezi na spinanie rele
« kdy: Prosinec 24, 2016, 11:03:28 dopoledne »
Dobrý deň
priatelia vedel by mi niekto poradiť, ako vytvoriť podmienku pre moj stávajúci kód v arduinu.

Jedná sa o dvojitý snímač teploty postavený na arduino mega, 2x čidlo dallas temperature, jedno kanálové relé a pripojený liquid cristal cez i2c.
všetko mi funguje , na displeji sa mi ukazujú v pravej časti hore teplota kotla, pod nou dole v druhom riadku teplota nádrže.na lavej strane v hornom riadku svieti nápis rele a v spodnom lavom rohu by mlo prepinať  nápis ON  a OFF podľa toho či je spustene rele.
a problém je že neviem nastaviť podmienku kde je vyhodnotená  prvá teplota teda UK  a tá je porovnávaná pokiaľ je vyššia, ako 25 st C zopne relé a spustí čerpadlo , pokiaľ je nižšia ako 22 st C vypne čerpadlo no a tu som sa zacyklil už nad tým koumám 2 dni a  nie a nie to spustiť.
vedeli by ste mi poradiť kde je chyba ?

tu je celý kód :




/*

/*-----( Import needed libraries )-----*/

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

/*-----( Declare Constants and Pin Numbers )-----*/
// Data wire is plugged into port 10 on the Arduino (can be changed)
#define ONE_WIRE_BUS 2    // NOTE: No ";" on #define 



//#define  LED_OFF  0
//#define  LED_ON  1
int relay =8;
/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass address of our oneWire instance to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Start the LCD display library
//LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7); // 0x27 0x3F is the default I2C bus address of the backpack-see article
/*-----( Declare Variables )-----*/
// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://arduino-info.wikispaces.com/Brick-Temperature-DS18B20#Read%20individual


 // WP 1
DeviceAddress Probe01 = { 0x28, 0xFF, 0xAF, 0x77, 0x55, 0x16, 0x03, 0xD0 }; // "4"      28 FF AF 77 55 16 3 D0
DeviceAddress Probe02 = { 0x28, 0xFF, 0xAE, 0x2A, 0x55, 0x16, 0x03, 0x58 }; // "5"      28 FF AE 2A 55 16 3 58
//DeviceAddress Probe03 = { 0x28, 0x9A, 0x80, 0x40, 0x04, 0x00, 0x00, 0xD5 }; // "4" Again for test
//DeviceAddress Probe04 = { 0x28, 0x10, 0xA4, 0x57, 0x04, 0x00, 0x00, 0xA9 };


void setup()   /****** SETUP: RUNS ONCE ******/
{
//------- Initialize the Temperature measurement library--------------
  sensors.begin();
  // set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
  sensors.setResolution(Probe01, 10);
  sensors.setResolution(Probe02, 10);
 // sensors.setResolution(Probe03, 10);
 // sensors.setResolution(Probe04, 10);

//---------------- Initialize the lcd ------------------ 
       lcd.begin (16,2); // 16 x 2 LCD module
       lcd.setBacklightPin(3,POSITIVE); // BL, BL_POL
       lcd.setBacklight(HIGH);


  pinMode(8, OUTPUT); //slovensky: nastav rele pin 8 ako výstup
}
void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  sensors.requestTemperatures(); // Send the command to get temperatures

 
 

  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print("UK:");
  displayTemperature(Probe01); 
  lcd.println("*C");
 

 

 
  lcd.setCursor(0,1); //Start at character 0 on line 1
  lcd.print("AN:");
  displayTemperature(Probe02);
  lcd.println("*C");
 
  lcd.setCursor(10,0); //Start at character 0 on line 1
  lcd.print(" RELE ");
 
 
  lcd.setCursor(10,1); // TO LEN ZATIAL AZ BUDE PODMIENKA POTOM VYMAZAT
  lcd.print("  OFF ");
 
 
 
  //lcd.setCursor(0,2); //Start at character 0 on line 2
  //lcd.print("3: ");
  //displayTemperature(Probe03); 
 
  //lcd.setCursor(0,3); //Start at character 0 on line 3
  //lcd.print("4: ");
  //displayTemperature(Probe04); 
 
  delay(2000);

}//--(end main loop )---

/*-----( Declare User-written Functions )-----*/
void displayTemperature(DeviceAddress deviceAddress)
{

float tempC = sensors.getTempC(deviceAddress);

//----------------------------------------------------------------------------------------------------------------------------
  //TU JE PROBLÉM

        //toto neviem nastavit        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!                     
        //if (Probe01 >25);
        //  digitalWrite(8,HIGH);
        // if (Probe01 < 23);
       //   digitalWrite(8,LOW);
//-----------------------------------------------------------------------------------------------------------------------------
   if (tempC == -127.00) // Measurement failed or no device found
   {
    lcd.print("CHYBA");
   }
   else
   {
   //lcd.print("C=");
   lcd.print(tempC);
   //lcd.print(" F=");
   //lcd.print(DallasTemperature::toFahrenheit(tempC)); // Convert to F
   }
}// End printTemperature

//*********( THE END )***********

« Poslední změna: Prosinec 24, 2016, 11:05:04 dopoledne od drawtt »

Offline astromik

  • Pokročilý bastlíř
  • ***
  • Příspěvků: 115
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #1 kdy: Prosinec 24, 2016, 12:26:00 odpoledne »
Jestli to správně chápu, tak "Probe01" je adresa čidla, ale ty potřebuješ testovat hodnotu teploty, takže proměnnou "tempC".

A to vyhodnocování bych dal až do té části podmínky, kdy je jisté, že je teplota v pořádku.

Zkusil bych tu zobrazovací část upravit takto:


Kód: [Vybrat]
.
.
.
.

   float tempC = sensors.getTempC(deviceAddress);

   if (tempC == -127.00) // Measurement failed or no device found
   {
    lcd.print("CHYBA");
   }
   else  // kdyz je teplota v poradku ...
   {
    // ... vyhodnoceni teploty s hysterezi a sepnuti rele
      if (deviceAddress == Probe01)   // rele se ovlada pouze v pripade, ze se jedna o teplotu z cidla UK
        {
          if (tempC >25)  digitalWrite(8,HIGH);
          if (tempC <23)  digitalWrite(8,LOW);
        }


   //lcd.print("C=");
   lcd.print(tempC);
   //lcd.print(" F=");
   //lcd.print(DallasTemperature::toFahrenheit(tempC)); // Convert to F
   }
.
.
.
.


EDIT:
Až teď jsem si všimnul, že tam jsou teploměry dva, takže ta moje původní úprava by vyhodnocovala obě teploty zároveň.
Takže to chce ještě ošetřit tak, aby se relé ovládalo jen v případě, že adresa čidla bude "Probe01".

« Poslední změna: Prosinec 24, 2016, 12:37:14 odpoledne od astromik »

Offline drawtt

  • Bastlíř začátečník
  • *
  • Příspěvků: 48
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #2 kdy: Prosinec 24, 2016, 12:47:45 odpoledne »
ano su tam dva probe 01 a probe 02 , 3 a 4 su vyradene  lebo to je iný okruh  . a ja potrebujem len probe 01 lebo ked  som to aj rozchodil vcera prave to to robilo ze  vyhodnocovalo obe cidla a relé cyklovalo

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #3 kdy: Prosinec 24, 2016, 13:00:40 odpoledne »
a v čem má to tvoje řešení problém?
Jen bych v Setup() přednastavil pin 8 na LOW jako výchozí hodnota a je to .
Podle toho co máš za požadavek tak by to mělo fungovat.  jak píšeš tak by to mělo při > 25 st sepnout a při < 22 st vypnout a to máš.
V čem je problém?

Offline drawtt

  • Bastlíř začátečník
  • *
  • Příspěvků: 48
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #4 kdy: Prosinec 24, 2016, 13:05:02 odpoledne »
Práve som to nahral je to perfektne  velmi pekne dakujem  a uz vidim kde somm robil chybu , no co zaciatocník

if (deviceAddress == Probe01)  presne tu  som dával len jedno =  alebo Probe01 do zátvoriek

este raz dakujem 100%  :)

Offline drawtt

  • Bastlíř začátečník
  • *
  • Příspěvků: 48
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #5 kdy: Prosinec 24, 2016, 13:09:46 odpoledne »
Este jedna podotázka  :)

keby som chcel teplotu spínania nastavovat tlacídlami , aky by bol postup ? lebo mam aj tlacidlovy LCD
jedna sa o to ze ked by som chcel napr nastavit vyssiu teplotu aby som nemusel  znovu pripájat arduino k pc ale len tlacidlom ho nastiskat a teda bud tym co mam na inom displeji ze by som prehopdil displeje, alebo k tomuto funkcnemu kodu dopisat co je potreba .





« Poslední změna: Prosinec 24, 2016, 13:59:21 odpoledne od drawtt »

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #6 kdy: Prosinec 24, 2016, 13:51:24 odpoledne »
musel bys vytvořit menu a do eeprom si ukládát aktuální hodnoty.
S menu by ti mohlo pomoci toto:
http://posjirka.pise.cz/arduino/122016/

Jinak bych to spíš řešil pomocí trimrů. Těmi bys na analogových vstupech nastavoval hodnotu (teplotu) a při každé smyčce Loop() by sis změřil kolik je nastavena a na to reagoval.
Je to jednoduché, elegantní řešení bez menu a eeprom. Přtom snadno nastavitelné. Ještě je pak 2 varianty a to použití digitálního pinu pro měření analogové hodnoty, ale je to takové ... no zvláštní:
http://gcbasic.sourceforge.net/help/output/html5/images/potb1.JPG
prostě použije Trimr a kondenzátor, seriově mezi pin azem. Pam pin nechá dost dlouhou dobu v log.0 (aby se vybil kondenzátor) a pak čekáš za jak dlouho se nabije. No a ta doba = nastavení trimru.
nebo použít multipex:
http://electronics.stackexchange.com/questions/67004/how-do-i-extend-the-number-of-analog-input-pins-available-to-me

Offline drawtt

  • Bastlíř začátečník
  • *
  • Příspěvků: 48
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #7 kdy: Prosinec 24, 2016, 14:00:36 odpoledne »
No to budem teda skusat cez sviatky  :)

este by som tam chcel doplnit  vypisovanie stavu ON OFF  rele na iných kodoch mi to ide a tuto to  vymaže *C a neprepne to hlasku kde robim chybu ?

  // ... vyhodnoceni teploty s hysterezi a sepnuti rele
      if (deviceAddress == Probe01)   // rele se ovlada pouze v pripade, ze se jedna o teplotu z cidla UK
        {
          if (tempC >25)  digitalWrite(8,HIGH);
          lcd.setCursor(10,1);
          lcd.print("  ON ");         
          if (tempC <23)  digitalWrite(8,LOW);
          lcd.setCursor(10,1);
          lcd.print("  OFF ");
        }
       
   }
}// End printTemperature

//*********( THE END )***********

Offline drawtt

  • Bastlíř začátečník
  • *
  • Příspěvků: 48
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #8 kdy: Prosinec 24, 2016, 14:06:23 odpoledne »
https://www.youtube.com/watch?v=peI-ZczdzxU

toto mam kod z jednym cidlom  tam to je vidiet ako mi to prepina  na lcd
v tomto
je :
UK 22.25*C   RELE
AN 25.25.*C    OFF/ON
takto by to malo vyzerat
« Poslední změna: Prosinec 24, 2016, 14:09:27 odpoledne od drawtt »

Offline astromik

  • Pokročilý bastlíř
  • ***
  • Příspěvků: 115
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #9 kdy: Prosinec 24, 2016, 18:02:51 odpoledne »
Pokud za podmínkou IF následuje jen jeden příkaz, je možné ho zapsat přímo za tu podmínku.
Když je ale za IF více příkazů, musí se spojit do bloku a uzavřít složenými závorkami:
Kód: [Vybrat]
  // ... vyhodnoceni teploty s hysterezi a sepnuti rele
      if (deviceAddress == Probe01)   // rele se ovlada pouze v pripade, ze se jedna o teplotu z cidla UK
        {

          if (tempC >25)
            {
               digitalWrite(8,HIGH);
               lcd.setCursor(10,1);
               lcd.print("  ON ");         
            }         

         if (tempC <23)
           {
             digitalWrite(8,LOW);
             lcd.setCursor(10,1);
             lcd.print("  OFF ");
           }

        }
       
   }
}// End printTemperature

//*********( THE END )***********

Offline drawtt

  • Bastlíř začátečník
  • *
  • Příspěvků: 48
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #10 kdy: Prosinec 24, 2016, 21:59:04 odpoledne »
dakujem funguje to
akurat   v tom spodnom  riadku kde je off a on  su dve policka vyciarkane
AN:36.00*C-- on  TAM KDE SU TIE DVE CIARKY JE ICH V KAZDOM POLICKU 4KS TO JE ZREJME TREBA POSUNUT  NEJAKE POLE.
ALE INAK VELMI DAKUJEM SLAPE TO  OK

Offline K.K

  • Bastlíř amatér
  • **
  • Příspěvků: 79
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #11 kdy: Prosinec 25, 2016, 21:32:17 odpoledne »
Pokud za podmínkou IF následuje jen jeden příkaz, je možné ho zapsat přímo za tu podmínku.
Když je ale za IF více příkazů, musí se spojit do bloku a uzavřít složenými závorkami:
Když jsem začinal,dlouho jsem řešíl problem vyhodnocovaní vice podminek u řizení kotlu.
Nakonec vyhrako deklarace pole.
Pole třeba pro 10 podminek.
Do ních ukladam info 0-1.
Převedu na string  a mam třeba 001011000
A pak jen hazim podminky  ;D
Primitivni, jednoduche a posilam si to přes ser. port do rasi.

« Poslední změna: Prosinec 25, 2016, 21:34:17 odpoledne od K.K »

Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #12 kdy: Prosinec 25, 2016, 22:53:45 odpoledne »
já místo pole používám proměnnou "chyby" jsko byte a měním přímo jednotlivé bite.
šetřím místo v RAM :)

Offline drawtt

  • Bastlíř začátečník
  • *
  • Příspěvků: 48
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #13 kdy: Prosinec 26, 2016, 07:02:07 dopoledne »
Priatelia tak teraz  sa  vo  vašej reči načisto strácam, upozorňujem zo som  čo sa týka Arduina  začiatočník a k práci s ním ma priviedla potreba digitalizácie kotolne , ktorá je teraz analógová. Teda klasické termostaty a relé. Takže ja ju prerábam trojokruhovo , prvý okruh je tento čo tu riešime , druhý bude zložitejší  bude priebežne ovládať 8 kanálové relé a tretí solárny kolektor. To len  aby som objasnil prečo Arduino.
Teraz ku kódu.
Priznám sa že len hmlisto mi  niečo hovorí čo tu  výš popisujete v posledných dvoch príspevkoch  zobrazovania na displeji. Mne by to zrejme pomohlo v reálnom kóde . tak sa mi to lepšie chápe  .
Takže : na displej  má svietiť v prvom riadku :
UK:22,25*C_RELE_

V druhom riadku :
AN:22,25*C__OFF_
Alebo
AN:22,25*C___ON_
Podľa toho ci je zapnuté relé na základe podmienky .

No po nahratí kódu s podmienkou  to robí nasledovne :
V prvom riadku  sa stratia *C 
V druhom riadku  sa stratia *C , pribudnú tam dva čiarkové znaky  a za OFF alebo ON sa objaví  *C

No a nakoniec keď  napríklad ide relé teda teplota je vyššia , ako podmienka a vypnem a zapnem Arduino / vytiahnem, z PC usb /  tak displej nabehne , všetko ukazuje okrem  situácie čo vykonáva relé teda ON tam nesvieti , zapne až OFF keď skončí podmienka , inak je tam čisto.
Pokiaľ relé stoji a je OFF tak displej po vypnutí Arduina nabehne normálne.
Tak by som chcel teda ešte raz poprosiť či  by sa nedal priamo poopraviť tento môj kód  aby fungoval a ja si tam aj mrknem , že kde robím chybu  .
Tu je aktuálny kód :

/*

/*-----( Import needed libraries )-----*/

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

/*-----( Declare Constants and Pin Numbers )-----*/
// Data wire is plugged into port 10 on the Arduino (can be changed)
#define ONE_WIRE_BUS 2    // NOTE: No ";" on #define 



//#define  LED_OFF  0
//#define  LED_ON  1
int relay =8;
/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass address of our oneWire instance to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Start the LCD display library
//LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7); // 0x27 0x3F is the default I2C bus address of the backpack-see article
/*-----( Declare Variables )-----*/
// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://arduino-info.wikispaces.com/Brick-Temperature-DS18B20#Read%20individual


 // WP 1
DeviceAddress Probe01 = { 0x28, 0xFF, 0xAF, 0x77, 0x55, 0x16, 0x03, 0xD0 }; // "4"      28 FF AF 77 55 16 3 D0
DeviceAddress Probe02 = { 0x28, 0xFF, 0xAE, 0x2A, 0x55, 0x16, 0x03, 0x58 }; // "5"      28 FF AE 2A 55 16 3 58
//DeviceAddress Probe03 = { 0x28, 0x9A, 0x80, 0x40, 0x04, 0x00, 0x00, 0xD5 }; // "tu zadavame mac adresu cidla
//DeviceAddress Probe04 = { 0x28, 0x10, 0xA4, 0x57, 0x04, 0x00, 0x00, 0xA9 };


void setup()   /****** SETUP: RUNS ONCE ******/
{
//------- Initialize the Temperature measurement library--------------
  sensors.begin();
  //  tu nastavuj rozlíšenie na 10 bitov (Môže byť 9 až 12 bitov .. menšia je rýchlejší)
  sensors.setResolution(Probe01, 10);
  sensors.setResolution(Probe02, 10);
 // sensors.setResolution(Probe03, 10);
 // sensors.setResolution(Probe04, 10);

//---------------- Initialize the lcd ------------------ 
       lcd.begin (16,2); // 16 x 2 LCD module
       lcd.setBacklightPin(3,POSITIVE); // BL, BL_POL
       lcd.setBacklight(HIGH);


  pinMode(8, OUTPUT); //slovensky: nastav rele pin 8 ako výstup
}
void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  sensors.requestTemperatures(); // Posiela príkaz na získaie teplot

   
  lcd.setCursor(0,0); //prve cidlo funkcne
  lcd.print("UK: ");
  displayTemperature(Probe01);
  lcd.println("*C");             
 
   
  lcd.setCursor(0,1); //druhe cidlo funkcne
  lcd.print("AN: ");
  displayTemperature(Probe02);
  lcd.println("*C");
 
  lcd.setCursor(10,0); //nápis  v pravom hornom rohu
  lcd.print(" RELE ");
 
 
 //lcd.setCursor(10,1); // TO LEN ZATIAL AZ BUDE PODMIENKA POTOM VYMAZAT
 //lcd.print("   ON ");
 
 
 
  //lcd.setCursor(0,2); //tretie  cidlo zatial ostavene
  //lcd.print("3: ");
  //displayTemperature(Probe03); 
 
  //lcd.setCursor(0,3); //stvrte cidlo zatial odstavene
  //lcd.print("4: ");
  //displayTemperature(Probe04); 
 
  delay(2000);

}//--(end main loop )---

/*-----( Declare User-written Functions )-----*/
void displayTemperature(DeviceAddress deviceAddress)
{

float tempC = sensors.getTempC(deviceAddress);


   if (tempC == -127.00) // Meranie zlyhalo alebo  sa zariadenie nenašlo
   {
    lcd.print("CHYBA");
   }
   else
   {
   //lcd.print("C=");
   lcd.print(tempC);
   

    // ... vyhodnoceni teploty s hysterezi a sepnuti rele
     if (deviceAddress == Probe01)   // rele se ovlada pouze v pripade, ze se jedna o teplotu z cidla UK
        {

          if (tempC >25)
            {
               digitalWrite(8,HIGH);
               lcd.setCursor(10,1);
               lcd.print("  ON ");         
            }         

         if (tempC <23)
           {
             digitalWrite(8,LOW);
             lcd.setCursor(10,1);
             lcd.print("  OFF ");
           }

        }
       
   }
}// End printTemperature

//*********( THE END )***********





Offline posjirka

  • Zkušený bastlíř
  • ****
  • Příspěvků: 433
Re:Nastavnie hysterezi na spinanie rele
« Odpověď #14 kdy: Prosinec 26, 2016, 11:18:01 dopoledne »
to mizení *C:
máš chybu v kodu. nepatří tam
Kód: [Vybrat]
lcd.println("*C");    ale
Kód: [Vybrat]
lcd.print("*C");   
indikace sepnutí / vypnutí rele bych vyřešil pomocí znaku 0 nebo 1.Proč? protože ho můžeš číst z pinu a přímo zobrazovat.
Celé menu bych vyřešil tak, že by se ti automaticky třeba po 5s přepínali obrazovky pro jednotlivé okruhy a tlačítkem by ses mohl posunou o obrazovku dal.