loading


This video can be found on youtube.
http://www.youtube.com/watch?v=h5n0rw8wo14
Check out the other one, and some other of my videos


This is merely an instructable to explain how this device operates. I hope everything is not too obfuscated.


This prototype consists of three 8x8” modules. Each module operates independently of each other. Each module consists of 4 “pixels”. Each pixel is 4 inches square and consists of 21 LEDs, two IR emitting diodes, and two IR photodiodes. The mode of sensing is active infrared.

Check out my Color Changing Glowing Faucet
http://www.youtube.com/watch?v=mBzTNcXIbWA



Step 1: Infrared Sensor

The IR sensor is a simple voltage divider former by two parallel IR photodiodes which are wired reversed biased. When a photodiode is reversed biased (like an LED connected up backwards) it acts like a variable resistor which changes resistance with respect to the amount of light (mainly infrared light) falling on it. The high resistance of the second static value 1 Megohm (R2) provides a voltage divider with the dividing node rising in voltage with an increase in IR light falling onto the photodiodes(R1).

V-in is 5 volts.

 

Step 2: IR Emitters

The IR emitters are 3mm infrared LEDs that I got from mouser.com. In order to experience greater sensing range, the IR emitters have to be very bright. Thus we have to push a lot of current through them. The datasheet for these say they are capable of maintaining a forward max current of around 100mA and a pulsed current (of less than 100 microseconds) of around 1 amp. Now having a whole array of IR emitters that are always on would be a very power hungry set up. To get around this, the IR emitters are connected to the darlington chip to so the controller can trigger when they are on and off. Because an ADC conversion happens so quickly, we can simply turn on the IR emitters, wait a bit for the IR sensor to settle, take an ADC reading, and then turn them off. This doesn’t take very long, maybe 200 microseconds total. Since one IR emitter is on per every Timer 1 ISR firing, we can get an average power usage of the IR emitters.  Timer 1 counts from 0 to 65535, for a total of 65536 clock cycles. At 8MHz fCPU, it takes the controller roughly 8.2 milliseconds to count from 0 to 65535. So we know that an IR sensing sequence happens once every 8.2 milliseconds. We simply get the average power consumption by finding the percentage of time that the IR emitters are on. Since the IR sensing sequence takes roughly 200 microseconds (0.2 milliseconds) of the entire 8.2 millisecond, that’s 0.2/8.2 == roughly 2.5%. The IR emitters have roughly 140mA pushed through them. So simply 2.5% of 140mA == roughly 3.5mA total to accomplish the same level of sensitivity as if the IR emitters stayed totally on.  This equates to dissipating only 18 mWatts instead of 700mW per module.

 

Two IR emitters are connected in series per pixel. The supply voltage is 5 volts. The rest of the voltage is dropped by  a small 10 ohm resistor to regulate the high current flow. The IR emitters and IR photodiodes are connected to the 5V supply. Whenever the IR emitters are turned on, a small amount of current is actually pulled away from the IR photodiode voltage divider arrangement. The photodiodes being reversed biased allows this to happen. This reverse flow creates a dip in the voltage level at the node where the ADC reading is taken. I got rid of this dip by putting a small value capacitor (47pF – 100 pF) across the 1Mohm resistor of the voltage divider. This greatly reduces the level of dip, but also costs time to charge up the capacitor when the voltage level rises quickly. All of this is easily seen with an oscilloscope. I have attached snap shots of my screen oscilloscope reading. This is the source of requiring a software delay, to allow time for the voltage level to reach its peak at the sampled node of the voltage divider.

Step 3: The Code

So I just copy and pasted the code. I will have the copied pasted code in bold, and my notes about sections of the code in italics. These notes will be added after the fact, so italic notes and regular //commented notes comprise the My notes will be added to this, so if you include them in your code, be sure to //comment them out.

