• Most regisztráltál, de nem tudsz privát üzenetet küldeni?

    Kérjük olvasd el milyen korlátozások vonatkoznak rád, miután regisztrációd jóvá lett hagyva.
    Regisztrációs korlátozások

Építsünk akváriumvezérlőt Arduino-ból

Sziasztok,

Nem tudom, hogy a korábbi hozzászólásokban volt-e már erről szó...

PWM vezérléssel oldottam meg az akváriumom (250 liter, édesvizi) világítását, azaz este nem lekapcsol a fény, hanem "beesteledik", egy óra alatt megy le nullára a fő világításom.
Reggel pedig fordítva. Ha valakit érdekel, ebben tudok segíteni.

Kiegészítés; mivel nálunk nagyon ritka az áramszünet, így külső óra IC helyett szoftveres RTC-t használtam, így nincs kommunikációs probléma az órával és egyszerűbb. Ha áramszünet lesz, akkor egy kicsit macerásabb a dolog, mert újra be kell állítani (tehát kényes feladatokra nem jó), de a világítás ha keresztbe is áll; nem tragédia.
 
Szia,

Amit első klikkre látok, hogy a reléket kezdéskor nem lekapcsolod, hanem fel... Ettől pesze még lehet, hogy negatív vezérlésed van, és akkor ez jó.
De a pinMode megadásnak illik megelőznie a digitalWrite utasítást, szóval ez fordított sorrendnek tűnik.

