- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello all,
I want to turn on and turn off LED using IR receiver which connected to My cy8c4245axi-483. I am using IR IRM-3638, Modulation frequency of 38 kHz. LED should turn On and turn off by both the ways, i.e. by capsense button and by remote also. how could i do this? i have already completed through On/Off by Capsense. I have gone through example which is given here. PSoC 4 Pioneer Kit Community Project#091 – RC-5... | element14 | Cypress Kits.
Thanks & Regards,
Prem KB
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I posted the following sample
Some notes:
- You need to test if the timing is OK with your RC5 remote
- You need to test the address and command of the button you'd like to use to toggle the LED
- In the main loop of the receiver program, check if the address and command matches with what you expected and if both matches, toggle LED
I hope this could be some hints.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Prem,
Can you share your project and let us know where you are facing issues? Were you able to get the signals from the remote to the PSoC?
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @Esteem_123 ,
Does your IR receiver follow the NEC protocol. If yes, can you check this thread that has IR receiver (NEC protocol) implemented in PSoC 4 device.
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The sample you are specifying is using PSoC as a transceiver (remote controller),
but your description sounds like a receiver (controlled by a remote controller or remote IR light).
It would be helpful if you can specify with what kind of IR light/signal you want to switch the LED connected to the PSoC board or if you want to control a remote device from PSoC 4.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Let me clear what actually I wanted to do. I have one IR receiver which is connected to one pin of MCU. I have separate remote to send signals to this IR receiver. Now I have to control one LED connected to other pin of MCU. When I press button of IR remote that LED should turn on. Again when I press button LED should turn off. Turn on and off LED by using Capsense I have already completed. But I don't know how on/off LED with Remote. Note that my remote using RC5 protocol. I have attached IR receiver details.
Thanks,
Prem KB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @Esteem_123
Were you able to interface the IR to PSoC? Can you get an interrupt or a gpio signal when you press the button on the remote? If so, then the remaining process is extremely simple. You can generate an interrupt and in the ISR, you can toggle the pin.
I cannot see the datasheet that you have shared, I get a 404 error...
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @Hari @MotooTanaka @BragadeeshV
I found one project example on IR receiver with PSoC 4 with Sony protocol. I wanted to do same with RC5 protocol. This code is working for me but when I press any button on remote LED gets toggled. I wanted to assign a particular remote switch for particular button. Can you please look in to it? I don't want LED char displayed in this project instead of I want to print in UART it self.
Thanks & Regards,
Prem KB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @Esteem_123
You can easily port the LCD functionality to UART by using the SCB or software transmit UART components. You can take a look at CE195366 and CE195379.
Are you using a kit for the project or is it a custom PCB? Note that the 042 kit requires an external connection for UART to kitprog.
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
> This code is working for me but when I press any button on remote LED gets toggled.
Seeing the attached project, I could not figure out how it can receive the data sent in the RC5 protocol.
But assuming that it is working, then you should get some value sent from the remote
and according to the value you should decide if flip the LED.
If the received value is theValue and the value of button which will toggle LED is expectedButtonValue
then you could modify the code something like
if (theValue == expectedButtonValue) {
ledstatus = Pin_RedLED_Read();
if (ledstatus == 0) {
ledstatus = 1;
} else {
ledstatus = 0;
}
Pin_RedLED_Write(ledstatus);
}
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I posted the following sample
Some notes:
- You need to test if the timing is OK with your RC5 remote
- You need to test the address and command of the button you'd like to use to toggle the LED
- In the main loop of the receiver program, check if the address and command matches with what you expected and if both matches, toggle LED
I hope this could be some hints.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Respected sir,
thank you for sharing this project. it has solved my problem. it is working fine.
Thanks,
Prem KB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello @MotooTanaka @BragadeeshV @Hari,
i have made modification to NEC receiver project which i have found Cypress community. i am trying to operate LED with both Remote and Capsense. i can able to operate it with remote but it is not working with Capsense. C code i have attached here. I know i have put Capsense inside if(framereceived),so that capsense is not working. But if i put after frame received then only capsense is working not NEC receiver. Please give me suggestions.
#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 flag[10];
/*****************************/
typedef enum
{
IDLE,
ADDRESS_FRAME,
DATA_FRAME,
}state;
state nec_state;
/* CountFlag is 0 only once or during the start of the frame */
volatile uint16_t countFlag;
uint16_t timerPeriod;
asm (".global _printf_float");
/* For GCC compiler revise _write() function for printf functionality */
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);
int main(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
CapSense_Start();
OF_8_Write(1);
CapSense_InitializeAllBaselines();
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(;;)
{
CapSense_ProcessAllWidgets();
CapSense_ScanAllWidgets();
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");
}
//ResetFlags
countFlag = 0;
timeEnd = 0;
timeStart = 0;
frameReceived = 0;
address_temp = 0;
data_temp = 0;
address_inv = 0;
address = 0;
data_inv = 0;
status=CapSense_IsWidgetActive(CapSense_BUTTON08_WDGT_ID);
if(status || data==6)
{
if(flag[8]==0)
{flag[8]=1;OF_8_Write(0);
}
else
{flag[8]=0;OF_8_Write(1);
}
while(status)
{
CapSense_ProcessAllWidgets();
while(CapSense_IsBusy());
CapSense_ScanAllWidgets();
status = CapSense_IsWidgetActive(CapSense_BUTTON08_WDGT_ID);
}
}
}
}
}
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;
}
}
}
Thanks && Regards,
Prem KB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
As the nature of the question is different from the original question,
it may be better to ask this question in a newly created question,
so that more people will notice/look into your new question.
Having written that, following is my short opinion.
As you have 2 asynchronous operation in the main loop,
basically you should not have "while()" wait inside.
So I would try some thing like below
unsigned char prev_status = 0 ; // after the line of status=0
... in main()
CapSense_ProcessAllWidgets();
CapSense_ScanAllWidgets();
for(;;) {
if (pulseReceived) {
// do process for pulse received
}
if (frameReceived) {
// do process for frame received
}
if (!CapSense_IsBusy()) {
CapSense_ScanAllWidgets();
status = CapSense_IsWidgetActive(CapSense_BUTTON08_WDGT_ID);
if (!prev_status && status) {
// do process for CapSense Activated edge
}
prev_status = status ;
CapSense_ProcessAllWidgets();
}
}
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hello Sir,
i have modified as per you have suggested. LED should operate by both ways capsense and Remote. but it is not working.
if (!CapSense_IsBusy()) {
CapSense_ScanAllWidgets();
status = CapSense_IsWidgetActive(CapSense_BUTTON08_WDGT_ID) ||(data==18);
if (status && !prev_status)
// do process for CapSense Activated edge
{
if(flag[8]==0)
{flag[8]=1;OF_8_Write(0);}
else
{flag[8]=0;OF_8_Write(1);}
}
prev_status = status ;
CapSense_ProcessAllWidgets();
}
Thanks,
Prem KB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
First of all, it was my bad that the sequence of
CapSense_ProcessAllWidgets()
and
CapSense_ScanAllWidgets()
in my previous code snippet was wrong,
it should have been something like
if (CapSense_NOT_BUSY == CapSense_IsBusy()) {
/* Process data for all widgets */
CapSense_ProcessAllWidgets();
status = CapSense_IsWidgetActive(CapSense_BUTTON08_WDGT_ID);
if (status && !prev_status) {
// do process for CapSense Activated edge
}
prev_status = status ;
/* Initiate new scan for all widgets */
CapSense_ScanAllWidgets();
}
Meantime, I think that the LED on/off by IR Remote should be taken care of outside of
if (CapSense_NOT_BUSY == CapSense_IsBusy()) {
block, to make CapSense and IR Remote independent.
And please debug and make sure both methods are working individually
by comment out the other method in the main loop.
As I don't know about the NEC protocol stuff,
I'm not paying attention about IR part this time.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hello sir,
it is working with capsense properly. but at a same time if i pressed remote button to make it toggle, it won't work with remote or capsense. Please have look in this video.https://www.mediafire.com/file/jov256zx09qyr8n/WhatsApp+Video+2021-04-08+at+10.22.35+PM.mp4/file
Thanks for your quick response,
Prem KB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
So I added a CapSense to my RC5 receiver sample.
Schematic
And I assigned the Green LED on CY8CKIT-042 as LED
P1.1 as button08
P1.5 as button07
Pins
As I tested, I noticed that when IR signal is being detected,
CapSense needed to be stopped.
And it needed to be started again after RC5 timer process completed.
I assigned the RC5 address 3 to MY_IR_ADDRESS
command 7 to MY_IR_COMMAND.
You need to test your remote controller and get the address and command number
which you'd like to use to turn on/off the LED.
So I modified the main.c as
#include "project.h"
#include "stdio.h"
#include "tty_utils.h"
#define IR_ST_IDLE 0
#define IR_ST_START_BIT 1
#define IR_ST_TOGGLE 2
#define IR_ST_ADDRESS 3
#define IR_ST_COMMAND 4
#define IR_ST_DATA_READY 5
#define IR_ADDRESS_WIDTH 5
#define IR_COMMAND_WIDTH 6
#define MY_IR_ADDRESS 3
#define MY_IR_COMMAND 7
volatile int ir_status = IR_ST_IDLE ;
volatile int ir_address_bit = 0 ; /* 5bit */
volatile int ir_command_bit = 0 ; /* 6bit */
volatile int ir_toggle = 0 ;
volatile int ir_address = 0 ;
volatile int ir_command = 0 ;
volatile int capsense_running = 0 ;
CY_ISR_PROTO(timer_isr) ;
CY_ISR(ir_isr)
{
isr_ir_ClearPending() ;
if (ir_status == IR_ST_IDLE) {
if (capsense_running) {
CapSense_Stop() ;
capsense_running = 0 ;
}
ir_status = IR_ST_START_BIT ;
isr_ir_Disable() ;
isr_ir_ClearPending() ;
isr_bit_ClearPending() ;
isr_bit_StartEx(timer_isr) ;
bit_timer_ClearInterrupt(bit_timer_INTR_MASK_CC_MATCH) ;
bit_timer_WriteCounter(0) ;
bit_timer_Enable() ;
}
}
CY_ISR(timer_isr)
{
int ir_in ;
bit_timer_ClearInterrupt(bit_timer_INTR_MASK_CC_MATCH) ;
ir_in = IR_input_Read() ;
switch(ir_status) {
case IR_ST_IDLE: // should not come here
break ;
case IR_ST_START_BIT:
if (ir_in == 1) {
ir_status = IR_ST_TOGGLE ;
} else {
ir_status = IR_ST_IDLE ;
}
break ;
case IR_ST_TOGGLE:
ir_toggle = ir_in ;
ir_status = IR_ST_ADDRESS ;
break ;
case IR_ST_ADDRESS:
ir_address <<= 1 ;
ir_address |= ir_in ;
if (++ir_address_bit >= IR_ADDRESS_WIDTH) {
ir_status = IR_ST_COMMAND ;
}
break ;
case IR_ST_COMMAND:
ir_command <<= 1 ;
ir_command |= ir_in ;
if (++ir_command_bit >= IR_COMMAND_WIDTH) {
ir_status = IR_ST_DATA_READY ;
isr_bit_Disable() ;
isr_bit_ClearPending() ;
bit_timer_Stop() ;
}
break ;
case IR_ST_DATA_READY: // should not come here
default: // should not come here
break ;
}
}
void clear_data(void)
{
ir_toggle = 0 ;
ir_address = 0 ;
ir_address_bit = 0 ;
ir_command = 0 ;
ir_command_bit = 0 ;
}
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
tty_init() ;
splash("RC5 Test") ;
isr_ir_ClearPending() ;
isr_ir_StartEx(ir_isr) ;
isr_bit_ClearPending() ;
isr_bit_StartEx(timer_isr) ;
bit_timer_Init() ;
capsense_running = 1 ;
CapSense_Start() ;
CapSense_ScanAllWidgets() ;
}
int main(void)
{
uint8_t status, prev_status ;
int my_ir_address = MY_IR_ADDRESS ;
int my_ir_command = MY_IR_COMMAND ;
int toggle_led_flag = 0 ;
init_hardware() ;
for(;;)
{
if (ir_status == IR_ST_DATA_READY) {
snprintf(str, STR_BUF_LEN, "toggle: %d address %d: command %d\n\r",
ir_toggle, ir_address, ir_command) ;
print(str) ;
if ((ir_address == MY_IR_ADDRESS) && (ir_command == MY_IR_COMMAND)) {
print("IR Command Hit!\n\r") ;
toggle_led_flag = 1 ;
}
if (capsense_running == 0) {
capsense_running = 1 ;
CapSense_Start() ;
CapSense_ScanAllWidgets() ;
}
clear_data() ;
ir_status = IR_ST_IDLE ;
isr_ir_ClearPending() ;
isr_ir_StartEx(ir_isr) ;
// isr_ir_Enable() ;
}
if (capsense_running && (CapSense_NOT_BUSY == CapSense_IsBusy())) {
CapSense_ProcessAllWidgets() ;
status = CapSense_IsWidgetActive(CapSense_BUTTON08_WDGT_ID) ;
if (status && !prev_status) { /* CapSense Activated Edge */
print("CapSense Button08 Touched!\n\r") ;
toggle_led_flag = 1 ;
}
prev_status = status ;
CapSense_ScanAllWidgets() ;
}
if (toggle_led_flag) {
toggle_led_flag = 0 ;
print("LED: ") ;
if (LED_Read()) {
LED_Write(0) ;
print("ON\n\r") ;
} else {
LED_Write(1) ;
print("OFF\n\r") ;
}
}
}
}
Now when the serial output of CY8CKIT-042 was
After starting,
(1) I touched the button, LED turned ON
(2) I touched the button, LED turned OFF
(3) I sent 0 0 0 from the emulator on CY8CKIT-044
received 0 0 0
(4) I sent 0 1 2 received 0 1 0
(5) I sent 0 3 7 received 0 3 0
(6) I sent 0 3 7 received 0 3 6
(7) I sent 0 3 7 received 0 3 7 (command matched) LED turned ON
(8) I sent 0 3 7 received 0 3 7 (command matched) LED turned OFF
(9) I touched the button, LED turned ON
(10) I touched the button, LED turned OFF
(11) I sent 0 3 7 received 0 3 7 (command matched) LED ON
(12) I sent 0 3 7 received 0 3 7 (command matched) LED OFF
(13) I touched the button, LED turned ON
(14) I sent 0 3 7 received 0 3 7 (command matched) LED OFF
(15) I sent 0 3 7 received 0 7 0
(16) I sent 0 3 7 received 0 3 7 (command matched) LED ON
(17) I touched the button, LED turned OFF
So basically, both RC5 signal and CapSense are working,
but with my program, sometimes the receiver fails to receive correct RC5 value(s),
this may be cause by the accuracy of the clock
or CapSense interrupt and/or some other system level interrupts are
causing the inaccuracy of the timer value.
Although I could have spent much more time, I decided to stop here.
moto