• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Sterownik do akwarium by Tedy24
#1
Witam wszystkich. Piszę tutaj ponieważ po dwutygodniowych wertowaniach internetu nie mogę rozwiązać swojego problemu. Jak pisałem w powitaniu robię sterownik do akwarium.  Niestety mam problem. 
Kod programu zawiera menu z poziomu którego chciałbym włączać lub wyłączać dane elementy pokrywy tj. wentylatory i oświetlenie, ale także zawiera opcję AUTO w której to wentylatory będą załączane tylko wtedy gdy temperatura przekroczy zadaną wartość. Niestety nie umiem sobie poradzić z opcją AUTO . Umiem zrobić, że zczytuje temperaturę i załącza dane sekcje wentylatorów ale wtedy nie mogę ich wyłączyć tak aby nie włączały się wcale lub włączyć tak aby działały cały czas. 

Może ktoś z Was będzie wiedział jak pomóc mi w moim problemie. Wiem mój kod nie należy do najpiękniejszych. W większości gdy go pisałem posiłkowałem się tym co jest w internecie. Przyznaję się w C++ jestem laikiem. Miałem to kiedyś w liceum i na studiach ale uleciało mi to z głowy  Big Grin
Poniżej kod programu. 


Kod:
#include <MenuBackend.h>    //MenuBackend library - copyright by Alexander Brevig
#include <LiquidCrystal_I2C.h> //this library is included in the Arduino IDE
#include <Wire.h> 
#include <IRremote.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
#define wentylewy 8
#define wentylprawy 7
#define wentprzodlewy 6
#define wentprzodprawy 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C lcd(0x27, 2,1,0,4,5,6,7);
int RECV_PIN = 3;//pilot
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean stan=0;//pilot
const int lamptyl = 4;
const int lamprzod = 9;

//Menu variables
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems
    
    MenuItem menu1Item1 = MenuItem("1. Chlodzenie     ");
    
         MenuItem menuItem1SubItem1 = MenuItem("1.1 Tyl lewy        ");
               MenuItem menuItem1SubItem1Item1 = MenuItem("1.1.1 ON      ");
               MenuItem menuItem1SubItem1Item2 = MenuItem("1.1.2 OFF      ");
               MenuItem menuItem1SubItem1Item3 = MenuItem("1.1.3 AUTO      ");
    
         MenuItem menuItem1SubItem2 = MenuItem("1.2 Tyl prawy       ");
               MenuItem menuItem1SubItem2Item1 = MenuItem("1.2.1 ON      ");
               MenuItem menuItem1SubItem2Item2 = MenuItem("1.2.2 OFF      ");
               MenuItem menuItem1SubItem2Item3 = MenuItem("1.2.3 AUTO      ");
               
         MenuItem menuItem1SubItem3 = MenuItem("1.3 Przod lewy        ");
               MenuItem menuItem1SubItem3Item1 = MenuItem("1.3.1 ON      ");
               MenuItem menuItem1SubItem3Item2 = MenuItem("1.3.2 OFF      ");
               MenuItem menuItem1SubItem3Item3 = MenuItem("1.3.3 AUTO      ");
    
         MenuItem menuItem1SubItem4 = MenuItem("1.4 Przod prawy     ");
               MenuItem menuItem1SubItem4Item1 = MenuItem("1.4.1 ON       ");
               MenuItem menuItem1SubItem4Item2 = MenuItem("1.4.2 OFF      ");
               MenuItem menuItem1SubItem4Item3 = MenuItem("1.4.3 AUTO      ");
    
    MenuItem menu1Item2 = MenuItem("2. Oswietlenie         ");
    
         MenuItem menuItem2SubItem1 = MenuItem("2.1 Tyl        ");
               MenuItem menuItem2SubItem1Item1 = MenuItem("2.1.1 ON      ");
               MenuItem menuItem2SubItem1Item2 = MenuItem("2.1.2 OFF      ");
               MenuItem menuItem2SubItem1Item3 = MenuItem("2.1.3 AUTO      ");
         
         MenuItem menuItem2SubItem2 = MenuItem("2.2 Przod      ");
               MenuItem menuItem2SubItem2Item1 = MenuItem("2.2.1 ON      ");
               MenuItem menuItem2SubItem2Item2 = MenuItem("2.2.2 OFF      ");
               MenuItem menuItem2SubItem2Item3 = MenuItem("2.2.3 AUTO      ");
         
    MenuItem menu1Item3 = MenuItem("3. Czujki ");
    MenuItem menu1Item4 = MenuItem("4. Wylacz wszystko ");
    MenuItem menu1Item5 = MenuItem("5. Wlacz wszystko ");
    