void setup() {
// Set the relay to off immediately
digitalWrite(lightRelay1, HIGH);
digitalWrite(lightRelay2, HIGH);
digitalWrite(lightRelay3, HIGH);
digitalWrite(lightRelay4, HIGH);
digitalWrite(lightRelay5, HIGH);
digitalWrite(lightRelay6, HIGH);
Serial.begin(9600);
Wire.begin();
RTC.begin();

// Set the pinmode
pinMode(lightRelay1, OUTPUT);
pinMode(lightRelay2, OUTPUT);
pinMode(lightRelay3, OUTPUT);
pinMode(lightRelay4, OUTPUT);
pinMode(lightRelay5, OUTPUT);
pinMode(lightRelay6, OUTPUT);

Mit értesz azon, hogy nem kapcsol rendesen?
 
És elkészült az időzítő lib is!
Ezt is ugyanúgy kell telepíteni, ahogy a többi library-t. A működéséhez szükség lesz az Adafruit féle RTClib-re is, ez segít az óra modullal való kommunikációban, ezt is mellékelem. Megírtam a példákat DS1307-re és DS3231-re is, az examples könyvtárban találjátok.

Először egy nagyon egyszerű példát mutatnék, pl: fénycsöves világítás ki-be kapcsolásához (ahol nem kell dimmelni), DS3231-el:
Kód beillesztése:
#include <RTClib.h>

// Itt mondjuk meg neki, hogy milyen órát használjon, ezt még a timer #include-ja előtt meg kell tenni!
#define WITH_DS3231       
#include <AquaTimer.h>

// A pin száma ami pl. a reléhez megy
const int LIGHTS_PIN = 6; 

// Ez nagyon fontos, hogy pontosan 'rtc' nevű változó kell a timernek, hogy be tudja olvasni az időt
RTC_DS3231 rtc;          

// Itt definiáljuk a timer objektumot, a paraméterek: PIN száma, bekapcs, kikapcs
// Fontos, hogy String-ben kell megadni a be és kikapcsolási időket, és az órákat is ki kell egészíteni 2 számjegyre,
// vagyis "6:00" nem jó, hanem "06:00" kell! - De ki akarna olyan korán világítani? :)
AquaTimer LedTimer(LIGHTS_PIN, "14:00", "22:00");

void setup() {
  // Óra modul indítása
  rtc.begin();
  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  // ez a sor pedig kiírja a megadott pinre az adott időnek megfelelő értéket
  LedTimer.write();
}


Itt pedig egy példa 3 tápadagoló időzítéséhez. A kimenetek (6,7,8) relékkel, vagy mosfetekkel vezérlik a pumpák motorjait. A hardveres részt itt nem részletezném, a lényeg inkább a kód:
Kód beillesztése:
#include <RTClib.h>
#define WITH_DS3231
#include <AquaTimer.h>

RTC_DS3231 rtc;

// Ugyanaz, mint fent, csak egymás után több kimenetet kapcsolunk különböző időpontokban
// PIN, bekapcs, kikapcs
AquaTimer Micro(6, "13:40:00", "13:40:04");
AquaTimer Macro(7, "13:40:20", "13:40:24");
AquaTimer Carbo(8, "13:40:40", "13:40:44");

void setup() {
  rtc.begin();
  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  // Külön-külön meg kell hívni az egyes kimenetekre a kiíratást
  Micro.write();
  Macro.write();
  Carbo.write();
}


És végül egy kicsit komplettebb példa, ahol már van led átmenet, holdfény effekt, szűrő kikapcs, és 4 tápadagoló:
Kód beillesztése:
#include <RTClib.h>
#include <AutoSwitch.h>

#define WITH_DS3231
#include <AquaTimer.h>

RTC_DS3231 rtc;

const int LED_PIN = 6;
const int FILTER_PIN = 7;

// A világítás bekapcsoló gombja, egy óra után kikapcsolja magát
AutoSwitch LedButton(2, 3600);
// A szűrő stop etetéshez, ami 5 perc után újraindítja a szűrőt
AutoSwitch FilterStopButton(3, 300);

AquaTimer LedTimer;
AquaTimer Micro(8, "13:40:00", "13:40:04");
AquaTimer Macro(9, "13:40:20", "13:40:24");
AquaTimer Carbo(10, "13:40:40", "13:40:44");
AquaTimer Phosphate(11, "13:41:00", "13:41:04");

void setup() {
  pinMode(FILTER_PIN, OUTPUT);
  rtc.begin();
  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  // Világítás beállításai. A sok paraméter miatt metódus láncolással, hogy olvashatóbb legyen
  // A LED dimmeléséhez a PWM kimenet miatt relé helyett itt egy MOSFET-re lesz szükség!
  LedTimer
  .setPin(LED_PIN)
  .setOn("14:00")         // bekapcs
  .setTransition("30")    // átmenet ideje percben
  .setOff("22:00")        // kikapcs
  .setMoonDuration("60")  // holfény derengés ideje percben, a kikapcs után
  .setMaxVal("75%")       // a teljes fényerő dimmeléséhez. Ha 100% kellene, akkor elhagyható
  .setMoonVal(1);         // a holfény fényereje. Itt szándékosan van int, a lehető legkisebb fényerő kedvéért
}

void loop() {
  // Tápadagolók
  Micro.write();
  Macro.write();
  Carbo.write();
  Phosphate.write();

  // Világítás a teljes fényerő gombbal
  int buttonState = LedButton.getState();
  LedTimer.write(buttonState);

  // Szűrő stop -  a relén a NC (Normally Closed) kimenetre érdemes kötni a szűrő konnektorát
  int filterStopState = FilterStopButton.getState();
  digitalWrite(FILTER_PIN, filterStopState);
}

Ez a kód egyébként csak 29%-ot használ el egy UNO memóriájából, szóval a maradék 10 szabad lábra még bőven lehet konfigurálgatni hőmérőt, kijelzőt, etető automatát, twinstart, vagy amit épp gondoltok.

Jó kódolást!


Üdv, rájöttem mi a probléma, az én relé paneljeim fordítva működnek, azt tudom hogy a low és high fel kell cserélnem, de a kódon belül nem találom, valaki tudja hol keressem?
 
Ha az AquaTimer libet használod, akkor nincs nagyon triviális megoldás (még), de pl a Micro.write(now); helyett így lehet megoldani:
Kód beillesztése:
if (Micro.getVal(now)) {
  digitalWrite(micro-relé-pin, LOW);
} else {
  digitalWrite(micro-relé-pin, HIGH);
}
 
Ha az AquaTimer libet használod, akkor nincs nagyon triviális megoldás (még), de pl a Micro.write(now); helyett így lehet megoldani:
Kód beillesztése:
if (Micro.getVal(now)) {
  digitalWrite(micro-relé-pin, LOW);
} else {
  digitalWrite(micro-relé-pin, HIGH);
}

Üdv kicseréltem ,de nem fordul le. megnéznéd hogy nálad a csere után lefordul?
 
A micro-relé-pin szöveget természetesen át kell írnod a megfelelő kimeneted számára. És ezt minden egyes relédhez külön meg kell csinálnod.
 
A micro-relé-pin szöveget természetesen át kell írnod a megfelelő kimeneted számára. És ezt minden egyes relédhez külön meg kell csinálnod.


Kód beillesztése:
#include <RTClib.h>
#include <AutoSwitch.h>

#define WITH_DS3231
#include <AquaTimer.h>

RTC_DS3231 rtc;

const int LED_PIN = 6;
const int FILTER_PIN = 7;

// A világítás bekapcsoló gombja, egy óra után kikapcsolja magát
AutoSwitch LedButton(2, 3600);
// A szűrő stop etetéshez, ami 5 perc után újraindítja a szűrőt
AutoSwitch FilterStopButton(3, 300);

AquaTimer LedTimer;
AquaTimer Micro(8, "13:40:00", "13:40:04");
AquaTimer Macro(9, "13:40:20", "13:40:24");
AquaTimer Carbo(10, "13:40:40", "13:40:44");
AquaTimer Phosphate(11, "13:41:00", "13:41:04");

void setup() {
  pinMode(FILTER_PIN, OUTPUT);
  rtc.begin();
  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  // Világítás beállításai. A sok paraméter miatt metódus láncolással, hogy olvashatóbb legyen
  // A LED dimmeléséhez a PWM kimenet miatt relé helyett itt egy MOSFET-re lesz szükség!
  LedTimer
  .setPin(LED_PIN)
  .setOn("14:00")         // bekapcs
  .setTransition("30")    // átmenet ideje percben
  .setOff("22:00")        // kikapcs
  .setMoonDuration("60")  // holfény derengés ideje percben, a kikapcs után
  .setMaxVal("75%")       // a teljes fényerő dimmeléséhez. Ha 100% kellene, akkor elhagyható
  .setMoonVal(1);         // a holfény fényereje. Itt szándékosan van int, a lehető legkisebb fényerő kedvéért
}

void loop() {
  // Tápadagolók
  if (Micro.getVal(now)) {
  digitalWrite(micro-relay-8, LOW);
} else {
  digitalWrite(micro-relay-8, HIGH);
}
  if (Macro.getVal(now)) {
  digitalWrite(macro-relay-9, LOW);
} else {
  digitalWrite(macro-relay-9, HIGH);
}
  if (Carbo.getVal(now)) {
  digitalWrite(carbo-relay-10, LOW);
} else {
  digitalWrite(carbo-relay-10, HIGH);
}
  if (Phosphate.getVal(now)) {
  digitalWrite(phosphate-relay-11, LOW);
} else {
  digitalWrite(phosphate-relay-11, HIGH);
}

  // Világítás a teljes fényerő gombbal
  int buttonState = LedButton.getState();
  LedTimer.write(buttonState);

  // Szűrő stop -  a relén a NC (Normally Closed) kimenetre érdemes kötni a szűrő konnektorát
  int filterStopState = FilterStopButton.getState();
  digitalWrite(FILTER_PIN, filterStopState);
}

Üdv így?
 
Majdnem :)

A digitaWrite, csak egy számot kér:
Kód beillesztése:
if (Micro.getVal(now)) {
  digitalWrite(8, LOW);
} else {
  digitalWrite(8, HIGH);
}
 
Kód beillesztése:
#include <RTClib.h>
#include <AutoSwitch.h>

#define WITH_DS3231
#include <AquaTimer.h>

RTC_DS3231 rtc;

const int LED_PIN = 6;
const int FILTER_PIN = 7;

// A világítás bekapcsoló gombja, egy óra után kikapcsolja magát
AutoSwitch LedButton(2, 3600);
// A szűrő stop etetéshez, ami 5 perc után újraindítja a szűrőt
AutoSwitch FilterStopButton(3, 300);

AquaTimer LedTimer;
AquaTimer Micro(8, "13:40:00", "13:40:04");
AquaTimer Macro(9, "13:40:20", "13:40:24");
AquaTimer Carbo(10, "13:40:40", "13:40:44");
AquaTimer Phosphate(11, "13:41:00", "13:41:04");

void setup() {
  pinMode(FILTER_PIN, OUTPUT);
  rtc.begin();
  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  // Világítás beállításai. A sok paraméter miatt metódus láncolással, hogy olvashatóbb legyen
  // A LED dimmeléséhez a PWM kimenet miatt relé helyett itt egy MOSFET-re lesz szükség!
  LedTimer
  .setPin(LED_PIN)
  .setOn("14:00")         // bekapcs
  .setTransition("30")    // átmenet ideje percben
  .setOff("22:00")        // kikapcs
  .setMoonDuration("60")  // holfény derengés ideje percben, a kikapcs után
  .setMaxVal("75%")       // a teljes fényerő dimmeléséhez. Ha 100% kellene, akkor elhagyható
  .setMoonVal(1);         // a holfény fényereje. Itt szándékosan van int, a lehető legkisebb fényerő kedvéért
}

void loop() {
  // Tápadagolók
  if (Micro.getVal(now)) {
  digitalWrite(8, LOW);
} else {
  digitalWrite(8, HIGH);
}
  if (Macro.getVal(now)) {
  digitalWrite(8, LOW);
} else {
  digitalWrite(8, HIGH);
}
  if (Carbo.getVal(now)) {
  digitalWrite(8, LOW);
} else {
  digitalWrite(8, HIGH);
}
  if (Phosphate.getVal(now)) {
  digitalWrite(8, LOW);
} else {
  digitalWrite(8, HIGH);
}

  // Világítás a teljes fényerő gombbal
  int buttonState = LedButton.getState();
  LedTimer.write(buttonState);

  // Szűrő stop -  a relén a NC (Normally Closed) kimenetre érdemes kötni a szűrő konnektorát
  int filterStopState = FilterStopButton.getState();
  digitalWrite(FILTER_PIN, filterStopState);
}

Üdv, átirtam, most sem fordul le.
Hiba:
C:\Users\tomi\Documents\Arduino\sketch_jan22b\sketch_jan22b.ino: In function 'void loop()':

sketch_jan22b:44: error: 'now' was not declared in this scope

if (Micro.getVal(now)) {

^

sketch_jan22b:49: error: 'now' was not declared in this scope

if (Macro.getVal(now)) {

^

sketch_jan22b:54: error: 'now' was not declared in this scope

if (Carbo.getVal(now)) {

^

sketch_jan22b:59: error: 'now' was not declared in this scope

if (Phosphate.getVal(now)) {

^

exit status 1
'now' was not declared in this scope
 
Szia Tamás! Ne haragudj meg, de szerintem akkor érdemes arduino programozással foglalkozni, ha te magad is érted, hogy hogyan is működik egy ilyen mikrokontroller, és legalább nagyjából képben vagy az adott programozási nyelv alapjaival, és utasításaival. Úgy biztosan nem fog menni, ha csak a fórumról próbálsz bemásolgatni kódokat anélkül, hogy megértenéd mi történik.
Ha komolyan meg szeretnéd tanulni, akkor érdemes az alapoktól indulni, és végigolvasni a tutorialokat, megcsinálgatni az alap kapcsolásokat (pl led blink), és amikor már ezek mennek, akkor fokozatosan építeni feljebb a rendszeredet RTC-vel, PWM-mel, relékkel, és egyéb perifériákkal. Ez nyilván nagyon sok idő, amit csak akkor éri meg igazán rászánni, ha egyébként élvezed az ilyesmit.

Egyéb esetben meg van itt a fórumon néhány kolléga, aki szokott megrendelésre is ilyen vezérlőket építeni, lehet, hogy náluk lenne érdemes érdeklődnöd.
 
Üdv!
Nagyjából összeállt a vezérlőm, már élesben megy. Tudja a a tápadagolást, reléket kapcsolgatja, potival tudom állítani a max fényerőt, viszont a napfelkelte és naplemente az már nem igazán akar menni(tömb kéne hozzá gondolom az meg már sok nekem). Valaki nem tudna kisegíteni egy kóddal? Köszönöm!
 
Pl ez a függvény kiszámolja neked az adott pillanathoz tartozó fényerőt.
Nálam másodpercenként hívódik meg, miután beállítottam a "secsToday" változót, mégpedig a mai napon eltelt másodpercek számára. (pl reggel 8 óra = 8 * 60 * 60 = 28800, este 10 = 22 * 60 * 60 = 79200) Ezt gondolom ki tudod nyerni az RTC-ből vagy kiszámolni valahogy.

Utána szintén másodpercenként meghívhatod a getLedVal() függvényt, ami visszaadja az aktuális fényerőt, amit simán ki is írathatsz analogWrite-tal a megfelelő pwm pinre. A bekapcs időponttól fokozatosan növeli a fényerőt a max-ig a beállított átmenet idő alatt, majd a kikapcs előtt fordítva. A végén nálam még egy órát dereng 1-es fényerőn a holdfény, de ha nem kell ez, akkor vedd le a moonDuration-t 0-ra (vagy töröld ki a moonLight részt).

Amúgy volt itt korábban elegánsabb, nem-lineáris megoldás is, ha visszakeresel biztos megtalálod.

Kód beillesztése:
unsigned long secsToday;

unsigned long led1On = 50400; // bekapcs 14:00
unsigned long led1Off = 79200; // kikapcs 22:00
int led1Power = 204; // max fényerő 80%
const int transition = 1800; // átmenetek 30 perc 
const int moonDuration = 3600;  // éjszakai "holdfény" a lekapcsolás után 60 percig
const byte moonVal = 1;  // éjszakai fényerő

// PWM számolása
byte getLedVal()
{
  byte val = 0;

  // warm up
  if (secsToday >= led1On && secsToday < led1On + transition) {
    val = led1Power * (secsToday - led1On) / transition;
  }
  // lights on
  if (secsToday >= led1On + transition && secsToday < led1Off - transition) {
    val = led1Power;
  }
  // fade off
  if (secsToday >= led1Off - transition && secsToday < led1Off) {
    val = led1Power * (led1Off - secsToday) / transition + moonVal;
  }
  // moonLight
  if (secsToday >= led1Off && secsToday < led1Off + moonDuration) {
    val = moonVal;
  }
  // off
  if (secsToday >= led1Off + moonDuration) {
    val = 0;
  }

  return val;
}
 
Pl ez a függvény kiszámolja neked az adott pillanathoz tartozó fényerőt.
Nálam másodpercenként hívódik meg, miután beállítottam a "secsToday" változót, mégpedig a mai napon eltelt másodpercek számára. (pl reggel 8 óra = 8 * 60 * 60 = 28800, este 10 = 22 * 60 * 60 = 79200) Ezt gondolom ki tudod nyerni az RTC-ből vagy kiszámolni valahogy.

Utána szintén másodpercenként meghívhatod a getLedVal() függvényt, ami visszaadja az aktuális fényerőt, amit simán ki is írathatsz analogWrite-tal a megfelelő pwm pinre. A bekapcs időponttól fokozatosan növeli a fényerőt a max-ig a beállított átmenet idő alatt, majd a kikapcs előtt fordítva. A végén nálam még egy órát dereng 1-es fényerőn a holdfény, de ha nem kell ez, akkor vedd le a moonDuration-t 0-ra (vagy töröld ki a moonLight részt).

Amúgy volt itt korábban elegánsabb, nem-lineáris megoldás is, ha visszakeresel biztos megtalálod.

Kód beillesztése:
unsigned long secsToday;

unsigned long led1On = 50400; // bekapcs 14:00
unsigned long led1Off = 79200; // kikapcs 22:00
int led1Power = 204; // max fényerő 80%
const int transition = 1800; // átmenetek 30 perc
const int moonDuration = 3600;  // éjszakai "holdfény" a lekapcsolás után 60 percig
const byte moonVal = 1;  // éjszakai fényerő

// PWM számolása
byte getLedVal()
{
  byte val = 0;

  // warm up
  if (secsToday >= led1On && secsToday < led1On + transition) {
    val = led1Power * (secsToday - led1On) / transition;
  }
  // lights on
  if (secsToday >= led1On + transition && secsToday < led1Off - transition) {
    val = led1Power;
  }
  // fade off
  if (secsToday >= led1Off - transition && secsToday < led1Off) {
    val = led1Power * (led1Off - secsToday) / transition + moonVal;
  }
  // moonLight
  if (secsToday >= led1Off && secsToday < led1Off + moonDuration) {
    val = moonVal;
  }
  // off
  if (secsToday >= led1Off + moonDuration) {
    val = 0;
  }

  return val;
}
Köszönöm szépen! Azt hiszem működik is, majd még megpróbálom a potméteres fényerő állítást beleépíteni és jó is lesz. Bár ha potival állítgattam a fényerőt volt egy kis villódzás, a poti miatt,hogy minimálisan ugrál az ellenállása, ha nem tudom megoldani akkor lehet marad így. Mondjuk jó lenne még Nextionra rákötni, vagy esetleg blynk-ről vezérelni, de addig még nagyon sokat kell olvasgatni és gyakorolni :D
 
Köszönöm szépen! Azt hiszem működik is, majd még megpróbálom a potméteres fényerő állítást beleépíteni és jó is lesz. Bár ha potival állítgattam a fényerőt volt egy kis villódzás, a poti miatt,hogy minimálisan ugrál az ellenállása, ha nem tudom megoldani akkor lehet marad így. Mondjuk jó lenne még Nextionra rákötni, vagy esetleg blynk-ről vezérelni, de addig még nagyon sokat kell olvasgatni és gyakorolni :D
Ha mindenképpen potival szeretnéd állítani a fényerőt, akkor azt javasolnám, hogy a potméter értékével a led1Power változót update-eld 0 és 255 között pl így:
Kód beillesztése:
val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
led1Power = map(val, 0, 1023, 0, 255);     // scale it to use it with the servo (value between 0 and 255)
(A szervó példából loptam: https://www.arduino.cc/en/Tutorial/Knob)
 
Pl ez a függvény kiszámolja neked az adott pillanathoz tartozó fényerőt.
Nálam másodpercenként hívódik meg, miután beállítottam a "secsToday" változót, mégpedig a mai napon eltelt másodpercek számára. (pl reggel 8 óra = 8 * 60 * 60 = 28800, este 10 = 22 * 60 * 60 = 79200) Ezt gondolom ki tudod nyerni az RTC-ből vagy kiszámolni valahogy.

Csak pici kiegészítést tennék. Csak azért, hogy a nem egész órás kapcsolások számítása is tiszta legyen (igaz az előző oldalon foglalkoztunk már vele, csak akkor perc alapon....) A napi eltelt másodperceket számoljuk ebben a példában és ahhoz viszonyítunk! A bekapcsolás változó értékét pld. így kapjuk meg: (óra * 3600) + (perc*60) + (másodperc), tehát 10 óra 20 perc 12 másodperc eredménye : 10*3600 + 20*60 + 12 = 37212 (persze a másodperc alapú kapcsolás ebben az esetben kicsit túlzás..., én a perc alap híve vagyok).

Más:
Arduinós fórumokban is kérdeztem, de itt hátha előbb nyújt nekem valaki segítő jobbot (vagy balt):
A DS3231 RTC eepromját (AT24C32) szeretném Due mellett használni, de még soha nem volt dolgom semmiféle eeprommal, így elég láma vagyok.
A feladat az volna, hogy 50-60db uint32_t változót (Nextion HMI miatt a number-eket így kell deklarálni - ezért van ez a pazarlás) kellene elmentenem gombnyomásra az eepromba (akár egyszerre az összeset vagy külön címenként - nem tudom mi a célravezetőbb). A változók értékei egyébként csak 0-255 közötti egész számok lehetnek (tehát elméletben elég egy byte egy változónak, ha jól értem) . Egy-egy változónak fix helyen!? kellene lennie, hogy esetleges újraindítást követően visszaolvasásakor megtalálja és felül tudja írni az elmentett értékkel a deklarált változó tartalmát. Mivel viszonylagosan ritkán lenne felülírási ciklus (max napi 1-2 ), az eeprom élettartama (100.000 ciklus) nem meghatározó.

Így leírva nem is hangzik bonyolultnak, de mégis.... Hogy álljak neki?
Elgondolkodtam esetleg külső külön eeprom (24LC256) használatán is. A címzésnél lehet ütközés ebben az esetben (RTC 0x68 ; 24LC256 0x50)?
Köszi a segítséget!
 
Szia @nagyharcos!

Az EEPROM-ot úgy kell elképzelni, mint egy nagy memóriatábla ahova bájtonként tudsz írni, és onnan olvasni. Bárhova írhatsz, de azt hogy melyik címre milyen adatot írtál, azt neked (vagy a programodnak) kell tudni. Nincs struktúra, nincsenek változók vagy könyvtárak, csak byte címek és azok értékei. A korai arduino verziók még csak egy-egy byte-ot tudtak írni és olvasni a read/write metódusokkal, vagyis a 2 vagy 4 byte-os változókkal kicsit dolgozni kellett, de szerencsére most már belekerült két újabb metódus is, a get és put, ami figyelembe veszi, hogy mekkora méretű változót akarsz kiírni, vagy beolvasni, így még kényelmesebb a használata. Nálam így néz ki az induláskor az eltárolt adatok beolvasása:
Kód beillesztése:
  EEPROM.get(0, led1On);
  EEPROM.get(4, led1Off);
  EEPROM.get(8, led1Power);
stb...
Vagyis a 0. a 4. és a 8. címről olvasom be a 3 db változót, amelyek 4 byte-os long-ok. A másik oldalon, a mentéskor, igyekeztem a megfelelő változókat ugyanezekre a címekre kiírni:
Kód beillesztése:
  EEPROM.put(0, led1On);
  EEPROM.put(4, led1Off);
...
Kb ennyi.

Az uint32_t is 4 byte (=32bit) szóval neked is az lesz a feladatod, hogy 4 byte-onként kiírogasd és beolvasgasd az értékeket. 50-60 db változóra elég "repetitív" feladat lesz megírnia kódot, ha nincsenek tömbökbe rendezve valahogy, de gondolom meg tudod oldani.

A fentiek az arduino uno/nano beépített EEPROMjára és az alap EEPROM library-ra vonatkoznak (https://www.arduino.cc/en/Reference/EEPROM), nekem csak ezzel van tapasztalatom.

Van viszont egy nagyon jónak tűnő lib az AT24C32-höz is, ami a DS3231-en van: https://github.com/cyberp/AT24Cx
Elég alapos a leírása, a lényege pontosan ugyanaz, ahogy nézem csak annyi a különbség, hogy get/put helyett readLong / writeLong metódusokat kell használni a 4 byte-os változókhoz. Én azt gondolom, hogy ha már úgyis be van kötve az RTC, és ott van rajta 32k eeprom, akkor akkor fölösleges lenne még egy újabb eszközt beizzítani. Próbáld meg ezzel, mennie kell!
 
Szia @nagyharcos!

Az EEPROM-ot úgy kell elképzelni, mint egy nagy memóriatábla ahova bájtonként tudsz írni, és onnan olvasni. Bárhova írhatsz, de azt hogy melyik címre milyen adatot írtál, azt neked (vagy a programodnak) kell tudni. Nincs struktúra, nincsenek változók vagy könyvtárak, csak byte címek és azok értékei. A korai arduino verziók még csak egy-egy byte-ot tudtak írni és olvasni a read/write metódusokkal, vagyis a 2 vagy 4 byte-os változókkal kicsit dolgozni kellett, de szerencsére most már belekerült két újabb metódus is, a get és put, ami figyelembe veszi, hogy mekkora méretű változót akarsz kiírni, vagy beolvasni, így még kényelmesebb a használata. Nálam így néz ki az induláskor az eltárolt adatok beolvasása:
Kód beillesztése:
  EEPROM.get(0, led1On);
  EEPROM.get(4, led1Off);
  EEPROM.get(8, led1Power);
stb...
Vagyis a 0. a 4. és a 8. címről olvasom be a 3 db változót, amelyek 4 byte-os long-ok. A másik oldalon, a mentéskor, igyekeztem a megfelelő változókat ugyanezekre a címekre kiírni:
Kód beillesztése:
  EEPROM.put(0, led1On);
  EEPROM.put(4, led1Off);
...
Kb ennyi.

Az uint32_t is 4 byte (=32bit) szóval neked is az lesz a feladatod, hogy 4 byte-onként kiírogasd és beolvasgasd az értékeket. 50-60 db változóra elég "repetitív" feladat lesz megírnia kódot, ha nincsenek tömbökbe rendezve valahogy, de gondolom meg tudod oldani.

A fentiek az arduino uno/nano beépített EEPROMjára és az alap EEPROM library-ra vonatkoznak (https://www.arduino.cc/en/Reference/EEPROM), nekem csak ezzel van tapasztalatom.

Van viszont egy nagyon jónak tűnő lib az AT24C32-höz is, ami a DS3231-en van: https://github.com/cyberp/AT24Cx
Elég alapos a leírása, a lényege pontosan ugyanaz, ahogy nézem csak annyi a különbség, hogy get/put helyett readLong / writeLong metódusokat kell használni a 4 byte-os változókhoz. Én azt gondolom, hogy ha már úgyis be van kötve az RTC, és ott van rajta 32k eeprom, akkor akkor fölösleges lenne még egy újabb eszközt beizzítani. Próbáld meg ezzel, mennie kell!

Szia @mbence! Köszi, valami ilyesmire gondoltam én is, csak kellett a megerősítés! Sajna a Due csupaszon EEPROMtalan. Ez a lib elkerülte a figyelmemet, jónak tűnik és elég egyszerű is a használata. Alapból kerülöm a lib-ek használatát, - ha lehet, mert a Due marha kényes jószág - de ezt kipróbálom. Azt hiszem a tömbök irányába mozdulok...
A saját vezérlőm beüzemelés előtt újragondoltam, mert futás közben belassult, valszeg nem voltam elég figyelmes a programozás során. Elég sok dolgot tároltam bufferekben, sztem ott volt a galiba. Most tiszta lappal újraindulok, és hát ilyenkor jönnek az újabb ötletek :).
 
Utoljára módosított:
Szia @mbence! Köszi, valami ilyesmire gondoltam én is, csak kellett a megerősítés! Sajna a Due csupaszon EEPROMtalan. Ez a lib elkerülte a figyelmemet, jónak tűnik és elég egyszerű is a használata. Alapból kerülöm a lib-ek használatát, - ha lehet, mert a Due marha kényes jószág - de ezt kipróbálom. Azt hiszem a tömbök irányába mozdulok...
A saját vezérlőm beüzemelés előtt újragondoltam, mert futás közben belassult, valszeg nem voltam elég figyelmes a programozás során. Elég sok dolgot tároltam bufferekben, sztem ott volt a galiba. Most tiszta lappal újraindulok, és hát ilyenkor jönnek az újabb ötletek :).

Beigazolódott a gyanúm, sajnos nem illeszthető a projektembe a lib. Már az első meghíváskor megáll a program futása... De próbálkozom tovább!
 
Beigazolódott a gyanúm, sajnos nem illeszthető a projektembe a lib. Már az első meghíváskor megáll a program futása... De próbálkozom tovább!
Én nem adnám fel ilyen könnyen. Itt is van szó arról, hogy gondok vannak a Due-val: https://forum.arduino.cc/index.php?topic=462554.0
Az a tipp, hogy a Wire.begin() miatt száll el a cpp 115. sorában: https://github.com/cyberp/AT24Cx/blob/master/AT24CX.cpp#L115
Szóval én annyit még megpróbálnék, hogy ott azt a sort kikommentelem a cpp.ben, és később a setup() elején adnám ki a wire.begin()-t. Nyugodtan átírhatod a saját gépen lévő libeket, fordításkor újra beolvassa az arduino ide.
Nekem nincs Duem sajnos, szóval nem tudom kipróbálni.
 
Lassan elkészül az új lámpám ami valamivel több mint 10A fog felvenni. Mik a tapasztalatok a FET panelekkel? 1csatornán gondolom eléggé melegedne. Ha 4 fele osztom az elég lehet vagy igy is érdemes lehet valami kis bordát rárakni?
 
Back
Oldal tetejére