Objective

The objective of this laboratory is to demonstrate a standard of infrared communication, i.e., the Samsung Protocol.

Preparation

The following schematic details the hardware setup.

Table 1 lists the components used in the schematic.

IDComponentManufacturer Part No.ValueQty.
Base Components
IC1MCUPIC24FJ256GA702-I/SP1
IC2RegulatorLM1117T-3.3/NOPB3.3V / 800mA1
C1 & C2Capacitor (tantalum)TAP106K025SRW10uF / 25V2
C3 & C4Capacitor (ceramic)SR155C103KARTR10.01uF / 50V2
C5 & C6Capacitor (ceramic)SR155C104KARTR10.1uF / 50V2
C7 & C8Capacitor (ceramic)SR151A150JARTR115pF / 100V2
C9Capacitor (ceramic)FG16X7R1E106KRT0610uF / 25V1
Y1CrystalABL-16.000MHZ-B216MHz1
R1ResistorSFR2500001002FR50010kΩ1
R2ResistorSFR2500001004FR5001MΩ1
J1Header (6-way)
(PICkit 5)
22-27-20611
Additional Components
R3ResistorSFR2500001050FR500105Ω1
D1LED (infrared)WP710A10F3C20mA1
Table 1: Components

Slides #1 to #9 represent an infrared signal from a Samsung television remote control (button #1), captured by an oscilloscope, using an infrared receiver module, as shown at the top of this page. There are three terminals; signal (orange), power (red), and ground (black). Slide #1 is an overview of the Leading pulse, the 32-bit code, and a STOP pulse. The oscilloscope trigger was set to capture the infrared signal, with a total time of approximately 62ms. The measured leading pulse, as shown in slide #2, closely resembles the timing of the leading edge explained in the Infrared theory page. Likewise, the measured times for signal 1 and signal 0, as shown in slides #3 to #4 and slide #5, respectively, closely resemble the timing of signal 1 and signal 0, respectively, as explained in the Infrared theory page. The same can be said about the STOP pulse at the end.

Refer to the following source code.

/*                           Infrared (source code)                           */  
/*                            MCU: PIC24FJ256GA702                            */
/*                              Author: Michael                               */

/**************************** Configuration Bits ******************************/

// FSEC
#pragma config BWRP = OFF                                                       // Boot Segment Write-Protect bit (Boot Segment may be written)
#pragma config BSS = DISABLED                                                   // Boot Segment Code-Protect Level bits (No Protection (other than BWRP))
#pragma config BSEN = OFF                                                       // Boot Segment Control bit (No Boot Segment)
#pragma config GWRP = OFF                                                       // General Segment Write-Protect bit (General Segment may be written)
#pragma config GSS = DISABLED                                                   // General Segment Code-Protect Level bits (No Protection (other than GWRP))
#pragma config CWRP = OFF                                                       // Configuration Segment Write-Protect bit (Configuration Segment may be written)
#pragma config CSS = DISABLED                                                   // Configuration Segment Code-Protect Level bits (No Protection (other than CWRP))
#pragma config AIVTDIS = OFF                                                    // Alternate Interrupt Vector Table bit (Disabled AIVT)

// FBSLIM
#pragma config BSLIM = 0x1FFF                                                   // Boot Segment Flash Page Address Limit bits (Enter Hexadecimal value)

// FOSCSEL
#pragma config FNOSC = PRIPLL                                                   // Oscillator Source Selection (Primary Oscillator with PLL module (XT + PLL, HS + PLL, EC + PLL))
#pragma config PLLMODE = PLL96DIV4                                              // PLL Mode Selection (96 MHz PLL. Oscillator input is divided by 4 (16 MHz input))
#pragma config IESO = OFF                                                       // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)

// FOSC
#pragma config POSCMD = HS                                                      // Primary Oscillator Mode Select bits (HS Crystal Oscillator Mode)
#pragma config OSCIOFCN = ON                                                    // OSC2 Pin Function bit (OSC2 is general purpose digital I/O pin)
#pragma config SOSCSEL = OFF                                                    // SOSC Power Selection Configuration bits (Digital (SCLKI) mode)
#pragma config PLLSS = PLL_PRI                                                  // PLL Secondary Selection Configuration bit (PLL is fed by the Primary oscillator)
#pragma config IOL1WAY = OFF                                                    // Peripheral pin select configuration bit (Allow multiple reconfigurations)
#pragma config FCKSM = CSDCMD                                                   // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are disabled)

// FWDT
#pragma config WDTPS = PS1                                                      // Watchdog Timer Postscaler bits (1:1)
#pragma config FWPSA = PR32                                                     // Watchdog Timer Prescaler bit (1:32)
#pragma config FWDTEN = OFF                                                     // Watchdog Timer Enable bits (WDT and SWDTEN disabled)
#pragma config WINDIS = OFF                                                     // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
#pragma config WDTWIN = WIN50                                                   // Watchdog Timer Window Select bits (WDT Window is 50% of WDT period)
#pragma config WDTCMX = WDTCLK                                                  // WDT MUX Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits)
#pragma config WDTCLK = SYSCLK                                                  // WDT Clock Source Select bits (WDT uses system clock when active, LPRC while in Sleep mode)