void setup()
{
Serial.begin(9600);
sensors.begin();
irrecv.enableIRIn();//pilot
pinMode(wentylewy, OUTPUT);
 pinMode(wentylprawy, OUTPUT);
 pinMode(wentprzodlewy, OUTPUT);
 pinMode(wentprzodprawy, OUTPUT);
 pinMode(lamptyl, OUTPUT);
 pinMode(lamprzod, OUTPUT);
lcd.begin(16, 2);
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(HIGH);
  //configure menu
  menu.getRoot().add(menu1Item1);
    menu1Item1.addRight(menu1Item2).addRight(menu1Item3).addRight(menu1Item4).addRight(menu1Item5);
      menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2).addRight(menuItem1SubItem3).addRight(menuItem1SubItem4);;
       
        menuItem1SubItem1.add(menuItem1SubItem1Item1).addRight(menuItem1SubItem1Item2).addRight(menuItem1SubItem1Item3);
        menuItem1SubItem2.add(menuItem1SubItem2Item1).addRight(menuItem1SubItem2Item2).addRight(menuItem1SubItem2Item3);
        menuItem1SubItem3.add(menuItem1SubItem3Item1).addRight(menuItem1SubItem3Item2).addRight(menuItem1SubItem3Item3);
        menuItem1SubItem4.add(menuItem1SubItem4Item1).addRight(menuItem1SubItem4Item2).addRight(menuItem1SubItem4Item3);
        
      menu1Item2.add(menuItem2SubItem1).addRight(menuItem2SubItem2);;
      
        menuItem2SubItem1.add(menuItem2SubItem1Item1).addRight(menuItem2SubItem1Item2).addRight(menuItem2SubItem1Item3);
        menuItem2SubItem2.add(menuItem2SubItem2Item1).addRight(menuItem2SubItem2Item2).addRight(menuItem2SubItem2Item3);
        
        
  menu.moveUp();
  //lcd.print("T       ");
  delay(500);
 lcd.setCursor(1,0);  
  lcd.print("Czujnik-1: ");
  lcd.print(sensors.getTempCByIndex(0));
 
  lcd.setCursor(11,1);  
  lcd.print("Menu>");
  
}

 void translateIR() // takes action based on IR code received

{
MenuItem currentMenu=menu.getCurrent();
  switch(results.value)
  {

  case  16742535:   //if the current menu has a child and has been pressed enter then menu navigate to item below
        menu.moveDown();
        break;
  
  case  16722135:  //otherwise, if menu has no child and has been pressed enter the current menu is used
        menu.use();
        break;

  case 16732335:  
        menu.moveUp();
        break;
 
  case 16728255:
        menu.moveRight();   
        break;
  
  case 16752735: 
        menu.moveLeft();
        break;
 
  case 16771095:
        menu.toRoot();
        break;
  
 case 16757325:
       lcd.noDisplay();
       lcd.setBacklight(LOW);
       menu.toRoot();
        break;
 
  case 16738455:
       lcd.display();
       lcd.setBacklight(HIGH);
       break; 

  }
   delay(300);
  }
void czujnik1()

  sensors.requestTemperatures();
if(sensors.getTempCByIndex(0) < 27) 
  {
  digitalWrite( wentylewy, HIGH);
  } else 
  {
    digitalWrite( wentylewy, LOW);
  }
  
}
void czujnik2() 
{
sensors.requestTemperatures();
  if(sensors.getTempCByIndex(1) >= 26) 
  {
    digitalWrite(wentylprawy, HIGH);
  }
  else 
  {
     digitalWrite(wentylprawy, LOW);
  }
}
void czujnik3() 
{
sensors.requestTemperatures();
  if(sensors.getTempCByIndex(2) >= 27) 
  {
    digitalWrite(wentprzodlewy, HIGH);
  }
  else
 {
    digitalWrite(wentprzodlewy, LOW);
 }
}
void czujnik4() 
{
sensors.requestTemperatures();
  if(sensors.getTempCByIndex(3) >= 27) 
  {
    digitalWrite(wentprzodprawy, HIGH);
  }
  else
 {
    digitalWrite(wentprzodprawy, LOW);
 }

}
void loop()

{
sensors.requestTemperatures();
navigateMenus();  //in some situations I want to use the button for other purpose (eg. to change some settings)

  if (irrecv.decode(&results)) // have we received an IR signal?
  
  {
    translateIR();
    irrecv.resume(); // receive the next value
    results.value=0; 
  }

}
void menuChanged(MenuChangeEvent changed){

  MenuItem newMenuItem=changed.to; //get the destination menu
  
  lcd.setCursor(0,1); //set the start position for lcd printing to the second row
  
   if(newMenuItem.getName()==menu.getRoot()){
    lcd.clear();

  lcd.setCursor(11,1);
  lcd.print("Menu>");
     
 }else if(newMenuItem.getName()=="1. Chlodzenie     "){
     lcd.print("1. Chlodzenie     ");
  
  }else if(newMenuItem.getName()=="1.1 Tyl lewy        "){
      lcd.print("1.1 Tyl lewy        ");
      
      }else if(newMenuItem.getName()=="1.1.1 ON      "){
            lcd.print("1.1.1 ON      ");
      }else if(newMenuItem.getName()=="1.1.2 OFF      "){
            lcd.print("1.1.2 OFF      ");
      }else if(newMenuItem.getName()=="1.1.3 AUTO      "){
            lcd.print("1.1.3 AUTO      ");
            
                      
  }else if(newMenuItem.getName()=="1.2 Tyl prawy       "){
      lcd.print("1.2 Tyl prawy       ");
      
      }else if(newMenuItem.getName()=="1.2.1 ON      "){
          lcd.print("1.2.1 ON      ");
      }else if(newMenuItem.getName()=="1.2.2 OFF      "){
          lcd.print("1.2.2 OFF      ");
      }else if(newMenuItem.getName()=="1.2.3 AUTO      "){
          lcd.print("1.2.3 AUTO      ");
          
  }else if(newMenuItem.getName()=="1.3 Przod lewy        "){
      lcd.print("1.3 Przod lewy        ");
      
      }else if(newMenuItem.getName()=="1.3.1 ON      "){
            lcd.print("1.3.1 ON      ");
      }else if(newMenuItem.getName()=="1.3.2 OFF      "){
            lcd.print("1.3.2 OFF      ");
      }else if(newMenuItem.getName()=="1.3.3 AUTO      "){
            lcd.print("1.3.3 AUTO      ");
             
  }else if(newMenuItem.getName()=="1.4 Przod prawy     "){
      lcd.print("1.4 Przod prawy     ");
      
      }else if(newMenuItem.getName()=="1.4.1 ON       "){
            lcd.print("1.4.1 ON       ");
      }else if(newMenuItem.getName()=="1.4.2 OFF      "){
            lcd.print("1.4.2 OFF      ");
      }else if(newMenuItem.getName()=="1.4.3 AUTO      "){
            lcd.print("1.4.3 AUTO      ");
      
  }else if(newMenuItem.getName()=="2. Oswietlenie         "){
      lcd.print("2. Oswietlenie         ");
      
     }else if(newMenuItem.getName()=="2.1 Tyl        "){
      lcd.print("2.1 Tyl        ");
      
      }else if(newMenuItem.getName()=="2.1.1 ON      "){
            lcd.print("2.1.1 ON      ");
      }else if(newMenuItem.getName()=="2.1.2 OFF      "){
            lcd.print("2.1.2 OFF      ");
      }else if(newMenuItem.getName()=="2.1.3 AUTO      "){
            lcd.print("2.1.3 AUTO      ");
            
            
  }else if(newMenuItem.getName()=="2.2 Przod      "){
      lcd.print("2.2 Przod      ");
      
      }else if(newMenuItem.getName()=="2.2.1 ON      "){
          lcd.print("2.2.1 ON      ");
      }else if(newMenuItem.getName()=="2.2.2 OFF      "){
          lcd.print("2.2.2 OFF      ");
      }else if(newMenuItem.getName()=="2.2.3 AUTO      "){
          lcd.print("2.2.3 AUTO      ");
          
    
  

}else if(newMenuItem.getName()=="3. Czujki "){
      lcd.print("3. Test - Empty ");
}else if(newMenuItem.getName()=="4. Wylacz wszystko "){
      lcd.print("4. Wylacz wszystko ");
}else if(newMenuItem.getName()=="5. Wlacz wszystko "){
      lcd.print("5. Wlacz wszystko ");
  }
}
void menuUsed(MenuUseEvent used){
 
  lcd.setCursor(0,0);  
  lcd.print("Wybrano        ");
  delay(1000);
  //menu.moveUp();
  lcd.setCursor(0,0);  
  lcd.print("               ");

 

if ((used.item.getName()) == "1.1 Chłodzenie")
{

  //menu.moveUp();  //back to Main
}

if ((used.item.getName()) == "1.1.1 ON      ")
{
  digitalWrite(wentylewy, HIGH);}


if ((used.item.getName()) == "1.1.2 OFF      ")
{
  digitalWrite(wentylewy, LOW);}
     

 if ((used.item.getName()) == "1.1.3 AUTO      ")

  czujnik1();
}

 if ((used.item.getName()) == "1.2.1 ON      ")
{
  digitalWrite(wentylprawy, HIGH)
;}

