Infrared with msp430

Everything related to protocols and IR codes
TuranOlmez
Posts: 10
Joined: Sat Mar 16, 2019 1:10 pm

Re: Infrared with msp430

Post by TuranOlmez »

AnalysIR wrote: Mon Mar 25, 2019 12:46 pm Have you tried using the IRremote library with Energia?

https://github.com/energia/Energia/tree ... s/IRremote
Thank you very much, but i don't use Energia unfortunately.
i would like consult something to you.
should i use uart? or a simple protocol created by myself? which one is the more simple?
Regards.
User avatar
AnalysIR
Site Admin
Posts: 776
Joined: Sat Aug 31, 2013 3:51 pm
Location: Dublin, Ireland
Contact:

Re: Infrared with msp430

Post by AnalysIR »

but i don't use Energia unfortunately.
OK, but you could study it to check how it is done for MSP430!

I would not advise using a UART for IR.(Although we have some posts on our blog showing how to generate IR using a UART).
In generat I would suggest using something like the NEC protocol as a good/simple starting point. Of course you can design an even simlet protocol.

Note: IR receivers invert the signal received!
TuranOlmez
Posts: 10
Joined: Sat Mar 16, 2019 1:10 pm

Re: Infrared with msp430

Post by TuranOlmez »

Hi again (My keyboard is not work'ng properly sorry for punctuation )
I tried something but didnt work
Can you examine my codes on below please ? I cant understand where the problem is

TRANSMITTER CODE

Code: Select all

 #include "msp430g2553h"

#define NUMBER_OF_PULSES 12 
#define DELAY_IR_ON 9
#define DELAY_IR_OFF 10

#define BTN1 BIT0
#define BTN1_DIR P2DIR &= ~BTN1
#define BTN1_REN P2REN |= BTN1
#define BTN1_OUT P2OUT |= BTN1

#define IR_BIT BIT0
#define IR_OUT P1DIR |= IR_BIT
#define IR_ON P1OUT |= IR_BIT
#define IR_OFF P1OUT &= ~IR_BIT

void init(void);
void configClock(void);
void transmitBit0(void);
void transmitBit1(void);
void delay_ms(unsigned int ms);
void transmit(unsigned long data_word, unsigned char number_of_bits);


void main( void )
{
  WDTCTL   = (WDTPW | WDTHOLD);

  init();
while(1)
{
if((P2IN & BTN1) == 0)
{
unsigned int j;
for(j=0; j<2; j++) 
{
transmit(110001001000010,15);
delay_ms(40);
}
while((P2IN & BTN1) == 0);
}

}
  
}

void init(void)
{
IR_OUT, IR_OFF;
BTN1_DIR, BTN1_REN, BTN1_OUT;

configClock();
}

//====================
void configClock(void)
{
if(CALBC1_1MHZ == 0xFF) // If calibration constant erased
{
while(1); // Do not load up, trap CPU!
}
DCOCTL = 0; // Select lowest DCOx and MODx
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
}

//====================
void transmit(unsigned long data_word, unsigned char number_of_bits) // sending out bits, one by one, LSB first, maximum 16 bits (1 word)
{
unsigned char i;
unsigned int mask;
for(i=0; i<number_of_bits; i++)
{
mask = (1 << i);
if((data_word & mask) == 0) // bit '0'
{
transmitBit0();
}
else // bit '1'
{
transmitBit1();
}
}
}

//====================
void transmitBit0(void)
{
// bit '0' = 12 pulses (~320 microseconds) + 680 microseconds silent
unsigned char i;
for(i=0; i<NUMBER_OF_PULSES; i++)
{
IR_ON;
__delay_cycles(DELAY_IR_ON);
IR_OFF;
__delay_cycles(DELAY_IR_OFF);
}
__delay_cycles(680);
}

//====================
void transmitBit1(void)
{
// bit '1' = 12 pulses (~320 microseconds) + 1,680 microseconds silent
unsigned char i;
for(i=0; i<NUMBER_OF_PULSES; i++)
{
IR_ON;
__delay_cycles(DELAY_IR_ON);
IR_OFF;
__delay_cycles(DELAY_IR_OFF);
}
__delay_cycles(1680);
}

//====================
void delay_ms(unsigned int ms)
{
unsigned int i;
for(i=0; i<ms; i++)
{
__delay_cycles(1000);
}
}
RECEIVER

Code: Select all

#include <msp430.h>

//========== Macros & Constants Definition ==========//

#define LOW 0
#define HIGH 1
#define FALSE 0
#define TRUE 1

// space/separator time (time_in_low) = ~320 microseconds in theory
#define TIME_OF_SPACE_MIN 200
#define TIME_OF_SPACE_MAX 400

// bit 0 time (time_in_high) = ~680 microseconds in theory
#define TIME_OF_BIT0_MIN 500
#define TIME_OF_BIT0_MAX 800

// bit 1 time (time_in_high) = ~1680 microseconds in theory
#define TIME_OF_BIT1_MIN 1500
#define TIME_OF_BIT1_MAX 1800

#define CYCLE_FOR_20ms 20000
#define IR_REC_BIT BIT1
#define IR_REC_IN (P1DIR &= ~IR_REC_BIT)
#define IR_REC_INPUT_IS_HIGH ((P1IN & IR_REC_BIT) != 0)
#define TIMER_GETS_OVERFLOW ((TACTL & TAIFG) != 0)
#define TIMER_NEVER_GETS_OVERFLOW ((TACTL & TAIFG) == 0)
#define CCR1_COMPARE_MATCHED ((TACCTL1 & CCIFG) != 0)

#define LED1 BIT0
#define LED1_DIR P2DIR |= LED1
#define LED1_ON P2OUT |= LED1
#define LED1_OFF P2OUT &= ~LED1

#define LED2 BIT1
#define LED2_DIR P2DIR |= LED2
#define LED2_ON P2OUT |= LED2
#define LED2_OFF P2OUT &= ~LED2

#define RECEIVE_BIT0 0
#define RECEIVE_BIT1 1
#define FUNCTION_1 110001001000010


//========== Functions Declaration ==========//

void init(void);
void configClock(void);
void configIO(void);
void configTimer(void);
void startTimer(void);
void stopTimer(void);
void clearTimer(void);
unsigned int readTimer(void);
unsigned char timeOut(void);
void listen_IR(void);
void read_IR_DATA(void);
void Function1(void);
void Function1_ON(void);
void Function1_OFF(void);


//========== Variables Declaration ==========//

unsigned char old_ir_receive_input,
time_out;
unsigned int overflow_times,
time_in_low,
time_in_high;
unsigned short count1 = 0;
unsigned short count2 = 0;
unsigned long data, bitFrame;

/*
* main.c
*/

//==============================

int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

init();

while(1)
{
listen_IR();
}
}

//==============================

void init(void)
{
configIO();
configTimer();
configClock();

// get the first status of the IR Receiver's Output
if(IR_REC_INPUT_IS_HIGH)
old_ir_receive_input = HIGH;
else
old_ir_receive_input = LOW;
}

//==============================

void listen_IR(void)
{
if(IR_REC_INPUT_IS_HIGH)
{
// yes, being high
if(old_ir_receive_input == LOW)
{
// it was low last time --> there is a rising edge (LOW to HIGH)
stopTimer();
time_in_low = readTimer(); // read before clearing
clearTimer();
startTimer();

// check if timer measured a good space/separator (between bits).
// a space/separator is defined as 320 microseconds in low state of the receiver's output
if(TIMER_NEVER_GETS_OVERFLOW)
{
if((time_in_low > TIME_OF_SPACE_MIN) && (time_in_low < TIME_OF_SPACE_MAX))
{
// good space (separator)
}
else
{
// bad space (separator)
}
}
}
else
{
// it remains high --> there is no rising edge
// check if CCR1 compare matched --> time out (that means no more bit coming/ or frame ended, the last bit was received is "1")
if(time_out == FALSE)
{
if(timeOut() == TRUE)
{
time_out = TRUE;
stopTimer();
// bit "1" received...

}
}
}

// update the variable for next cycle processing
old_ir_receive_input = HIGH;

}
else
{
// no, being low
if(old_ir_receive_input == HIGH)
{
// it was high last time --> there is a falling edge (HIGH to LOW)
stopTimer();
time_in_high = readTimer(); // read before clearing
clearTimer();
startTimer();

// decode/recognize the bit just received by checking the timer value
if((time_in_high > TIME_OF_BIT0_MIN) && (time_in_high < TIME_OF_BIT0_MAX))
{
// bit "0" received...
data = (data << 1) | RECEIVE_BIT0;

}
else if((time_in_high > TIME_OF_BIT1_MIN) && (time_in_high < TIME_OF_BIT1_MAX))
{
// bit "1" received...
data = (data << 1) | RECEIVE_BIT1;

}
else
{
bitFrame = data;
read_IR_DATA();

}
}
else
{
// it remains low --> there is no falling edge
// check if timer gets overflow --> time out (that means a wrong space/separator)
if(timeOut() == TRUE)
{
stopTimer();
}
}

// update the variable for next cycle processing
old_ir_receive_input = LOW;

}
}

//==============================

void read_IR_DATA(void)
{
switch(bitFrame)
{
case FUNCTION_1:
Function1();
break;

}
}

//==============================

void Function1(void)
{
count1 += 1;
if(count1 == 1)
{
Function1_ON();
}
else if(count1 == 2)
{
count1 = 0;
Function1_OFF();
}
}

//==============================

void Function1_ON(void)
{
LED1_ON;
}

//==============================

void Function1_OFF(void)
{
LED1_OFF;
}

//==============================

void Function2(void)
{
count2 += 1;
if(count2 == 1)
{
Function2_ON();
}
else if(count2 == 2)
{
count2 = 0;
Function2_OFF();
}
}

//==============================

void Function2_ON(void)
{
LED2_ON;
}

//==============================

void Function2_OFF(void)
{
LED2_OFF;
}

//==============================

void startTimer(void)
{
TACCTL1 &= ~CCIFG; // clear the time out flag
TACTL = TASSEL_2 + MC_2; // clock source: SMCLK, mode 2: count up to 0xFFFF
}

//==============================

void stopTimer(void)
{
TACTL = 0;
}

//==============================

void clearTimer(void)
{
TACTL |= TACLR;
}

//==============================

unsigned int readTimer(void)
{
return TAR;
}

//==============================

void configClock(void)
{
//1Mhz
if (CALBC1_1MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
}

//==============================

void configIO(void)
{
IR_REC_IN;
LED1_DIR, LED1_OFF;
LED2_DIR, LED2_OFF;
}

//==============================

void configTimer(void)
{
TACCR1 = CYCLE_FOR_20ms;
}

//==============================

unsigned char timeOut(void)
{
if(CCR1_COMPARE_MATCHED)
return TRUE;
else
return FALSE;
}
User avatar
AnalysIR
Site Admin
Posts: 776
Joined: Sat Aug 31, 2013 3:51 pm
Location: Dublin, Ireland
Contact:

Re: Infrared with msp430

Post by AnalysIR »

Sorry...I am not familiar enough with msp430 to comment or debug your code for you.

However, if you do a google search for msp430 and NEC, you should find some examples as I did.

Also, when posting code online, make sure to use code tags and indent the code to make it readable. What you have posted above is not very readable. (I will try to add tags to your post)

Best of luck.
TuranOlmez
Posts: 10
Joined: Sat Mar 16, 2019 1:10 pm

Re: Infrared with msp430

Post by TuranOlmez »

AnalysIR wrote: Mon Apr 01, 2019 11:28 am Sorry...I am not familiar enough with msp430 to comment or debug your code for you.

However, if you do a google search for msp430 and NEC, you should find some examples as I did.

Also, when posting code online, make sure to use code tags and indent the code to make it readable. What you have posted above is not very readable. (I will try to add tags to your post)

Best of luck.
I couldn't see tags. I'm sorry. I will add tags next time.
Best regards.
TuranOlmez
Posts: 10
Joined: Sat Mar 16, 2019 1:10 pm

Re: Infrared with msp430

Post by TuranOlmez »

Hi again.
I know you said you are not familiar with MSP430 but i'm trying just blink two leds. but i can't. can you just take a look to my codes?
https://stackoverflow.com/questions/558 ... munication
User avatar
AnalysIR
Site Admin
Posts: 776
Joined: Sat Aug 31, 2013 3:51 pm
Location: Dublin, Ireland
Contact:

Re: Infrared with msp430

Post by AnalysIR »

Hi
As you suspect, it would take too much time for me to dive into your code on MSP430.

An important part of learning to code, is to use an effective debugging process, that informs you of where you code is not working as you might expect. I appreciate the platform you are using may not have many 'friendly' features available (compared to Arduino) so you could try to implement it on an Arduino first and then with better understanding of the challenge port the code over to your target platform.

If you tried to use an interrupt in the IR Rx pin and capture timestamps every time the signal changes level (or the interrupt is fired)...it may be a simpler approach for you.

However, I did a quick search on google and found some examples that might be helpful.

Use search strings/terms like
MSP430 RC5 decode
MSP430 RC6 decode
MSP430 NEC decode
MSP430 Infrared decoder

Alternatively, look at our blog post, which might provide some inspiration. (Arduino based)
https://www.analysir.com/blog/2014/03/1 ... s-arduino/
Post Reply