Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Micro-Controller based multi-channel Remote controlled fan regulator

Status
Not open for further replies.

Mithun_K_Das

Advanced Member level 3
Joined
Apr 24, 2010
Messages
899
Helped
24
Reputation
48
Reaction score
26
Trophy points
1,318
Location
Dhaka, Bangladesh, Bangladesh
Activity points
8,252
I'm interested to make a multi-channel remote controlled fan regulator. Can anyone help in this case?

- - - Updated - - -

What is the working mechanism?
 

You create some bit pattern like 10101010, 1100110011... for eight channels (8 patterns). Then you modulate it and transmit using 38 KHz IR transmitter. The receiver receives the modulated IR and demodulates it and your MCU id fed with the actual pattern. Your MCU reads the pattern and compares it with pattern stored in memory. Lets say pattern matches pattern 1, then MCU will do some operation like activating a relay for device 1.
 

I don't want to design new remote. I want to use my TV remote. As far I know, each button sends different code. Now what I want to do is to detect that codes using micro-controller. And then using that buttons I want to do the other works.

I'm able to do most of the job. But don't know how to detect the code/particular frequency sent from the TV remote. Need help in this case.
 

Use a Sony TV remote. The frequency and codes are very well documented and easy to decode with a microcontroller.

as described here and on many other sites.
 
Then you have to get the details of your remote. Ask the manufacturer to give you the IR patterns generated for your remote keys.

receive IR signals from your TV remote and demodulate it and feed it to MCU and try to print the received IR data on UART as hex value. See what values you get. It will give the binary pattern of your IR codes.
 

Yes, I want to regulate the speed. If the buttons can be detected, many things can be done.

- - - Updated - - -

Yes, I want to regulate the speed. If the buttons can be detected, many things can be done.
 

read the bits serially and print its hex value on PC hyper terminal. if you get repeated ir bursts like 255225522552 then 2552 is your IR code.
 

IR protocol analyzer
http://ostan.cz/IR_protocol_analyzer/

ir_protocol_analyzer_screenshot.png
 

Go to bottom right corner and click to "Ignore...." web will showup.

I have NOD32 Smart Security and there is no problem, also I monitor system on PC to see what happenning without protection and there is no attack.
 

Oh ya!

I've a idea. If a timer interrupt is used to find the data from the signal then we can get the value. Let, TMR0 is always checking if the start bit is sent(comparing with counter), then it pass to the command loop, get the data, save the data in a array, then get the data loop, save the data in another array.
Finally a decimal/hexa can be found from those arrays.

So we get a data behind each signal.....

:D
 

Yes............ Finally I've made it possible.

here is the modified code.....
Code:
// Receive Sony IR Remote signals using PIC12F675
// internal oscillator 4MHz (make sure it is calibrated), watchdog disabled
// connect 3-pin IR receiver module to GPIO 0 input
// Sony TV remote will toggle:
//     GPIO 1 output for TV '1' button
//     GPIO 2 output for TV '2' button
//     GPIO 4 output for TV '3' button
//     GPIO 5 output for TV '4' button
//   all outputs off for TV '0' button
//   all outputs on  for TV '9' button

sbit ir_rx at GPIO.B0;                  // IR receiver 40KHz

// function prototypes
void get_mark_time(void);               // get Sony IR mark time


// global variables
unsigned char counter = 0;
unsigned char shadow = 0;
unsigned char bitcount;
unsigned char ir_address;
unsigned char ir_command;
unsigned int mark_time;

void interrupt() 
{

    if (INTCON.T0IF) 
    {
        counter++;                       // increment counter
        INTCON.T0IF = 0;                 // Clear Timer0 overflow interrupt flag
    }
}

void main() 
{

    CMCON = 7;                    // disable comparator
    ANSEL = 0;                    // disable analogue
    OPTION_REG = 0x03;            // TMR0 prescaler set to 1:16
    TRISIO = 0x01;                // IR b0 = input, rest output
    GPIO = 0;                     // all outputs off


    // start timer 0 counting
    INTCON.GIE = 1;               // Global interrupt enable
    INTCON.T0IE = 1;              // Enable Timer0 overflow interrupt
    
    while(1)
    {
        ir_command = 0;                                        // initialise to prevent false trigger
        ir_address = 0;                                        // initialise to prevent false trigger
        get_mark_time();                                       // get Sony leader - 2.4mS Mark, 1.2mS space
        if ((mark_time > 0x80) && (mark_time < 0xB0))
        {         // ignore anything but 2.4mS mark
        
             for(bitcount = 0 ; bitcount < 7 ; bitcount++)
             {    // 7 bit command
                get_mark_time();                               // get a Sony IR bit
                ir_command >>= 1;                              // shift
                ir_command &= 0x7f;                            // top bit zero
                if (mark_time > 0x40)
                {                         // > 40 is assumed to be a 1
                    ir_command ^= 0x80;                        // top bit 1
                }
            }
            ir_command >>= 1;                                  // shift 1 unused bit
            ir_command &= 0x7F;                                // clear top bit

            for(bitcount = 0 ; bitcount < 5 ; bitcount++)
            {     // 5 bit address
                get_mark_time();                               // get a Sony IR bit
                ir_address >>= 1;                              // shift
                ir_address &= 0x7f;                            // top bit zero
                if (mark_time > 0x40)
                {
                    ir_address ^= 0x80;                        // top bit 1
                }
            }
            ir_address >>= 3;                                  // shift 3 unused bits
            ir_address &= 0x1F;                                // clear top 3 bits

        }
        
        if(ir_address == 1)
        {                                   // TV
            if(ir_command == 0)
            {                               // button 1
                                                // toggle output 1
                GP1_bit = ~GP1_bit;
            }
            if(ir_command == 1)
            {                               // button 2
                                                // toggle output 2
                GP2_bit = ~GP2_bit;
            }
            if(ir_command == 2)
            {                               // button 3
                                               // toggle output 4
                GP4_bit = ~GP4_bit;
            }
            if(ir_command == 3)
            {                               // button 4
                                                // toggle output 5
                GP5_bit = ~GP5_bit;
            }
            if(ir_command == 8)
            {                               // button 9
                                                 // all outputs on
                GPIO = 0xFF;
            }
            if(ir_command == 9)
            {                               // button 0
                                                 // all outputs off
                GPIO = 0x00;
            }
            Delay_ms(200);                                      // avoid double toggle
        }
    }
}