// FPOR
#pragma config BOREN = OFF                                                      // Brown Out Enable bit (Brown Out Disabled)
#pragma config LPCFG = OFF                                                      // Low power regulator control (No Retention Sleep)
#pragma config DNVPEN = DISABLE                                                 // Downside Voltage Protection Enable bit (Downside protection disabled when BOR is inactive)

// FICD
#pragma config ICS = PGD1                                                       // ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1)
#pragma config JTAGEN = OFF                                                     // JTAG Enable bit (JTAG is disabled)

// FDEVOPT1
#pragma config ALTCMPI = DISABLE                                                // Alternate Comparator Input Enable bit (C1INC, C2INC, and C3INC are on their standard pin locations)
#pragma config TMPRPIN = OFF                                                    // Tamper Pin Enable bit (TMPRN pin function is disabled)
#pragma config SOSCHP = ON                                                      // SOSC High Power Enable bit (valid only when SOSCSEL = 1 (Enable SOSC high power mode (default))
#pragma config ALTI2C1 = ALTI2CEN                                               // Alternate I2C pin Location (SDA1 and SCL1 on RB9 and RB8)

/************************* Configuration Bits (end) ***************************/

#define FCY 16000000                                                            // FCY = FOSC / 2 (FCY: Instruction clock cycle) (FOSC: System clock cycle)
#define LED_IR_1 LATBbits.LATB6                                                 // LED_IR_1 associated with MCU Pin #15

#include <libpic30.h>                                                           // Delay functions
#include <xc.h>                                                                 // MCU pin mapping

int main(void)                           
{
    
    // Set pin direction
    TRISBbits.TRISB6 = 0;                                                       // Set MCU Pin #15 to output (LED_IR_1)        
    
    /************************* configure MCU modules **************************/
    
    // Analog Ports
    ANSA = 0;                                                                   // Disable A (PIC24FJ256GA702 datasheet p.126 Table 11-1)
    ANSB = 0;    
    
    // Comparators
    CM1CONbits.CEN = 0;                                                         // Disable #1 (PIC24FJ256GA702 datasheet p.310 Register 25-1)
    CM2CONbits.CEN = 0;                                                         
    CM3CONbits.CEN = 0;                                                                                                                        
    
    // ADC
    AD1CON1bits.ADON = 0;                                                       // Disable module (PIC24FJ256GA702 datasheet p.291 Register 24-1) 

    /********************** configure MCU modules (end) ***********************/ 

    /*************************** declare functions ****************************/
    
    void Carrier(void)                                                          // Function to generate carrier frequency (38kHz)
    {
        LED_IR_1 = 1;
        __delay_us(13);
        LED_IR_1 = 0;
        __delay_us(13);
    }
       
    void Leading_Edge(void)                                                     // Function to generate leading edge
    {
        
        for (int i = 0; i < 171; i ++)                                          // 171 cycles of carrier frequency for HIGH period 
        {
            Carrier();
        }
        
        LED_IR_1 = 0;
        __delay_us(4500);                                                       // Delay for LOW period
   
    }
    
    void Signal_1(void)                                                         // Function for HIGH signal (1) 
    {
        
        for (int i = 0; i < 21; i ++)                                           // 21 cycles of carrier frequency for HIGH period 
        {
            Carrier();
        }
        
        LED_IR_1 = 0;
        __delay_us(1710);                                                       // Delay for LOW period
          
    }
    
    void Signal_0(void)                                                         // Function for LOW signal (0) 
    {
        
        for (int i = 0; i < 21; i ++)                                           // 21 cycles of carrier frequency for HIGH period 
        {
            Carrier();
        }
        
        LED_IR_1 = 0;
        __delay_us(550);                                                        // Delay for LOW period
          
    }
    
    void STOP(void)                                                             // Function for STOP condition 
    {
        
        for (int i = 0; i < 21; i ++)                                           // 21 cycles of carrier frequency for HIGH period 
        {
            Carrier();
        }
        
        LED_IR_1 = 0;
        __delay_ms(1000);                                                   
          
    }
    
    
    /************************ declare functions (end) *************************/
    
    while (1)
    {

        Leading_Edge();                                                         // Initiate IR communication for Channel #1
        
        // Address
        Signal_1();
        Signal_1();
        Signal_1();
        Signal_0();
        Signal_0();
        Signal_0();
        Signal_0();
        Signal_0();
        
        // Address
        Signal_1();
        Signal_1();
        Signal_1();
        Signal_0();
        Signal_0();
        Signal_0();
        Signal_0();
        Signal_0();
        
        // Command 
        Signal_0();
        Signal_0();
        Signal_1();
        Signal_0();
        Signal_0();
        Signal_0();
        Signal_0();
        Signal_0();
        
        // Command (inv.)
        Signal_1();
        Signal_1();
        Signal_0();
        Signal_1();
        Signal_1();
        Signal_1();
        Signal_1();
        Signal_1();
        
        STOP();                                                                 // Initiate a STOP pulse
                        
    }

    return 0;
    
}
Testing

Connect a power supply, point the infrared LED towards a Samsung television, and observe the channel change to 1.

Conclusion

The code can be modified to include a keypad, with each button controlling a specific signal such as channel #1, #2, #3, volume up, volume down, ON/OFF, etc. Based on the television responding to the infrared LED, this setup can be used as a basis for projects.