IR Communication Link: Code

Our code consists of a receiver and a transmitter program, each installed on a different A3BU.
LED Emitter Code for the A3BU

#include <asf.h>

#include <util/delay.h>



int main (void)

{

struct pwm_config mypwm[5]; //For your PWM configuration –CKH

sysclk_init();



board_init();



/* Set up a PWM channel with 500 Hz frequency. Here we will output 4 different pulse trains on 4 pins of the A3BU Xplained.*/



pwm_init(&mypwm[0], PWM_TCC0, PWM_CH_A, 500);//this is SDA on J1 on the A3BU Xplained

pwm_init(&mypwm[1], PWM_TCC0, PWM_CH_B, 500);//On A3BU Xplained board, SCL on J1

pwm_init(&mypwm[2], PWM_TCC0, PWM_CH_C, 500);//On A3BU Xplained board, RXD on J1

pwm_init(&mypwm[3], PWM_TCC0, PWM_CH_D, 500);//On A3BU Xplained board, TXD on J1

pwm_init(&mypwm[4], PWM_TCD1, PWM_CH_B, 500); //On A3BU Xplained board, LED onboard



pwm_start(&mypwm[0],50);

pwm_start(&mypwm[1],30);

pwm_start(&mypwm[2],60);

pwm_start(&mypwm[3],80);

pwm_start(&mypwm[4],50);



int i = 0;

int push = 0;

while(1) {

if(gpio_pin_is_low(GPIO_PUSH_BUTTON_0))

{

if(push == 0)

{

pwm_set_duty_cycle_percent(&mypwm[0], 100);

push = 1;

_delay_ms(1000);

}

else{

pwm_set_duty_cycle_percent(&mypwm[0], 0);

push = 0;

_delay_ms(1000);

}

}

}

}

LED Receiver and Display Code for the A3BU

#include <asf.h>

#include <stdio.h>

#include <conf_example.h>

#include <util/delay.h>



//! The latest, computed temperature.

static volatile int16_t last_temperature;

int counter = 0;

char letter[3] = "NNN";

char display = ' ';



static void output(){

if(letter[0] == 'S'){

if(letter[1] == 'S'){

if(letter[2] == 'S'){

display = 'A';

}

else if(letter[2] == 'L'){

display = 'B';

}

}

else if(letter[1] == 'L'){

if(letter[2] == 'S'){

display = 'C';

}

else if(letter[2] == 'L'){

display = 'D';

}

}

}

else if(letter[0] == 'L'){

if(letter[1] == 'S'){

if(letter[2] == 'S'){

display = 'E';

}

else if(letter[2] == 'L'){

display = 'F';

}

}

else if(letter[1] == 'L'){

if(letter[2] == 'S'){

display = 'G';

}

else if(letter[2] == 'L'){

display = 'H';

}

}

}

else{

display = 'N';

}

}



static void adc_handler(ADC_t *adc, uint8_t ch_mask, adc_result_t result)

{

#ifdef CONF_BOARD_OLED_UG_2832HSWEG04

gfx_mono_draw_filled_rect(0,0,128,32,GFX_PIXEL_CLR);

#endif

char out_str[OUTPUT_STR_SIZE];

char out_str2[OUTPUT_STR_SIZE];

char out_str3[OUTPUT_STR_SIZE];

if(result > 1750){

result = 1;

counter++;

_delay_ms(500);

}

else{

result = 0;

if(counter > 0){

if(counter > 1 && counter < 6){

if(letter[0] == 'N'){

letter[0] = 'S';

}

else if(letter[1] == 'N'){

letter[1] = 'S';

}

else if(letter[2] == 'N'){

letter[2] = 'S';

output();

}

else{

letter[0] = 'S';

letter[1] = 'N';

letter[2] = 'N';

}

}

if(counter >= 8){

if(letter[0] == 'N'){

letter[0] = 'L';

}

else if(letter[1] == 'N'){

letter[1] = 'L';

}

else if(letter[2] == 'N'){

letter[2] = 'L';

output();

}

else{

letter[0] = 'L';

letter[1] = 'N';

letter[2] = 'N';

}

}

}

counter = 0;

}



// Write result to display

snprintf(out_str, OUTPUT_STR_SIZE, "Counter: %d   ", counter);

gfx_mono_draw_string(out_str, 0, 0, &sysfont);

snprintf(out_str2, OUTPUT_STR_SIZE, "Array: %s", letter);

gfx_mono_draw_string(out_str2, 0, 10, &sysfont);

snprintf(out_str3, OUTPUT_STR_SIZE, "Char: %c", display);

gfx_mono_draw_string(out_str3, 0, 20, &sysfont);



// Start next conversion.

adc_start_conversion(adc, ch_mask);

}



int main(void)

{

struct adc_config         adc_conf;

struct adc_channel_config adcch_conf;



board_init();

sysclk_init();

sleepmgr_init();

irq_initialize_vectors();

cpu_irq_enable();

gfx_mono_init();



// Enable backlight if display type is not OLED

#ifndef CONF_BOARD_OLED_UG_2832HSWEG04

ioport_set_pin_high(LCD_BACKLIGHT_ENABLE_PIN);

#endif



// Initialize configuration structures.

adc_read_configuration(&ADCB, &adc_conf);

adcch_read_configuration(&ADCB, ADC_CH0, &adcch_conf);



/* Configure the ADC module:

* - unsigned, 12-bit results

* - VCC voltage reference

* - 200 kHz maximum clock rate

* - manual conversion triggering

* - temperature sensor enabled

* - callback function

*/

adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12,

ADC_REF_VCC);

adc_set_clock_rate(&adc_conf, 200000UL);

adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);

adc_enable_internal_input(&adc_conf, ADC_INT_TEMPSENSE);



adc_write_configuration(&ADCB, &adc_conf);

adc_set_callback(&ADCB, &adc_handler);



/* Configure ADC channel 0:

* - single-ended measurement from temperature sensor

* - interrupt flag set on completed conversion

* - interrupts disabled

*/

adcch_set_input(&adcch_conf, ADCCH_POS_PIN1, ADCCH_NEG_NONE,

1);

adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);

adcch_enable_interrupt(&adcch_conf);



adcch_write_configuration(&ADCB, ADC_CH0, &adcch_conf);



// Enable the ADC and start the first conversion.

adc_enable(&ADCB);

adc_start_conversion(&ADCB, ADC_CH0);



do {

// Sleep until ADC interrupt triggers.

sleepmgr_enter_sleep();

} while (1);

}

IR Communication Link: The Big Picture

Idea: Use an infrared (IR) LED signal to send a coded message from one A3BU to another.

Process: We built an emitter that used the A3BU on board button to pulse an infrared LED. Another A3BU with a photoresistor circuit connected to it received the signal and translated it into a letter. For example, three short pulses would be ‘A’.

The video below shows an example of the project.