// get time of mark, then ignore space
void get_mark_time(void)
{
    while(ir_rx);                           // wait for a mark
    counter=0;
    TMR0 = 0;
    while(!ir_rx);                          // wait for space
    mark_time = (counter << 8) + TMR0;      // collect integer mark time

}


And its working.....
 

Yes............ Finally I've made it possible.

here is the modified code.....
Code:
// Receive Sony IR Remote signals using PIC12F675
// internal oscillator 4MHz (make sure it is calibrated), watchdog disabled
// connect 3-pin IR receiver module to GPIO 0 input
// Sony TV remote will toggle:
//     GPIO 1 output for TV '1' button
//     GPIO 2 output for TV '2' button
//     GPIO 4 output for TV '3' button
//     GPIO 5 output for TV '4' button
//   all outputs off for TV '0' button
//   all outputs on  for TV '9' button

sbit ir_rx at GPIO.B0;                  // IR receiver 40KHz

// function prototypes
void get_mark_time(void);               // get Sony IR mark time


// global variables
unsigned char counter = 0;
unsigned char shadow = 0;
unsigned char bitcount;
unsigned char ir_address;
unsigned char ir_command;
unsigned int mark_time;

void interrupt() 
{

    if (INTCON.T0IF) 
    {
        counter++;                       // increment counter
        INTCON.T0IF = 0;                 // Clear Timer0 overflow interrupt flag
    }
}

void main() 
{

    CMCON = 7;                    // disable comparator
    ANSEL = 0;                    // disable analogue
    OPTION_REG = 0x03;            // TMR0 prescaler set to 1:16
    TRISIO = 0x01;                // IR b0 = input, rest output
    GPIO = 0;                     // all outputs off


    // start timer 0 counting
    INTCON.GIE = 1;               // Global interrupt enable
    INTCON.T0IE = 1;              // Enable Timer0 overflow interrupt
    
    while(1)
    {
        ir_command = 0;                                        // initialise to prevent false trigger
        ir_address = 0;                                        // initialise to prevent false trigger
        get_mark_time();                                       // get Sony leader - 2.4mS Mark, 1.2mS space
        if ((mark_time > 0x80) && (mark_time < 0xB0))
        {         // ignore anything but 2.4mS mark
        
             for(bitcount = 0 ; bitcount < 7 ; bitcount++)
             {    // 7 bit command
                get_mark_time();                               // get a Sony IR bit
                ir_command >>= 1;                              // shift
                ir_command &= 0x7f;                            // top bit zero
                if (mark_time > 0x40)
                {                         // > 40 is assumed to be a 1
                    ir_command ^= 0x80;                        // top bit 1
                }
            }
            ir_command >>= 1;                                  // shift 1 unused bit
            ir_command &= 0x7F;                                // clear top bit

            for(bitcount = 0 ; bitcount < 5 ; bitcount++)
            {     // 5 bit address
                get_mark_time();                               // get a Sony IR bit
                ir_address >>= 1;                              // shift
                ir_address &= 0x7f;                            // top bit zero
                if (mark_time > 0x40)
                {
                    ir_address ^= 0x80;                        // top bit 1
                }
            }
            ir_address >>= 3;                                  // shift 3 unused bits
            ir_address &= 0x1F;                                // clear top 3 bits

        }
        
        if(ir_address == 1)
        {                                   // TV
            if(ir_command == 0)
            {                               // button 1
                                                // toggle output 1
                GP1_bit = ~GP1_bit;
            }
            if(ir_command == 1)
            {                               // button 2
                                                // toggle output 2
                GP2_bit = ~GP2_bit;
            }
            if(ir_command == 2)
            {                               // button 3
                                               // toggle output 4
                GP4_bit = ~GP4_bit;
            }
            if(ir_command == 3)
            {                               // button 4
                                                // toggle output 5
                GP5_bit = ~GP5_bit;
            }
            if(ir_command == 8)
            {                               // button 9
                                                 // all outputs on
                GPIO = 0xFF;
            }
            if(ir_command == 9)
            {                               // button 0
                                                 // all outputs off
                GPIO = 0x00;
            }
            Delay_ms(200);                                      // avoid double toggle
        }
    }
}

// get time of mark, then ignore space
void get_mark_time(void)
{
    while(ir_rx);                           // wait for a mark
    counter=0;
    TMR0 = 0;
    while(!ir_rx);                          // wait for space
    mark_time = (counter << 8) + TMR0;      // collect integer mark time

}


And its working.....

very nice project . hope lot help it other people.
but i have 1 confusion,
in ur clear the valve
command == 0
is button 1 & so all
but not clear the address valve
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top