In this project I am trying to measure the speed of paintballs moving at approximately 300 feet / second. Bare with me for this is my first project that's moving at 300 feet / second. I did some math and conversions and I believe what I'm doing is not too fast for the arduino to AnalogRead...
300ft/sec = 91.44 mm / 1mS
So the 16mm paint ball will move one full width in .176ms or 175.82 uS / 16 mm.
When looking at my IR Emitter and Detector they are both 5mm led's so I imagine it's a 5mm beam the ball is breaking.
| - 5mm - | < - Beam
@ 9uS/mm it blocks a 5mm beam in 45uS.
| (BALL | 11mm )
The ball will cross the beam for a full width (16mm) 175.82 uS / 16 mm
(BALL 11mm | ) |
So I did a simple test program and I see that with the beam being blocked for 175 micros I can AnalogRead at least 8 times while the ball is in front of the first sensor.
I am using code to set the prescale at 16 giving an ADC clock of 1MHz as stated here: Faster Analog Read? - #3 by jmknapp - Frequently-Asked Questions - Arduino Forum
Currently I'm able to drop a ball through the tube and get 9-10 Feet / second..
I just adjusted my code to only take the initial blocking of my first sensor because I believe the compressed air following the ball is throwing off my first sensor after the ball goes through it.
Here is my new code:
#define FASTADC 1
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
int averageFirst;
int averageSecond;
unsigned long start ;
unsigned long endTime;
int gateOne = 0;
int i ;
unsigned int val[20];
unsigned int val2[20];
unsigned int total;
unsigned int total2;
int times = 8;
float seconds;
void setup() {
#if FASTADC
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
#endif
pinMode(13, OUTPUT);
Serial.begin(9600) ;
Serial.println("CHRONOGRAPH INITIATING: ") ;
for (i = 0 ; i < times ; i++){
val[i] = analogRead(0);
delay(100);}
for (i = 0 ; i < times ; i++){
val2[i] = analogRead(5);
delay(100);}
//Calculate Total
for (int i = 0; i<times; i++){
total+=val[i]; }
for (int i = 0; i<times; i++){
total2+=val2[i]; }
//Calculate Average
averageFirst = total/times;
averageSecond = total2/times;
Serial.print("First Average: ");Serial.println(averageFirst);
delay(1000);
Serial.print("Second Average: ");Serial.println(averageSecond);
Serial.println("READY...");
Serial.println("");
i=0;
}
void loop() {
if (analogRead(0)<averageFirst-5) {
start = micros() ;
i ++;
gateOne ++;}
while (i==1){
if(analogRead(5)<averageSecond-5) {
endTime=micros();
if(gateOne==1){
//Fire Completed Sucessfully
Serial.println("End uS - Start uS: ");Serial.print(endTime);Serial.print(" - ");Serial.println(start);
Serial.print(endTime - start);Serial.print(" uS");Serial.println(" / 1,000,000");
seconds = (endTime-start)/1000000.0000;
Serial.print(seconds);Serial.println(" S");
Serial.print(".896 FT / ");Serial.print(seconds);Serial.print(" S");Serial.println("");
Serial.print(0.8960/seconds);Serial.println(" FT/Sec");
Serial.println("");
delay(1000);
gateOne=0;
i=0;}
else{
Serial.println("Missed First Gate");delay(100);}
}
}
}
With this older code I had a problem where I received a calculated time of 56uS = (7874836 - 7874780) meaning the ball was moving at "16000.00 FT/Sec" =( :
#define FASTADC 1
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
int averageFirst;
int averageSecond;
unsigned long start ;
unsigned long endTime;
int gateOne = 0;
int i ;
unsigned int val[20];
unsigned int val2[20];
unsigned int total;
unsigned int total2;
int times = 8;
float seconds;
void setup() {
#if FASTADC
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
#endif
pinMode(13, OUTPUT);
Serial.begin(9600) ;
Serial.println("CHRONOGRAPH INITIATING: ") ;
for (i = 0 ; i < times ; i++){
val[i] = analogRead(0);
delay(100);}
for (i = 0 ; i < times ; i++){
val2[i] = analogRead(5);
delay(100);}
//Calculate Total
for (int i = 0; i<times; i++){
total+=val[i]; }
for (int i = 0; i<times; i++){
total2+=val2[i]; }
//Calculate Average
averageFirst = total/times;
averageSecond = total2/times;
Serial.print("First Average: ");
Serial.println(averageFirst);
delay(1000);
Serial.print("Second Average: ");
Serial.println(averageSecond);
Serial.println("READY...");
Serial.println("");
}
void loop() {
if (analogRead(0)<averageFirst-5) {
start = micros() ;
gateOne=1;}
if(analogRead(5)<averageSecond-5) {
endTime=micros();
if(gateOne==1){
Serial.println("End uS - Start uS: ");Serial.print(endTime);Serial.print(" - ");Serial.println(start);
Serial.print(endTime - start);Serial.print(" uS");Serial.println(" / 1,000,000");
seconds = (endTime-start)/1000000.0000;
Serial.print(seconds);Serial.println(" S");
Serial.print(".896 FT / ");Serial.print(seconds);Serial.print(" S");Serial.println("");
Serial.print(0.8960/seconds);Serial.println(" FT/Sec");
Serial.println("");
delay(1000);
gateOne=0;}
else{
Serial.println("Missed First Gate");delay(100);}
}
}
I've attached what the jig looks like and a simple schematic drawing of how I have the emitter and detector connected w/ the RadioShack ir 276-0142 information.