Pages: [1] 2   Go Down
Author Topic: Doppler Speed Radar  (Read 7543 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi. I just started with Arduino last week and am loving it so far.

For this project, I'm trying to build a simple speed radar and am at a sticking point. Would love some help.

The sensor is a 10.525 GHz X-band doppler sensor: http://docs.microwave-solutions.com/createPdf.php?id=MDU1720
It outputs the doppler shift frequency.

I'm using an LM386 to amplify the signal with a gain of 200: http://www.ti.com/lit/ds/snas545a/snas545a.pdf (page 5, top right)

I've adapted my code from this tutorial's main code. And the second code example here.

My code currently looks like this:
Code:
// These are the counts needed for 250 msec interrupt
// using the timer prescaler settings set to 128.
const uint16_t TICK_CNT = 34286; // 65536-(16MHz/128/4Hz) 
static uint16_t freq = 0;
double sped = 0; //"speed" seems to be a reserved term

void setup() {

  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
 
  Serial.begin(115200);

  noInterrupts();                     // disable all interrupts while we configure 
  // init Timer1 - 16-bit timer/counter
  TCNT1   = 0;                                  // start count at zero.       
  TCCR1B  |= _BV(CS12) | _BV(CS11) | _BV(CS10); // Increment T1 input on each positive edge
                                                // using an external source. Table 16-5, pg 139.
 
  // init Timer2 - 8-bit timer/counter
  TCNT2   = TICK_CNT;                 // preload Timer2 to interrupt every 250 msec
  TIMSK2  = _BV(TOIE2);               // enable the Timer2 overflow interrupt
  TCCR2B  |= _BV(CS22) | _BV(CS20);   // init clock prescaler to 128. Table 18-9, page 164.
  interrupts();                       // enable all interrupts
 
  Serial.println("Ready...");
}

ISR(TIMER1_OVF_vect) {
  // do nothing. this is just a dummy ISR in case it actually overflows.
  Serial.println("Inside Timer1 Overflow Interrupt.");
}

ISR(TIMER2_OVF_vect) {
  //Serial.print("TCNT1: ");
  //Serial.println(TCNT1);
  freq = TCNT1;
  //Serial.println(freq);
  TCNT1 = 0;
  TCNT2 = TICK_CNT;
}

void loop() {
 
  if (freq != 0) {
      freq = freq << 2;      // multiple the frequency * 4 (using leftshift 2 places). 250ms*4 = 1 sec.
      sped = freq * .03225;  // multiplying freq * 0.0325 will give speed in mph. 31Hz == 1 mph.
                             // see: http://www.microwave-solutions.com/contents/en-uk/d13_System_Design.html
      Serial.print("Freq: ");
      Serial.print(freq, DEC);
      Serial.print(" Hz, Speed: ");
      Serial.print(sped, 3);
      Serial.println(" mph");
  }
}

I've found that the only pin that gives any output when the output of the amplifier is connected to it is Digital pin5. (I'm not sure why this is, and would love to know.)

When I wave my hand in front of or near the sensor, my output looks like this:
Code:
Ready...
Freq: 4 Hz, Speed: 0.129 mph
Freq: 16 Hz, Speed: 0.516 mph
Freq: 4 Hz, Speed: 0.129 mph
Freq: 16 Hz, Speed: 0.516 mph
Freq: 4 Hz, Speed: 0.129 mph
Freq: 16 Hz, Speed: 0.516 mph
Freq: 16 Hz, Speed: 0.516 mph
Freq: 64 Hz, Speed: 2.064 mph
Freq: 4 Hz, Speed: 0.129 mph
Freq: 4 Hz, Speed: 0.129 mph
Freq: 16 Hz, Speed: 0.516 mph
Freq: 4 Hz, Speed: 0.129 mph

Couple of questions:

1. Why Digital Pin 5? I thought it would've been one of the analog pins.

2. I'm pretty sure I'm waving my hand faster than 2mph. Why does my output give such low speeds? When I hook up my multimeter, set to Hz, to the output of the amplifier, I'm getting readings > 100 Hz when I wave my hand. (I also get a standing frequency of 100Hz when connected to the output and 60Hz with just the ground connected and the positive floating in the air.)

3. From my understanding of what the code is supposed to be doing, it has set Timer1 to count rising edges from an input. Timer2 has been configured to wait 250ms, then interrupt and read the # of pulses into freq variable from Timer1, reset Timer1 back to 0, and preload to interrupt again in 250ms. Is my understanding correct?

4. Is there something wrong with my TICK_CNT (preload amount) and prescaler selection that is causing me to not count all of the pulses?

Thanks in advance!
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One problem is that you don't set freq back to 0 after you display the speed.  This causes a count of 1 to be reported as 4, 16, 64.

It would be good to check Timer2 to see that it is actually triggering every 250 milliseconds.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Edison Member
*
Karma: 50
Posts: 1702
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When checking the speed it would probably be better to use something metallic to wave at the sensor to give a better reflection of the signal.

Pete
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I changed the sketch to increment freq in the Timer2 ISR and ran for 10 seconds.  Got 245.1 interrupts per second, not 1 interrupt every 250 milliseconds (4 interrupts per second).  That's why your frequency counts are so low.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the replies.

Of course, after I posted, I realized that Timer2 is an 8-bit timer, not a 16-bit timer.

That means that my TICK_CNT is incorrect.

Now, I'm looking at 255-(16Mhz/1024/62Hz) for roughly 3 as a TICK_CNT preload.

