Hi, I’m trying to measure the length of wires by timing the time it takes for the electrical pulses or electromagnetic waves travel along the wires. To do this I’m just using the onboard 16mhz oscillator to time and a software denounced button on one transmitting arduino which has a wire from d7 connecting to d2 on the receiving arduino and then a wire from d7 on the receiving arduino to d3 on the transmitting one.(I’ll attach a sketch of this below.
I am aware that this will only measure to a resolution of 18.7ish meters and I do have wire longer than that. If I can get it working as it is then I’ll probably get a faster oscillator and a microcontroller that can work with it. This is mainly a test/practice before I upgrade.
The problem is that when I press the button the first result is 532, and x=2 (x was added to find any bugs). Then have a another completely different number (I think this is the bug since the x number goes negative and/or crazily high). These “random” numbers keep repeating every time I press the button. Does anyone know why or what I’m doing wrong.
Below is the results and then I’ve attached the code in each arduino
Frequency Counter
Took: 532
1
2
counts.
9.37 meters.
Took: 994
463
11318
counts.
4336.32 meters.
Took: 992
461
31217
counts.
4317.59 meters.
Took: 994
463
-22218
counts.
4336.32 meters.
Took: 994
463
-11588
counts.
4336.32 meters.
Transmitting arduino (arduino 1)
volatile boolean first;
volatile bool buttonPushed = false;
volatile boolean triggered;
volatile unsigned long overflowCount;
volatile unsigned long startTime;
volatile unsigned long finishTime;
int x = 1;
unsigned long n;
float l;
// timer overflows (every 65536 counts)
ISR (TIMER1_OVF_vect)
{
overflowCount++;
} // end of TIMER1_OVF_vect
ISR (TIMER1_CAPT_vect)
{
// grab counter value before it changes any more
unsigned int timer1CounterValue;
timer1CounterValue = ICR1; // see datasheet, page 117 (accessing 16-bit registers)
unsigned long overflowCopy = overflowCount;
// if just missed an overflow
if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF)
overflowCopy++;
// wait until we noticed last one
if (triggered)
return;
if (first)
{
startTime = (overflowCopy << 16) + timer1CounterValue;
first = false;
return;
}
finishTime = (overflowCopy << 16) + timer1CounterValue;
triggered = true;
TIMSK1 = 0; // no more interrupts for now
} // end of TIMER1_CAPT_vect
void prepareForInterrupts ()
{
noInterrupts (); // protected code
first = true;
triggered = false; // re-arm for next time
// reset Timer 1
TCCR1A = 0;
TCCR1B = 0;
TIFR1 = bit (ICF1) | bit (TOV1); // clear flags so we don't get a bogus interrupt
TCNT1 = 0; // Counter to zero
overflowCount = 0; // Therefore no overflows yet
// Timer 1 - counts clock pulses
TIMSK1 = bit (TOIE1) | bit (ICIE1); // interrupt on Timer 1 overflow and input capture
// start Timer 1, no prescaler
TCCR1B = bit (CS10) | bit (ICES1); // plus Input Capture Edge Select (rising on D8)
interrupts ();
} // end of prepareForInterrupts
void PushButton() //interrupt with debounce
{
volatile static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 50UL) // ignores interupts for 50milliseconds
{
buttonPushed = true;
}
last_interrupt_time = interrupt_time;
}
void receive(){
digitalWrite(8, HIGH);
digitalWrite(8, LOW);
x=x+1;
}
void setup ()
{
pinMode(8, OUTPUT);
Serial.begin(250000);
Serial.println("Frequency Counter");
prepareForInterrupts (); // set up for interrupts
attachInterrupt(digitalPinToInterrupt(2), PushButton,RISING);
attachInterrupt(digitalPinToInterrupt(3), receive,RISING);
} // end of setup
void loop ()
{ if(buttonPushed)
{buttonPushed = false;
delay(100);
digitalWrite(8, HIGH);
digitalWrite(8, LOW);
digitalWrite(7,HIGH);
digitalWrite(7,LOW);
delay(1000);
}
else{
return;
}
if (!triggered)
return;
// period is elapsed time
unsigned long elapsedTime = finishTime - startTime;
// frequency is inverse of period, adjusted for clock period
n = elapsedTime-531;
//l = n/5.3386282;
l = n/0.10677256;
Serial.print ("Took: ");
Serial.println(elapsedTime);
Serial.println (n);
Serial.println (x);
Serial.println (" counts.");
Serial.print (l);
Serial.println (" meters. ");
// so we can read it
delay(1500);
prepareForInterrupts ();
} // end of loop
Receiving arduino code (arduino 2)
void setup() {
pinMode(7, OUTPUT);
attachInterrupt(digitalPinToInterrupt(2), transmit, RISING);
}
void loop() {
// put your main code here, to run repeatedly:
}
void transmit(){
digitalWrite(13, HIGH);
digitalWrite(13, LOW);
digitalWrite(7, HIGH);
digitalWrite(7, LOW);
//The longer this is the bigger the random number gets
}
Any solutions or ideas would be helpful