Doppler Radar for Collision Avoidance
by Mayur Patel
ECE 4760, Fall 2014
Contents
Hardware and
Software Tradeoffs
Figure 1 General Concept of
Functionality
My project uses Doppler radar sensors in order to provide the
user with movement, speed, and distance information of their environment. An
array of Doppler radar sensors are placed on the user’s head and vibration
motors are placed on the user’s chest, neck, back, and/or arms in order to
provide input to the user without impeding any of their other senses. When
something moves within about 25 feet of the user, the corresponding vibration
motor for the particular direction relative to the user where the movement was
detected will activate with a certain intensity to indicate how far away the
movement was detected. In cases where an object is moving rapidly towards the
user at a high speed, an emergency notification is sent such that all motors
are activated and will pulse, while the motor corresponding with the direction
the danger is in will be continuous and at a higher intensity to alert the user
to where the danger is.
The reason for this project is that from looking at new
safety features being implemented in cars such as forward collision warning, I
found a great opportunity to use a similar technology to provide almost another
sense for people that may be walking, bicycling, or otherwise. This project is
intended to provide added safety to users in multiple situations. For example, this
can provide added comfort and safety to users walking at night by alerting them
towards anything they may not be able to see. In addition, when walking on the
street, this can alert users of bicyclists or electric vehicles coming from
behind that they might have not noticed. Lastly, this can also be used for
those who have visual or audio impairment by provided extra information about
their surroundings to improve their safety and comfort. For example, this
project also allows users to be able to detect that they are walking towards an
object like a wall, and can help avoid walking users from colliding into
things.
It is becoming increasingly interesting to have wearable
technology, but one type, we have had for decades: technology to help the
health and safety of people. This is just another kind of wearable device that
can help many people in their daily lives. Inspired from safety technology in
modern cars that car alert, and even prepare the car for dangers. One such
system is the forward collisions warning or mitigating system that detect an
imminent crash and can even help prevent it. With more and more people
including wearable technology into their daily lives, this would be a great
opportunity to integrate technology similar to the forward collision warning
system, but for people. Not only would this device be useful to those with
visual or audio impairments by providing almost another sensor to them, but
also any other person in their daily lives. Walking at night can be
uncomfortable and with very quiet hybrid and electric vehicles, it is difficult
to sense the presence of them, which can lead to dangerous situations. This
system helps provide extra information from every direction. However, we do not
want to impede the user. For example, blind people heavily rely on their
hearing to be able to understand their surroundings. This should not impair
their hearing, perhaps by requiring their use headphones, as that takes away
from their sense of their surroundings.
The main piece of information required is that Doppler radar
implements the Doppler shift effect. This means that the results we get are
relative to the user. So, if the user is stationary and an object is coming
towards the user, or if the object is stationary but the user to moving towards
the object, we get, for all practical purposes, the same result.
Here, is the original microwave frequency emitted by
the sensor, which is at 10.525 GHz. Using the second equation as an
approximation, the return frequency
is just a function of the original frequency and
the relative velocity of the object. This is the fundamental property that
allows both an object moving and the user moving to be essentially the same;
thus enabling both collision avoidance and obstacle avoidance.
Approaching the design of the project, it is important to
first create an overall structure. For this project, there were two logical
components: the sensor system, and the notification system. In addition, both
of those systems are divided into the hardware and software systems. This
division not only has helped in the process of developing, testing, and
developing the project, but also modulizes the components so they could be
upgraded or changed in the future. In real development, this modularity was
actually kept up; for example, the vibration software is completely separate
from the sensor software and, instead, provides an easy to use interface to the
sensor software to control the vibration motors.
Figure
2 Logical Layout
of System
As shown in the figure above, the sensor provides an IF
(intermediate frequency) signal to a band pass filter, which not only filters
the frequency but also greatly amplifies the signal. The distance can actually
be taken from the band pass filter, as it is just the voltage of the signal. The
output of the band pass filter is also fed into a comparator, which outputs a
0-5V digital signal for movement changes. The higher the frequency of change,
the faster the object is moving. These two signals are fed into the
microcontroller, an ATmega1284P in this case. The sensor software measures the
frequency using timers and distance using the ADC. It then determines the
current situation and invokes vibration motor control functions. The software
changes the PWM output for each of the vibration motors periodically using the
input from the sensor software. The PWM drives a simple motor driver circuit
and invokes the motor to vibrate. Each sensor has a corresponding vibration
motor.
In addition to the core of the project, the extra piece is a
mode selector. The mode controller’s hardware is composed of a push button and
three differently colored LEDs for status indication. Pushing the button will
cycle through the three different modes: normal mode, near distance mode, and emergency
only mode. Each mode has a unique LED color to indicate to the user. This
system simply adjusts the sensor software to only trigger the vibration
software when certain conditions are met. This allows for more use scenarios as
normal mode might be too informative in certain situations. For example, for
most people, it is not an issue to be notified of every movement around them as
they walk through a busy street; in this scenario, emergency only mode is much
more appropriate as it will only alert them in dire situations.
One of the major engineering decisions that need to be made
is how much to do in hardware and how much to do in software. For this project,
I opted to use each of their strengths as a basis of how I split apart the systems.
In terms of signal filtering, I could have implemented it in both hardware and
software. However, to be precise with the IF signal on the magnitude of
millivolts, I would have needed much more than 10 bits of data from the
internal ADC to be able to read the IF input. In addition, this imposes
processing delay. Analog on the other hand was a much better choice because it
is able to process it instantaneously for all practical uses and it was not
limited by a finite resolution ADC. For the sensor information processing,
software was an obvious choice. This can actually be implemented in digital
hardware using basic logic gates, registers, and counters; however, the
hardware would require too much space and would be difficult to change or
upgrade.
There were also compromises required in order to produce
manageable results. The sensor provided information from relatively large
distances (about 25 ft.), permeates through many materials such as wood and
some metal, and, with the high frequency of 10.525GHz, can detect very small
movements as well. However, in order to actually make sense of the signal, it
required a sensitive signal processing circuit which required a lot of
calibration, a very consistent power source, and was fairly large. It would
have been possible to use ultrasonic sensors with much less signal processing
requirements; however, this greatly reduces resolution, permeability, and
distance. For a system that should warn a user about an incoming collision, it
is necessary to warn the user much earlier as it takes time for humans to
respond, and ultrasonic would not have enough distance and resolution to
provide the couple of seconds that people need to react.
As with any project, the IEEE Code of Ethics is always
relevant. Being a relatively-long term project, it is always a good idea to be
aware of the safety of others, good social conduct, and honesty. In addition,
there are other standards to comply with is the frequency for the microwave
sensor. The module complies with FCC rules, Part 15, Section 15.245, which
talks about radiation emissions. In addition, falling under the “motion sensor”
category, it must comply with the specified frequency for the US, which is
10.525 GHz. The specific module used compiles with both of the standards. The
module is QC passed, so it has been verified to meet these standards. Lastly, I
complied with the ISO C90 standard in which all variable declarations are done
at the top of a function. This is done to follow convention and to allow anyone
reading the code to be able to quickly reference the variable declarations in a
consistent spot.
There have been some similar implementations as this;
however, the form factors, interfaces, and technologies vary widely. Some such
implementations include a single sensor in a cane to detect movement in front
of the user, and a belt to detect movement around the user. However, none have referenced
using Doppler radar or as many use cases as this project. For example, the cane
can only sense ahead of the user, and is generally only useful for those who
carry canes, and the belt would get a lot of user interfaces since the arms and
hands tend to stay at about the waist level. In addition, none have reference
multiple modes, or any user interface at all, include how they notify the user.
Thus, I concluded there is no patents, trademarks, and copyrights relevant.
The high level circuit diagram is included in the Appendix. Since the ATmega1284P only has 3 regular interrupt
ports, I used the pin change interrupt ports instead. From the sensor system,
the frequency outputs were connected to pin change interrupt ports. In order to
help with both wire and software organization, two sensors were designated to
port B pins and the other two to port D pins. The distance readings require the
ADC, so they were all connected to port A pins. Lastly, the vibration motors
PWM ports where attached to the PWM pins for the designated port. So the first
two sensors (designated to port B) used B.3 and B.4 for the PWM and the other
two (designated port D) used D.6 and D.7 for the PWM.
As previously mentioned, the sensor system requires a band
pass filter and a comparator to output an analog signal for distance and a
digital signal for frequency. Not only does this require frequency filtering
and amplification, but also noise reduction. Since the IF signal shown below is
just a few millivolts and very susceptible to noise, it is important to have a
consistent circuit. Note that the signal almost consistently stays within a
20mV peak-to-peak and that moving something in front of the sensor causes only
about 2mV difference in the signal. Also note the time base, with is 50ms per division. The signal is constantly changing, even at
this fine granularity.
Figure
3 Raw IF Signal
from Doppler Unit. (1) No movement. (2) Hand moving directly in front of
device.
As a basis, I used Mathieu Stephan’s circuit and swapped out
some parts and made some changes to better fit this project. The circuit
composed of a small power circuit that provided a capacitor charged filtered 5V
and 2.5V power source, and, for each of the four sensors, a two stage band pass
filter and comparator.
Figure
4 Power
Distribution Circuit
As shown to the right, there is a simple power circuit that
filters out high frequency noise, stores charge in capacitors in order to
provide a consistent voltage, and also goes through a voltage divider that
outputs a simple 2.5V. I included just one of these circuits in the system to
provide the power to all of the filtering circuits.
Figure
5 Sensor
Filtering Circuit
Each of the sensors had a filtering circuit to output an
analog distance measure and a digital frequency measure. In the figure above, I
highlighted parts of the circuits to help break apart the circuit into more
understandable parts. First, the purple nodes on the left are inputs and the
red nodes on the right are outputs. First, the non-inverting BPF (band pass
filter) and the inverting BPF provide precise filtering and high amplification.
With a two stage filtering system, we add more poles and zeros to create
ascends and descents our Bode plot. This first filter passes between 3.39 Hz
and 72.34 Hz. This is derived from the formula below such that the 10kW resistor and 4.7mF capacitor
is the low pass filter and the 1MW resistor
and 2.2nF capacitor is the high pass filter. In addition, it also amplifies the
signal by 100 (1MW / 10kW). Similarly, the second filter has a band width from 4.23 Hz
to 72.34 Hz, derived in the same way as the previous filter. The amplification
is 125, making it a system total of 12500.
Figure
6 Equation for
Center Frequency for Filter
Finally, we have the comparator. It takes the output from the
filter and compares it to a filtered 2.25V, established with a voltage divider (8.2/(8.2+10))
on the 5V supply. In addition, I added hysteresis on the comparator in order to
provide stability in the output of the system. Since the amplification of the
two filters is so high, noise can be greatly amplified. Adding hysteresis is
one of the ways noise is combatted in the system. The other major way noise is
combatted is the two BPF are actually in the same IC and I used the LF353,
which provides a CMRR (common-mode rejection ratio) of 100dB. The comparator
outputs a 0-5V digital signal to indicate a frequency change.
Finally, we have the line with the diode in it. I used a Schottky
diode, which has a lower voltage drop, and thus, higher efficiency. The resistor
and capacitor is in fact a passive low pass filter; however, in this case it is
being used as an integrator. It provides a voltage measurement of the output of
the sensor, which corresponds with how far the moving object is, although this
output is not linear to the distance of the object.
Figure 7 Motor Driver Circuit
For these small motors, it is easy to simply drive them with
the generic motor circuit, shown below. PWM is fast enough to be able to, at
least to any human, control intensity of the motor while continuously running. The
PWM signal is connected to the base of a NPN transistor; this allows us to
control the current flow through the circuit. When we output a digital low, the
transistor turns off and the motor no longer can get current to flow from VCC
to ground. When we output a digital high, the transistor turns on and allows
current to flow, activating the motor.
Note that the circuit also includes a diode across the motor.
This is very good practice to include, as it is a flyback diode, which absorbs
large voltage spikes caused by inductance from the motor. Without the
diode, we can have nasty spikes in voltage, governed by the equation. These
spikes can be of very large magnitude (50+ V for typical motors) and can wear
out parts of the circuit or even destroy them. The diode allows for a space way
for current to be dissipated when the transistor turns off and there is
suddenly no other path for the voltage to follow.
The hardware for the mode selector was very basic, as it did
not need to be complicated. The selector was just a switch in functionality
such that pushing it once would connect the 5V to the rest of the circuit and
then the microcontroller would be able to read a digital high on the connected
port. Pushing it again would disconnect the 5V source and the microcontroller
would read a digital low, as the lower part of the circuit is grounded. The
mode indicators were just a resistor and LED in series.
Figure
8 Mode Selector
and Indicator Circuit
As previously noted, the software was divided into two
sections: the sensor system and the notification system. Not only did this help
during the process for designing, coding, and debugging, but can also help in
the future if any upgrades or changes are needed. I used interrupts to capture
the frequency changes, which makes the most sense. In addition, I used interrupts
to detect mode selection. This is done because polling for these is not
efficient and is unnecessary. However, I would need a way to measure speed
using the frequency data in a consistent manner. I decided to implement a
completely interrupt based system. The main function, after some
initialization, will just idle, and interrupts will prompt the system to update
the state. So, I defined a sensor cycle to run at 120 Hz, or about every 8.3 milliseconds
using timer 1. This means that I will process collected data from the sensors
120 times in a second. I chose this as it was not fast enough that the response
would feel instantaneous, but long enough to collect enough data to be able to
determine a relative speed and whether the object was moving closer or farther
away. As for the vibration controller, I used the same approach in order to
provide a guaranteed minimum run time for each vibration using timer 0. The
vibration cycle runs at about 20 Hz, or about every 50 milliseconds. While this
may seem slow, the vibration is for humans, and this speed is sufficient to
provide up to date information without having situations where a single
movement detection only invokes a few milliseconds of vibration, which would be
virtually undetectable to users. However, timer 0 actually interrupts at about
980 Hz. The vibration state is only handled at 20 Hz, but other mechanisms,
such as the ramp vibration pattern, are handled at a much higher speed to achieve
a smooth transition in the pattern. The diagram below shows the general
software flow, which will be further explained below.
Figure
9 Overview of
Software Flow
The sensor system has two components: data addition and data
accounting. Data addition is done through the frequency interrupts from the
sensor. Since we can have four sensor interrupting at the same time and they can
interrupt as frequently as every 1.5 milliseconds (determined through testing),
this code needs to be relatively quick. The frequency signal is active low, and
since we have to use pin change interrupts, we would get two interrupts for
every movement detection. Each cycle takes 62.5 ns and we could possible
interrupt at 187.5 ns at the worst case, which gives us 3 cycles per interrupt.
Obviously this is impossible to achieve, and it is also very unlikely that it
will get to that point. Nevertheless, I implemented a “best effort” system that
is actually allowed to and designed to drop interrupts. When it gets to the
point that we are fighting for cycles, we can load the CPU as much as we can,
and calibrate our parameters to be able to understand and properly assess the situation.
So, if we take interrupts as fast as possible, we can at least take a large number
of the interrupts and we set our thresholds to slightly lower than this large
number. With this, we can tell that the CPU is at its maximum load and that the
particular object is at its maximum speed. In the interrupt, since it is a pin
change interrupt, we check if it was a valid interrupt (a negative edge),
update an interrupt counter for the sensor and take the distance measurement to
store it as the latest value.
In the data accounting section that runs at 120 Hz, we make
sense of all of data we had accumulated in that sensor cycle. For each of the
sensors, we look at the latest distance measurement to determine how far the
object is, we take the difference between the first and last distance measurement
to determine what direction the object is moving (towards or away from the
user), then we use the counter to determine the speed of the object. The more
interrupts we got, the faster the object was going. Using all of this computed
data, we invoke the vibration software, giving it a certain duration, pattern,
and intensity appropriate to the situation. We also determine if this was an
emergency situation. For each sensor that encountered an emergency situation,
we invoke an emergency notification. After the current sensor cycle is handled,
we clear all of the collected data so we can start fresh for the new sensor
cycle.
Similar to the sensor software, this runs in two components: state
set and state update. State set is invoked by the user of the software and
simply updates local variables. The three state set functions, vib_on, vib_off, and vib_emergency take in arguments and updates the pattern,
duration, power level, and/or start flag for each motor. The state update is
invoked, as the state diagram shows, through timer 0. At about 20 Hz, it
updates the state of the vibration motors by changing the PWM output compare
registers. When the duration of a motor expires, it stops the PWM output. When
a state update set the start flag, it will start a PWM output. This handles the
accounting for the vibration. Next, it handles PWM ramping. This happens at the
speed of interrupts, 980 Hz, and it simply updates the output compare registers
for the PWM output for motors that have a RAMP vibration pattern set. One ramp
period takes 127 cycles, so it runs at about 7.8 Hz. For the first 25 cycles,
it linearly ramps up to the full value of the set power level, and for the last
25 cycles, it ramps down. For the rest of the cycle, it sustains the maximum
output for the given power level. After that, it simply updates its internal
counter for timing and toggles the status LED, which is just used for purposes
of debugging (to check if the system is still running and making progress).
As previously mentioned, this runs through the pin change interrupt.
The push button switch provides an interrupt, letting us know to cycle through
the three modes. The mode is just a status variable that gets checked in the
sensor software. In order to debounce the button, we take advantage of the fact
that we already have timer1 setup and in use. After a mode change, we start the
debouncer, which is simply a counter. In each timer1 interrupt, when the counter
is set, it will increment the value until it reaches 5 counts, at which point
it resets. When the button is pressed and the debouncer is active, the pin
change interrupt for the mode selector will simply do nothing. However, if the
button is pressed after the debouncer is reset, it will change modes. This is a
very simply way to debounce – simply waiting about 33.3 ms between button
pushes. I chose this method because it was simple and required minimal effort.
Since this button would not be pushed very often, there is no need to load the
microcontroller with additional demand.
VARIABLES/MACROS |
DESCRIPTION |
S# (0,1,2,3) |
Pin number for where the frequency input for the sensor is connected
to |
S#_F (0,1,2,3) |
Value for current frequency pin of the sensor |
S#_D (0,1,2,3) |
Accessor to an 8-bit number, taken from the ADC. Does not invoke the
ADC to measure |
GRN |
Bit value
for the pin the green LED is connected to |
ORG |
Bit value for the pin the yellow-orange LED is connected to |
RED |
Bit value
for the pin the red LED is connected to |
STATE_NORM |
Enum for normal mode. Pertains to the state variable |
STATE_NEAR |
Enum for
near distance mode. Pertains to the state
variable |
STATE_EMERG |
Enum for emergency only mode. Pertains to the state variable |
NORM_DUR |
Configuration
parameter: duration for a normal vibration invocation |
NO_HISTORY |
Pertains to pin_history1 and
pin_history3. This value is what a
no history would be for those two variables. |
EMERGENCY_CNT |
Configuration
parameter: threshold for how many interrupt counts are required for a sensor
per sensor cycle to be determined as an emergency |
NO_EMERGNECY |
Serves no other purpose than just to make the code a little bit more readable |
DIST0 |
Configuration
parameter: minimum distance reading for the closest distance level |
DIST1 |
Configuration parameter: minimum distance reading for the 2nd
closest distance level |
DIST2 |
Configuration
parameter: minimum distance reading for the 3rd closest distance
level |
s#_cnt (0,1,2,3) |
Interrupt counter per sensor cycle. Pertains to the speed of the
movement |
s#_fst (0,1,2,3) |
First
distance measurement per sensor cycle |
s#_lst (0,1,2,3) |
Latest distance measurement per sensor cycle |
pin_history1 |
Holds the
last port B pin values. Required to determine if there was a negative edge
due to the way pin change interrupts work. This is for PCINT1 |
pin_history3 |
Holds the last port D pin values. Required to determine if there was
a negative edge due to the way pin change interrupts work. This is for PCINT3 |
state |
Current mode
of the system (normal, near distance, or emergency only) |
debounce_cnt |
Counter for debouncer |
FUNCTIONS |
DESCRIPTION |
ISR (TIMER1_COMPA_vect) |
Performs sensor data accounting, as described in the sensor software
section |
ISR (PCINT#_vect) (1,3) |
Performs
sensor data collection, as described in the sensor software section |
ISR (PCINT2_vect) |
Performs mode selector handling, as described in the mode selection
software |
measure_ADC |
Given a
sensor number (0,1,2,3), this will change ADMUX, the ADC multiplexer to the appropriate pin and invoke an
ADC measurement. |
initialize |
Initializes the sensor system, required microcontroller hardware, and
initialize internal data. |
main |
Initializes
the sensor system, the vibration motor system, turns on interrupts, then
idles |
VARIABLES/MACROS |
DESCRIPTION |
DELTA |
Enum for vibration pattern. This just says stay on continuously |
RAMP |
Enum for
vibration pattern. This just says use a ramp pattern |
EMERG |
Enum for
vibration pattern. This just says use an emergency pattern |
VIB_LVLOFF |
Power level
for the motor being off |
VIB_LVL# (0,1,2,3) |
Power level for the motor being on. 0 is the weakest and 3 is the
strongest. They are not linearly distributed. Instead, they are distributed
using experimental results to be noticeably different |
M# (0,1,2,3) |
Output compare
registers for each of the given motors. This controls the PWM output |
D_E_MAIN |
Duration for Emergency: Main motors |
D_E_ACCS |
Duration for
Emergency: Accessory motors |
m#p (0,1,2,3) |
Current motor pattern |
m#d (0,1,2,3) |
Current motor
duration left |
m#l (0,1,2,3) |
Current motor power level |
m#s (0,1,2,3) |
Motor start
flag. Setting this indicates to start the PWM for the motor in the next
vibration cycle. If not set and it was turned off, it will not start |
counter |
Used to keep track of pattern cycles and vibration cycles through
timer 0 |
vib_ramp |
Ramp table.
[power_level][index]. Precomputed for quick execution in the ISR |
FUNCTIONS |
DESCRIPTION |
ISR (TIMER0_OVF_vect) |
Performs state updates, as described in the vibration system software
section |
vib_on |
Using the
provided enums in the header file, can turn on a motor by providing a
pattern, duration, and power level for a given motor |
vib_off |
Turns off the given motor |
vib_emergency |
Turns on
emergency mode using bitwise numbering. This allows multiple motors to be a
main emergency motor and the rest will be accessory ones |
In order to get intuitive use, there was a lot of calibration
that went into getting the results. For example, determining the distances for
what was near and what was difficult. The
distance measurement was not linear, and the farther away the moving object
was, the less resolution I had. In addition, the signal was not perfectly a
0-5V signal, so there was added scaling that was necessary. Through testing and
measurements, as shown below, I was able to determine the levels. The closest
level was at about 2.94V or above. This was in the vicinity of 4-5 feet
radially from the user. The next level was a voltage as low as 1.96V, which
corresponded to about 7-8 feet away. The next level was as low as 0.98V, which
was up to about 15 feet away, and lower than that would be greater than 15 feet
away.
Figure
10 Raw Distance
Output. Moving towards the sensor.
Next, the frequency needed some calibration. It was more that
the software needed to be calibrated to understand what relative speed of the
object. In this case, I took multiple instances to determine speed. One was up
and down movement of a hand, another was forwards and backwards movement of a
hand at high speeds, another was just normal classroom movement, and others. Some
of the oscilloscope screenshots are below. Using this data, I was able to
assess how fast the object was moving.
Figure
11 Frequency
outputs. (1) Up and down movement. (2) Towards and away movement. (3) Three
steps back, 1 lunge forward.
Other performance tests for the sensor included permeability.
I testing how well the sensor could not detect movement if it was being
shielded by a 3cm. piece of wood and also a 5mm piece of metal. For both instances,
the sensor was able to detect movement for over 15ft away. The scope shots are
shown below.