/***                   
PIN ASSIGNMENTS ON ATMEGA48

PC6 (PCINT14/RESET)            
PC5 (ADC5/SCL/PCINT13)            // I2C Clock input
PC4 (ADC4/SDA/PCINT12)            // I2C Data input
PC3 (ADC3/PCINT11)                    //Sensor 4 IR Receiver
PC2 (ADC2/PCINT10)                    //Sensor 3 IR Receiver
PC1 (ADC1/PCINT9)                      //Sensor 2 IR Receiver
PC0 (ADC0/PCINT8)                      //Sensor 1 IR Receiver

PB7 (PCINT7/XTAL2/TOSC2)         //IR 4 Trigger
PB6 (PCINT6/XTAL1/TOSC1)         //IR 3 Trigger
PB5 (SCK/PCINT5)                           //IR 2 Trigger
PB4 (MISO/PCINT4)                        //IR 1 Trigger
PB3 (MOSI/OC2A/PCINT3)            //PWM 3
PB2 (SS/OC1B/PCINT2)           
PB1 (OC1A/PCINT1)               
PB0 (PCINT0/CLKO/ICP1)           

PD0 (PCINT16/RXD)                
PD1 (PCINT17/TXD)                
PD2 (PCINT18/INT0)                
PD3 (PCINT19/OC2B/INT1)         //PWM 4
PD4 (PCINT20/XCK/T0)            
PD5 (PCINT21/OC0B/T1)             //PWM 2
PD6 (PCINT22/OC0A/AIN0)         //PWM 1
PD7 (PCINT23/AIN1)             
***/

#define IR_1_ON PORTB |= (1<<4)
#define IR_2_ON PORTB |= (1<<5)
#define IR_3_ON PORTB |= (1<<6)
#define IR_4_ON PORTB |= (1<<7)
#define IR_1_OFF PORTB &= ~(1<<4)
#define IR_2_OFF PORTB &= ~(1<<5)
#define IR_3_OFF PORTB &= ~(1<<6)
#define IR_4_OFF PORTB &= ~(1<<7)

#define PWM1 6                    //PORTD        PWM pin assignments
#define PWM2 5                    //PORTD
#define PWM3 3                    //PORTB
#define PWM4 3                    //PORTD

#define F_CPU 8000000UL

#include

#include

#include
//#include


/****Function Declarations****/
int ADC_read(void);
void A2D_Channel_Select(unsigned char channel);
void Init_ADC(void);
void Init_Timer0(void);
void Init_Timer1(void);
void Init_Timer2(void);
void Delay(void);
void Calibrate_Sensors(void);
//void Init_I2C_Slave_Rx(void);

All, but one, of these variables is declared volatile because basically all of the work is done in
interrupt service routines


/****Global Variable Declarations****/
volatile char Sensor_Values_Updated = 0;                   
volatile char Timer1_Overflow = 0;
volatile unsigned char channel = 0;
volatile int Amb_Sensor_1 = 0, Amb_Sensor_2 = 0, Amb_Sensor_3 = 0, Amb_Sensor_4 = 0;
volatile int Sensor_1 = 0, Sensor_2 = 0, Sensor_3 = 0, Sensor_4 = 0;
volatile int Initial_1 = 0, Initial_2 = 0, Initial_3 = 0, Initial_4 = 0;
volatile int New_PWM1 = 0, New_PWM2 = 0, New_PWM3 = 0, New_PWM4 = 0;               
volatile int Old_PWM1 = 0, Old_PWM2 = 0, Old_PWM3 = 0, Old_PWM4 = 0;

unsigned char buffer = 8;

int main(void)
{
    DDRB = 0xff;
    //make sure IR emitters are turned off, and PWM 3
    PORTB &= ~((1 << 7)|(1 << 6)|(1 << 5)|(1 << 4)|(1 << 3));               
    DDRC = 0x00;                    //make PORT C inputs
   
    DDRD = 0xff;
    PORTD = 0x00;                    //set all of PORT D low. ensures
       
    Init_ADC();

    sei();
   
    Calibrate_Sensors();

    PORTD |= (1 << PWM1);            //blink to indicate end of Calibration
    _delay_ms(600);
    PORTD &= ~(1 << PWM1);

    Init_Timer0();
    Init_Timer2();

    //Init_I2C_Slave_Rx();

    while(1)
        {
            //do something?
            //. . .
        }

}


With the clock running at roughly 8MHz, and Timer 1 counting up to 65535. The timer will overflow roughly 122 times a second. This ISR will fire and the timer overflow variable will increment, and then the SWITCH/CASE function will choose the next pixel to test

