Algoritmo iterativo per utilizzare più sensori capacitivi con Arduino
Nella precedente lezione hai creato lo script con il numero di sensori necessari per il tuo dispositivo tattile, ma il codice non era particolarmente snello e mantenibile poiché, seguendo le indicazioni, hai ripetuto:
- l’istruzione per inizializzare ogni CapacitiveSensor, indicando di volta in volta i PIN utilizzati
- l’acquisizione del dato capacitiveSensor per ogni sensore CapacitiveSensor, impostando la risoluzione (la medesima per tutti i sensori)
- il controllo del superamento della soglia per ogni dato
- le operazioni nel caso di superamento della soglia
Adesso lavorerai sulla versione iterativa del codice. Come avrai intuito, l’obiettivo è rendere cicliche le quattro operazioni sopra descritte.
Partiamo dal nuovo script già completo, per visualizzarlo e commentarlo insieme. Noterai già che il codice è decisamente breve nonostante lavori con 10 sensori capacitivi
#include <CapacitiveSensor.h>
const int commonpin = 13;
const int numbersensors = 10;
CapacitiveSensor* capSensor[numbersensors];
int threshold = 500;
void setup() {
Serial.begin(9600);
int i = 0;
while(i < numbersensors){
if(i!=commonpin){
capSensor[i] = new CapacitiveSensor(commonpin,i+2);
i++;
}
}
}
void loop() {
long sensorValue;
for(int i=0;i < numbersensors;i++){
sensorValue = capSensor[i]->capacitiveSensor(30);
if(sensorValue > threshold){
Serial.println(i+1);
}
}
delay(50);
}
Dopo l’inclusione della liberia, abbiamo dichiarato due valori costanti: il PIN utilizzato come trasmettitore e il numero di sensori capacitivi. Sono dichiarati in alto per rappresentare gli unici valori che vanno cambiati per personalizzare applicare il codice alle proprie esigenze.
I sensori CapacitiveSensor, anziché inizializzarli uno ad uno in una variabile singola, li inizializzeremo all’interno di un array di tipo CapacitiveSensor, grande quanto il numero di sensori capacitivi precedentemente indicati nella costante numbersensors.
Con la riga
CapacitiveSensor* capSensor[numbersensors];
creiamo l’array vuoto.
Passiamo alla funzione start. Dopo aver dichiarato la funzione per lanciare la connessione Seriale, abbiamo creato un ciclo while per inizializzare i sensori capacitivi:
int i = 0;
while(i < numbersensors){
if(i!=commonpin){
capSensor[i] = new CapacitiveSensor(commonpin,i+2);
i++;
}
}
Per inizializzare i sensori, creo un ciclo e un puntatore i, ed eseguo il ciclo un numero di volte pari al numero di sensori (numbersensors) e all’interno creo un nuovo CapacitiveSensor inserendolo all’interno dell’array in posizione i.
L’oggetto CapacitiveSensor avrà il PIN digitale 13 come trasmittente, e il PIN i+2 come ricevente. Perché +2? Perché PIN0 e PIN1 sono utilizzati per la trasmissione dati, ad esempio se usassimo un modulo bluetooth o un collegamento tra due board Arduino, quindi li lasciamo liberi nel caso in cui volessimo espandere le funzionalità. Quindi partiamo dal PIN2 (0+2 nella prima iterazione del ciclo while).
Avrai notato che all’interno del ciclo while è presente un controllo per verificare se i è diverso dal PIN trasmittente, saltando l’operazione di inizializzazione nel caso in cui incontriamo il PIN trasmittente. In questo modo non generiamo errori inizializzando un CapacitiveSensor con PIN contemporaneamente ricevitore e trasmettitore.
Passiamo infine alla funzione loop. Anche qui abbiamo ottimizzato il codice inserendo le operazioni dentro un ciclo for:
for(int i=0;i < numbersensors;i++){
sensorValue = capSensor[i]->capacitiveSensor(30);
if(sensorValue > threshold){
Serial.println(i+1);
}
}
Anche questo ciclo è eseguito un numero di volte pari al numero di sensori (numbersensors). La variabile sensorValue memorizza di volta in volta i valori di output di ogni sensore capacitivo e con la funzione di soglia verifico se il valore di output del sensore capacitivo “i” ha superato la soglia.
In questa versione iterativa, tutto ruota attorno all’array e al puntatore che esegue ciclicamente le operazioni su ogni sensore, indicato dal puntatore i. L’unica condizione limitante di questa soluzione è che i sensori devono essere posizionati in PIN digitali tutti di seguito, senza lasciare PIN vuoti tra un sensore e l’altro.
Per comodità, ecco il codice comprensivo di commenti:
#include <CapacitiveSensor.h>
// indichiamo il PIN utilizzato come trasmettitore per tutti i sensori capacitivi
const int commonpin = 13;
// indichiamo il numero di sensori capacitivi inseriti.
//Cambia questo valore in base alle tue esigenze
const int numbersensors = 3;
CapacitiveSensor* capSensor[numbersensors];
int threshold = 500;
void setup() {
Serial.begin(9600);
//inizializzazione dei sensori capacitivi
int i = 0;
// creo un ciclo, eseguendolo un numero di volte pari al numero di sensori
while(i < numbersensors){
// questo controllo lo eseguo perché possiamo utilizzare anche PIN superiori al 13
// con questo controllo superiamo il 13, andiamo al 14 e non incrementando la variabile i
// così da eseguire il controllo per il numero di sensori indicati in numbersensors
if(i!=commonpin){
// nella versione con bluetooth, PIN0 e PIN1 sono utilizzati per la trasmissione dati
//quindi li lasciamo liberi, partendo dal PIN2 (0+2 nella prima iterazione del ciclo while)
capSensor[i] = new CapacitiveSensor(commonpin,i+2);
i++;
}
}
}
void loop() {
long sensorValue;
for(int i=0;i < numbersensors;i++){
// catturo i valori di output di ogni sensore capacitivo
sensorValue = capSensor[i]->capacitiveSensor(30);
//per verificare il funzionamento di tutti i sensori, de-commenta la riga successiva
//Serial.println(sensorValue);
// verifico se il valore di output del sensore capacitivo "i" ha superato la soglia
if(sensorValue > threshold){
// invio l'ID (partendo da 1 anziché 0)
Serial.println(i+1);
}
}
// fine del ciclo for per la cattura dei valori di output
delay(50);
}
Puoi scaricare questo codice completo in formato .ino per IDE Arduino o Eclipse.