Časové rozmezí

Michal_123
Příspěvky: 9
Registrován: 31 říj 2023, 20:44
Reputation: 0

Časové rozmezí

Příspěvek od Michal_123 » 31 říj 2023, 21:44

Ahoj všem.
Prosím o pomoc, a kdyby mi někdo vysvětlil, kde dělám chybu, tak bych byl opravdu rád. Začínám s arduinem a hned na začátku jsem narazil na, pro mě nepřekonatelný problém. Když zadám sepnutí a rozepnutí v určitý čas, tak je vše v pohodě. Třeba něco takového.

Kód: Vybrat vše

if ((datumCas.hour() == 7 ) && ( datumCas.minute() == 30))
V 7 30h sepnu pin. Ok, ale funguje jen a pouze v tuto dobu. Když vypadnul proud a nebo jsem pustil arduino po tomto čase, tak se už pin nesepne. Tak jsem to změnil na toto.

Kód: Vybrat vše

if ((datumCas.hour() >= 7 ) && (datumCas.hour() <= 18 ) && ( datumCas.minute() >= 30) && ( datumCas.minute() <= 40))
{
      digitalWrite(8, HIGH); 
      Serial.println("DEN ");                                             
  }
   else 
   {
      digitalWrite(8, LOW); 
      Serial.println("NOC ");
   } 
delay(1000);
pak toto

Kód: Vybrat vše

if ((datumCas.hour() >= 7 ) && ( datumCas.minute() >= 30) || (datumCas.hour() <= 18 ) && ( datumCas.minute() <= 40))
a nebo toto

Kód: Vybrat vše

if ((datumCas.hour() >= 7 ) && ( datumCas.minute() >= 30) && (datumCas.hour() <= 18 ) && ( datumCas.minute() <= 40)) 
myslím, že toto nešlo vůbec

Kód: Vybrat vše

if (( datumCas.hour() > 7 < 18 ) && ( datumCas.minute() > 30 < 40 ))
if (( 7 > datumCas.hour()  < 18 ) && ( 30 > datumCas.minute()  < 40 ))
A už si opravdu nevím rady. Všechno to funguje, pokud tam je jenom hodina a nebo jenom minuta. Pokud nastavím hodinu i minutu, tak to nespíná a nebo je to naopak sepnuté stále a někdy si to dělá co chce.
Prosím našel by se tu někdo, kdo by mi vysvětlil, jakou chybu opakuji stále dokola?
Předem moc děkuji
EDIT: Přidal jsem tam tagy code to je to tlačítko </> nahoře. Používej to pro kódy, mnohem líp se to čte. Gilhad

peterple
Příspěvky: 156
Registrován: 22 zář 2021, 20:20
Reputation: 0

Re: Časové rozmezí

Příspěvek od peterple » 31 říj 2023, 23:15

Problém je v tom že porovnávaš neporovnateľné. Ten chrobák robí presne čo mu napíšeš, za logickú správnosť ručíš ty ako programátor.

Kód: Vybrat vše

(datumCas.hour() >= 7 ) && (datumCas.hour() <= 18 ) && ( datumCas.minute() >= 30) && ( datumCas.minute() <= 40)
Tento test je pravda ak je hodina v rozsahu (7 až 18) a súčasne minuta je v rozsahu (30 až 40).
Teda zapnuté to máš od 7:30 - 7:40, 8:30 - 8:40, 9:30 - 9:40 atd až po 18:30 - 18:40

Zvyšok podmienok sú celkom dobré príklady na testy pre študentov C jazyka. Ale nechce sa mi to všetko vypisovať.

Keď chceš urobiť test na časový interval tak sa to robí tak, že sa hodiny a minúty prepočítajú na minuty a potom sa to už porovnávať dá.

Kód: Vybrat vše

int casvmin = datumCas.hour()*60+ datumCas.minute();
if((casvmin >= 7*60+30 ) && ( casvmin <= 18*60+40))

Michal_123
Příspěvky: 9
Registrován: 31 říj 2023, 20:44
Reputation: 0

Re: Časové rozmezí

Příspěvek od Michal_123 » 01 lis 2023, 06:26

Moc děkuji. Když jsem zadal jen hodiny, tak to naprosto spolehlivě fungovalo, ale ty minuty 😠 14 dni si říkám, že na to přijdu a nespočet pokusů, ale toto by mě nenapadlo a ani jsem to nikde na fóru nenašel. Opravdu moc děkuji. Hned večer to zkusím. Předpokládám kdybych zadával sekundy, třeba 10 secund, tak to převedu na minuty a přičtu k tomu.

Uživatelský avatar
gilhad
Příspěvky: 788
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Časové rozmezí