Of course, this means I'm interrupting 62 times per second instead of 4, but 62 was the smallest number that I could work out where the TICK_CNT wasn't negative and it was close to a whole number. Maybe I'm thinking about this the wrong way though because it means I need to multiply the number of counted pulses by Timer1 by 62 in order to get an estimate of the speed.

The maximum speed that I'm looking to capture would be 200 mph. That means 31Hz * 200 = 6200 Hz, which should still be able to be captured even if I'm interrupting 62 times per second. Right?

Updated sketch:
Code:
const uint16_t TICK_CNT = 3; // 255-(16MHz/1024/62Hz) 
static uint16_t freq = 0;
double sped = 0; //"speed" seems to be a reserved term

void setup() {

  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
 
  Serial.begin(115200);

  noInterrupts();                     // disable all interrupts while we configure 
  // init Timer1 - 16-bit timer/counter
  TCNT1   = 0;                                  // start count at zero.       
  TCCR1B  |= _BV(CS12) | _BV(CS11) | _BV(CS10); // Increment T1 input on each positive edge
                                                // using an external source. Table 16-5, pg 139.
 
  // init Timer2 - 8-bit timer/counter
  TCNT2   = TICK_CNT;                 // preload Timer2 to interrupt every 250 msec
  TIMSK2  = _BV(TOIE2);               // enable the Timer2 overflow interrupt
  TCCR2B  |= _BV(CS22) |_BV(CS21) | _BV(CS20);   // init clock prescaler to 1024. Table 18-9, page 164.
  interrupts();                       // enable all interrupts
 
  Serial.println("Ready...");
}

ISR(TIMER1_OVF_vect) {
  // do nothing. this is just a dummy ISR in case it actually overflows.
  Serial.println("Inside Timer1 Overflow Interrupt.");
}

ISR(TIMER2_OVF_vect) {
  //Serial.print("TCNT1: ");
  //Serial.println(TCNT1);
  freq = TCNT1;
  //Serial.println(freq);
  TCNT1 = 0;
  TCNT2 = TICK_CNT;
}

void loop() {
 
  if (freq != 0) {
      freq = freq * 62;      // multiple the frequency * 4 (using leftshift 2 places). 250ms*4 = 1 sec.
      sped = freq * .03225;  // multiplying freq * 0.03225 will give speed in mph. 31Hz == 1 mph.
                             // see: http://www.microwave-solutions.com/contents/en-uk/d13_System_Design.html
      Serial.print("Freq: ");
      Serial.print(freq, DEC);
      Serial.print(" Hz, Speed: ");
      Serial.print(sped, 0);
      Serial.println(" mph");
      freq = 0;
  }
}

Updated output: Looking better!
Code:
Ready...
Freq: 62 Hz, Speed: 2 mph
Freq: 310 Hz, Speed: 10 mph
Freq: 186 Hz, Speed: 6 mph
Freq: 62 Hz, Speed: 2 mph
Freq: 248 Hz, Speed: 8 mph
Freq: 310 Hz, Speed: 10 mph
Freq: 186 Hz, Speed: 6 mph
Freq: 248 Hz, Speed: 8 mph
Freq: 310 Hz, Speed: 10 mph
Freq: 124 Hz, Speed: 4 mph
Freq: 434 Hz, Speed: 14 mph
Freq: 310 Hz, Speed: 10 mph
Freq: 248 Hz, Speed: 8 mph
Freq: 992 Hz, Speed: 32 mph
Freq: 124 Hz, Speed: 4 mph
Freq: 434 Hz, Speed: 14 mph
Freq: 124 Hz, Speed: 4 mph
Freq: 310 Hz, Speed: 10 mph
Freq: 496 Hz, Speed: 16 mph
Freq: 372 Hz, Speed: 12 mph
Freq: 372 Hz, Speed: 12 mph
Freq: 62 Hz, Speed: 2 mph

Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4837
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Doppler will only give you speed along the radar beam relative to the emitter. Waving your hand across the beam won't give you much frequency change. Wave you hand at the emitter instead.



Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Doppler will only give you speed along the radar beam relative to the emitter. Waving your hand across the beam won't give you much frequency change. Wave you hand at the emitter instead.
Thanks. FWIW, that's what I am doing.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

Just wondering, is this the full code?
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, Just wondering, is this the full code?

The sketch compiles so it is probably complete.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, in this coding,where the code indicates signal come from.....?
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, in this coding,where the code indicates signal come from.....?

It's using the pulse counting feature of Timer/Counter 1.  That would be the signal called "T1" which on the ATmega328P is pin 5 of  Port D.  Arduino calls it Pin 5.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i see......but i thought he want to analyse doppler frequency.so,instead analyse doppler frequency, is he analyse frequency by generates pulse from timer?
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i see......but i thought he want to analyse doppler frequency.so,instead analyse doppler frequency, is he analyse frequency by generates pulse from timer?

You can measure frequency by measuring pulses per unit time (or time per pulse).

Timer/Counter1 is counting pulses.  Timer/Counter2 is interrupting 62 times per second.  Each time Timer/Counter2 interrupts he grabs the count from Timer/Counter1.  Multiply that by 62 to get counts per second: frequency.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4837
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is there somewhere that he is subtracting frequency of output to that received?
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26632
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is there somewhere that he is subtracting frequency of output to that received?
That's usually already done in the mixer within the module.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pages: [1] 2   Go Up
Jump to: