• 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
Akwarium Komputer
#1
Video 
Witam,

Przygodę z arduino zacząłem w momencie kiedy wpadłem na pomysł postawienia nowego akwarium.
Z powodu tego iż muszę mieć pomiar parametry wody najprościej było zrobić to na arduino niż kupować komputer za parę tyś. zł. I oto moje wypociny:

Podzespoły:

Arduino Mega 2560

RTC DS1302 zegar czasu rzeczywistego

Wyświetlacz 20x4 z modułem I2C

Sterownik PWM LED RGB 3x6A P9813

Czujnik temperatury LM35

Lampa LED    ( https://pl.aliexpress.com/item/1pcs-Led-...4c0600cc8d )



Niedługo o ile dojedzie, będą dodane moduły:

http://www.tme.eu/pl/details/df-sen0161/...t/sen0161/

http://www.tme.eu/pl/details/df-sen0165/...t/sen0165/



Niestety nie działa  do końca tak jak powinno:
Data - szaleje rok się zmienia godzina przy zaniku prądu pokazuje np. 34:34:23 (jak mu się podoba)

Temperatura szaleje

Poniżej link do filmiku:
https://youtu.be/Wm7dY2N7K8c


Opis działania:
Zegar standardowo do zarządzania reszta parametrów,
Pomiar temperatury wody
Pomiar parametrów wody
Sterowanie lampą - ściemnianie, rozjaśnianie wg. zegara - symulacja zachodu i wschodu słońca.

KOD PROGRAMU:
Kod:
#include <stdio.h>
#include <DS1302.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "RGBdriver.h"
#define CLK 2//pins definitions for the driver        
#define DIO 3
LiquidCrystal_I2C lcd(0x3F,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
float tem = 0;
namespace {

// Set the appropriate digital I/O pin connections. These are the pin
// assignments for the Arduino as well for as the DS1302 chip. See the DS1302
// datasheet:
//
//   http://datasheets.maximintegrated.com/en/ds/DS1302.pdf
const int kCePin   = 12;  // Chip Enable
const int kIoPin   = 11;  // Input/Output
const int kSclkPin = 10;  // Serial Clock

// Create a DS1302 object.
DS1302 rtc(kCePin, kIoPin, kSclkPin);
RGBdriver Driver(CLK,DIO);
int opcja=0;
int liczonko=0;
int hwl=6;//godz rozjasniania
int mwl=00;//min rozjasniania
//int swl=0;//sek rozjasniania
int hwy=21;//godz sciemniania
int mwy=0;//min sciemniania
//int swy=0;//sek sciemniania
float ledblue=0;
float ledwhite=0;

/*String dayAsString(const Time::Day day) {
 switch (day) {
   case Time::kSunday: return "Nie";
   case Time::kMonday: return "Pon";
   case Time::kTuesday: return "Wto";
   case Time::kWednesday: return "Sro";
   case Time::kThursday: return "Czw";
   case Time::kFriday: return "Pia";
   case Time::kSaturday: return "Sob";
 }
 return "(unknown day)";
}
*/

void printTime() {// obsluga zegara
 // pobierz dzien.
 Time t = rtc.time();

 // jak chcesz aby wyswietlilo dzien tygodnia odkomentuj nizej i tabelke z dniami.
 //const String day = dayAsString(t.day);

 // scalenie daty i czasu do buforu.
 char buf_1[21];
 //char buf_2[9];
 snprintf(buf_1, sizeof(buf_1), "%04d-%02d-%02d  %02d:%02d:%02d", t.yr, t.mon, t.date, t.hr, t.min, t.sec);
 //snprintf(buf_2, sizeof(buf_2), "%02d:%02d:%02d",day.c_str(), t.hr, t.min, t.sec);

 // wypluj na ekran date i czas
 lcd.setCursor(0,0);
 lcd.print(buf_1);
 //lcd.setCursor(7,1);
 //lcd.print(buf_2);
}

}
 
void printTemperature(){// obsluga termometra
 tem = (5.0 * analogRead(A1) * 100.0) / 1024;//5/1024=0.0048828125;1000/10=100
 lcd.setCursor(0,1);
 lcd.print("Temperatura= ");
 lcd.setCursor(13,1);
 lcd.print(tem);
 lcd.print(char(223));//print the unit" ℃ "
 lcd.print("C");
 
}
void printPH(){// obsluga sady ph
 lcd.setCursor(0,2);
 lcd.print("PH=");
 lcd.setCursor(4,2);
 lcd.print("...%   OCR= ...%");
}

void setup() { //inicjalizacja po resecie lub zaniku napiecia
 lcd.init(); //initialize the lcd
 lcd.backlight(); //open the backlight
 opcja=5;// po wyl zasilania gdzie ma isc
 liczonko=0;
 rtc.writeProtect(false);
 rtc.halt(false);
 // aby ustawilo godzine wpisz ponizejpoprawna i wyciagnij baterie
 // rok,miesiac,dzien,godzina,minuta,sekunda,dzien tygodnia z tabelki linie zakmentowana
  Time t(2017, 7,26, 10,13, 00, Time::kMonday);
 //wpisz date i czas.
  rtc.time(t);
}

void printJasnosc(){ //obsluga czasow zmian jasnosci
 Time t = rtc.time();//pobierz czas z rtc
 if (opcja!=5){// sprawdz czy czas na zmiany
       if((t.hr==hwl)&&(t.min==mwl)){// godzina wlaczenia&&(t.sec=swl)
           //liczonko=10;
           opcja=1;
       }
       if((t.hr==hwy)&&(t.min==mwy)){// godzina wtlaczenia &&(t.sec=swy)
           //liczonko=10;
           opcja=2;
       }
 }      
 else{ // po braku zasilania        
       if ((t.hr>= hwl)&&(t.min>=mwl)){//dzien sie zacza (t.hr<=hwy)&&&&(t.min<=mwy
         if (t.hr<hwy){ // do godziny wylaczenia
           //liczonko=10;
           opcja=3;
         }
           else if ((t.hr==hwy)&&(t.min<=mwy)){ //godzina wylaczenia i minuty
           opcja=3;  
           }
           else{ //powyzej zakresu noc
            opcja=4;
             }
           }
        else {//noc
           //liczonko=10;
           opcja=4;
        }
 }
 

// aby co 10 sek o jedna wartosc rozjasnilo lub sciemnilo
lcd.setCursor(0,3);
//lcd.print("Jasność");
//lcd.print(" ");
lcd.print("BLUE=");
lcd.setCursor(5,3);
lcd.print((ledblue/255*100));
lcd.setCursor(8,3);
lcd.print("%");
lcd.print(" WHITE=");
lcd.print((ledwhite/255*100));
lcd.setCursor(19,3);
lcd.print("%");

liczonko==liczonko++;
 
if (liczonko==10){ //co 10 sek zmien wartosc zaleznie od opcji
     swiatlosc();
     liczonko=0; //licz od nowa
}    
}
void swiatlosc (){// co 10 sek zmienia ustawienia lampy

 if (opcja==0){//jest jasno lub ciemno bez zmian
   ledblue=ledblue;
   ledwhite=ledwhite;
 }  
 if (opcja==1){// rozjasnianie z nocy
   
   if ((ledwhite>=25)){//oba rosna razem
     ledwhite==ledwhite++;
     ledblue=ledwhite;
     if (ledwhite>=255){ //max jasnosc
       opcja=0;
     }
   }
   else if ((ledblue<25)&&(ledwhite<25)){// niebieski 0>10% bialy 0>10% po utracie zasilania
   ledwhite==ledwhite++;
   ledblue==ledblue++;
   }
   else{//niebieski 10% bialy 0>10%
     ledwhite==ledwhite++;
     ledblue=25;
   }
   
 }
 if (opcja==2){// sciemnianie po dniu
   if (ledblue<=25){// niebieski 10% bialy 100%>10%
       ledwhite==ledwhite--;
       ledblue=25;
       if (ledwhite==0){// max ciemnosc
           opcja=0;
       }
   
   }
   else{// oba maleja
     ledwhite==ledwhite--;
     ledblue=ledwhite;
   }
   
 }
 if (opcja==3){// rozjasnianie po zaniku pradu
     ledwhite==ledwhite++;
     ledblue=ledwhite;
   if (ledwhite==255){ //max jasnosc
     opcja=0;
   }
 }
 if (opcja==4){// rozjasnianie nocne po zaniku pradu
     ledwhite==0;
     ledblue==ledblue++;
   if (ledblue>=25){ //10 % w nocy
     opcja=0;
   }
 }
 Driver.begin(); // begin
 Driver.SetColor(ledblue,ledwhite,0); //nieb bialy  niepodlaczony
 Driver.end();  
}
// Loop and print the time every second.

void loop() {
 printTime();
 printTemperature();
 printPH();
 printJasnosc();
 if (ledwhite<80){ //wylacz podswietlenie gdy jasnosc bialych mniejsza od 100
   lcd.setBacklight(LOW);
 }
 else{
   lcd.setBacklight(HIGH);
 }
 delay(870);
}



Jakby mógł ktoś mi dopomóc dlaczego tak się dzieje??

Pozdrawiam.
 
Odpowiedź
#2
Wymień baterię w RTC, albo jeśli masz w układzie zegara pin BAT, to podłącz do VCC.
Swoją drogą, co to za przestrzeń nazw i w jaki sposób się wywołuje funkcje z tej przestrzeni nie mając przedrostka?
To w ogóle ma jakiś głębszy sens, bo może jestem głupi i czegoś nie rozumiem?
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#3
Zmiana baterii nic nie dała.
 
Odpowiedź
#4
A zmieniłeś na dobrą baterię?
Podłączyłeś pin BAT?
Nie odpowiedziałeś mi na pytanie o przestrzeni nazw.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#5
hm.....

1) Nie wyciągnąłem baterie z zegarka i włożyłem używaną...
2) Jak byś dobrze przeczytał mój post i sprawdził jakie moduły użyłem to byś wiedział iż nie ma tam pina BAT.
3)Co do przestrzeni nazw... program jest pisany prze zemnie i jest moją własna inicjatywą więc mogę sobie zmienne nazywać jak mi się podoba. Raczej problemu nie ma z wywoływaniem ich.

Ok
Po dłuższej zabawie doszyłem do tego gdy lampa świeci z mocą 100% (wszystkie kolory) to zaczyna się dyskoteka na wyświetlaczu, gdy jest mniej niż 99% to wszystko działa poprawnie

Analizując   Int X wejście z zakresu 0 do 255 i chce to wyrazić w % na wyświetlaczu dla
x=0 ma być 0,0%
x=2 ma być 0.8%
x=25 ma być 10%
(pierwsza pozycja pusta)
x=255 ma być 100%

osiągając 100% czasem wychodzi tak że wyświetla 0.000.000 taki format i te kolejne zera nadpisują wiersze wyświetlacza dlatego inne linie szaleją.

Pytanie:
Czy ktoś wie w jaki sposób ustawić zmienne ułamkowe wyrażające procent (float)ograniczone do 3 znaków? od formatu 0,0 do 9,9 dla mniejszych od 10 natomiast dla reszty ma przyjmować dwie ostatnie pozycje (od 10 do 99)i 100% dla wartości 100


Pozdrawiam.
 
Odpowiedź
#6
Przeczytałem Twój post, a tam piszesz, że masz DS1302. Ten zegarek ma wyprowadzony pin BAT do zasilania i ładowania baterii, więc pewnie Ty nie przeczytałeś własnego posta, a nie ja.
Co do przestrzeni nazw, to owszem jest twój program i Ty nazywasz zmienne, ale owa przestrzeń nie tyczy się nazewnictwa zmiennych.
Przeczytaj mój post jeszcze raz (szczególnie o przedrostku), potem naucz się C++, a następnie odpowiedz na pytania.
To nie jest złośliwość z mojej strony, po prostu aby dać sobie pomóc, musisz jako autor kodu, wykazać się współpracą, ponieważ Ty znasz swój kod najlepiej, a my musimy zgadywać.

Co się tyczy zaokrąglania liczb do określonej ilości znaków, to myślę że można wykorzystać funkcję round.
Na przykład dla zmiennej 'i' mniejszej od 10, niech i=0,25 a chcesz aby było 0,2 to możesz dać round(ix10)/10;
A co znaczy "przyjmować dwie ostatnie pozycje", to nie wiem, ale jak chcesz dla i>10 zrezygnować z miejsc po przecinku, to po prostu round(i);
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości