while(1) { // reduces jitter
cli(); // UDRE interrupt slows this way down on arduino1.0
for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
while(!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = rStart | freq; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
fft_input[i] = k; // put real data into even bins
fft_input[i+1] = 0; // set odd bins to 0
for (int ii = 0; ii < 500; ii+=1) {
__asm__("nop\n\t"); ←------ 500 no-op commands
}
}
}
We require that the arduino record 6 consecutive peaks at 660 Hz in order to indicate that the signal was detected. We did this so that if we picked up a frequency in someone’s voice or other noise, we wouldn’t accidentally start the robot. The robot will also respond to a person singing a 660 Hz tone, as tested by the resident choir member of our team.
if (fft_log_out[19]>cutoff){
count += 1;
if (count == 6){
count -= 1;
Serial.println("on");
}
} else {
count = 0;
Serial.println("off");
}
First, we built the IR circuit with the phototransistor according to the diagram in the
lab notes and generated its 5V source with a function generator. Then, we turned on the IR
hat, generating its 9V source also with the function generator, and placed it above the
phototransistor.
As the IR hat was above the phototransistor, we were able to observe the following waveforms.
Since these waveforms were noisy, we created a low pass filter using a 1.8kohms resistor
and 10nF capacitor, to get a clearer 6.08kHz frequency that we would easily be able to
detect on the FFT. The signal also appeared to be clipped, which we solved by reducing
the input voltage to the sensor to 2.5 volts.
Since the amplitude was still small, we also then passed the output of the filter to
the same opamp we used for the microphone, except powered at 2.5V so that we could still
sense the 6.08kHz frequency at further distances.
IR Schematic including low pass filter and opamp:
Waveforms observed after passing it through the low pass filter and opamp:
We also then checked the FFT which showed us a clear peak at 6.08kHz around bin 42 when the IR hat was placed above the phototransistor.
After confirming our circuit worked, we connected it to the arduino and ran the FFT sample code provided by the FFT library. The FFT sample code’s sampling rate was left unchanged with a division factor of 32 since we were still able to see the frequency easily after plotting the sensed data. We then edited the sample code to print “on” if it sensed the 6.08kHz around the 42nd bin, using a threshold of 100. All other times, it would print “off”.
In the video, you can see that when we have the IR hat, emitting a 6.08kHz signal, above the phototransistor, it would print “on”. This lets us know we can stop the robot once it senses another robot at 6.08kHz. Additionally, we checked that when a nearby decoy was emitting 18kHz, “on” is not printed to the serial monitor (which may have been an issue if we undersampled the IR). This worked, so we know that our robot can both stop if it sees another robot and ignore other decoy signals.