NEC IR remote control with Capsense

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Esteem_123
Level 2
Level 2
50 sign-ins 25 sign-ins 10 replies posted

Hello all,

I'm working on controlling LED with NEC remote control and Capsense(Using custom PCB with PSoC4 MCU cy8c4245axi-483). My Project which I have attached here is work fine with either through remote or Capsense button. As Problem is different from previous one, I have already opened thread regarding this issue. but problem has not been solved .https://community.cypress.com/t5/PSoC-4-MCU/IR-interfacing-with-Capsense-Button/m-p/273105/emcs_t/S2... .

Please Note that I wanted to operate LED by both the ways. Here I am attaching my Project(in which it is working only with CapSense)

 

 

#include "project.h"
#include "stdio.h"
#define TIMER_FREQUENCY 1000000UL
#define ADDRESS_SIZE    16U
#define DATA_SIZE       16U

volatile uint16_t timeStart;
volatile uint16_t timeEnd;
uint32_t pulseWidth;
volatile uint16_t pulseReceived;
volatile uint16_t overflow;
uint32_t timeDiff;
/******************************/
uint8_t startFrameFlag = 0;
uint8_t addressCount = 0;
uint8_t dataCount = 0;
uint16_t address_temp;
uint8_t address_temp2;
uint8_t address;
uint8_t address_inv;
uint16_t data_temp;
uint8_t data;
uint8_t data_inv;
uint8_t frameReceived;
unsigned char status=0;
unsigned char prev_status=0;
unsigned char flag[10];
/*****************************/
typedef enum 
{
    IDLE,
    ADDRESS_FRAME,
    DATA_FRAME,
}state;
state nec_state;
volatile uint16_t countFlag;
uint16_t timerPeriod;
asm (".global _printf_float");
int _write(int file, char *ptr, int len)
{
    (void) file;
    int i;
    for (i = 0; i < len; i++)
    {
        UART_UartPutChar(*ptr++);
    }
    return(len);
}
void Pin_ISR();
void Timer_ISR();
void DecodeProcotol(uint16_t pulseWidth);
CY_ISR(Pin_ISR)
{
    uint8 intrSrc;
    intrsrc=NEC_IN_ClearInterrupt();
    if(intrSrc != 0u)
    {
        if(countFlag == 0)
        {   
            timeStart = Timer_ReadCounter();
            countFlag = 1;
        }
        else
        {
            timeEnd = Timer_ReadCounter();
            pulseReceived = 1;
        }
    }
}
CY_ISR(Timer_ISR)
{
    if((Timer_GetInterruptSourceMasked() & Timer_INTR_MASK_TC ) != 0)
    {
        if(countFlag != 0)
        overflow++;
        Timer_ClearInterrupt(Timer_INTR_MASK_TC);
    }
}
void DecodeProcotol(uint16_t pulseWidth)
{
    uint8_t bit = 0;
    switch(nec_state)
    {
        case IDLE://Checks for start of frame
        {
            if(pulseWidth > 12000 && pulseWidth < 15000)
            {
                nec_state = ADDRESS_FRAME;
                startFrameFlag = 1;
            }
            else
            {
                //Invalid Frame received
                nec_state = IDLE;
            }
        
            break;
        }
        case ADDRESS_FRAME:
        {
            if(pulseWidth > 1100 && pulseWidth < 1160)
            {
                bit = 0;
            }
            else if(pulseWidth > 2200 && pulseWidth < 2300)
            {
                 bit = 1;
            }
            address_temp |= ( bit << addressCount);
            addressCount++;
            if(addressCount >= ADDRESS_SIZE)
            {
               addressCount = 0; 
               nec_state = DATA_FRAME;
            }
            break;
        }
        case DATA_FRAME:
        {
            if(pulseWidth > 1100 && pulseWidth < 1160)
            {
                bit = 0;
            }
            else if(pulseWidth > 2200 && pulseWidth < 2300)
            {
                bit = 1;
            }
           data_temp |= ( bit << dataCount);
           dataCount++;
            if(dataCount >= DATA_SIZE)
            {
               dataCount = 0; 
               nec_state = IDLE;
               frameReceived = 1;
            }
            break;
        }
    }
}
int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */
    CapSense_Start();
    CapSense_InitializeAllBaselines();
    CapSense_ProcessAllWidgets();
    CapSense_ScanAllWidgets();
    Pin_Interrupt_StartEx(Pin_ISR);
    Timer_Interrupt_StartEx(Timer_ISR);
    UART_Start();
    UART_UartPutString("Working\r\n");
    nec_state = IDLE;
    Timer_Start();
    timerPeriod = Timer_ReadPeriod();
    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    for(;;)
    {
            countFlag = 0;
            timeEnd = 0;
            timeStart = 0;
            frameReceived = 0;
            address_temp = 0;
            data_temp = 0;
            address_inv = 0;
            address = 0;
            data_inv = 0;
        if(pulseReceived)
        {
            if(timeEnd > timeStart)
            {
                timeDiff = (overflow * timerPeriod) + (timeEnd - timeStart);
            }
            else
            {
                timeDiff = (overflow * timerPeriod) - (timeStart - timeEnd);
            }
            timeStart = timeEnd;
            overflow = 0;
            pulseReceived = 0;
            pulseWidth = timeDiff; //in uS
            //printf("%u uS\r\n", pulseWidth);
            DecodeProcotol(pulseWidth);
        }
        if(frameReceived)
        {
            address_inv = address_temp >> 8;
            address = address_temp & 0x00FF;
            data_inv = data_temp >> 8;
            data = data_temp & 0x00FF;
                if((uint8_t)(~data) == data_inv)
                {
                    //printf("Data received: %u\r\n", data_temp);
                    printf("Data received: %u\r\n", data);
                }
                else
                {
                    printf("Data corrupted\n\r");
                }
        }
            if (CapSense_NOT_BUSY == CapSense_IsBusy()) {
            CapSense_ProcessAllWidgets();
            status  = CapSense_IsWidgetActive(CapSense_BUTTON08_WDGT_ID) || data==18;
            if (status && !prev_status) {
                if(flag[8]==0)// && (OF_1_Read()==1))  
                    {flag[8]=1;OF_8_Write(0);
                    }
            else
                    {flag[8]=0;OF_8_Write(1);
                    }
            }
            prev_status = status ;
            CapSense_ScanAllWidgets(); }
    } 
}

 

 

