Funzione If che su Arduino Due non Funziona [Problema aggirato]

Ma se è un output sei tu che lo setti e quindi sai sempre lo stato del pin

c'è tutta una parte del codice che controlla lo stato di pinOn in funzione della temperatura della casa, mentre il pinValvola si deve attivare quando pinFlussometro passa ad HIGH per permettere la produzione dell'acqua calda sanitaria ma questo puo avvenire solo se la il pinON è HIGH

BrainBooster:
Ma se è un output sei tu che lo setti e quindi sai sempre lo stato del pin

@BrainBooster
Sí é vero ma non é sbagliato leggere lo stato di un uscita.
@deepocean
Hai provato di stampare sulla seriale lo stato delle 2 letture
digitalRead(pinON) e digitalRead(pinFlussom)?
Ciao Uwe

Ho seguito il tuo consiglio,

e verificando sulla seriale il digitalRead(pinON) è sempre a low.

codice:

int pinValvola=9;     //Pin rele' valvola a tre vie
int pinFlussom=7;     //Pin Flussometro
int pinON= 2;        //Pin Accenzione 

void setup()
{
Serial.begin(9600); 
pinMode(pinFlussom, INPUT);      // inizializza pin digitale come Input
pinMode(pinValvola, OUTPUT);     // inizializza pin digitale come Output
pinMode(pinON, OUTPUT);          // inizializza pin digitale come Output

}
void loop()
{
  
    digitalWrite(pinON, HIGH); 
    if (digitalRead(pinON) == HIGH && digitalRead(pinFlussom) == HIGH)
    {
      digitalWrite(pinValvola, HIGH);

    } 
    else {

      digitalWrite(pinValvola, LOW);
    }  

Serial.println(" ");
Serial.print("Stato pinFlussom ") and Serial.println(digitalRead(pinFlussom), DEC);
Serial.print("Stato pin ON ") and Serial.println(digitalRead(pinON), DEC);
Serial.print("Stato pinValvola ") and Serial.println(digitalRead(pinValvola), DEC);
delay(1000);
}

risultato sulla seriale con pinFlussom a 0 :

Stato pinFlussom 0
Stato pin ON 0
Stato pinValvola 0

risultato sulla seriale con pinFlussom a 1 :

Stato pinFlussom 1
Stato pin ON 0
Stato pinValvola 0

codice modificato nella funzione if :

int pinValvola=9;     //Pin rele' valvola a tre vie
int pinFlussom=7;     //Pin Flussometro
int pinON= 2;        //Pin Accenzione 

void setup()
{
Serial.begin(9600); 
pinMode(pinFlussom, INPUT);      // inizializza pin digitale come Input
pinMode(pinValvola, OUTPUT);     // inizializza pin digitale come Output
pinMode(pinON, OUTPUT);          // inizializza pin digitale come Output

}
void loop()
{
  
    digitalWrite(pinON, HIGH); 
    if (digitalRead(pinFlussom) == HIGH)
    {
      digitalWrite(pinValvola, HIGH);

    } 
    else {

      digitalWrite(pinValvola, LOW);
    }  

Serial.println(" ");
Serial.print("Stato pinFlussom ") and Serial.println(digitalRead(pinFlussom), DEC);
Serial.print("Stato pin ON ") and Serial.println(digitalRead(pinON), DEC);
Serial.print("Stato pinValvola ") and Serial.println(digitalRead(pinValvola), DEC);
delay(1000);
}

risultato sulla seriale con pinFlussom a 0 :

Stato pinFlussom 0
Stato pin ON 0
Stato pinValvola 0

risultato sulla seriale con pinFlussom a 1 :

Stato pinFlussom 1
Stato pin ON 0
Stato pinValvola 1

quindi non legge lo stato di pinON !!!

e siccome anche pinValvola e un output non mi spiego il perchè?

Andiamo per gradi. Sembra che l'errore derivi da una incapacità del SAM3X di leggere lo stato di un proprio pin.
Escludiamo quindi questo problema con un test semplicissimo:

