Allora avrei necessità di popolare una variabile byte con gli stati di 8 pin, ma non riesco proprio a venirne fuori.
Suggerimenti?
Vedi le varie bitXXX qualcosa, esempio bitWrite() oppure bitSet() o bitClear()
http://arduino.cc/en/Reference/BitWrite
Ma sono tutti della stessa porta della MCU ? Intendo tutti su PORTB o PORTD ... ecc. ?
Guglielmo
no, vanno dal 2 al 9. Perché 8 bit ce li ha solo la il port D ma comprendono anche lo 0 e 1 che non voglio usare.
Se usi uno standalone e ti accontenti di lavorare ad 8 MHz, puoi usare anche la porta B: i pin PB6 e PB7 sono usati sull'Arduino per collegare il risuontore ceramico ma su uno standalone impostato per lavorare con l'oscillatore interno essi sono liberi,
... allora non hai scelta ... devi leggerti i pin che ti interessano e metterli assieme in un solo byte (fai degli shift e delle OR)
Guglielmo
Alla fine lavorando con bitSet() e bitClear() ho fatto così
void loop() {
if (digitalRead(bit0) == HIGH){
bitSet(temp_code, 0);
}
else{
bitClear(temp_code, 0);
}
if (digitalRead(bit1) == HIGH){
bitSet(temp_code, 1);
}
else{
bitClear(temp_code, 1);
}
if (digitalRead(bit2) == HIGH){
bitSet(temp_code, 2);
}
else{
bitClear(temp_code, 2);
}
if (digitalRead(bit3) == HIGH){
bitSet(temp_code, 3);
}
else{
bitClear(temp_code, 3);
}
if (digitalRead(bit4) == HIGH){
bitSet(temp_code, 4);
}
else{
bitClear(temp_code, 4);
}
if (digitalRead(bit5) == HIGH){
bitSet(temp_code, 5);
}
else{
bitClear(temp_code, 5);
}
if (digitalRead(bit6) == HIGH){
bitSet(temp_code, 6);
}
else{
bitClear(temp_code, 6);
}
if (digitalRead(bit7) == HIGH){
bitSet(temp_code, 7);
}
else{
bitClear(temp_code, 7);
}
Potresti anche semplificare, dato che la comparazione con HIGH equivale a fare così:
if (digitalRead(bit0)){
bitSet(temp_code, 0);
} else { ...
PS:
comunque io semplificherei con un for visto che i pin che leggi sono tutti in ordine
DjP4nd4:
Alla fine lavorando con bitSet() e bitClear() ho fatto così
Puoi semplificare con un for e un vettore anche se i numeri dei non sono vicini e se azzeri prima la temp_code la parte else non serve:
nell'esempio mio suppongo bit0,bit1 siano costanti bit0=2, bit1=3 etc.
// 0, 1, 2, 3, 4, 5, 6, 7 // indice array => posizione bit
byte pinArray[8]={bit0,bit1,bit2,bit3,bit4,bit5,bit6,bit7}; // per ogni cella indico il pin che mi serve
void loop() {
temp_code=0; // parto tutti a zero, else non serve più
for(byte pin=0;pin<=7;pin++) {
if (digitalRead( pinArray[pin] ) == HIGH){
bitSet(temp_code, pin);
}
}
Odio gli array.
Pur lavorando con i PLC (automazioni industriali), odio array e puntatori, quindi ti ringrazio ma ho solo semplificato il codice come suggerito dal leo.
Ora un altro dubbio solo di ottimizzazione senza aprire un altro Topic.
devo far eseguire 2 parte di codice separate a seconda di un input
-uso il goto label
-oppure mi eseguo la funzione che mi serve
void loop() {
if (digitalRead(micro)==HIGH) {
corretto();
}else{
erratto();
}
}
nid69ita:
se azzeri prima la temp_code la parte else non serve:
E questa ne hai tenuto conto? Levi 8 else.
.. allora non hai scelta ... devi leggerti i pin che ti interessano e metterli assieme in un solo byte (fai degli shift e delle OR)
Io seguirei il suggerimento di Guglielmo ..
byte portad = PORTD; // legge i pin 2-7 (bit 2-7)
byte portab = PORTB; // legge i pin 8-9 (bit 0-1)
portad = portad & B11111100; // azzerra bit 0-1 non utilizzati
portab = portab & B00000011; // azzerra bit 2-7 non utilizzati
byte porta = portad | portab; // unisce le due porte
Nel codice finale puoi riunire la lettura e l'operazione di and "&" in una unica riga.
Rispetto alla serie di "if" ritengo che questo codice si più veloce.
lelebum:
...
Io seguirei il suggerimento di Guglielmo ..
...
... io non ho insistito perché ... DjP4nd4 (... senza offesa) non mi sembra ancora preparato su Arduino/ATmega328P per utilizzare direttamente i port e lavorare a basso livello ...
... e, del resto, affermazioni come queste :
DjP4nd4:
... odio array e puntatori ...
....
... uso il goto label ...
... di certo non rassicurano ![]()
Guglielmo
ho risolto, con il mio metodo e funziona alla grande.
Ringrazio comunque tutti per suggerimenti e critiche.
Ora ho un problema all'apparenza semplice. Ora se mi trovate un problema di conoscenza anche qui smetto di programmare ![]()
#define apertura 7 //comando apertura
#define chiusura 8 //comando chiusura
#define aperto 9 //finecorsa apertura
#define chiuso 10 //finecorsa chiusura
#define microswitch 6 //micro avvio
void setup() {
pinMode(apertura, OUTPUT);
pinMode(chiusura, OUTPUT);
pinMode(aperto, INPUT);
pinMode(chiuso, INPUT);
pinMode(microswitch, INPUT);
}
if (digitalRead(microswitch) == HIGH && digitalRead(aperto) == LOW) {
digitalWrite(chiusura, LOW);
delay(500);
digitalWrite(apertura, HIGH);
lcd.clear();
lcd.setCursor(4,1);
lcd.print("APERTURA");
lcd.setCursor(4,0);
lcd.print("SISTEMA");
}
Elettricamente c'è un positivo comune (+5V arduino), per i due finecorsa e il microswitch
I segnali se ne vanno ognuno sul rispettivo pin.
Il problema è che se io collego un filo sui pin 9 o 10 mi trovo una tensione di 5v come se mi stesse dando un uscita, nonostante io li abbia configurati come INPUT.
Di conseguenza se io collego il filo del microswitch il sistema parte anche se non viene premuto.
Il pin 9 lo tieni in una situazione STABILE (c_on una resistenza di pull-up o di pull-down_) o lo lasci flottante ???
Perché NON devi assolutamente lasciare pin in INPUT flottanti ... sono ad alta impedenza e captano qualsiasi disturbo !
Guglielmo
no, non sto usando le resistenze di pull up esterne
non ho spazio fisico per metterle
posso usare anche quelle interne (software)?
es.
pinMode(6, INPUT_PULLUP);
mi rispondo da solo ![]()
ho usato la pullup interna.
ero in dubbio perché non funzionava, ma avevo dimenticato di dover usare i segnali al contrario.
... quindi è andato tutto a posto immagino ? ![]()
Guglielmo
P.S. : ... quelle interne NON è che sono software, sono attivate attraverso un comando che dai da software, ma sono delle vere resistenze !