top of page

Infrared Detection Circuit

For this project, I designed a circuit capable of detecting the frequency of a blinking infrared LED. The LED was driven with a square wave from a function generator and had to be detected 1 meter away to be considered successful. This kind of signal detection is key for communication with and between robots.

 

The high signal would be detected by a circuit using an op amp to amplify the small change in resistance of the IR photoresistor that acted as a sensor. This signal was fed into a pin on the Itsy Bitsy microcontroller. Through this project, I learned how to write embedded code for microcontrollers to parse and act on signals.

 

The code counted the time between "rising edges" (pin going from low to high) with the internal clock. This time was then calculated to give a frequency and a simple moving average was applied to ensure consistently lit output visible spectrum LEDs. Two "special" frequencies were targeted, 662 Hz and 25 Hz. If the detected frequency was sufficiently close to either of these special frequencies, either the the green or red LED circuits would be powered on the PORTB pins. Check out the video of it working below!

IMG_9595_edited.jpg

Circuit Layout (probes connected to function generator)

Screenshot 2024-10-06 at 5.06.51 PM.png

Circuit Diagram

Testing the Circuit from 1 meter away

#include "MEAM_general.h"  // includes the resources included in the MEAM_general.h file
#include "m_usb.h"

void initialize() {
    // Set B5 and B6 as outputs for the LEDs
    set(DDRB, PB5);  // Set B5 as output
    set(DDRB, PB6);  // Set B6 as output

    // Set C7 as input for detecting the frequency signal
    clear(DDRC, PC7);  // Set C7 as input
    clear(PORTC, PC7); // No pull-up resistor on C7

    // Configure Timer0 for 1-second timing
    set(TCCR3B, CS32);
    set(TCCR3B, CS30); // Set prescaler to 1024 (16 MHz / 1024 = 15625 Hz)
}

int main(void) {
    initialize();  // Initialize the timer and GPIO

    float frequency = 0;
    int state = 0;
    int last_state = 0;
    int time = 0;
    int counter = 0;
    float time1 = 0;
    float time2 = 0;
    float time3 = 0;
    int last_counter = 0;
    
    while (1) {
        // Count the number of rising edges (which gives the frequency)
       
        if (bit_is_set(PINC, 7) && last_state == 0) { // Rising edge detected
            state = 1;
            last_state = 1;
            time = TCNT3;  // Capture timer value on rising edge
            counter ++;
            TCNT3 = 0; //sets up the counter so it will count until next rising edge
        }
        else if (!bit_is_set(PINC, 7)&& last_state == 1) {
            last_state = 0;  // Reset to detect the next rising edge
            //TCNT3 = 0;
            //at high frequencies, duty cycle between the falling edge and rising edge is not reliably 50% so can't use freq = 15625/period/2 anymore.
            state = 0;//sets state to off after falling edge
        }
        
        if (counter > last_counter){ //some software filtering
            time3 = time2;
            time2 = time1;
            time1 =time;
            last_counter = counter;
        }
        time = (time1+time2+time3)/3;
        
        float period = (float)time;
        frequency = 15625/period;
        /*if (!bit_is_set(PINC, 7)){
            last_state = state;
            state = 0;
        }
        
        while (state == 0 && last_state == 0){
            time = TCNT3;
            last_state = state;
            if (bit_is_set(PINC, 7)){
                state = 1;
            }
            time = TCNT3;
        }
        float period = (float)time;
        frequency = 15625/period;
        TCNT3 = 0;*/

        // Check the frequency and control the LEDs accordingly
        if (frequency > 20 && frequency < 30) {
            set(PORTB, PB6);   // Turn on B6 LED (25Hz) (Red)
            clear(PORTB, PB5); // Turn off B5 LED
        } else if (frequency > 650 && frequency < 680) {
            set(PORTB, PB5);   // Turn on B5 LED (662Hz) (Green)
            clear(PORTB, PB6); // Turn off B6 LED
        } else {
            clear(PORTB, PB5); // Turn off both LEDs if frequency doesn't match
            clear(PORTB, PB6);
        }
    }
}

 

Code (Language: C)

bottom of page