![]() |
|
Per testare il sensore di prossimità ho scritto una semplice applicazione che mi permette di regolare il tempo di esposizione tramite due tasti della tastiera (su e giu) e quindi comunicare ad arduino il tempo di acquisizione richiesto senza dover riprogrammare ogni volta. In piu' proietto in un grafico tempo / distanza 3 curve:
- La curva che rappresenta la durata dell'esposizione (curva bianca)
- La curva che rappresenta la quantità di luce riflessa dal sensore (curva rossa)
- Le curva che parresenta la quantità di luce riflessa / durata esposizione (curva blu)
Grazie a queste 3 curve è possibile analizzare la risposta del sensore e testare se è o no lineare nella risposta, (cioè se la curva blu rimane una retta). In piu' con questo programma è possibile veder rappresentata la percezione del sensore e sperimentarne il range. Rimango tutt'ora stupito delle incredibili capacità di questo sistema, paragonato a qualsiasi coppia di emettitore / fotoresistore o fotodiodo o fototransistor, nessuno di questi componenti mi ha permesso range elevati quanto il sistema a LED.
Il codice per Arduino:
#define irEmitter 12 // polo positivo emettitore
#define irReceiverN 11 // polo negativo ricevitore
#define irReceiverP 10 // polo positivo ricevitore
long distance = 0;
int interval = 10;
void setup() {
Serial.begin(57600); // inizializza seriale a 9600 baud
pinMode(irEmitter, OUTPUT); // il led emettitore è un output
pinMode(irReceiverP, OUTPUT); // il polo positivo del let ricevitore è un output
digitalWrite(irReceiverP, LOW); // e deve essere LOW
}
void focus() {
distance = readLight(true) - readLight(false);
if(distance < 0) distance = 0;
// processing
int data = int(Serial.read()); //ottieni seriale
if(data == '1') interval++; //se processing chiede di aumentare aumenta
if(interval > 0) if(data == '2') interval--; //se non sei a 0 diminuisci
Serial.print(distance); //spedisci a processing distanza
Serial.print(" "); //suddivisa da uno spazio
Serial.println(interval); //e l'intervallo
}
double readLight(boolean lightOn) {
digitalWrite(irEmitter, lightOn ? HIGH : LOW);
pinMode(irReceiverN, OUTPUT);
digitalWrite(irReceiverN, HIGH); //carico ricevitore di induttanza
long reading = 0;
pinMode(irReceiverN, INPUT);
digitalWrite(irReceiverN, LOW);
long lightTime = millis();
while((millis() - lightTime) < interval)
if(digitalRead(irReceiverN) == 0)
reading++;
return reading;
}
void loop() {
focus();
}
Dopo aver caricato questo codice bisogna avviare Processing e caricare lo sketch seguente:
import processing.serial.*;
PFont font;
Serial serial;
int x = 0;
int y = 0;
int y1 = 0;
int lastX = 0;
int lastY = 0;
int lastY1 = 0;
int interval = 0;
void setup() {
font = loadFont("muktinarrowbold-12.vlw");
size(1100, 750);
serial = new Serial(this, Serial.list()[0], 57600);
serial.bufferUntil('\n');
background(#333333);
}
void draw() {}
void keyPressed() {
if (keyCode == UP) serial.write('1'); //se schiacci su manda un 1 ad arduino, lui capirà ;)
if (keyCode == DOWN) serial.write('2'); //se schiacci giu manda un 2
}
void serialEvent(Serial serial) {
String valueStr = serial.readStringUntil('\n'); //leggi la seriale suddivisa da a capo
if(valueStr != null) { //se la stringe non è nulla
valueStr = trim(valueStr); //trimmo
String[] data = split(valueStr, ' '); //spezzo la stringa dove c'è lo spazio
y = int(data[0]) / 30; //y = primo pezzo dell'array
interval = int(data[1]); //interval = secondo pezzo
if(interval != 0) y1 = (y / interval) * 10; //y della curva blu
text("Usa tasto su e giu per regolare intervallo", 550, 730);
stroke(#FF0000); //curva rossa
line(lastX, lastY, x, y);
stroke(#135CAE); // curva blu
line(lastX, lastY1, x, y1);
stroke(#FFFFFF);
point(x, interval);
lastX = x;
lastY = y;
lastY1 = y1;
if(x++ >= width) {
lastX = 0;
lastY = 0;
x = 0;
y = 0;
background(#333333);
}
}
}
Ecco il video che dimostra il funzionamento e la comunicazione tra i due programmi.
Spero possa esservi utile e possa divertirvi ;)