ISR(TIMER1_OVF_vect)  
    {
        Timer1_Overflow++;            //increment timer overflow variable
       
        switch(Timer1_Overflow)
            {
                case 1:                   
                    A2D_Channel_Select(0);                            //select ADC channel 0
                    Amb_Sensor_1 = ADC_read();                 //take ambient IR sensor reading
                    IR_1_ON;                                                        //turn on IR 1 LED, PORTB |= (1<<4)
                    Delay();                                                           //delay for the IR receiver to settle
                    Sensor_1 = ADC_read();                            //take active ADC reading of IR receiver
                    IR_1_OFF;                                                       //turn off IR 1 LED   

                    New_PWM1 = (Sensor_1 - Amb_Sensor_1) - Initial_1;    //condition readings
                    if(New_PWM1 <= 0)    { New_PWM1 = 0; }                //prevent negative numbers
                   
               simple low-pass filter, (87.5% * Old) + (12.5% * New). It just takes the old value and   weights it more than the older value. Has the same effect of slowing down change, which is crucial in providing fluid changes in brightness
                    New_PWM1 = ((7*Old_PWM1)>>3) + (New_PWM1>>3);     
 
                    if(OCR0A >= 1)    {DDRD |= (1 << PWM1);}
                    else { DDRD &= ~(1 << PWM1); }                        //turn off LEDs completely

//artificially increase the value of sensor reading, not entirely necessary, but makes the sensor seem more sensitiveby being brighter sooner
                    New_PWM1 <<= 2;                                  
                    if(New_PWM1 > 255)    { New_PWM1 = 255; }
                    OCR0A = New_PWM1;
                    New_PWM1 >>= 2;


The below code that is entirely commented out is a different brightness algorithm. It is a triggering algorithm that will fade the LEDs on when something comes within a threshold. And the LEDs will fade out slowly when the object is out of the threshold distance. This is useful because the operation could be more reliable and the fade out time can be adjusted to be very long or however long you want it. I haven't tested this code so I am not sure if it will work 100%

                /*****        //Trigger sequence
                    if(New_PWM1 > Initial_1)
                        {
                            DDRD |= (1 << PWM1);

                            if(OCR0A < 255)   
                                {
                                    OCR0A += (255 - OCR0A)>>2 ;
                                    //OCR0A++;
                                }

                            if (New_PWM1 < (Initial_1 + 8))
                                {
                                    Initial_1 = ((7*Initial_1)>>3) + (New_PWM1>>3);
                                }
                        }

                    else if(New_PWM1 < Initial_1)
                        {
                            if(OCR0A > 0)   
                                {
                                    OCR0A -= (OCR0A >> 4)+1;
                                    //OCR0A--;
                                }
                            else if(OCR0A <= 0)   
                                {
                                    DDRD &= ~(1 << PWM1);
                                }
                        }           
               *****/   
                    Old_PWM1 = New_PWM1;                       
                    break;
       
                case 2:
                    A2D_Channel_Select(1);                            //select ADC channel 1
                    Amb_Sensor_2 = ADC_read();
                    IR_2_ON;                                        //turn on IR 2 LED, PORTB |= (1<<5)
                    Delay();                                        //delay for the IR receiver to settle
                    Sensor_2 = ADC_read();                            //take ADC reading
                    IR_2_OFF;                                        //turn off IR 2 LED   

                    New_PWM2 = (Sensor_2 - Amb_Sensor_2) - Initial_2;
                    if(New_PWM2 < 0)    { New_PWM2 = 0; }
                   
                    New_PWM2 = ((7*Old_PWM2)>>3) + (New_PWM2>>3);
                    if(OCR0B >= 1)    {DDRD |= (1 << PWM2);}
                    else { DDRD &= ~(1 << PWM2); }

                    New_PWM2 <<= 2;
                    if(New_PWM2 > 255)    { New_PWM2 = 255; }
                    OCR0B = New_PWM2;
                    New_PWM2 >>= 2;
                /*
                    if(New_PWM2 > Initial_2)
                        {
                            DDRD |= (1 << PWM2);

                            if(OCR0B < 255)   
                                {
                                    OCR0B += (255 - OCR0B)>>2 ;
                                    //OCR0B++;
                                }

                            if (New_PWM2 < (Initial_2 + 8))
                                {
                                    Initial_2 = ((7*Initial_2)>>3) + (New_PWM2>>3);
                                }
                        }

                    else if(New_PWM2 < Initial_2)
                        {
                            if(OCR0B > 0)   
                                {
                                    OCR0B -= (OCR0B >> 4)+1;
                                    //OCR0B--;
                                }
                            else if(OCR0B <= 0)   
                                {
                                    DDRD &= ~(1 << PWM2);
                                }
                        }           
                    */
                    Old_PWM2 = New_PWM2;   
                    break;
                   
                case 3:
                    A2D_Channel_Select(2);                            //select ADC channel 2
                    Amb_Sensor_3 = ADC_read();
                    IR_3_ON;                                        //turn on IR 3 LED, PORTB |= (1<<6)
                    Delay();                                        //delay for the IR receiver to settle
                    Sensor_3 = ADC_read();                            //take ADC reading
                    IR_3_OFF;                                        //turn off IR 3 LED   

                    New_PWM3 = (Sensor_3 - Amb_Sensor_3) - Initial_3;
                    if(New_PWM3 < 0)    { New_PWM3 = 0; }
                   
                    New_PWM3 = ((7*Old_PWM3)>>3) + (New_PWM3>>3);
                    if(OCR2A >= 1)    {DDRB |= (1 << PWM3);}
                    else { DDRB &= ~(1 << PWM3); }
                    New_PWM3 <<= 2;
                    if(New_PWM3 > 255)    { New_PWM3 = 255; }
                    OCR2A = New_PWM3;
                    New_PWM3 >>= 2;
                /*
                    if(New_PWM3 > Initial_3)
                        {
                            DDRB |= (1 << PWM3);

                            if(OCR2A < 255)   
                                {
                                    OCR2A += (255 - OCR2A)>>2 ;
                                    //OCR2A++;
                                }

                            if (New_PWM3 < (Initial_3 + 8))
                                {
                                    Initial_3 = ((7*Initial_3)>>3) + (New_PWM3>>3);
                                }
                        }

                    else if(New_PWM3 < Initial_3)
                        {
                            if(OCR2A > 0)   
                                {
                                    OCR2A -= (OCR2A >> 4)+1;
                                    //OCR2A--;
                                }
                            else if(OCR2A <= 0)   
                                {
                                    DDRB &= ~(1 << PWM3);
                                }
                        }           
                    */
                    Old_PWM3 = New_PWM3;   
                    break;
                   
                case 4:
                    A2D_Channel_Select(3);                            //select ADC channel 3
                    Amb_Sensor_4 = ADC_read();
                    IR_4_ON;                                        //turn on IR 4 LED, PORTB |= (1<<7)
                    Delay();                                        //delay for the IR receiver to settle
                    Sensor_4 = ADC_read();                            //take ADC reading
                    IR_4_OFF;                                        //turn off IR 4 LED   

                    New_PWM4 = (Sensor_4 - Amb_Sensor_4) - Initial_4;
                    if(New_PWM4 < 0)    { New_PWM4 = 0; }
                   
                    New_PWM4 = ((7*Old_PWM4)>>3) + (New_PWM4>>3);
                    if(OCR2B >= 1)    {DDRD |= (1 << PWM4);}
                    else { DDRD &= ~(1 << PWM4); }
                    New_PWM4 <<= 2;
                    if(New_PWM4 > 255)    { New_PWM4 = 255; }
                    OCR2B = New_PWM4;
                    New_PWM4 >>= 2;
                /*
                    if(New_PWM4 > Initial_4)
                        {
                            DDRD |= (1 << PWM4);

                            if(OCR2B < 255)   
                                {
                                    OCR2B += (255 - OCR2B)>>2 ;
                                    //OCR2B++;
                                }

                            if (New_PWM4 < (Initial_4 + 8))
                                {
                                    Initial_4 = ((7*Initial_4)>>3) + (New_PWM4>>3);
                                }
                        }

                    else if(New_PWM1 < Initial_4)
                        {
                            if(OCR2B > 0)   
                                {
                                    OCR2B -= (OCR2B >> 4)+1;
                                    //OCR2B--;
                                }
                            else if(OCR2B <= 0)   
                                {
                                    DDRD &= ~(1 << PWM4);
                                }
                        }           
                */
                    Old_PWM4 = New_PWM4;
                   
                    Timer1_Overflow = 0;                    //reset                                       
                    Sensor_Values_Updated = 1;                //new values ready   
                       
                    break;       
            }//end switch
    }//end ISR


This is something I am going to try and figure out later. It is untested elementary code which could allow me to use the Two Wire Interface (I2C) so several controllers and communicate with each other or have one master and a bunch of slaves.
/****
ISR(TWI_vect)            //to include later when I get this figured out
    {
        switch(TWSR)
            {
                case TW_SR_SLA_ACK:         //0x60        //Own address Rx
                    Byte_Number == 1;
                    break;
                   
                case TW_SR_DATA_ACK:        // 0x80    , data in TWDR               
                    switch(Byte_Number)
                        {
                            case 1:
                                Reg_Addr = TWDR;
                                Byte_Number++;
                                break;
                               
                            case 2:
                                Reg_Val = TWDR;
                                Byte_Number = 0;    //reset, unless more bytes are coming
                                break;
                               
                            case Max_Bytes_Expected:
                                Reg_Val = TWDR;
                                Byte_Number = 0;    //reset, unless more bytes are coming
                                break;   
                        }       
                    break;
                   
                case TW_SR_GCALL_DATA_ACK:        // 0x90   
                    if(Byte_Number == 1)
                        {
                            Reg_Addr = TWDR;
                            Byte_Number++;
                        }
                    else if(Byte_Number == 2)
                        {
                            Reg_Val = TWDR;
                            Byte_Number = 0;        //reset, unless more bytes are coming
                        }
                    break;   
            }//end switch   
    }//end ISR


void Init_I2C_Slave_Rx(void)
    {
        //Set Device Address in TWAR
        TWAR = 10;                    //maybe make this as an argument to this function
       
        TWCR |= ((1 << TWEA)|(1 << TWEN));
        TWCR &= ~((1 << TWSTA)|(1 << TWSTO));
    }
****/