byte pinON= 2;        //Pin AccenSione :-P
void setup() {
  delay(2000);  
  Serial.begin(9600); 
  pinMode(pinON, OUTPUT);          
  digitalWrite(pinON, HIGH); 
  Serial.println(digitalRead(pinON), DEC);
}

void loop() {}

Che dice?

sempre 0 !!!

deepocean:
sempre 0 !!!

Ok. Quindi il SAM3X non è capace di leggere lo stato dei suoi pin, secondo il tuo test...

Ora guarderò il datasheet, nel frattempo devi solo implementare una semplice variabile di tipo boolean in cui memorizzare lo stato di quel pin, tutto lì.
Quindi, tutte le volte che metti HIGH il pin pinON, farai:
digitalWrite(pinON, HIGH);
stato_pinON = HIGH;

e tutte le volte che metti il pin su LOW farai:
digitalWrite(pinON, LOW);
stato_pinON = LOW;

Il controllo diventa:
if (stato_pinON == HIGH && digitalRead(pinFlussom) == HIGH)

nel post precedente se vedi i risultati sulla seriale legge sia quello dei pinValvola che quello di pinFlussom,
ora prendendo il tuo codice ho fatto la prova sul pin 9 (pinValvola) e come risultato da 0

byte pinON= 9;      //Pin Accen[u]S[/u]ione .... :-P  
void setup() {
  delay(2000);  
  Serial.begin(9600); 
  pinMode(pinON, OUTPUT);          
  digitalWrite(pinON, HIGH); 
  Serial.println(digitalRead(pinON), DEC);
}

void loop() {}

PS:
che poi non credo sia un limite del chip ma più del core.

@ leo72

Quindi, tutte le volte che metti HIGH il pin pinON, farai:
digitalWrite(pinON, HIGH);
stato_pinON = HIGH;

e tutte le volte che metti il pin su LOW farai:
digitalWrite(pinON, LOW);
stato_pinON = LOW;

Il controllo diventa:
if (stato_pinON == HIGH && digitalRead(pinFlussom) == HIGH)

si mangia un po di memoria ma cmq funziona e si aggira il problema.
:slight_smile: :slight_smile: :slight_smile:

deepocean:
si mangia un po di memoria ma cmq funziona e si aggira il problema.
:slight_smile: :slight_smile: :slight_smile:

Bene, mi fa piacere. :wink:

Hai provato a riscrivere l'if con doppio test con due if?

void loop()
{ digitalWrite(pinON, HIGH);
if (digitalRead(pinON) == HIGH)
{ if( digitalRead(pinFlussom) == HIGH)
{ digitalWrite(pinValvola, HIGH);
}
else
{ digitalWrite(pinValvola, LOW);
}
}
else
{ digitalWrite(pinValvola, LOW);
}
}

Questa sera provo e vi faccio sapere !!!

Idem anche così non legge il primo digitalRead!!!!

deepocean:
Idem anche così non legge il primo digitalRead!!!!

Credo sia un limite del core.
Anche perché sul datasheet c'è scritto che si può leggere lo stato dal registro.

da wiring_digital.c:

int digitalRead(uint8_t pin)
{
	uint8_t timer = digitalPinToTimer(pin);
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);

	if (port == NOT_A_PIN) return LOW;

	// If the pin that support PWM output, we need to turn it off
	// before getting a digital reading.
	if (timer != NOT_ON_TIMER) turnOffPWM(timer);

	if (*portInputRegister(port) & bit) return HIGH;
	return LOW;
}

io direi che il problema si nasconde in quella portInputRegister

edit: a quanto pare il fatto di poter leggere con una digitalRead un pin output è un bug lasciato per retrocompatibilità! :slight_smile:

Bravo, bella scoperta :wink:

Complimenti :slight_smile: :slight_smile: :slight_smile:

bhe comunque tradotto: legegere i pin di output con la digitalWrite è una cattiva e sbagliata abitudine dettata da un bug che permetteva di farlo. Gli arduino basati su chip AVR orami restano conformi al bug, ma le nuove schede AVR si "staccano" dal bug per seguire lo standard.

Consiglio di seguire il progetto arduino su github, si imparano tante cose interessanti dal bug tracer.