Controllare stato dei pin

Salve ragazzi,

esiste una funzione oppure un modo per capire se un determinato pin è impostato come OUTPUT oppure INPUT?

salvob:
Salve ragazzi,

esiste una funzione oppure un modo per capire se un determinato pin è impostato come OUTPUT oppure INPUT?

Ho trovato questo nel PlayGround, prova a vedere se ti può tornare utle.

hai due modi:

  1. quando setti una porta alta o bassa ti salvi lo stato su una variabile
    2)Arduino Reference - Arduino Reference
    leggi lo stato dal registro..

alexdb:
Arduino Reference - Arduino Reference
leggi lo stato dal registro..

Quoto

come ti hanno detto prima dei usare il port manipulation, in particolare con DDRx x sta per il nome della porta quale a,b,c,d ecc a sconda del microcontrollore. se un pin è settato a 1 allora significa che è un output. DDRx ti restituisce mi pare un byte, ogni bit corrisponde a un pindi quella porta

Dunque:
PORTD = 0x00; resetta le linee DATA ponendole a LOW (0xFF = tutte HIGH)
DDRD = 0x00; imposta le linee DATA come ingressi (0xFF = tutte uscite)

Naturalmente è possibile scrivere il dato in formato binario tipo 0b00000000
Sinceramente non ho mai provato se scrivendo semplicemente

DDRD
PORTD

viene restituito il valore attuale o meno, sarebbe interessante saperlo, oltretutto si risolverebbe all'istante il problema di salvob.

Ma al limite credo lo si possa assegnare ad una variabile e risovere facilmente

michele ti correggo, non si puo scrivere b00000000 ma B00000000 o 0b0000000, altrimenti andiamo di hex :sweat_smile:

stasera faccio una prova io per vedere se DDR restituisce il valore.

si restituisce il valore...dovete vederlo come se fosse una variabile qualsiasi...

in pratica:
supponiamo che devi leggere il valore del digital pin 9..
il digital pin 9 è il bit 1 della porta B, cioè PB1..(vedi Datasheet)
quindi:

stato=PORTB & 0x40;

//oppure

stato=PORTB & 0b0100000;

stato vale true se l'uscita è alta e false se è bassa...

poco fa ho provato e posso confermare che si puo usare come uan variabile. ovviamente se vuoi vedere i singoli bit devi farti delel conversioni da decimale a binario.
leggiti il prot mapping così ti sarà faile avere lo stato di tutti i pin in poche righe di codice. :wink:

IGOR come la fai lunga, a buon rendere ]:smiley:
@ entrambi: grazie delle prove fatte, ora potreste anche essere così gentili e scrivere una piccola lib con cui si possa interrogare lo stato di un QUALSIASI PIN del micro (prevedete le porte da A a D), di una qualsiasi "linea" (0-7A,B,C,D) o dell'intero gruppo di linee? Ve la cavate con poco e rendete un bel servizio al Forum. Chi se la prende la responsabilità? O devo al solito mettermi io mentre voi state a divertirvi? ]:smiley:

basterebbe riprendere il codice usato per il digitalWrite in teoria ma invece che in scrittura va in lettura :stuck_out_tongue:

superlol:

[quote author=Michele Menniti link=topic=120097.msg904982#msg904982 date=1346018085]
IGOR come la fai lunga, a buon rendere ]:smiley:
@ entrambi: grazie delle prove fatte, ora potreste anche essere così gentili e scrivere una piccola lib con cui si possa interrogare lo stato di un QUALSIASI PIN del micro (prevedete le porte da A a D), di una qualsiasi "linea" (0-7A,B,C,D) o dell'intero gruppo di linee? Ve la cavate con poco e rendete un bel servizio al Forum. Chi se la prende la responsabilità? O devo al solito mettermi io mentre voi state a divertirvi? ]:smiley:

basterebbe riprendere il codice usato per il digitalWrite in teoria ma invece che in scrittura va in lettura :stuck_out_tongue:
[/quote]
quindi ancora più semplice! bene, bene, ci pensi tu allora?

quindi ancora più semplice! bene, bene, ci pensi tu allora?
[/quote]

boolean whatWritten(int pin) {
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);

	return *portInputRegister(port) & bit;
}

per ora sono arrivato a questo, i fase di test in quanto sembra funzionare ma non mi pare fare lo shift del bit ad esempio

boolean whatWritten(int pin) {
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);

	return *portInputRegister(port) & bit;
}

void setup() {
  Serial.begin(9600);
  pinMode(5, OUTPUT);
  
  Serial.println(whatWritten(5));
  
  digitalWrite(5, HIGH);
  Serial.println(whatWritten(5));
  
  digitalWrite(5, LOW);
  Serial.println(whatWritten(5));
}

void loop() { };

in seriale printa

0
32
0

ho aggirato il problema XD
modo poco elegante lo so ma ammetto che operazioni coi bit non le so fare :roll_eyes:

testate ma dovrebbe andare

EDIT:
ok ok usiamo il bit shift XD

boolean whatWritten(int pin) {
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
        
        int rimanda = *portInputRegister(port) & bit;
	return rimanda >> pin;
}

Non l'ho testato ma ho una domanda. Perché usi un integer quando i registri sono ad 8 bit, quindi gestibili con un semplice tipo byte?

leo72:
Non l'ho testato ma ho una domanda. Perché usi un integer quando i registri sono ad 8 bit, quindi gestibili con un semplice tipo byte?

hai ragione. Addirittura potrei non usare la variabile rimanda così da risparmiare anche 1 byte di ram XD piuttosto credo di aver fatto un errore sullo shift del bit. Funziona per le prime 8 porte ma poi correggo solo che non so se è più utile fare una cosa del tipo

Rimanda = (rimanda == 0) ? 0:rimanda/rimanda;

sono arrivato troppo tardi; vedo se mi metto al lavoro pure io tanto per fare qualcosa..
non ho visto bene, @sl hai fatto una funziona da mettere drettamente nello sketch?

superlol:

Rimanda = (rimanda == 0) ? 0:rimanda/rimanda;

si è molto meglio..., però scrivilo così:

rimanda= (rimanda==0)?0:1;

così risparmi una divisione.. :wink:

igor97:
sono arrivato troppo tardi; vedo se mi metto al lavoro pure io tanto per fare qualcosa..
non ho visto bene, @sl hai fatto una funziona da mettere drettamente nello sketch?

si ma puoi anche metterla in un file a parte e chiamarla "libreria" XD solo che mettere una libreria per una funzione mi pare brutto,sarebbe carino se si facesse qualche altra funzione e si ingloba il tutto, allora avrebbe senso :slight_smile:

alexdb:

superlol:

Rimanda = (rimanda == 0) ? 0:rimanda/rimanda;

si è molto meglio..., però scrivilo così:

rimanda= (rimanda==0)?0:1;

così risparmi una divisione.. :wink:

vero, le cose più faicili non mi vengono mai XD

ok allora il codice diventa

boolean whatWritten(int pin) {
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
        
	return ((*portInputRegister(port) & bit) == 0) ? 0:1;
}

superlol:
si ma puoi anche metterla in un file a parte e chiamarla "libreria" XD solo che mettere una libreria per una funzione mi pare brutto,sarebbe carino se si facesse qualche altra funzione e si ingloba il tutto, allora avrebbe senso :slight_smile:

cavolo :grin:
io pensavo di fae così:
chiamo funzione e li dico il pin in questione
la funzione fa quel ch deve
il return sarà di due valori se è possibile ovvero sia la direzione del pin che il suo valore (alto o basso), altrimenti una funzine in piu