Příspěvek od gilhad » 01 lis 2023, 07:17

No, sice by to šlo, ale musel bys používat nepřesný a pomalý float.
Mnohem lepší je to v takovém případě přepočítat na sekundy všechno.

peterple
Příspěvky: 156
Registrován: 22 zář 2021, 20:20
Reputation: 0

Re: Časové rozmezí

Příspěvek od peterple » 01 lis 2023, 07:21

ani nie. Ak by si previedol 10 sekund na minúty, dostal by si desatinné číslo. Desatinné čísla sú vždy na MCU problém. Jednak zožerú pomerne veľa flash lebo počítanie s nimi nie je jednoduché. Potom to dlhšie trvá. Ale najhoršie je že nie sú také presné ako celé čísla. Napríklad 1!=1.0
Viem že excel to tak robí, ale ten nebeží na MCU ale na min 32bitovom železe ktoré má k dispozícii matematický koprocesor.

Preto sa to prevádza na sekundy. A tam je schovaných zase zopár nášlapných mín jazyka C. Nikde totiž nie je povedané ako dlhý int je. Niekde je 16 bitový a niekde je 32bitový. Keď vypočítaš počet sekund za jeden deň tak zistíš že sa to do 16bitového int nezmestí. Teda treba použiť long.

Druhá mína je keď počítaš tú konštantu na 16 bitovom int. Tak výpočet

Kód: Vybrat vše

60*60*24
nevedie k správnemu číslu. To pretože normálna veľkosť pre výpočet je 16 bit. Každé číselko sa prevedie na 16 bitové číselko a potom pri násobení vznikne pretečenie, ktoré opäť C nerieši a spolieha sa na programátora. Je to jeho job aby to bolo správne. V tomto prípade:

Kód: Vybrat vše

60L*60L*24L

Michal_123
Příspěvky: 9
Registrován: 31 říj 2023, 20:44
Reputation: 0

Re: Časové rozmezí

Příspěvek od Michal_123 » 01 lis 2023, 18:24

Děkuji za odpovědi.
Tak jsem doma a přepsal jsem to do kódu místo mého původního pokusu. A stejně se ta dioda nerozsvítila v tu dobu, kdy měla. Tak nevím, co by mělo být špatně. IDE to v pohodě pustil dál, ale na pinu se nic neděje. Tak jsem to pro jistotu překopíroval a stejně nic. Předpokládám, že je to správně v loop. Prosím co by tam mohlo ještě chybět.

Uživatelský avatar
gilhad
Příspěvky: 788
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Časové rozmezí

Příspěvek od gilhad » 01 lis 2023, 19:33

To bude tím překlepem na támhletom řádku jak na něj právě koukám :lol:

Ne, vážně, tady ti nikdo nevidí přez rameno, takže vezmi celý ten kód a zkopíruj ho sem, do tagu code (nebo ho pak označ a stiskni tlačítko </> nahoře).

Michal_123
Příspěvky: 9
Registrován: 31 říj 2023, 20:44
Reputation: 0

Re: Časové rozmezí

Příspěvek od Michal_123 » 01 lis 2023, 20:13