void Calibrate_Sensors(void) //establish initial ambient sensor values
    {
        char q = 0;   
       
        Init_Timer1();

        for(q=0; q<32; q++)            //should take one second-ish
            {
                //wait for Sensor cycle to be done, then gather sensors values
                while(Sensor_Values_Updated == 0)    {}
               
                Initial_1 += (Sensor_1 - Amb_Sensor_1);        //initial difference
                Initial_2 += (Sensor_2 - Amb_Sensor_2);
                Initial_3 += (Sensor_3 - Amb_Sensor_3);
                Initial_4 += (Sensor_4 - Amb_Sensor_4);
   
                Sensor_Values_Updated = 0;                //reset
            }//end for

//condition Initial Ambient Sensor values, plus a buffer
            Initial_1 = (Initial_1 >> 5) + buffer;          
            Initial_2 = (Initial_2 >> 5) + buffer;
            Initial_3 = (Initial_3 >> 5) + buffer;
            Initial_4 = (Initial_4 >> 5) + buffer;   
    }

void Init_ADC(void)
    {
        ADMUX |= 1 << REFS0;                //AVCC with external capacitor at AREF pin
        ADMUX |= (1<    
     }

 void Init_Timer0(void)                            //PWM for sensors 1 & 2
    {
        //Fast PWM, non-inverting, WGM02-WGM00 == 011, no overflow interrupt
        TCCR0A |= ((1 << COM0A1)|(1 << COM0B1)|(1 << WGM01)|(1 << WGM00));
        TCCR0B |= (1 << CS00);        //start clock, no prescale
    }
   
void Init_Timer1(void)
    {
        //no PWM, enable overflow interrupt,
        //TOP == 0xFFFF == 65536 cycles == roughly 122 overflow interrupts/sec
        TCCR1B |= (1 << CS10);
        TIMSK1 |= (1 << TOIE1);
    }
   
void Init_Timer2(void)                            //PWM for sensors 3 & 4
    {
        //Fast PWM, non-inverting, WGM22-WGM20 == 011, no overflow interrupt
        TCCR2A |= ((1 << COM2A1)|(1 << COM2B1)|(1 << WGM21)|(1 << WGM20));
        TCCR2B |= (1 << CS20);        //start clock, no prescale
    }   


int ADC_read(void)                        /***select ADC channel prior to calling this function***/
    {       
        int ADC_value = 0;
        int ADCsample;
        char i;
       
        ADCSRA |= (1<         ADCSRA |= (1<         while ((ADCSRA & ADSC));                //Wait for conversion to complete, and forget about it

//this is done no more than 64 times,
any longer and ADC1_value will need to be larger than an unsigned int!!!!!!   
        for (i=0; i<64; i++)                   
            {
                ADCSRA |= (1<                 while ((ADCSRA & ADSC));        //wait for conversion to finish
//change back to ADCL for 10 bit precision, and remove left-shift bit setting
                ADCsample = ADCH;        
                //ADCsample += (ADCH<<8);        //Left shift the top two bits 8 places                       
                ADC_value += ADCsample;            //add ADCsample to ADC_sensor
            }               
//average sample by right shifting 6 places, same as dividing by 64
        ADC_value = (ADC_value >> 6);           
               
        return ADC_value;   
       
      ADCSRA &= ~(1<
void A2D_Channel_Select(unsigned char channel)               
    {
       
        switch (channel)
            {
                case 0:            //select A2D channel 0
                    ADMUX &= ~((1 << 3)|(1 << 2)|(1 << 1)|(1 << 0));
                    break;   
       
                case 1:            //select A2D channel 1
                    ADMUX &= ~((1 << 3)|(1 << 2)|(1 << 1));
                    ADMUX |= (1 << 0);
                    break;
               
                case 2:            //select A2D channel 2
                    ADMUX &= ~((1 << 3)|(1 << 2)|(1 << 0));
                    ADMUX |= (1 << 1);
                    break;   
       
                case 3:            //select A2D channel 3
                    ADMUX &= ~((1 << 3)|(1 << 2));
                    ADMUX |= ((1 << 1)|(1 << 0));
                    break;
                /*    I am not using these for this project
                case 4:            //select A2D channel 4
                    ADMUX &= ~((1 << 3)|(1 << 1)|(1 << 0));
                    ADMUX |= (1 << 2);
                    break;
                   
                case 5:            //select A2D channel 5
                    ADMUX &= ~((1 << 3)|(1 << 1));
                    ADMUX |= ((1 << 2)|(1 << 0));
                    break;
                */           
            }//end switch
    }
   
void Delay(void)
    {
        _delay_us(100);
    }


Step 4: The Circuit


Circuit schematic, all of the components were drawn and IC pins were labeled or the IC has the effective internal circuit drawn in it to illustrate what is going on inside the IC. This also does not include the 6 prong connection for the programmer that is wired to pins on the uC.

Circuit build design, for the size perf board that I had, this is the drawing that tries to show how ICs were arranged and connections were routed. The idea is that the solid lines are wires, and dotted lines are soldered connections. The dotted lines try to trace only vertical and horizontal lines and follow solder points, but it is not perfect.

Step 5: More Pictures

Hope you enjoyed!

Step 6: Parts List

Here is a synopsis of the parts used.
I get most of my parts from mouser.com
I have them listed as:

Mouser Part Number
Item/Manufacturer
Slight Description


556-ATMEGA48-20PU
Atmel Microcontrollers (MCU)
4kB Flash 0.256kB

638-IR204-A
Everlight Infrared Emitters
Infrared LED 940nm

512-QSD2030F
Fairchild Photodiodes
PIN PHOTODIODE

757-ULN2803APG(5,M)
Toshiba Darlington Transistors
8CH. 50V/.5A IFD IC

595-TLC274CN
TI Op Amps
Quad LiMCMOS

511-L7805CV
ST Linear Regulators - Standard
5.0V 1.0A Positive

571-1-390261-3
Tyco IC & Component Sockets
14P ECONOMY TIN

571-1-390261-5
Tyco IC & Component Sockets
18P ECONOMY TIN

571-1-390261-9
Tyco IC & Component Sockets
28P ECONOMY TIN SKT

I got the perf board off of
http://www.allelectronics.com/make-a-store/category/455/Perf-Boards/1.html

I got the 24v power supply off of ebay



 


<p>Hi, first of all, very interesting project! Could you tell me which type of visible LED's you used? I am currently working on something similar, but can't really figure out what the intensity (Lumen) of my LED's should be.</p>
<p>Hi I would like to do a similar project to this however, instead of using the Atmega48 am I able to use an arduino uno instead?</p>
<p>Hope, you've got your answer till now and you can help me out with this?</p>
<p>I noticed that on the final product there are two radial capacitors that don't have values accounted for in the schematic. Could someone explain these to me please? One appears to be 22uf and the other looks like 47uf but I want to make sure.</p>
<p>it looks like those are bypass capacitors, basically put in to reduce noise in the circuit. i found this article about choosing the correct value bypass capacitor - https://www.intersil.com/content/dam/Intersil/documents/an13/an1325.pdf, will try and figure it out...</p>
<p>Great! Thank you. Do those just hook up bridging the positive and ground? </p>
<p>Yes, I believe so. From what I've read, the capacitors here help to even out the signal and filter the noise.Any AC passed on from the transformer will pass through the capacitor to the ground. I'm just about finished with the first board, I'll let you know if it works!</p>
hey did you finish the project and the two caps valued 470 and 22, what were their voltage?
<p>From the some of the other images, it looks like the capacitor values are 22uf and 470uf.</p>
<p>I've been playing around with this for a few evenings. With a 3.3v supply connected to the photodiode and a 1Mohm resistor to ground, I get nearly full voltage on the photodiode/resistor connection with just the ambient light falling on it.</p><p>I've tried a 10K or 20K resistor, which helps, but I don't get anywhere near 0v like in the scope pictures, pictured above.</p>
<p>I'm now using a 20K resistor and everything works fine.</p><p>I have a slightly different way of doing things. I pulse the IR LED when I need to take a reading, but I only drive it at 25mA. This seems to work fine. I have tried it with the room dark and with sunlight coming in from the window. Also it works under my LED room lights.</p><p>I don't have a smoothing capacitor as I want to keep the component count down, but I get around the stray ambient IR a different way.</p><p>When first powered up, I take 50 readings for ambient light and take an average. I also take 50 readings with the IR LED on and take the average. I then save the 'calibrated' difference in a register.</p><p>When my program loop goes around, I take 1 ambient reading and 1 reading with the IR LED on and check to see if the difference is greater than the calibrated difference + sensitivty (30 works for my setup). I the difference is greater, I don't count it as a valid reading unless it is greater for the next 5 loops of the program.</p><p>This seems to work very well. I have tested this setup by calibrating it in the dark, then pointing at the window and it still detects my hand infront of it. It also seems to work through a piece of 3mm black Perspex which I can't even see through when holding it up to the sun.</p><p>I am planning on making a 9cm x 9cm board with 9 x WS2812b RGB LEDs for the illumination, and have the boards clip together and communicate with each other in order to keep them all synced and taking the readings at the same time.</p><p>Anyway, great instructable, very informative.</p><p>A scope is very handy when playing around with this, but I also found that using a 128x64 OLED was even handier for debugging as I used it to show me various things like calibrated ambient light etc. so I could actually see what the PIC microprocessor was dealing with.</p>
<p>You've inspired me to pull out the soldering iron again. Thanks, I think ;) </p><p>I was curious about the close up of one of the boards - it looks like a crystal oscillator (long silver component). On the image of the backside of full table, only one of the boards has that component. Is it necessary? Remnant of prototyping?</p>
<p>I believe what you're talking about is the 5 volt regulator because only the main board needs it because the others feed off of it </p>
<p>Makes a ton of sense, thanks mate.</p>
<p>Seems bits of the program were somehow lost when the author copied it into the instructable. I copied it out by hand from the screenshots, which produces a syntactically correct program. You can get the working version from here: http://pastebin.com/UEawXgrz</p>
<p>Thank you Calsykes...</p>
<p>Has anyone tried substituting a buck converter for the l7805 linear voltage regulator in this circuit? A little more expensive, lot less power hungry, possibly more noise from the buck converter. </p>
<p>Ah, it's the L7805... just looked weird with the camera angle. Fun project.</p>
What Are The Materials? <br>
<p>see step 6</p>
<p>what the items needed to make this project ?? can you tell me plz</p><p>thanks</p>
<p>see step 6</p>
<p>Dear Sir ,</p><p>This is awesome, since I only know Atmega328 do you have a code for this uP ,</p><p>if so can I get it .</p><p>Many Thanks </p><p>Bose</p>
<p>love the idea</p>
I'm sorry for so many questions but the 511-L7805CV <br>ST Linear Regulators - Standard <br>5.0V 1.0A Positive you use this for the 5 v in to uC, from the 24 V supply?, i ask you before for a wiring diagram with more accuracy, how i put it the component in the schematic
and one thing i just run the code with the comment put on , but still there are some errors, if you can put the main file , that you put in the uC, xxxxxx.C thx:)
hi, cand you put a wiring diagram more explicit, what i looking for, is the pin on microcontroller , connection between components and how connect 2 module.(which ones are the IR emitters and ir photodiodes on your schematic)
I want to do the circuit, but there are two one-pole capacitor values, what is it? can you give a complete parts list. Thanks
I see on your YouTube channel that you have a newer way that you have done this. One with less components. The newest video you have on there. Can you make an instructable for that one?
hey okay you have a 470uF and a 22uF but what resistance is on the 511-L7805CV ST Linear Regulators? and on the 556-ATMEGA48-20PU that little blue resistance? <br>
if i use an ATmega168 or ATmega328 how much will stuff have to change?
Well, the analog 5 volt supply to the AVR goes through a 10uH inductor (aqua green, next to 7805) and a 100nF bypass cap (tiny blue cap). There is a 5.6k resistor across 5volts to the reset pin. <br><br>I also included a PPTC resettable fuse(yellowish) going to the 5v reg. <br><br>Sorry about not having the best schematic.
how to make the header file?
Dear Friend<br>Do you have compiled hex code? please if you have send it to my email.I want to try this one.<br>email: slwthr@yahoo.com<br>Regards,<br>Harith.
DID U GET THE HEX FILE I SO PLEASE GIVE ME AT domdomgin@yahoo.com
No my friend.He haven't send it yet.I don't know why. Did you try to compile his code? I tried a lot times.But the code which he given here is wrong.Its not working and even its not compiling..So many errors. Please if you got right code let me know. my email : slwthr@yahoo.com
Two words: Lite Brite!
Dear Friend<br>Do you have compiled hex code? please if you have send it to my email.I want to try this one.<br>email: slwthr@yahoo.com<br>Regards,<br>Harith.
Hello,I really want to make this one.And also I collect all the parts..And waiting to know about how to compile this code.Really I tried a lot times and it says errors and warnings too.Please can you tell me how to compile this code without any trouble.There is some errors with the functions.Please do you have any compiled hex code for this?? If you have please send it to me.<br>My email: slwthr@yahoo.com
Two words: Peg board.
wrong size holes on the peg board ;)
Hello Grahmaustin,<br>first off, I must say that this is a great project !! Well done man !! But could you answer me one thing ? I was looking at the schematic and the board layout, and was trying to figure out if the resistor at pini1 of the Atmega48 connects to pin 7 and gets 5V(red wire) ?<br>2. Does pin 1 go to the coil also (purple wire)?<br>3. Is the pink wire connected to the coil middle pin also ?<br>Thanks.
hello<br><br>resistor from pin1 does goes to pin 7. This is the pull-up resistor for the reset pin. <br><br>pin1 also connects to the purple wire, this goes to the 6pin programming port. This allows the programmer to reset the chip.<br><br>The pink wire should be the MOSI wire. Simply connects the programmer to the chip and also to the darlington array. It should not connect directly to 5V or gnd. <br><br>cheers
I know how hard to do such a thing. GREAT GREAT WORK!!!!!!!!!!!!!!! no doubt about that.<br>i like to visit your house. that may be a electronic kingdom.<br><br>hats off............
its this kind of instructable that makes me want to pimp out my entire life with led lights and microcontrollers
yaaaa..... me too. im dying to do such a amazing work !!!!!!!!!!!!!<br><br>Great gob grahmaustin !!!!!!!!!
where r the leds connected and ir leds..please let me know..
Ok, ive got a question... say that I wanted the entire thing you did, in my pocket, could i just connect the photodiodes to an LED and then to a power source, and then the same kinda thing would happen, coz im a big noob at this and dont really understand how it works?
can't imagine that would work, at least I can't make it work. Let me know if you do or find someone that does. Sorry I can't help you there. Stay motivated.
ok thanks, i havnt been able to find anything yet though :(

About This Instructable

117,940views

524favorites

License:

Bio: I want to build everything
More by grahmaustin:Infrared Proximity Sensing Coffee Table Module & Color Changing Glowing Faucet Light-Up Bar Table! Stainless Steel Jigger/Pony Shot Glass 
Add instructable to: