Go Down

Topic: Irrigazione automatica (Read 6467 times) previous topic - next topic

karnhack

#60
May 28, 2019, 11:27 pm Last Edit: May 28, 2019, 11:42 pm by karnhack
Sto facendo delle prove per vedere se riesco scrivere e leggere nella eeprom, in pratica nel void loop ho inserito
Code: [Select]

    int ORE = now.hour();
    int MINUTI = now.minute();
    ... // tralasciando il resto del codice per semplificare
    Serial.println(EEPROM.read(ORE), DEC);
    Serial.print(':');
    Serial.println(EEPROM.read(MINUTI), DEC);
    delay(1000);


Poi in un cambio di stato ho inserito (giusto come prova, non ha nessun senso ma voglio provare a scrivere l'eeprom,  e leggerla)

Code: [Select]
case PRIMA_ACCENSIONE:
        EEPROM.write(ORE, MINUTI);
        fase = RIPOSO; // cambio di stato
        break;

        case RIPOSO:
        digitalWrite(pinPompa, ACCESO); // l'accensione del relay indica che lo stato PRIMA_ACCENSIONE è stato eseguito
        break;



Però per l'ora che mi ritrovo sul monitor seriale sono le 26:160  :o

karnhack

#61
May 28, 2019, 11:59 pm Last Edit: May 29, 2019, 12:00 am by karnhack
Però per l'ora che mi ritrovo sul monitor seriale sono le 26:160  :o
Mi cito da solo... probabilmente l'eeprom era scritta da prima ecco perchè avevo numeri completamente sballatii. Ho cancellato l'EEPROM tramite un esempio presente nella libreria esempi "eeprom_clear" ed ora va un pochino meglio in quanto segna le 55:0 dove 55 sono i minuti ( che sono corretti anche se nella posizione delle ore)

Claudio_FF

#62
May 29, 2019, 07:00 am Last Edit: May 29, 2019, 07:17 am by Claudio_FF
Sto facendo delle prove per vedere se riesco scrivere e leggere nella eeprom
La EEPROM è come un array di 1024 byte.

Quando vuoi scrivere un byte specifichi in quale (indirizzo da 0 a 1023) e cosa (valore da 0 a 255).
Code: [Select]
EEPROM.write(indirizzo_del_byte, valore);
Quando vuoi leggere un byte specifichi da quale (indirizzo da 0 a 1023).
Code: [Select]
mio_byte = EEPROM.read(indirizzo_del_byte);

Quindi capisci ben che un codice come questo non ha alcun senso logico... qui punti il byte di indirizzo ORE (quindi una cella di memoria dalla 0 alla 23) e ci scrivi il valore di MINUTI:
Code: [Select]
EEPROM.write(ORE, MINUTI);
Mentre qui leggi un byte dall'indirizzo minuti, cioè da una cella compresa tra 0 e 59:
Code: [Select]
Serial.println(EEPROM.read(MINUTI), DEC);

Quote
ora va un pochino meglio in quanto
In informatica le cose non possono andare "un pochino meglio", o vanno esattamente come si vuole, o sono sbagliate. Se sono sbagliate si studia da zero il singolo argomento, in questo caso come scrivere e leggere un valore nella/dalla EEPROM. Poi si applica la conoscenza della EEPROM (come scrivere e leggere un byte da una cella di memoria di indirizzo ben preciso) alla logica che si vuole realizzare. Ho l'impressione che siano di nuovo tentativi alla cieca (tra l'altro non ho capito perché vuoi usare la EEPROM).
* * * * Una domanda ben posta è già mezza risposta * * * *

karnhack

#63
May 29, 2019, 11:18 am Last Edit: May 29, 2019, 11:20 am by karnhack
Ho l'impressione che siano di nuovo tentativi alla cieca (tra l'altro non ho capito perché vuoi usare la EEPROM).
Perchè mi sembrava la via più semplice... a dire il vero la via più semplice è quella del delay di 86400000 millesimi, anche perchè della precisione in questo caso non so che farmene, mi serve solo per rimandare il prossimo stato e far decantare l'acqua. Certo che se va via la luce è un "problema", ma neanche troppo grande, a meno che non collego arduino ad una batteria tampone ma non ne vale la pena secondo me.
Poi ho pensato che essendoci la EEPROM potevo sfruttarla ed ho fatto dei tentativi... alla cieca è vero.
Però le ultime 6 ore fino alle 2 di notte le ho passate a cercare informazioni sulla eeprom, a guardare gli sketch di esempi eeprom di arduino ecc ecc. la volontà di studiare c'è stata, ma se devo essere sincero mancano i manuali.
Su internet è un casino perchè ognuno ha il suo metodo e dice la sua, chi fa esempi cosi 0X00 chi colì e sai bene che per fare una ricerca decente devi sapere cosa cerchi e usare i termini giusti altrimenti è un mare di lucciole.

Scusa lo sfogo  :smiley-sweat:

gpb01

#64
May 29, 2019, 11:27 am Last Edit: May 29, 2019, 11:27 am by gpb01
... ma se devo essere sincero mancano i manuali.
Tieni, ecco una buona guida che offre oltretutto vari spunti e semplificazioni ;)

NON usa la libreria di Arduino, ma quella di base <avr/eeprom.h> (su cui quella di Arduno è costruita) che si trova in AVR libc, libreria automaticamente sempre inclusa dall'IDE di Arduino ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

zoomx

Ci sarebbe anche la memoria I2C contenuta nel modulo RTC.

gpb01

#66
May 29, 2019, 12:00 pm Last Edit: May 29, 2019, 12:02 pm by gpb01
Ci sarebbe anche la memoria I2C contenuta nel modulo RTC.
In effetti ... visto che usa il DS1307 ...



... dall'indirizzo 0x08 a 0x3F (58 bytes) è tutta memoria a disposizione dell'utente per salvarci quello che si vuole :)

Guglielmo
Search is Your friend ... or I am Your enemy !

zoomx

Oltre alla memoria contenuta nell'RTC sul modulo TinyRTC c'è montata una memoria I2C.

maubarzi

La EEPROM ha senso per salvare informazioni che resistano al riavvio, si rileggono nel setup e poi si lavora in memoria, a meno che le informazioni non siano proprio tante da non stare in memoria e allora si usa come appoggio per le cose meno usate.
Io la avevo intesa così quando ti ho incoraggiato sulla EEPROM.
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

gpb01

#69
May 29, 2019, 12:45 pm Last Edit: May 29, 2019, 12:46 pm by gpb01
Oltre alla memoria contenuta nell'RTC sul modulo TinyRTC c'è montata una memoria I2C.
... quella mi sembra un'inutile complicazione ! ::)

Considera che lui ha già (a gratis) le chiamate per leggere e scrivere nella memoria del DS1307, difatti la libreria RTClib, che lui usa, include i seguenti metodi:

Code: [Select]
uint8_t readnvram(uint8_t address);
void readnvram(uint8_t* buf, uint8_t size, uint8_t address);
void writenvram(uint8_t address, uint8_t data);
void writenvram(uint8_t address, uint8_t* buf, uint8_t size);

Guglielmo
Search is Your friend ... or I am Your enemy !

karnhack

#70
May 29, 2019, 12:49 pm Last Edit: May 29, 2019, 01:01 pm by karnhack
La EEPROM ha senso per salvare informazioni che resistano al riavvio, si rileggono nel setup e poi si lavora in memoria, a meno che le informazioni non siano proprio tante da non stare in memoria e allora si usa come appoggio per le cose meno usate.
Io la avevo intesa così quando ti ho incoraggiato sulla EEPROM.
A me serve solo ritardare una fase di 24 ore, tutto qui. Siccome la fase RIPOSO sarà quella che deciderà quando perchè irrigare ho bisogno che questo delay di 24ore sia isolato, altrimenti ci sarà sempre un ritardo di 24 ore prima di ogni irrigazione.
Per questo motivo  ho inserito una fase PRIMA_ACCENSIONE con lo scopo di creare un ritardo di 24 ore solo alla prima accensione, e mai più.

Code: [Select]
switch (fase)
    {
      case RIEMPIMENTO_START:
        // riempie il contenitore e l'acqua dovrà decantare 24 ore
        fase = PRIMA_ACCENSIONE; 

      case PRIMA_ACCENSIONE:
        // aspetta 24 ore (decantazione)
        break;
       
      case RIPOSO:
        // attende la condizione su base mensile ed oraria
        break;

      case CONCIMAZIONE:
        // se il mese rientra nella condizione inserisce il concime nel contenitore altrimenti passa alla fase IRRIGAZIONE
        break;

      case IRRIGAZIONE:
      // Irriga e a fine operazione ritorna alla fase RIPOSO
      break;


Come ho detto precedentemente un delay di 86400000 millesimi basterebbe, ma avendo il TinyRTC stavo cercando altre vie. Mi è venuta in mente l'EEPROM ma io ignoro il 99% delle vie possibili quindi può essere una stupidaggine bella e buona usarla

zoomx

... quella mi sembra un'inutile complicazione ! ::)
Ricorda che quei 56 byte non sono in flash ma alimentati a batteria, quella dell'RTC.

gpb01

#72
May 29, 2019, 02:25 pm Last Edit: May 29, 2019, 02:25 pm by gpb01
Ricorda che quei 56 byte non sono in flash ma alimentati a batteria, quella dell'RTC.
Che si spera sia sempre carica (durano anni) e che comunque serve SOLO se manca l'alimentazione al modulo.
Considera che se gli si scarica ... addio anche a data/ora ... e quindi ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

zoomx

Considera che se gli si scarica ... addio anche a data/ora ... e quindi ;)
E questo è anche vero!

karnhack

Però fatemi capire la differenza perché ora sto facendo delle prove... sul mio RTC c'è scritto "TinyRTC I2C Module" quindi con cosa sto lavorando con RTC o con I2C? Nello sketch precedente ho impostato l'ora dell'RTC con
Code: [Select]
RTC.adjust(DateTime(2019, 05, 28, 23, 10, 00)); // decommentare per regolare ora e data (yyyy,mm,dd,hh,mm,ss)


Ora provando a scrivere sulla ram dell'RTC richiamando la libreria WIRE noto che i due orari sono diversi quindi sono un po confuso... questo è l'esempio che mi ha confuso:
Code: [Select]
#include <Wire.h> //include la libreria I2C

void setup()
{
Serial.begin(9600); //inizializza la seriale

Wire.begin(); //inizializza libreria

Wire.beginTransmission(0x68); //attiva la comunicazione con il DS1307 all'indirizzo RTC 0x68
Wire.write((byte)0x00); //il primo byte stabilisce il registro iniziale da scrivere i SECONDI da 0x00 a 0x59
Wire.write((byte)0x10); //il secondo byte specifica il tempo  MINUTI da 0x00 a 0x59
Wire.write((byte)0x80 | 0x10); //il terzo byte specifica il tempo  da 0x00 a 0x24
Wire.endTransmission();
}

void loop()
{
Wire.beginTransmission(0x68); //inizializza la trasmissione
Wire.write((byte)0x00); // partendo dall'indirizzo 0x00
Wire.endTransmission();

Wire.requestFrom(0x68, 3); //richiedo 3 byte dal dispositivo con indirizzo 0x68
byte secondi = Wire.read(); //recupero 1 byte dei secondi
byte minuti = Wire.read(); //recupero 1 byte dei minuti
byte ora = Wire.read(); //recupero i 1 byte delle ore

Serial.print("Orario corrente: ");
Serial.print(ora, HEX);
Serial.print(":");
Serial.print(minuti, HEX);
Serial.print(":");
Serial.println(secondi, HEX);
Serial.println();

delay(1000);
}

Go Up