Crosswalk Simulator/Stoplight Code Snippet

You can see the commented code we used below:



/**
 * \file
 *
 * \brief Empty user application template
 *
 */

/**
 * \mainpage User Application template doxygen documentation
 *
 * \par Empty user application template
 *
 * Bare minimum empty user application template
 *
 * \par Content
 *
 * -# Include the ASF header files (through asf.h)
 * -# "Insert system clock initialization code here" comment
 * -# Minimal main function that starts with a call to board_init()
 * -# "Insert application code here" comment
 *
 */

/*
 * Include header files for all drivers that have been imported from
 * Atmel Software Framework (ASF).
 */
/*
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 */
#include <asf.h>
#include <delay.h>
#include <avr/io.h>
#include <stdio.h>
#include <conf_example.h>

int adc_result;
//Function to get the result from the ADC pin and save it to the above global variable
static void adc_handler(ADC_t *adc, uint8_t ch_mask, adc_result_t result)
{ 
 adc_result = 0;
 #ifdef CONF_BOARD_OLED_UG_2832HSWEG04
 gfx_mono_draw_filled_rect(0,0,128,32,GFX_PIXEL_CLR);
 #endif

 adc_result = (uint8_t)result;
}

//this function checks if a "pedestrian" is at the intersection
//if the result from the ADC pin is between 100 and 200, then return true
//otherwise return false
bool checkForPedestrian(ADC_t *adc, uint8_t ch_mask)
{
 adc_start_conversion(adc, ch_mask);
 if(adc_result > 100 && adc_result < 200)
 return true;
 else
 return false;
}

//draw a walk sign using ASCII characters on the screen
void drawWalkSign()
{
 gfx_mono_draw_string(" O", 10, 10, &sysfont);
 gfx_mono_draw_string(" v|\\", 10, 17, &sysfont);
 gfx_mono_draw_string(" / \\", 10, 25, &sysfont);
}

//draw a don't walk hand on the screen using ASCII characters
void drawHand()
{
 gfx_mono_draw_string("^^^^", 30, 0, &sysfont);
 gfx_mono_draw_string("|||||^", 28, 7, &sysfont);
 gfx_mono_draw_string("||||| |", 28, 14, &sysfont);
 gfx_mono_draw_string("\\____/", 30, 23, &sysfont);
}

//draw a timer bar on the screen and also make the speaker beep
void drawBar(struct pwm_config buzzer)
{
 int count = 0;
 int count_2 = 0;
 //this will delay the whole process by 14 seconds
 while(count < 140)
 {
 //draw a rectangle that grows across the screen
 gfx_mono_draw_rect(0, 0, count, 6, GFX_PIXEL_SET);
 count += 10;
 count_2++;
 //turn the speaker on
 pwm_start(&buzzer,100);
 //wait for a second
 delay_ms(1000);
 //turn the speaker off
 pwm_start(&buzzer, 50);
 }
 //turn the speaker completely off
 pwm_start(&buzzer, 0);
 //reset the ADC result
 adc_result = 0;
}

int main (void)
{ 
 //initialize everything
 board_init();
 sysclk_init();
 gfx_mono_init();
 ioport_set_pin_high(LCD_BACKLIGHT_ENABLE_PIN);
 
 //PWM configs for the various LEDs
 struct pwm_config green;
 struct pwm_config red;
 struct pwm_config yellow;
 struct pwm_config walk;

 struct pwm_config green_2;
 struct pwm_config red_2;
 struct pwm_config yellow_2;
 struct pwm_config buzzer;
 
 /* 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(&red, PWM_TCC0, PWM_CH_A, 500); //this is SDA on J1 on the A3BU Xplained 
 pwm_init(&green, PWM_TCC0, PWM_CH_B, 500); //On A3BU Xplained board, SCL on J1 
 pwm_init(&yellow, PWM_TCC0, PWM_CH_C, 500);//On A3BU Xplained board, RXD on J1 
 pwm_init(&walk, PWM_TCC0, PWM_CH_D, 500); //On A3BU Xplained board, TXD on J1
 
 pwm_init(&red_2, PWM_TCE0, PWM_CH_A, 500); //this is SDA on J1 on the A3BU Xplained 
 pwm_init(&green_2, PWM_TCE0, PWM_CH_B, 500); //On A3BU Xplained board, SCL on J1 
 pwm_init(&yellow_2, PWM_TCE0, PWM_CH_C, 500);//On A3BU Xplained board, RXD on J1 
 pwm_init(&buzzer, PWM_TCE0, PWM_CH_D, 2000); //On A3BU Xplained board, TXD on J1
 
 // Set each of the 4 PWM channel duty cycles independently, and start them going 
 pwm_start(&red,100);
 pwm_start(&green,100);
 pwm_start(&yellow,100); 
 pwm_start(&walk,100);
 
 pwm_start(&red_2,100);
 pwm_start(&green_2,100);
 pwm_start(&yellow_2,100); 
 pwm_start(&buzzer,0);
 
 /*************************/
 //ADC initialization steps
 /*************************/
 struct adc_config adc_conf;
 struct adc_channel_config adcch_conf;

 sleepmgr_init();
 irq_initialize_vectors();
 cpu_irq_enable();

 // 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
 adc_enable(&ADCB);
 
 //ON and OFF duty cycle values
 int ON = 100;
 int OFF = 0;
 //bool to check for pedestrians in the intersection
 bool pedestrian = false;
 //loop forever
 while(1) {
 //as long as there is no pedestrian at the intersection
 //leave the green and red_2 LEDs on, and the rest off
 while(!pedestrian)
 {
 pwm_start(&red,OFF);
 pwm_start(&green,ON);
 pwm_start(&yellow,OFF);
 
 pwm_start(&red_2,ON);
 pwm_start(&green_2,OFF);
 pwm_start(&yellow_2,OFF);
 
 //check the ADC pin to see if a pedestrian is at the intersection
 pedestrian = checkForPedestrian(&ADCB, ADC_CH0);
 }
 
 /***a pedestrian has pressed the button, now transition***/
 //reset pedestrian value
 pedestrian = false;
 //wait for a half second
 delay_ms(500);
 //turn green off and turn yellow on
 pwm_start(&green,OFF);
 pwm_start(&yellow,ON);
 //wait for 3 seconds
 delay_ms(3000);
 
 //turn yellow off and turn red on
 pwm_start(&yellow,OFF);
 pwm_start(&red,ON);
 //wait for 2 seconds
 delay_ms(2000);
 
 //turn red_2 off and turn green_2 on
 pwm_start(&green_2,ON);
 pwm_start(&red_2,OFF);
 //clear the LCD screen
 gfx_mono_init();
 //draw the walk signs and the timer bar, and start the speaker
 drawWalkSign();
 drawBar(buzzer);
 //clear the LCD screen
 gfx_mono_init();
 //draw the Don't Walk hand
 drawHand();
 //wait for 5 seconds to prevent a pedestrian from immediately pushing the button again
 delay_ms(5000);
 
 //as long as there is no pedestrian at the intersection
 //leave the green_2 and red LEDs on, and the rest off
 while(!pedestrian)
 {
 pwm_start(&red_2,OFF);
 pwm_start(&green_2,ON);
 pwm_start(&yellow_2,OFF);
 
 pwm_start(&red,ON);
 pwm_start(&green,OFF);
 pwm_start(&yellow,OFF);
 
 //check the ADC pin to see if a pedestrian is at the intersection
 pedestrian = checkForPedestrian(&ADCB, ADC_CH0);
 }
 
 /***a pedestrian has pressed the button, now transition***/
 //reset pedestrian value
 pedestrian = false;
 //wait for a half second
 delay_ms(500);
 //turn green_2 off and turn yellow_2 on
 pwm_start(&green_2,OFF);
 pwm_start(&yellow_2,ON);
 //wait for 3 seconds
 delay_ms(3000);
 
 //turn yellow_2 off and turn red_2 on
 pwm_start(&yellow_2,OFF);
 pwm_start(&red_2,ON);
 //wait for 2 seconds
 delay_ms(2000);
 //turn red off and turn green on
 pwm_start(&green,ON);
 pwm_start(&red,OFF);
 //clear the LCD screen
 gfx_mono_init();
 //draw the walk signs and the timer bar, and start the speaker
 drawWalkSign();
 drawBar(buzzer);
 //clear the LCD screen
 gfx_mono_init();
 //draw the Don't Walk hand
 drawHand();
 //wait for 5 seconds to prevent a pedestrian from immediately pushing the button again
 delay_ms(5000);
 
 /***Repeat the whole process again***/
 }
}

C Code created in Atmel Studio 7 that dictates the actions of our LCD and circuit