Tady to je. Jedna část by měla ovládat 1000l akvário (4x světlo, intenzitu světla, co2, 2-4x tekuté hnojivo, odvětrání světel, hlídání PH, přepad do spodního filtru (servo, krokový motor).... Druhá část možná líheň na vejce. Hodně věcí je tam podobně ovládaných.
Bude to asi arduino mega , datalogger, HTU21D, topení....
Toto je můj úplně první projekt a chtěl bych se na něm trochu rozkoukat, tak si to popisuji jako tupec, abych se v tom trochu vyznal.

Kód: Vybrat vše

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"
#include "SparkFunHTU21D.h"

int hodina = 7;                                                     //čas spuštění světla hodina
int minuta = 30;                                                    //čas spuštění světla minuta
int svetlo = 12;                                                    //doba svícení (hodina + minuta + světlo)

/*
const int fan_1 = 2;                                                // mega PWM pin na ventilator  
const int fan_2 = 3;                                                // mega PWM pin na ventilator 
const int fan_3 = 4;                                                // mega PWM pin na ventilator 
const int fan_4 = 5;                                                // mega PWM pin na ventilator 
  */

RTC_DS1307 DS1307;                                                  //hodiny                 vytvoření instance DS1307 z knihovny RTClib
HTU21D mujHTU;                                                      //teploměr a vlhkoměr    inicializace senzoru z knihovny

const int sd_CS = 10;                                               //SDkarta                 nastavení pinu CS pro SD kartu
const int analogPin = A0;                                           //hodiny                  pin pro čtení analogové hodnoty

char seznamDni[7][8] = {"nedele", "pondeli", "utery", "streda", "ctvrtek", "patek", "sobota"};

void setup () {
  
  Serial.begin(9600);
  mujHTU.begin();
  
  if (! DS1307.begin())                                             // kontrola připojeného obvodu reálného času
  {                           
    Serial.println("Hodiny nejsou pripojeny!");
    while (1);
  }
  
  if (! DS1307.isrunning())                                         // kontrolu spuštění obvodu reálného času
  {
    Serial.println("Hodiny nejsou spusteny! Spoustim nyni..");
  }
 
  if (!SD.begin(sd_CS))                                             // kontrola připojené SD karty
   {                                                                // na mega zmenit (sd_CS) na piny
    Serial.println("SD karta neni pripojena nebo je vadna!");
    return;
  }
  
      // následující příkaz v pořadí rok, měsíc, den, hodina, minuta, vteřina
      // DS1307.adjust(DateTime(2023, 10, 16, 20, 27, 5));

    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);    //  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   Nepoužívat (pouze pro ladění)   
    digitalWrite(9, HIGH); //  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   Nepoužívat (pouze pro ladění)                  
     // pinMode(10, OUTPUT);                                        Nepoužívat (obsazeno datalogger)
    pinMode(12, OUTPUT);

/*
    pinMode(fan_1, OUTPUT);                                        // mega PWM pin na ventilator
    pinMode(fan_2, OUTPUT);                                        // mega PWM pin na ventilator
    pinMode(fan_3, OUTPUT);                                        // mega PWM pin na ventilator
    pinMode(fan_4, OUTPUT);                                        // mega PWM pin na ventilator

*/

}

void loop () {
   
  DateTime datumCas = DS1307.now();                             // načtení aktuálního času a data do proměnné datumCas

  float teplota = mujHTU.readTemperature();                   // teplota
  float vlhkost = mujHTU.readHumidity();                         // vlhkost

  
  Serial.print("Aktualni cas ");                                          // vypsání informací čas a datum
  Serial.print(datumCas.hour());
  Serial.print(':');
  Serial.print(datumCas.minute());
  Serial.print(':');
  Serial.print(datumCas.second());
  Serial.print(", ");
  Serial.print(seznamDni[datumCas.dayOfTheWeek()]);
  Serial.print(" ");
  Serial.print(datumCas.day());
  Serial.print('.');
  Serial.print(datumCas.month());
  Serial.print('.');
  Serial.print(datumCas.year());
  Serial.println();
 
 
  String dataString = "Analog pin: ";                               // vytvoření proměnné dataString pro uložení
                                                                                  // zprávy, která bude zapsána na SD kartu
  int sensor = analogRead(analogPin);                           // načtení analogové hodnoty z nastaveného pinu
 
  dataString += String(sensor);                                     // připsání hodnoty z pinu do zprávy dataString
  dataString += ", cas: ";
 
  dataString += String(datumCas.hour()) + ":" + String(datumCas.minute()) + ":" + String(datumCas.second());
                                                                    // připsání aktuálního času do zprávy dataString,
                                                                    // jako oddělovač slouží +
  File zapisDat = SD.open("mereni.txt", FILE_WRITE);                // otevření souboru na SD kartě s názvem mereni.txt

 

  if (zapisDat)                                                     // v případě, že je soubor bez problémů vytvořen (pokud neexistuje),
   {                                                                     // nebo otevřen (pokud existuje), zapiš do něj dataString a ukonči zápis
    zapisDat.println(dataString);
    zapisDat.close();
    Serial.println("Zapis na kartu uspesny.");
  }
  
  else                                                                                       // v případě chyby při otevírání souboru vypiš chybu
  {
    Serial.println("Chyba pri otevreni souboru mereni.txt !");      // přidat pin na led s chybou
  }
  delay(1000);

 if (teplota > 150 | vlhkost > 100) {
    Serial.println("Chyba komunikace se senzorem HTU21D!");      // přidat pin na led s chybou
  }

  else
   {
    Serial.print("HTU21D | Teplota: ");                                        // přidat výpis na LCD
    Serial.print(teplota, 1);
    Serial.print(" st C | ");
    Serial.print("Vlhkost: ");
    Serial.print(vlhkost, 1);
    Serial.print("%");
    Serial.println();
  }
  delay(1000);

    int casvmin = datumCas.hour()*60 + datumCas.minute();
    if ((casvmin >= 7*60+30 ) && ( casvmin <= 18*60+40))
 
   //if ((datumCas.hour() >= 17 ) && ( datumCas.minute() >= 30) || (datumCas.hour() <= 18 ) && ( datumCas.minute() <= 40))
   //if (( datumCas.minute() >= 42) && (datumCas.minute() <= 45))          // ladící řádek
   //if (( datumCas.hour() > 17 < 18 ) && ( datumCas.minute() > 30 < 40 ))
   //if ((datumCas.hour() >= 17 ) && (datumCas.hour() <= 20 ) && ( datumCas.minute() >= 2) && ( datumCas.minute() <= 5))
   {
  		digitalWrite(8, HIGH);                         // svetlo   (den)
      Serial.println("DEN ");                                             
  }
   else 
   {
  		digitalWrite(8, LOW);                         // svetlo   (noc)
      Serial.println("NOC ");
   } 
delay(1000);

  if ((teplota > 1) && (teplota < 22))                   // topeni               Hlidani teploty, topeni a chlazeni
  {
    digitalWrite(4, HIGH);                                   // teplota nizka  (modra)
    digitalWrite(3, LOW);     //!!!!!!!!!!!!!!!!!!!!!!!!!!! doladit presnou teplotu na topeni a vlozit do promenne
    digitalWrite(2, LOW);
  }
  else if ((teplota >= 22) && (teplota <= 26))
  {
    digitalWrite(2, LOW);                                   // teplota OK (zelena)
    digitalWrite(3, HIGH); 
    digitalWrite(4, LOW);
  }
  else if (teplota > 27)
  {
    digitalWrite(3, LOW);                                  // teplota vysoka  (cervena)
    digitalWrite(2, HIGH);
    digitalWrite(4, LOW);
  //  analogWrite(fan_1, 255);
   // Serial.print("100%");                                 // rychlost ventilatoru pro orientaci
  }
  delay(1000);

   if ((vlhkost > 1) && (vlhkost <= 50))
  {
    digitalWrite(7, HIGH);                                 // zvlhčovač   (modra)
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);

  }
  else if ((vlhkost >= 51) && (vlhkost <= 69))    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!doladit vlhkost
  {
    digitalWrite(5, LOW);                                  // vlhkost OK   (zelena)
    digitalWrite(6, HIGH);
    digitalWrite(7, LOW);
  }
  else if (vlhkost > 70)
  {
    digitalWrite(7, LOW);                                  // odvlhčovač  (cervena)
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
  //  analogWrite(fan_1, 255);
  //  Serial.print("100%");                                 // rychlost ventilatoru pro orientaci
  }
  delay(1000);

  if ((teplota > 27) || (vlhkost > 70))               // rele odvětrání při poruše (test funkčnosti) nepoužívat
  {                                                                 // zaměnit za PWM ventilator
    digitalWrite(9, LOW);
  }
  else {
    digitalWrite(9, HIGH);
  }
 delay(1000);

}
EDIT: POUŽÍVEJTE TAG CODE !!!
Naposledy upravil(a) Michal_123 dne 01 lis 2023, 20:38, celkem upraveno 1 x.

Michal_123
Příspěvky: 9
Registrován: 31 říj 2023, 20:44
Reputation: 0

Re: Časové rozmezí

Příspěvek od Michal_123 » 01 lis 2023, 20:26

Teď to právě hledám, jak se to děla. Na příště se polepším

Uživatelský avatar
gilhad
Příspěvky: 788
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Časové rozmezí

Příspěvek od gilhad » 01 lis 2023, 20:43

Dělá se to tak, jak jsem napsal v tom příspěvku předtím, že to dá do tagu code - čili před to dáš slovo code v hranatých závorkách a za to slovo /code opět v hranatých (i s tím lomítkem).
Nebo označíš myší blok a stiskneš to tlačítko </> nad editačním polem a to ti tam ty tagy vloží samo.
a kliknutím na Náhled pod editačním polem uvižíš, jak se to povedlo.

Ten překlep, na který jsem koukal, by tadyhle (jedno svislítko místo dvou), ale ten moc nevadí a tudhle chybu nezpůsobuje :twisted:

Kód: Vybrat vše

 if (teplota > 150 | vlhkost > 100) {
Jinak to vypadá dobře, co ti to píše na Seriálu? Měl by tam být na začátku Aktualni cas a měl by být správně a někde dole by mělo být buď DEN, nebo NOC, podle toho vypsaného času.
Pokud to tak je, tak máš blbě zapojenou tu LED na 8, nebo je vadná, nebo je vadný ten procesor.
Pokud se to vypisuje špatně, tak si před tím ifem nech ještě vypsat ty casvmin, datumCas.hour(), datumCas.minute() a spočti si ručně, jestli to sedí.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 54 hostů