Stránka 1 z 2

Výměna vody v akvárium

Napsal: 27 úno 2019, 10:26
od jankas
Zdravím všechny,

pustil jsem se do projektu automatické výměny vody v akváriu (předem říkám, že jsem začátečník :D , tak mě omluvte jestli kód bude nepřehledný). Zatím to mám vymyšleno tak, že se v určitém čase spustí čerpadlo vypouštění. Hladinu "hlídá" senzor HC-SR05. Až se vypustí určité množství (podle výšky hladiny, denně cca. 10 litrů), čerpadlo se zastaví a sepne se čerpadlo napouštění. Až dosáhne určité výšky, tak se čerpadlo vypne. Tady mám problém - sériová linka se kousne a přestane vypisovat.

Používám Mega 2560 R3 (z Aliexpressu)
4x relé modul
RTC DS3231

Potřeboval bych "nakopnout", kde dělám chybu nebo jak by se to dalo udělat lépe. Zatím zkouším pokus/omyl.

Kód: Vybrat vše

#include <SPI.h>               
#include <Wire.h>
#include <DS3231.h>

#define DS3231_I2C_ADDRESS 0x68

// inicializace RTC z knihovny
DS3231 rtc;
// vytvoření proměnné pro práci s časem
RTCDateTime datumCas;

// Arduino Měřič vzdálenosti ultrazvukový

// piny pro připojení Trig a Echo z modulu
int pTrig = A0;
int pEcho = A1;
// inicializace proměnných, do kterých se uloží data
long odezva, vzdalenost;
 
void setup() {
  // komunikace přes sériovou linku rychlostí 9600 baud
  Serial.begin(9600);
  Wire.begin();
  // nastavení pinů modulu jako výstup a vstup
  pinMode(pTrig, OUTPUT);
  pinMode(pEcho, INPUT);
  // zahájení komunikace s RTC obvodem
  rtc.begin();
  // nastavení času v RTC podle času kompilace programu,
  // stačí nahrát jednou
  rtc.setDateTime(__DATE__, __TIME__);
  // přímé nastavení času pro RTC
  //rtc.setDateTime(__DATE__, "12:34:56");

  pinMode(8, OUTPUT);                    // pin pro čerpadlo vypouštění
  pinMode(9, OUTPUT);                    // pin pro čerpadlo napouštění
}

void loop()
{
  Serial.begin(9600);
  digitalWrite(pTrig, LOW);
  delayMicroseconds(2);
  digitalWrite(pTrig, HIGH);
  delayMicroseconds(5);
  digitalWrite(pTrig, LOW);
  odezva = pulseIn(pEcho, HIGH);
  // přepočet času na vzdálenost v cm
  vzdalenost = odezva / 58.31;
  int sensorValue = analogRead(A4);    //senzor pro alarm přetečení nádrže
  delay(200);

 
  // načtení času z RTC do proměnné
  datumCas = rtc.getDateTime();
  // postupný tisk informací po sériové lince
  Serial.print("Datum a cas: ");
  Serial.print(datumCas.hour);   Serial.print(":");
  Serial.print(datumCas.minute); Serial.print(":");
  delay(500);
  Serial.print("Vzdalenost je ");
  Serial.print(vzdalenost);
  Serial.println(" cm.");
  delay(500);
  Serial.println(sensorValue);
  delay(500);

 if (datumCas.hour == 21 && datumCas.minute == 40 ){
//Pokud je vše splněno, tak se začne vypouštět
  
digitalWrite(8, HIGH); // Vypouštění vody z akva (motor)
digitalWrite(9, LOW);
delay(300); // 

}

 if (vzdalenost>=4){
 digitalWrite(8, LOW);
 digitalWrite(9, HIGH);
 delay(400);
}
 
 if (vzdalenost<=2){
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
 delay(2000);
 }
}

Re: Výměna vody v akvárium

Napsal: 27 úno 2019, 11:35
od ohruska
Zdravím.
Nevím jestli je to ono, ale

Kód: Vybrat vše

Serial.begin(9600);
patří jen do hlavičky.

Zkuste to ze smyčky "loop" smazat.

Ota

Re: Výměna vody v akvárium

Napsal: 28 úno 2019, 08:45
od jankas
Děkuji za reakci, ale odstranění ze smyčky loop nepomohlo. Zdá se mi, že jednou to funguje, podruhé už zase ne a kousne se to.

Re: Výměna vody v akvárium

Napsal: 28 úno 2019, 11:33
od ohruska
Proč máte připojeno čidlo na A0 a A01.
Zkuste ho přepojit na digitální piny, třeba D3 aD4.
Ota

Re: Výměna vody v akvárium

