sto realizzando un progetto che, tra le altre cose, tiene conto dello stato di tre ingressi digitali ed a seconda della combinazione di questi si ha una funzione differente.
Di seguito riporto uno sketch che di fatto non fa parte del mio programma, ma è un esempio della logica che ho utilizzato:
int pin1;
int pin2;
int pin3;
int codBin;
void setup() {
Serial.begin(9600);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
}
void loop() {
if(digitalRead(5) == HIGH){
pin1 = 1;
}else{
pin1 = 0;
}
if(digitalRead(6) == HIGH){
pin1 = 10;
}else{
pin1 = 0;
}
if(digitalRead(7) == HIGH){
pin1 = 100;
}else{
pin1 = 0;
}
codBin = pin1 + pin2 + pin3;
Serial.println(codBin);
switch(codBin){
case 0: Serial.println("condizione 0");
break;
case 1: Serial.println("condizione 1");
break;
case 10: Serial.println("condizione 2");
break;
case 11: Serial.println("condizione 3");
break;
case 100: Serial.println("condizione 4");
break;
case 101: Serial.println("condizione 5");
break;
case 110: Serial.println("condizione 6");
break;
case 111: Serial.println("condizione 7");
break;
}
delay(500);
}
Premetto che con questo metodo ottengo esattamente quello che voglio ottenere, quindi ad oggi il progetto non ha problemi!!
Detto questo mi ritrovo a chiedervi aiuto in quanto nutro dei dubbi sul fatto che questo sia il corretto "modus operandi", infatti nel titolo di questo tread ho scritto "ingressi digitali<==>codice binario", perché volevo sapere se esiste qualche metodologia per raggruppare due,tre o quattro ingressi e "trasformarli" in un codice binario.
Per esempio nel "case 111", dello sketch di cui sopra, si fa riferimento allo stato alto dei tre ingressi, ma di fatto quel "111" non viene considerato come "1-1-1" (uno-uno-uno ovvero il n°7 dei numeri binari), ma esattamente come "111" (centoundici).
Spero di essermi spiegato correttamente su quelli che sono i miei dubbi ,
OK, questa tua risposta mi fa capire sicuramente una cosa, che i dubbi che avevo sul fatto che stavo utilizzando un metodo non proprio corretto erano fondati!!
Appena riesco oggi pomeriggio provo il consiglio che mi hai dato perché effettivamente, non essendo un programmatore, non riesco subito a coglierne il significato, della serie che se non ci sbatto la testa........
Poi mi piacerebbe discuterne!
@SukkoPera, l'unica cosa che mi viene da dirti è GRANDISSIMO!!!!
Ho provato, non che avessi dubbi sul funzionamento del suggerimento, il risultato è quello desiderato ma con uno sketch decisamente più "gradevole"!!
void setup() {
Serial.begin(9600);
}
void loop() {
byte b = digitalRead(5);
b = (b << 1) | digitalRead(6);
b = (b << 1) | digitalRead(7);
Serial.println(b);
switch(b){
case 0: Serial.println("condizione 0");
break;
case 1: Serial.println("condizione 1");
break;
case 2: Serial.println("condizione 2");
break;
case 3: Serial.println("condizione 3");
break;
case 4: Serial.println("condizione 4");
break;
case 5: Serial.println("condizione 5");
break;
case 6: Serial.println("condizione 6");
break;
case 7: Serial.println("condizione 7");
break;
}
delay(500);
}
Ho spilucchiate un po' qua ed un po' là per comprendere il significato di quanto scritto e ho, più o meno, capito che ci si sposta a sinistra di un bit, partendo come riferimento dal pin digitale 5, gli si aggiunge il valore letto del pin 6, ci si sposta ancora a sinistra di un bit e si aggiunge infine il valore letto sul pin 7!
Penso che da ignorante quale sono la spiegazione possa essere questa giusto?
cyberhs:
La soluzione di SukkoPera è elegante, ma devi conoscere bene il linguaggio.
Per i neofiti, ci sono sempre le istruzioni bit, bitRead, bitWrite, bitSet, bitClear, ecc.
Ora non riesco a fare dei test in quanto non ne ho la possibilità, quindi come detto prima se non ci sbatto un po' la testa facendo delle prove..........
Però ho letto qualcosa sulle istruzioni che mi hai consigliato e così su due piedi non saprei come gestirle.
Per esempio andando a leggere sul supporto di arduino la funzione bitRead(x,n), dove a quanto ho capito x è numero dal quale leggere il bit interessato ed n è la posizione dove leggerlo partendo da 0 come bit meno significativo (quello più a destra). Ora mi sembra di capire che qui vai a richiedere uno specifico bit avendo già un numero che ne contiene, o sbaglio?! Come posso usare questa istruzione per adattarla al mio caso?
meluino:
Ora non riesco a fare dei test in quanto non ne ho la possibilità, quindi come detto prima se non ci sbatto un po' la testa facendo delle prove..........
Però ho letto qualcosa sulle istruzioni che mi hai consigliato e così su due piedi non saprei come gestirle.
Per esempio andando a leggere sul supporto di arduino la funzione bitRead(x,n), dove a quanto ho capito x è numero dal quale leggere il bit interessato ed n è la posizione dove leggerlo partendo da 0 come bit meno significativo (quello più a destra). Ora mi sembra di capire che qui vai a richiedere uno specifico bit avendo già un numero che ne contiene, o sbaglio?! Come posso usare questa istruzione per adattarla al mio caso?
Grazie
Meluino
Se posso darti un consiglio, onde evitare di caricare in continuazione sketch su Arduino senza poi eseguire chissà quale Debug, per l istruzioni C pure (tra cui lo shift) puoi utilizzare un normalissimo compilatore C per windows. Io uso DEV C++ ed è un buon strumento anche per il DEBUG.
Sia chiaro: Non puoi copiare e incollare i sorgnti di arduinoin quanto non ci sono le libreire per la compilazione. Lo puoi usare come ambiente per capire prima bene i "comandi" C per poi applicarli su Arduino.
@inter1908 i consigli li accetto sempre ben volentiri, inoltre quello che mi hai dato lo apprezzo molto!! Spesso carico uno sketch dietro l'altro su arduino solo per "provare" comandi o variazioni su di essi ed ho sempre il pensiero che dai oggi dai domani............
volevo sapere se esiste qualche metodologia per raggruppare due,tre o quattro ingressi e "trasformarli" in un codice binario.
PIND - The Port D Input Pins Register - read only
PINB - The Port B Input Pins Register - read only
PINC - The Port C Input Pins Register - read only
es
se PIND == 255 i pin sono tutti a 1
se PIND == 7 i pin sono 00000111
se PIND == 3 i pin sono 00000011
ecc ecc
leggi il registro corrispondente e utilizza 3 pin sequenziali di quel Port, fai la sottrazione dei pin che non ti interessano
Sì, conoscevo queste istruzioni, le avevo usate in un altro "esperimento", ma sinceramente non le avevo prese in considerazione perché ero convinto che i pin di una porta o si programmavano tutti come input o tutti come output. Invece prima di risponderti sono andato a guardare il link per rispolverare un po' la memoria e mi sono reso conto che con con l'istruzione "DDRx" si possono settore singolarmente.
gpb01:
... beh ... Atmel garantisce almeno 10'000 scritture ... vedi un po' tu
Guglielmo
10'000??? Allora il mio arduino può stare tranquillo
Anche perché ora, dato che la parte hardware è testata e sto solo "sistemando" alcune istruzioni come quelle di questo topic, utilizzo un ATMega 328 in versione standalone su breadboard. Carico lo sketch tramite ICSP, quindi praticamente ho ancora 10'000 scritture da utilizzare.
Scherzi a parte, sembra molto interessante il simulatore che mi hai consigliato.
PIND - The Port D Input Pins Register - read only
PINB - The Port B Input Pins Register - read only
PINC - The Port C Input Pins Register - read only
es
se PIND == 255 i pin sono tutti a 1
se PIND == 7 i pin sono 00000111
se PIND == 3 i pin sono 00000011
ecc ecc
leggi il registro corrispondente e utilizza 3 pin sequenziali di quel Port, fai la sottrazione dei pin che non ti interessano
Corretto. Anche se poi, come è evidenziato dall'articolo stesso, è sconsigliato l'uso se non in quei casi in cui bisogna scalare sulle performance ed evitare che i dispositivi collegati possano andare in crisi per il delay con cui si spettano i pin di ingresso/uscita.
Visto che un 328 costa abbastanza poco, se anche ne danneggiassi uno a forza di riflasharlo, puoi sempre toglierlo dalla scheda e sostituirlo, e prima di arrivare anche solo agli 11€ del simulatore... Hai voglia! Ovviamente questo non vale per la Mega, Due, Leonardo e altre con MCU SMD.
La soluzione proposta da pablos è una delle altre a cui accennavo, ma oltre alla scarsa portabilità, risulta cervellotica se i pin che vuoi usare non sono contigui o sono su porte differenti.
SukkoPera:
Visto che un 328 costa abbastanza poco......
Su questo lato sono abbastanza sereno in quanto tramite il canale lavorativo ho accesso ad un quantitativo di componentistica molto ricco. Però rimango interessato a quelli che sono i vari simulatori in quanto più che le materie prime spesso manca la possibilità di portarsi appresso il progetto, mentre il PC è sempre a disposizione, quindi più per un discorso funzionale che "economico"!!
SukkoPera:
La soluzione proposta da pablos è una delle altre a cui accennavo, ma oltre alla scarsa portabilità, risulta cervellotica se i pin che vuoi usare non sono contigui o sono su porte differenti.
Sì, come ho detto prima questa soluzione la conoscevo, infatti pensavo che le prime risposte si sarebbero basate su di essa. Oltre ai problemi che state elencando, ero comunque convinto che questo metodo non fosse molto indicato per le esigenze che ho ora, in quanto come ho detto ero convinto che in una porta i pin potevano essere o solo input o solo output. Quindi questo topic è stato positivo anche per rivedere alcune mie convinzioni su questo argomento!
forse può essere interessante ricordare anche che in C le costanti possono essere indicate usando basi diverse semplicemente anteponendo un diverso prefisso: 0x per l'esadecimale, 0b per il binario. Quindi:
12 = 0xC (in esadecimale)
5 = 0b101 (in binario)
Questo può aiutarti a rendere più leggibile e facilmente interpretabile il tuo codice. Lo switch infatti diventa:
switch(b){
case 0b000: Serial.println("condizione 0");
break;
case 0b001: Serial.println("condizione 1");
break;
case 0b010: Serial.println("condizione 2");
break;
case 0b011: Serial.println("condizione 3");
break;
case 0b100: Serial.println("condizione 4");
break;
case 0b101: Serial.println("condizione 5");
break;
case 0b110: Serial.println("condizione 6");
break;
case 0b111: Serial.println("condizione 7");
break;
}
Per il compilatore non è cambiato assolutamente nulla... ma adesso ad occhio tu vedi subito quale combinazione di bit (input) attiva ciascuna condizione. Questo può essere ancora più utile quando usi un numero maggiore di bit. Già con 5 bit, scrivendo case 27: non ti viene subito in mente 11011.