I'm just a beginner, but here my 5 cent: use a IR led
if we charge for some millis the Negative pin of a IR led, then it will de-charge in function of response IR.
sorry for bad english, but essentialy: use 2 led IR, one emitter and one receiver.
turn on emitter, read the de-charge time, turn of emitter, read the de-charge time, the difference is in function of distance.
In italian forum gbm has get a distance of 2 meters using 2 remote led...
this is the basic code I've written:
#define irEmitter 13 // polo positivo emettitore
#define irReceiverN 2 // polo negativo ricevitore
#define irReceiverP 5 // polo positivo ricevitore
volatile unsigned long distance0 = 0;
volatile unsigned long distance1 = 0;
volatile unsigned long distance2 = 0;
volatile unsigned long lightTime = 0;
volatile boolean nuovaLettura = false;
volatile unsigned long lostRead = 0;
unsigned long lastRead = 0;
void setup() {
Serial.begin(9600); // 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
//start led read
init(false);
attachInterrupt(0, one, FALLING);
lastRead=millis();
}
void one() {
detachInterrupt(0);
distance0 = micros() - lightTime;
init(true);
attachInterrupt(0, two, FALLING);
}
void two(){
detachInterrupt(0);
distance1 = micros() - lightTime;
distance2 = distance0 - distance1;
distance1 = 0;
distance0 = 0;
if (nuovaLettura){
lostRead++;
}else{
nuovaLettura=true;
lostRead=0;
}
init(false);
attachInterrupt(0, one, FALLING);
}
void init(boolean emitterOn) {
if(emitterOn)
digitalWrite(irEmitter, HIGH);
else
digitalWrite(irEmitter, LOW);
lightTime = micros();
pinMode(irReceiverN, OUTPUT);
digitalWrite(irReceiverN, HIGH); //carico ricevitore di induttanza
pinMode(irReceiverN, INPUT);
digitalWrite(irReceiverN, LOW);
}
int tempLostRead;
unsigned long time_out_millis = 1000;//1 secondo
void loop() {
if (nuovaLettura){
nuovaLettura=false;
tempLostRead=lostRead;//questo perchè le serial sono lente, e se non si azzera lostRead subito potremmo avere una lettura inconsistente dopo
Serial.print("D: "); //disatnza
Serial.println(distance2);
Serial.print("L: "); //letture perse
Serial.println(tempLostRead);
Serial.println(); //lascia una riga vuota
lastRead=millis();
}
if (millis()-time_out_millis > lastRead){
Serial.println("ERROR! Time Out or millis() Overflow! restarting interrupt:");
detachInterrupt(0);
init(false);
attachInterrupt(0, one, FALLING);
lastRead=millis();
}
}
and here is the "evolution", but still untested (unfortunately actually I don't have any IR led)
ERER.h
#ifndef ERER_h
#define ERER_h
#include "WProgram.h"
class ERER {
public:
ERER(byte, byte, byte);
long getRawDistance();
private:
byte getBCDpin(byte);
void setStatus(byte, byte, boolean);
};
#endif
LITTLE problem: if you look at 2m the response time will be in order of 1 or 2 seconds.. So you can use a timer interrupt like every 200 or 500millis that will reset the count...
you won't see far, but you'll gain "reflex"
if the class is right, you can have 1 sensor every 2 pin (receiverP can be simply put to GND), and you can easily* build an array system.
*easily if the class works. I can give support, but you'll have to give many feedback