Napsal: 28 úno 2019, 13:40
od gilhad
Protože A0 a A1 jsou normální digitální piny stejně jako třeba D3 a D4 (pokud se jim nastaví pinMode() na OUTPUT, INPUT, nebo INPUT_PULLUP).

Stejně tak A2..A5. Jenom A6 a A7 nemaji digitalni I/O funkce. Viz datasheet.

Re: Výměna vody v akvárium

Napsal: 28 úno 2019, 15:18
od jankop
Správná je připomínka ohledně Serial.begin() ve smyčce loop(), to může dělat problémy.
Z technického hlediska se mi nelíbí ten ultrazvukový senzor, myslím si, že nevydrží vysokou vlhkost nad akváriem. Použil bych asi nějaké dva jazýčkové kontakty a plováček s magnetem. To se dají do plastové uzavřené trubičky dva jazýčkové kontakty a na tu trubku se navlékne nějaký plováček s magnetem, třeba ze starého ventilátoru chladiče procesoru nebo nějakého menšího fanu. Myslím, že se něco takového i prodává.
K vlastnímu programu:
1. Když je akva plné, tak platí nejspíš vzdalenost<=2 a to je tedy výchozí stav
2. Ve 21:40 se začne vypouštět
3. za 0,3 s poté se zkontroluje, jestli už není hladina na dolní požadované mezi vzdalenost>=4, aby se jedno čerpadlo vyplo a druhé zaplo, podmínka ovšem nejspíš ještě neplatí.
4. za dalších 0,4s se zkontroluje jestli není akvárium plné, vzdalenost<=2 a napouštěcí čerpadlo se vypne, protože akvárium nejspíš plné ještě je. Předpokládám, že za 0,7sekundy se hladina moc nepohne.
V konečném důsledku se ti bude 1 minutu s opakováním 4,4 sekundy, do 21:40:59 rychle zapínat a vypínat vypouštěcí čerpadlo. Ono se bude vypínat i napouštěcí, ale to nebude nikdy zapnuté, tak to nepoznáš.
Tak to vidím já a asi by to tak být nemělo. Na druhé straně, když ti akvárium praskne, tak bez ohledu na čas, ti napouštěcí čerpadlo bude přidávat neustále vodu a rybičky budou zachráněny :D
Pokud ti ustřeluje celý program, tak to může být také rušením od motorů čerpadel a chybami v rozvodech napájení, případně nevyužití galvanického oddělení relé. O těchto důležitých HW věcech se ovšem nezmiňuješ.

Re: Výměna vody v akvárium

Napsal: 02 bře 2019, 09:26
od pavelve
Jak píše jankop taky bych hledal chybu v zapojení HW. Jinak se dalají i vodotěsné ultazvukové senzory, vypadá to jak ty na auto (https://bit.ly/2INnl7E). Měl jsem to jednu dobu venku a bez problému za jakéhokoli počasí.

Re: Výměna vody v akvárium

Napsal: 03 bře 2019, 23:18
od ohruska
Zdravím.
Možná by se dalo zkusit, napsat si za každý příkaz, každý řádek "Serial.println" s příkazem, který se měl vykonat.
Tak by se mělo zjistit na čem program zatuhne.
Ota

Kód: Vybrat vše

  delay(500);
Serial.println("delay(500);");
 if (datumCas.hour == 21 && datumCas.minute == 40 ){
Serial.println("if (datumCas.hour == 21 && datumCas.minute == 40 ){");
//Pokud je vše splněno, tak se začne vypouštět
  
digitalWrite(8, HIGH); // Vypouštění vody z akva (motor)
Serial.println("digitalWrite(8, HIGH);");
digitalWrite(9, LOW);
Serial.println("digitalWrite(9, LOW);");

Re: Výměna vody v akvárium

Napsal: 12 bře 2019, 11:10
od jankas
Děkuji všem za reakce. Zkusil jsem znovu vše odpojit a zapojil tak, že teď už program normálně pokračuje. Mám v plánu přidat ještě solenoidy, které budou regulovat vypuštění/napuštění. Dále jsem zvýšil časovou kontrolu vypouštění na 15 sekund (kdy se už za tuto dobu něco vypustí a neděje se to jak psal jankop, že relé vypíná/zapíná ve velmi krátkém čase).

Akorát mám další problém :D - a to je zpožďování hodin. Za den je to o 5 minut. Nemá s tím někdo zkušenost?

Re: Výměna vody v akvárium

Napsal: 12 bře 2019, 12:43
od ohruska
Nevím jaký máš modul. Pokud je to DS1307, tak je to normální.
Zkusil bych DS3231. Měl by být stabilnější.