if ((used.item.getName()) == "1.2.2 OFF      ")
{
  digitalWrite(wentylprawy, LOW);}
  
 if ((used.item.getName()) == "1.2.3 AUTO      ")

  czujnik2();
  ;}

 if ((used.item.getName()) == "1.3.1 ON      ")
{
  digitalWrite(wentprzodlewy, HIGH);}

if ((used.item.getName()) == "1.3.2 OFF      ")
{
  digitalWrite(wentprzodlewy, LOW);}
  
 if ((used.item.getName()) == "1.3.3 AUTO      ")

  czujnik3();
  ;}

 if ((used.item.getName()) == "1.4.1 ON       ")
{
  digitalWrite(wentprzodprawy, HIGH);}

if ((used.item.getName()) == "1.4.2 OFF      ")
{
  digitalWrite(wentprzodprawy, LOW);}
  
 if ((used.item.getName()) == "1.4.3 AUTO      ")
{
  czujnik4();
  ;}
  
if ((used.item.getName()) == "2.1.1 ON      ")
{
  digitalWrite(lamptyl, HIGH);}

if ((used.item.getName()) == "2.1.2 OFF      ")
{
  digitalWrite(lamptyl, LOW);}
  
if ((used.item.getName()) == "2.1.3 AUTO      ")
{
  ;}
  
 if ((used.item.getName()) == "2.2.1 ON      ")
{
  digitalWrite(lamprzod, HIGH);}
  
 if ((used.item.getName()) == "2.2.2 OFF      ")
{
  digitalWrite(lamprzod, LOW);}
 
 if ((used.item.getName()) == "2.2.3 AUTO      ")
{
  ;}
 if ((used.item.getName()) == "4. Wylacz wszystko ")
{  
   digitalWrite(wentylewy, LOW);
   digitalWrite(wentylprawy, LOW);
   digitalWrite(wentprzodlewy, LOW);
   digitalWrite(wentprzodprawy, LOW);
   digitalWrite(lamptyl, LOW);
   digitalWrite(lamprzod, LOW);
 }
  if ((used.item.getName()) == "5. Wlacz wszystko ")
{  
   digitalWrite(wentylewy, HIGH);
   digitalWrite(wentylprawy, HIGH);
   digitalWrite(wentprzodlewy, HIGH);
   digitalWrite(wentprzodprawy, HIGH);
   digitalWrite(lamptyl, HIGH);
   digitalWrite(lamprzod, HIGH);
 }
 

 
 // menu.moveLeft();  //back to Main  
menu.moveUp();
}

void navigateMenus() {
  MenuItem currentMenu=menu.getCurrent();
  

  switch (results.value){
    case 16722135:
         menu.use();
         break;
    case 16742535:   //if the current menu has a child and has been pressed enter then menu navigate to item below
         menu.moveDown();
         break;
    case 16732335:
      menu.moveUp();  //back to main
      break;
    case 16728255:
      menu.moveRight();
      break;      
    case  16752735:
      menu.moveLeft();
      break;    
  
 }

 results.value=0; //reset the lastButtonPushed variable

}
 
Odpowiedź
#2
Witam
Chwila - chcesz odczytywać temperaturę z kilku czujników Dallasa, tak?
Tymczasem nie widzę w Twoim kodzie chociażby jednej definicji adresów dla każdego z czujników.
A każdy z nich ma swój UNIKALNY fabryczny adres, dzięki któremu biblioteka OneWire może się z nimi komunikować.
Zapomniałeś o adresach, bo nie widzę jakoś tego w kodzie.  Rolleyes
Tutaj:
http://akademia.nettigo.pl/ds18b20/#podl...do_arduino 
... masz opisane jak się podłącza kilka Dallasów do jednego pinu. Pamiętaj także o doborze rezystora "podciągającego" jeśli przewody są dość długie.
Pozdrawiam :-)
ps. Przydałoby się także pomyśleć o tzw. histerezie :-) Widzę, że jej nie ma.
 
Odpowiedź
#3
Wiem ze każdy ma swoj numer, wiem jak je podłączyć. Po dodaniu numerów również nie chciało mi działać. Rezystor oczywiście też jest dodany.
 
Odpowiedź
#4
Witam 
Wiesz...ale nie ma tego w kodzie.
Skąd program ma wiedzieć co czytać w funkcji czujnik?
Zanim zrobisz to w każdej ze swoich funkcji czujnik:
if(sensors.getTempCByIndex(0) < 27) 

... musisz najpierw pobrać adresy czujników i przypisać je do nich, za pomocą np. funkcji : getAddress
Może najpierw po prostu podłącz sam czujnik, wgraj przykładowy kod i zobacz o co tam biega :-)
Pozdrawiam
 
Odpowiedź
#5
Okej spoko. Po powrocie z roboty poprawie kod i zobaczę co się stanie. Pisałem oddzielny program w którym były cztery czujniki i cztery diody które program ma zapalić lub zgasić zależnie od temperatury itam wszystko działa.. Po przeklejeniu dodo menu juz nie działa.
 
Odpowiedź
#6
No i niestety dalej jest to samo. Zauważyłem, ze jak wybiorę AUTO i temperatura jest wyższa niż te 27 stopni to dioda się zapali ale nie chce zgasnąć jak temperatura zmaleje. Pali się dopóki nie wybiorę kolejny raz AUTO. Gdzie powinna być ta histereza i jak wyglądać ?
 
Odpowiedź
#7
Cześć, widzę podobne zastosowanie do arduino, fajnie, fajnie. Może z biegiem czasu zaczerpnę coś ciekawego.

Tu masz to fajnie przez Wojtka opisaną histereze: link .
 
Odpowiedź
#8
Witam
No chciałbym Ci pomóc kolego, ale mam wrażenie, że sam chyba tego nie chcesz :-)
Pisałem dzisiaj właśnie o metodzie małych kroczków, która powinna w Twoim przypadku zadziałać. Mianowicie zostaw na początek cały ten kod i w loopie daj tylko np. funkcję czujnik1() lub czujnik2().
Po niej np. delay(2000) i zobacz czy Ci działa :-)
Po drugie nie za bardzo rozumiem... czy wentylatory służą do schładzania, czy też do ogrzewania?
Bo jeśli do schładzania to nie bardzo rozumiem czemu w funkcji czujnik1() załączasz lewy wentylator wtedy gdy temperatura spada, a nie odwrotnie?


Kod:
void czujnik1()
{
 sensors.requestTemperatures();
if(sensors.getTempCByIndex(0) < 27)
 {
 digitalWrite( wentylewy, HIGH);
 } else
 {
   digitalWrite( wentylewy, LOW);
 }
 
}

Musisz testować swój kod dla każdego logicznie spójnego działania ODDZIELNIE. Jeśli każda z tych części działa osobno to potem będzie dużo łatwiej oblukać o co biega.
Pozdrawiam
 
Odpowiedź
#9
Wentylatory służą do schładzania. W czujniku1 wkrada się literówka ale to bez znaczenia bo w innych czujnikach jest dobrze a nie działa. Pisalem wcześniej ze pisałem oddzielny kod tylko dla działania czynników i wentylatorów i tam działa wyszło dobrze. Po dodaniu tego w menu nie działa.
 
Odpowiedź
#10
Witam
OKI... teraz zakumałem mniej-więcej o co biega :-)
Chcesz zatem powiedzieć, że Twój kod dołączony w pierwszym poście na 100% działa bez MENU?
Otóż nie jestem pewien... bo nie ma tam definicji adresów dla czujników...albo obaj czytamy i używamy innych bibliotek dla DALLASA (osobiście śmiem wątpić :-).
Co proponuję?
Weź na chwilę napisz funkcję np czujnik1() jako:
Kod:
void czujnik1()
{
digitalWrite(13,HIGH);
}
Wcześniej w setupie daj dla pewności pinMode(13,OUTPUT);
Zobacz czy teraz jak z menu wybierzesz AUTO dla pierwszego czujnika to zapali się dioda.... Jeśli tak to oznacza, że MENU jednak działa.:-)

Zrób to dla każdej funkcji czujnik 1,2,3 ( podmień odczyt temperatury na zapalenie diody).
Jeśli to zadziała, to oznacza, że nie ma podstaw do zwalania winy na MENU.
Problem być może polega na niewłaściwym, przypadkowym odczycie z DALLAS-ów.
Sprawdź to :-)
Pozdrawiam
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości