Control Logic

Contol Logic:

The following code takes input from all sensors and enables or disables audio (via a signal to the relays).  It is an infinite loop that polls the current state of every sensor and executes logic based on those states.  All of these inputs are ORed together so that the music will turn on if any one sensor is triggered.  When all of these sensors go quiet, we assume that the user has left the room.  A 5 second timer will start and the music will be shut off after the timer has expired if there is no more activity in the room.  In a production model, this timer shut-off period would be adjustable to fit the consumer's preference.

Our sound detection algorithm works by comparing the max amplitudes of the samples from our microphone and comparing it against a baseline that is recorded in a setup period.  If there is a certain amount contiguous samples that break the ambient threshold, then we know that there is someone present.

Two sets of IR sensors allow us to detect if a person is entering or leaving a room.  If the "far" IR beam is broken, a flag is set as a possible person entering the room.  If the "close" IR beam is then broken and the flag is still set, then this confirms movement into the room.  If the second beam is not broken within 1 second, then the flag is set to false and the logic reset.  The same could be said about a person leaving the room but in the reverse fashion.

 

#include <stddef.h>
#include <stdio.h>
#include "alt_alarm.h"
#include "alt_types.h"
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "altera_up_avalon_audio.h"
#include "io.h"

#define TRUE 1
#define FALSE 0

/* Global arrays for the baseline and the live signal */
int baseline_audio_samples[4000]; /* 4000 samples with 2 channels */
//int live_audio_samples[4000];
int live_audio_samples;
/* Audio Device */
alt_up_audio_dev * audio_dev;

/* FUNCTION PROTOTYPES */
void initialize_audio();
void getBaseline();
short personPresent();
void playBaseline();

volatile int *SW = (int *)0x000110d0; // Both 16 bits

        static alt_alarm alarm;
        static alt_alarm alarm3;
        static alt_alarm alarm4;
       
       
       
 int timer_started = 0;    
int init = 1;
int waiting=0;
int musicStop = 0;
int pos1=0;
int pos2=0;
int count3=0;
int leaving_wait=0;
int entering_wait=0;
int count=0;

int count1=0;

unsigned int total;
   /* used for audio record/playback */
        unsigned int l_buf;
        unsigned int r_buf;
       
/*
* The callback function.
*/
alt_u32 music_stop (void* context)
{
    /* This function will be called 5 seconds after no movement */
    alt_printf("music stop\n");
    IOWR_ALTERA_AVALON_PIO_DATA(MUSICLED_BASE, 0x0);
    alt_alarm_stop (&alarm);
    timer_started=0;
    waiting=1;
    musicStop = 1;
     IOWR_ALTERA_AVALON_PIO_DATA(RELAY_BASE, 0x0); //turn off relay
   
    return alt_ticks_per_second();
}


alt_u32 music_stop_0 (void* context) //entering
{
    /* This function will be called 5 seconds after the first of the IR beams
     * are broken */
    alt_printf("pos1 off\n");
    alt_alarm_stop (&alarm3);
    pos1 = 0;
    count3 = 0;
   
    entering_wait=0;
   
   
    return alt_ticks_per_second();
}

alt_u32 music_stop_1 (void* context) //leaving
{
    /* This function will be called 5 seconds after the first of the IR beams
     * are broken */
    alt_printf("pos2 off\n");
    alt_alarm_stop (&alarm4);
    pos2 = 0;
    count = 0;
   
    leaving_wait=0;
   
   
    return alt_ticks_per_second();
}


int main(void)
{
        //audio codec
        // open the Audio port
        audio_dev = alt_up_audio_open_dev (AUDIO_0_NAME);
        if ( audio_dev == NULL)
        alt_printf ("Error: could not open audio device \n");
        else
        alt_printf ("Opened audio device \n");
        alt_up_audio_reset_audio_core(audio_dev);
        alt_up_audio_disable_write_interrupt(audio_dev);
       
        //timer
        int result;
        int pir=0;
        int mic=0;
        int beam1=0;
        int beam2=0;
        int beam3=0;
        int doorway_entry=0;
       

       
    //sound detection   
    int i;


    /* Wait until switch 1 is truned on */
    while ((IORD(SW,0) & 0x1) == 0x0)
    {
        NULL;
    }
    alt_printf("Getting Base Signal\n");
    getBaseline();
    alt_printf("Done Getting Base Signal\n");

    while ((IORD(SW,0) & 0x4) == 0x0)
    {
        /* Show the base signal to understand it - probably not needed in final design */
        alt_printf("Base Signal\n");
        for (i = 0; i < 4000; i++)
        {
            alt_printf("%x:%x ", i, baseline_audio_samples[i]);
        }
        alt_printf("\n");

        while ((IORD(SW,0) & 0x1) != 0x0) // Wait till back down
        {
            NULL;
        }
        alt_printf("Done waiting\n");
        playBaseline();

        while ((IORD(SW,0) & 0x1) == 0x0) // Wait till back up
        {
            NULL;
        }
        alt_printf("Read Again waiting\n");
        getBaseline();
    }
      
   
        while(1){
            alt_printf("pir: %x mic: %x beam1: %x beam2: %x beam3: %x count: %x\n",pir,mic,beam1,beam2,beam3,count1);
           
           
            pir = IORD_ALTERA_AVALON_PIO_DATA(PIR_BASE);
            //mic = IORD_ALTERA_AVALON_PIO_DATA(MIC_BASE);
            beam1 = IORD_ALTERA_AVALON_PIO_DATA(BEAM1_BASE);
            beam2 = IORD_ALTERA_AVALON_PIO_DATA(BEAM2_BASE);
            beam3 = IORD_ALTERA_AVALON_PIO_DATA(BEAM3_BASE);
           
           
            //sound detection check
            if (personPresent() == TRUE)
            {
                alt_printf("Someone here\n");
                mic=1;
                IOWR_ALTERA_AVALON_PIO_DATA(MICOUT_BASE, 0x1);
            }
            else
            {
                alt_printf("Nobody here\n");
                mic=0;
                IOWR_ALTERA_AVALON_PIO_DATA(MICOUT_BASE, 0x0);
            }
   
            /* Check switch 2 if off to compare against */
            while ((IORD(SW,0) & 0x2) != 0x0)
            {
                NULL;
            }
           
           
            //doorway logic
             //checking if people entering room
            
                    if (beam3 == 1){
                        pos1 = 1;
                       
                        //start the timer...from room2 to room1
                        //if irbeam2 is not activated in a certain amount of time, pos1 = 0;
                        //implement a wait(), so the timer gets called once
                        count3++;
                        if ( count3 == 3 ) {
                            alt_alarm_start (&alarm3, alt_ticks_per_second()/10,music_stop_0,NULL);
                           
                        }
                       
                    }
                   
                    if (beam2 == 1 && pos1 == 1){
                        alt_printf("entering \n");
                        alt_printf("entering_wait: %x\n",count1);
                        entering_wait++;
                        if(entering_wait==3){
                            count1++;
                        }
                        alt_printf("Music1 start: IRBeam2 Broken, someone entered Room1 \n");
                        doorway_entry = 1;
                      
                    }
                   
                   
                    //checking if people leaving room
                    if (beam2 == 1){
                        pos2 = 1;
                        alt_printf("IRBeam2 broken! \n");
                       
                        //nested if statement for starting the timer...from room1 to room 2
                        //if irbeam3 is not activated in a certain amount of time, pos2 = 0;
                        //implement a wait(), so the timer gets called once
                        count++;
                        if ( count == 3 ){
                            alt_alarm_start (&alarm4, alt_ticks_per_second()/10,music_stop_1,NULL);
                           
                        }
                       
                    }
                   
                    if (beam3 == 1 && pos2 == 1){
                        leaving_wait++;
                        if(leaving_wait==3){
                            count1--;
                        }
                    
                            doorway_entry=0;
                        alt_printf("Someone leaving room \n");
                     
                    }
           
           
           
           
            //timer
            if((pir==0 && mic==0 && beam1==0 && doorway_entry==0) && timer_started==0 && init!=1 && waiting!=1)
            {
                   result = alt_alarm_start (&alarm, alt_ticks_per_second(),music_stop,NULL);
                   alt_printf("timer start\n");
                   timer_started=1;
                   waiting=1;
                    if (result < 0)
                         printf("[alarm test] failed to start alarm\n");
           
            }
       
             else if((pir==1 || mic==1 || beam1==1 || doorway_entry==1) && waiting==1)
             {
                   alt_alarm_stop (&alarm);
                   timer_started=0;
                   waiting=0;
                   musicStop=0;
                   IOWR_ALTERA_AVALON_PIO_DATA(RELAY_BASE, 0x1); //turn on relay
                     IOWR_ALTERA_AVALON_PIO_DATA(MUSICLED_BASE, 0x1);
                      alt_printf("music start\n");
            }
           
             else if((pir==1 || mic==1 || beam1==1 || doorway_entry==1) && timer_started==0 && init==1)
             {
                   alt_alarm_stop (&alarm);
                   timer_started=0;
                   init=0;
                   waiting=0;
                   musicStop=0;
                    IOWR_ALTERA_AVALON_PIO_DATA(RELAY_BASE, 0x1); //turn on relay
                     IOWR_ALTERA_AVALON_PIO_DATA(MUSICLED_BASE, 0x1);
                      alt_printf("music start\n");
            }
       }
       
        return 0;
}

/* Baseline collection algorithm */
void playBaseline()
{
    int i;
    short todo = TRUE;

    for(i = 0; i < 4000;i++)
    {
        while (todo == TRUE)
        {
            int fifospace = alt_up_audio_write_fifo_space (audio_dev, ALT_UP_AUDIO_LEFT);
            if ( fifospace > 0 ) // check if data is available
            {
                /* read audio buffer into the baseline array */
                alt_up_audio_write_fifo (audio_dev, &(baseline_audio_samples[i]), 1, ALT_UP_AUDIO_LEFT);
            }
            fifospace = alt_up_audio_write_fifo_space (audio_dev, ALT_UP_AUDIO_RIGHT);
            if ( fifospace > 0 ) // check if data is available
            {
                alt_up_audio_write_fifo (audio_dev, &(baseline_audio_samples[i]), 1, ALT_UP_AUDIO_RIGHT);
                todo = FALSE;
            }
        }
        todo = TRUE;
    }
}
/* Baseline collection algorithm */
void getBaseline()
{
    int i;
    short todo = TRUE;

    for(i = 0; i < 4000;i++)
    {
        while (todo == TRUE)
        {
            int fifospace = alt_up_audio_read_fifo_avail (audio_dev, ALT_UP_AUDIO_LEFT);
            if ( fifospace > 0 ) // check if data is available
            {
                /* read audio buffer into the baseline array */
                alt_up_audio_read_fifo (audio_dev, &(baseline_audio_samples[i]), 1, ALT_UP_AUDIO_LEFT);
                /* hear it just in case */
                alt_up_audio_write_fifo (audio_dev, &(baseline_audio_samples[i]), 1, ALT_UP_AUDIO_LEFT);
                alt_up_audio_write_fifo (audio_dev, &(baseline_audio_samples[i]), 1, ALT_UP_AUDIO_RIGHT);
                todo = FALSE;
            }
        }
        todo = TRUE;
    }
}

/* Live sample collection/filter */
short personPresent()
{
    int i;
    short todo = TRUE;
    int sample_compare;
    int single_sample_threshold = 25000000; /* Set to the value that is noise */
    int count_of_over_under_threshold = 0; /* for times that you break the threshold */
    int max_contiguous_threshold_break = 0; /* for the contiguous set of threshold breaks */
    short is_contiguous = FALSE;
    int current_contiguous = FALSE;
    int max_amp = 0;

    //alt_printf("Person Check\n");
    for(i = 0; i < 4000;i++)
    {
        while (todo == TRUE)
        {
            int fifospace = alt_up_audio_read_fifo_avail (audio_dev, ALT_UP_AUDIO_LEFT);
            if ( fifospace > 0 ) // check if data is available
            {             
                /* read audio buffer into the baseline array */
                alt_up_audio_read_fifo (audio_dev, &(baseline_audio_samples[i]), 1, ALT_UP_AUDIO_LEFT);
               
                alt_up_audio_write_fifo (audio_dev, &(baseline_audio_samples[i]), 1, ALT_UP_AUDIO_LEFT);
                alt_up_audio_write_fifo (audio_dev, &(baseline_audio_samples[i]), 1, ALT_UP_AUDIO_RIGHT);
                todo = FALSE;
            }
        }
        todo = TRUE;

        /* Subtract live from baseline -> absolute value */
//        alt_printf("before: %x\n", live_audio_samples);
        live_audio_samples = baseline_audio_samples[i] << 8;
//        alt_printf("after: %x\n", live_audio_samples);
        baseline_audio_samples[i] = live_audio_samples;
       
        /* count the number of times the sample is greater/less than a set threshold */
        if (live_audio_samples > single_sample_threshold)
        {
            count_of_over_under_threshold ++;  
           
            if (is_contiguous == FALSE)
            {  
                is_contiguous = TRUE;
                current_contiguous = 1;
            }
            else
            {
                current_contiguous++;
            }
           
            if (live_audio_samples > max_amp)
            {
                max_amp = live_audio_samples;
            }
        }
        else if (is_contiguous == TRUE)
        {
            is_contiguous = FALSE;
            if (current_contiguous > max_contiguous_threshold_break)
            {
                max_contiguous_threshold_break = current_contiguous;
            }
        }
    }

    for (i = 0; i < 4000; i++)
    {
       // alt_printf("%x:%x ", i, baseline_audio_samples[i]);
    }

   
    /* Determine if there's a person present */
    if(count_of_over_under_threshold > 10)
        return TRUE;
    /*else if (max_contiguous_threshold_break > 200)
        return TRUE;*/
    else
        return FALSE;
}

 

Project Links: 
Home 

Project Proposal

Detection Method

MATLAB Image Processing

Sensor Design and Construction

Test Room

VGA Sensor Display 

Control Logic

Costs

Conclusions and Future Work