. Please Have look. Your suggestions are always helpful for me.

Thanks & Regards,

Prem KB

 

@MotooTanaka @Hari @Bob_Marlowe @BragadeeshV 

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I don't think clearing variables in main loop is the problem.

 

But I would clear these variables after the block of

if (data==27) { }

to be safe.

 

Meantime one thing bothers me is that when the program hits

frameReceived = 1 ;

The timer and interrupts keep running.

 

I would stop interrupt and timer at the end of  if (frameReceived) {} block

if (frameReceived) {

...

Pin_Interrupt_Disable() ;

Timer_Interrupt_Disable() ;

Timer_Stop() ;

}

then I'd like to restart the interrupt and the timer there.

So it will look like 

if (frameReceived) {

....

if (data == 27) {

...

}

clear variables

restart interrupts

restart timer

}

moto

NOTE: This is my "GUESS", so it can be wrong.

 

 

View solution in original post

3 Replies
Hari
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hello @Esteem_123 

 

The main issue with the code seems to be due to the initialization of data inside the for loop. 

countFlag = 0;
timeEnd = 0;
timeStart = 0;
frameReceived = 0;
address_temp = 0;
data_temp = 0;
address_inv = 0;
address = 0;
data_inv = 0;

 

You need to set the data outside the for loop so that the modifications in the ISR take effect. Can you check the code that is working with IR sensor(without CapSense) and check the implementation?

 

Also, are you seeing the "data received" commands in the terminal?

 

Best regards, 
Hari

0 Likes
lock attach
Attachments are accessible only for community members.

Hello @Hari ,

I have tried your suggestion. I am receiving data on terminal correctly. But it is working only once. means I can toggle LED only once.

Please see i have done like this. but it is lengthier code. can you suggest me how can i sort this? I toggled LED by writting same code twice. (one for IR & one for Capsense).

Your suggestions are always welcomed.

@Hari @MotooTanaka @Bob_Marlowe @BragadeeshV 

 

 

for(;;)
    {
        if(pulseReceived)
        {
            //doing process
        }
        if(frameReceived)
        {
            //doing process
            countFlag = 0;
            timeEnd = 0;
            timeStart = 0;
            frameReceived = 0;
            address_temp = 0;
            data_temp = 0;
            address_inv = 0;
            address = 0;
            data_inv = 0;

            if (data==27) {
                ON_4_Write(0);OF_4_Write(1);
                    if(flag[8]==0)
                        {flag[8]=1;OF_8_Write(0);ON_8_Write(1);}
                    else
                        {flag[8]=0;OF_8_Write(1);ON_8_Write(0);}
            prev_status[8] = status[8] ;}
        }
        if (CapSense_NOT_BUSY == CapSense_IsBusy()) {
            CapSense_ProcessAllWidgets();
            status[8]  = CapSense_IsWidgetActive(CapSense_BUTTON08_WDGT_ID);
            if (status[8] && !prev_status[8]) {
                ON_4_Write(0);OF_4_Write(1);
                if(flag[8]==0) 
                    {flag[8]=1;OF_8_Write(0);ON_8_Write(1);
                    }
            else
                    {flag[8]=0;OF_8_Write(1);ON_8_Write(0);
                    }
            }
            prev_status[8] = status[8] ;
            CapSense_ScanAllWidgets();}
}

 

 

 

Thanks & Regards,

Prem KB

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I don't think clearing variables in main loop is the problem.

 

But I would clear these variables after the block of

if (data==27) { }

to be safe.

 

Meantime one thing bothers me is that when the program hits

frameReceived = 1 ;

The timer and interrupts keep running.

 

I would stop interrupt and timer at the end of  if (frameReceived) {} block

if (frameReceived) {

...

Pin_Interrupt_Disable() ;

Timer_Interrupt_Disable() ;

Timer_Stop() ;

}

then I'd like to restart the interrupt and the timer there.

So it will look like 

if (frameReceived) {

....

if (data == 27) {

...

}

clear variables

restart interrupts

restart timer

}

moto

NOTE: This is my "GUESS", so it can be wrong.