Close

Osvětlení akvaria Led pásky

Úvodní stránka Fórum Vaše projekty Arduino Osvětlení akvaria Led pásky

  • Toto téma obsahuje celkem 62 odpovědí. Do diskuze (9 diskutujících) se naposledy zapojil uživatel Nasranek a poslední změna proběhla před 8 roky.
Aktuálně je na stránce zobrazeno 15 příspěvků - 31. až 45. (celkem z 63)
  • Autor
    Příspěvky
  • #7201
    letakp
    Účastník

    Tak toto je moje verze upravená podle původního návrhu od vnouzirozbijsklo:

    #include „Wire.h“
    #define DS3231_I2C_ADDRESS 0x68
    // Convert normal decimal numbers to binary coded decimal
    byte decToBcd(byte val)
    {
    return( (val/10*16) + (val%10) );
    }
    // Convert binary coded decimal to normal decimal numbers
    byte bcdToDec(byte val)
    {
    return( (val/16*10) + (val%16) );
    }
    int svetlo1 = 9;
    int sviti = 0;
    int den = 0;
    int jas = 0;

    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

    void setup()
    {

    Wire.begin();
    Serial.begin(9600);
    // set the initial time here:
    // DS3231 seconds, minutes, hours, day, date, month, year
    //setDS3231time(30,27,19,7,15,11,15);
    }
    void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
    dayOfMonth, byte month, byte year)
    {
    // sets time and date data to DS3231
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set next input to start at the seconds register
    Wire.write(decToBcd(second)); // set seconds
    Wire.write(decToBcd(minute)); // set minutes
    Wire.write(decToBcd(hour)); // set hours
    Wire.write(decToBcd(dayOfWeek)); // set day of week (1=pondeli, 7=nedele)
    Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
    Wire.write(decToBcd(month)); // set month
    Wire.write(decToBcd(year)); // set year (0 to 99)
    Wire.endTransmission();
    }
    void readDS3231time(byte *second,
    byte *minute,
    byte *hour,
    byte *dayOfWeek,
    byte *dayOfMonth,
    byte *month,
    byte *year)
    {
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set DS3231 register pointer to 00h
    Wire.endTransmission();
    Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
    // request seven bytes of data from DS3231 starting from register 00h
    *second = bcdToDec(Wire.read() & 0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read() & 0x3f);
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());

    }
    void displayTime()
    {
    ;
    // retrieve data from DS3231
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
    &year);
    // send it to the serial monitor
    Serial.print(hour, DEC);
    // convert the byte variable to a decimal number when displayed
    Serial.print(„:“);
    if (minute<10)
    {
    Serial.print(„0“);
    }
    Serial.print(minute, DEC);
    Serial.print(„:“);
    if (second<10)
    {
    Serial.print(„0″);
    }
    Serial.print(second, DEC);
    Serial.print(“ „);
    Serial.print(dayOfMonth, DEC);
    Serial.print(„/“);
    Serial.print(month, DEC);
    Serial.print(„/“);
    Serial.print(year, DEC);
    Serial.print(“ Day of week: „);
    switch(dayOfWeek){
    case 7:
    Serial.println(„nedele“);
    break;
    case 1:
    Serial.println(„pondeli“);
    break;
    case 2:
    Serial.println(„utery“);
    break;
    case 3:
    Serial.println(„streda“);
    break;
    case 4:
    Serial.println(„ctvrtek“);
    break;
    case 5:
    Serial.println(„patek“);
    break;
    case 6:
    Serial.println(„sobota“);
    break;
    }
    }
    void loop()
    {

    pinMode(svetlo1,OUTPUT);
    displayTime(); // display the real-time clock data on the Serial Monitor,
    delay(1000); // every second

    byte s, m, h, dvt, dvm, mesic, r;
    readDS3231time(&s, &m, &h, &dvt, &dvm, &mesic, &r);

    if (h >= 9 && h < 21) den = 1; // nastaveni intervalu sviceni
    else den = 0;
    for (byte brightness = 0; den == 1 && sviti == 0 && brightness < 255; brightness ++) {
    analogWrite(svetlo1, brightness);
    if(brightness == 255) sviti = 1;
    delay(3500);
    }

    for (byte brightness = 255; den == 0 && sviti == 1 && brightness > 0; brightness –) {
    analogWrite(svetlo1, brightness);
    if(brightness == 0) sviti = 0;
    delay(3500);}

    }

    #7202
    letakp
    Účastník

    Tak jsem se díval na ty knihovny a zjistil jsem, že tam asi fakt nic není, tak jsem stáhl a nainstaloval knihovnu a potom se před #include „wire.h“ nainstalovalo toto:
    #include <RtcDateTime.h>
    #include <RtcDS3231.h>
    #include <RtcTemperature.h>

    Ale stejně to na monitoru vypisuje to stejné.

    #7210
    posjirka
    Účastník

    a co když zkusíš tenhle exampl.

    Tutoriál – užívání hodin reálného času DS1307 a DS3231 s Arduinem

    Ten funguje? Ten projekt osvětlení akvaria v podstatě jen rozšiřuje tento tutorial.

    Pak mě napadá jen pár věcí proč to nefunguje:
    – špatné zapojení (např prohození SDA a SCK)
    – špatný modul/čip DS3231
    – chybná adresa modulu (na modulu se dá nastavit tak můžeš mít nastavenou jinou než defaultní)

    DS3231 bohužel doma nemám a nedostává se mi času s tím experimentovat ….

    #7217
    letakp
    Účastník

    Ahoj, právě když jsem zkoušel všechny možnosti s RTC, tak mi to nefungovalo nikdy.
    Špatně zapojené SDA a SCK jsem vyloučil otočením a stále nic.
    Tak jsem si prohlédl čip pod lupou a zjistil jsem, že je polovina nožiček ve vzduchu. Dneska to přiletuju a večer doma odzkouším funkčnost. Díky zatím za malou nápovědu v čem by ten problém mohl být.

    #7218
    ArduXPP
    Účastník

    Když budu chtít u modulu použít baterii CR2032 je potřeba přerušit obvod dobíjecí ?

    #7220
    posjirka
    Účastník

    nechápu ???? Myslíš jako výměnu baterie nebo použití baterie jako primárního zdroje pro apliakci?

    #7221
    ArduXPP
    Účastník

    Koupil jsem si DS3231 a ten i baterii nabíjí. Baterie CR2032 je nenabíjecí.

    #7229
    posjirka
    Účastník

    tak ti nevím. V popsiu je Battery input takže bych to bral jako vstup.
    Pak jsem našel v datasheetu toto:
    The device is UL recognized to ensure against reverse charging when used with a primary lithium battery.

    no a na netu jsou i moduly s baterii cr2030:

    vzheldem k tomu, že to má pouze 1 vstup a nikde nabijecí pin nevidím … chtělo by to sehnat schéma toho tvého modulu.

    ještě mě napadlo: to že tam je baterie napevno (tzn. připájena na páskách, neznamená, že je nabijecí….

    #7233
    ArduXPP
    Účastník

    Četl jsem to v této diskuzi

    #7234
    letakp
    Účastník

    To-ArduXPP Ta baterie je jenom záložní, takže se nenabíjí. Má jenom 3,5V a do destičky se pouští 5V.
    To-posjirka Tak čip je odzkoušený a funkční. Teď ještě odladit prográmek pro to akvárko, něco se mi tam nezdá, ještě musím posledovat chování v průběhu dne a při různých poruchových stavech, zatím co jsem zjistil, že pokud je v režimu noc, tak LED TX bliká co 1sec. a když dopočítá 255 kroků do úplného rozednění, tak přestane LED TX blikat a ani na výpisu monitoru se neobjevují nové informace o čase. A taky se mi asi po cca 30 minutách resetuje a startuje znovu, ale LED nebliká.
    Datasheet k DS3231 je zde: https://datasheets.maximintegrated.com/en/ds/DS3231.pdf

    Tady je výpis mé úpravy programu z prvního příspěvku:
    [code]
    #include <Wire.h>
    #define DS3231_I2C_ADDRESS 0x68
    // Convert normal decimal numbers to binary coded decimal
    byte decToBcd(byte val)
    {
    return( (val/10*16) + (val%10) );
    }
    // Convert binary coded decimal to normal decimal numbers
    byte bcdToDec(byte val)
    {
    return( (val/16*10) + (val%16) );
    }
    int svetlo1 = 9;
    int sviti = 0;
    int den = 0;
    int jas = 0;

    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

    void setup()
    {

    Wire.begin();
    Serial.begin(9600);
    // set the initial time here:
    // DS3231 seconds, minutes, hours, day, date, month, year
    //setDS3231time(00,59,18,7,05,06,16);
    }
    void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
    dayOfMonth, byte month, byte year)
    {
    // sets time and date data to DS3231
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set next input to start at the seconds register
    Wire.write(decToBcd(second)); // set seconds
    Wire.write(decToBcd(minute)); // set minutes
    Wire.write(decToBcd(hour)); // set hours
    Wire.write(decToBcd(dayOfWeek)); // set day of week (1=pondeli, 7=nedele)
    Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
    Wire.write(decToBcd(month)); // set month
    Wire.write(decToBcd(year)); // set year (0 to 99)
    Wire.endTransmission();
    }
    void readDS3231time(byte *second,
    byte *minute,
    byte *hour,
    byte *dayOfWeek,
    byte *dayOfMonth,
    byte *month,
    byte *year)
    {
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set DS3231 register pointer to 00h
    Wire.endTransmission();
    Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
    // request seven bytes of data from DS3231 starting from register 00h
    *second = bcdToDec(Wire.read() & 0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read() & 0x3f);
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());

    }
    void displayTime()
    {
    ;
    // retrieve data from DS3231
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
    &year);
    // send it to the serial monitor
    Serial.print(hour, DEC);
    // convert the byte variable to a decimal number when displayed
    Serial.print(„:“);
    if (minute<10)
    {
    Serial.print(„0“);
    }
    Serial.print(minute, DEC);
    Serial.print(„:“);
    if (second<10)
    {
    Serial.print(„0″);
    }
    Serial.print(second, DEC);
    Serial.print(“ „);
    Serial.print(dayOfMonth, DEC);
    Serial.print(„/“);
    Serial.print(month, DEC);
    Serial.print(„/“);
    Serial.print(year, DEC);
    Serial.print(“ Den: „);
    switch(dayOfWeek){
    case 7:
    Serial.println(„nedele“);
    break;
    case 1:
    Serial.println(„pondeli“);
    break;
    case 2:
    Serial.println(„utery“);
    break;
    case 3:
    Serial.println(„streda“);
    break;
    case 4:
    Serial.println(„ctvrtek“);
    break;
    case 5:
    Serial.println(„patek“);
    break;
    case 6:
    Serial.println(„sobota“);
    break;
    }
    }
    void loop()
    {

    pinMode(svetlo1,OUTPUT);
    displayTime(); // display the real-time clock data on the Serial Monitor,
    delay(1000); // every second

    byte s, m, h, dvt, dvm, mesic, r;
    readDS3231time(&s, &m, &h, &dvt, &dvm, &mesic, &r);

    if (h >= 8 && h < 20) den = 1; // nastaveni intervalu sviceni
    else den = 0;
    for (byte brightness = 0; den == 1 && sviti == 0 && brightness < 255; brightness ++) {
    analogWrite(svetlo1, brightness);
    if(brightness == 255) sviti = 1;
    delay(5000);
    }

    for (byte brightness = 255; den == 0 && sviti == 1 && brightness > 0; brightness –) {
    analogWrite(svetlo1, brightness);
    if(brightness == 0) sviti = 0;
    delay(5000);}

    }
    [/code]

    #7235
    posjirka
    Účastník

    podle mých výpočtu by to mělo resetovat po 21 minutách 🙂

    Když se na ten program podívaáš, tak ve smyčce ( loop() ) ti neustále :
    – nastavuje vstup „svetlo1“ jako výstupní (pinmode)
    – pak ti zobrazí aktuální čas (displayTime)
    – počká 1 s
    – přečte si aktuální čas (readDS3231time)
    – zjistí jestli není náhodou den (if (h>=8 ….)
    – spustí sekvenci rozsvícení (podmíněnou dalšími faktory) a ta trvá 255 kroku * 5s zpoždění = cca 21minut.
    ….

    po tu dobu rozsvěcení vlastně cykluje sám v sobě a tím pádem nezobrazuje na „serialmonitor“ žádné hodnoty. jestli to chceš vypisovat tak musíš příkaz „displayTime();“ dát i do symček „for“.

    proč se ti resetuje / znovu načítá nevím, nekde je chybka v proměnných „den“, „sviti“, „brightness“. Když tak na to koukám, tak on ti vlastně nikdy nedojede v rozsvícení na „brightness = 255“, protože ve smyčce „for“ mu dáváš podmínku „brightness < 255“. Tzn. že ti skončí ve 254 kroku 🙂 .

    Já bych celou tuto situaci řešil asi trochu jinak. Na počátku bych si nadefinoval pole o 24 pozicích (0-23 hodin) do nich bych si zapsal jakou intenzitu mají mít v nulté minutě a pomocí fuknce „map()“ bych plynule přecházel mezi jednotlivými hodnotami.
    Ano trvalo by to 1 hodinu než by se rozsvítilo světlo naplno/zhasnulo ale bylo by to mnohem čistší řešení …

    nemám moc rád tyhle vnořené podmínky, člověk se v nich ztrácí.

    #7236
    ArduXPP
    Účastník

    Včera se mi nedal odkaz do příspěvku.

    Tak tady je https://bastlirna.hwkitchen.cz/tutorial-uzivani-hodin-realneho-casu-ds1307-a-ds3231-s-arduinem/

    Píše o tom Kolbis .

    #7238
    letakp
    Účastník

    To-posjirka Tak to, že by se to rozsvěcelo hodinu by nevadilo, ba naopak, jenom přesně nechápu, jak to myslíš s těmi poli, jestli máš chvilku, zkus mně alespoň navést, zkusim si o tom něco přečíst, uvidim, co ze mně vypadne. Díky.

    #7239
    letakp
    Účastník

    Zatím jsem upravil void loop a funguje mi to asi tak, jak jsem si představoval.
    výpis loop zde:
    void loop()
    {

    pinMode(svetlo1,OUTPUT);
    displayTime(); // display the real-time clock data on the Serial Monitor,
    delay(1000); // every second

    byte s, m, h, dvt, dvm, mesic, r;
    readDS3231time(&s, &m, &h, &dvt, &dvm, &mesic, &r);

    if (h >= 8 && h < 21) den = 1; // nastaveni intervalu sviceni
    else den = 0;
    for (byte brightness = 0; den == 1 && sviti == 0 && brightness <= 255; brightness ++) {
    displayTime(); // display the real-time clock data on the Serial Monitor,
    analogWrite(svetlo1, brightness);
    if(brightness == 255) sviti = 1;
    delay(5000);

    }

    for (byte brightness = 255; den == 0 && sviti == 1 && brightness >= 0; brightness –) {
    displayTime(); // display the real-time clock data on the Serial Monitor,
    analogWrite(svetlo1, brightness);
    if(brightness == 0) sviti = 0;
    delay(5000);}

    }

    #7240
    posjirka
    Účastník

    napsal jsem jednoduchý příklad.
    Je to myslim dobře okomentovaný takže princip by měl být jasný:

    // priklad principu regulace osvetleni akvaria
    // v01
    // by JP 2016
    //
    
    // knihovny
    
    #include <Time.h>
    
    // promenne
    int jas = 0; // pomocna promenna pro vypocet jasu
    const int LED = 10; // pin s LED diodou
    // nasatveni casovace
    int casovac[24] = {0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
    // jednotlive polozky casovace predstavuji intenzitu jaku v celou hodinu
    // 1. cislice je intenzita osvetleni v 0:00
    // 2. cislice je intenzita osvetleni v 1:00
    // ...
    // 23. cislice je intenzita osvetelni v 23:00
    // cislice jsou v rozsahu:
    // 0 = 0%
    // 255 = 100%
    
    void setup() {
      Serial.begin(9600); // nastaveni seriove komunikace
      pinMode(LED, OUTPUT); // nastaveni pinu jako vystup
    }
    
    void loop() {
      // vypis na seriovy port
      Serial.print(hour()); // hodiny
      Serial.print(":"); 
      Serial.print(minute()); // minuty
      Serial.print(":"); 
      Serial.print(second()); // sekundy
      Serial.print("   Jas:");
      Serial.println(jas); // aktualni jas
      // kdyz je 23 hodin je treba porovnavat hodnoty cislice 23 a 0
      if(hour() == 23) {
        // nastav jas podle aktualni minuty a hodiny 
        jas = map(minute(), 0, 59, casovac[23], casovac[0]);
        // ochrana proti hazardnimu stavu prepoctu
        jas = constrain(jas, casovac[23], casovac[0]);
      } else {
        // jinak porovnej hodnoty cilice pole = aktualni hodina a vedlejsi cislice
        jas = map(minute(), 0, 59, casovac[hour()], casovac[hour()+1]);
        // ochrana proti hazardnimu stavu prepoctu
        jas = constrain(jas, casovac[hour()], casovac[hour()+1]);
      }
      jas = constrain(jas, 0, 255); // omezeni rozsahu regulace
      analogWrite(LED, jas); // nastav aktualni intenzitu  
      delay(1000); // pauza 1s
    }
Aktuálně je na stránce zobrazeno 15 příspěvků - 31. až 45. (celkem z 63)
  • Pro reakci na toto téma se musíte přihlásit.