Example code for the Programmable High-Power Infra-Red Beacon with display Designed for use with the E-Puck and Pi Swarm robots for swarm research A number of preset frequencies (1, 2, 5, 10, 20, 30, 40 and 50Hz), powers (25%, 50%, 75% and 100%), duty-cycles (10%, 25%, 50%, 75% and 90%) are defined, and the chosen mode can be selected by holding the 'SET' button for 1 seconds, then moving through to the correct menu. Use as a basic structure should other functionality be required from the beacon, such as custom flash sequencies or alternating between the wide- and narrow- LEDs.

Dependencies:   mbed

PCB Image: [NB Missing connection from pin 1-4 of display] /media/uploads/jah128/board_fin2.png

Eagle Files: /media/uploads/jah128/irledboard_pro.sch /media/uploads/jah128/irledboard_pro.brd

Corel Draw file for laser-cutting box: /media/uploads/jah128/irbox_3.cdr

main.cpp

Committer:
jah128
Date:
2014-03-19
Revision:
0:d88fd55a27a6

File content as of revision 0:d88fd55a27a6:

/* University of York Robot Lab
 *
 * Programmable IR Beacon with Display Example Code
 *
 * This file is intended for use exclusively with the high-power IR Beacon with display
 * 
 * 
 *
 * (C) Dr James Hilder, Dept. Electronics & Computer Science, University of York
 *
 * March 2014
 *
 */

#include "mbed.h"
#include "display.h"        //Display driver for the Midas 16x2 I2C Display

DigitalIn button1(p23);     //"SET" Push-button
DigitalIn button2(p24);     //"SELECT" Push-button
PwmOut out_narrow(p21);     //PWM Output for the narrow (high intensity) LED driver
PwmOut out_wide(p22);       //PWM Output for the wide-angle LED driver

Display display;
Timer system_timer;         //System timer is used for timer the on-off periods for the LEDs
Timer button_timer;         //Button timer is used for debouncing the push buttons and pausing for entering 'SET' mode

char adjust = 0;
char mode = 0;
char power = 1;
char duty = 2;
char frequency = 2;

int on_period;
int off_period;
int total_period;
char phase;

int get_period()
{
    switch(frequency) {
        case 0:
            return 1000000;
        case 1:
            return 500000;
        case 2:
            return 200000;
        case 3:
            return 100000;
        case 4:
            return 50000;
        case 5:
            return 33333;
        case 6:
            return 25000;
        case 7:
            return 20000;
    }
    return 0;
}

void update_cycles()
{
    total_period = get_period();
    switch(duty){
        case 0: on_period=total_period/10;break;
        case 1: on_period=total_period/4;break;
        case 2: on_period=total_period/2;break;
        case 3: on_period=(total_period*3)/4;break;
        case 4: on_period=total_period-(total_period/10);break;    
    }
    off_period = total_period - on_period;
    phase = 0;
    system_timer.reset();
}

void init()
{
    display.init_display();
    display.set_position(0,2);
    display.write_string("YORK ROBOTICS",13);
    display.set_position(1,3);
    display.write_string("LABORATORY",10);
    wait(0.45);
    display.clear_display();
    display.set_position(0,2);
    display.write_string("Programmable",12);
    display.set_position(1,3);
    display.write_string("IR Beacon",9);
    wait(0.45);
}

char * mode_string()
{
    switch(mode) {
        case 1:
            return "WIDE  ";
        case 2:
            return "NARROW";
    }
    return "BOTH  ";
}

char * duty_string()
{
    switch(duty) {
        case 0:
            return " 10%";
        case 1:
            return " 25%";
        case 2:
            return " 50%";
        case 3:
            return " 75%";
        case 4:
            return " 90%";
    }
    return"???";
}

char * power_string()
{
    switch(power) {
        case 0:
            return " 25%";
        case 1:
            return " 50%";
        case 2:
            return " 75%";
        case 3:
            return "100%";
    }
    return"????";
}

char * freq_string()
{
    switch(frequency) {
        case 0:
            return " 1Hz";
        case 1:
            return " 2Hz";
        case 2:
            return " 5Hz";
        case 3:
            return "10Hz";
        case 4:
            return "20Hz";
        case 5:
            return "30Hz";
        case 6:
            return "40Hz";
        case 7:
            return "50Hz";
    }
    return "????";
}

// The normal mode display output: shows the frequency, power, duty-cycle and output mode (ie wide, narrow or both)
void display_status()
{
    display.clear_display();
    display.set_position(0,0);
    char line1[15] ;
    strcpy(line1, "F:");
    strcat(line1, freq_string());
    strcat(line1, " P:");
    strcat(line1, power_string());
    display.write_string(line1,13);
    char line2[17];
    strcpy(line2, "D:");
    strcat(line2, duty_string());
    strcat(line2, " M:");
    strcat(line2, mode_string());
    display.set_position(1,0);
    display.write_string(line2,16);
}

// The configuration mode; entered by holding the 'set' button for one second.  In this mode the user can through the options
// by pressing 'set' and change a setting by pressing 'select'.  The final screen in the loop allows the user to return to
// normal operation, this will also happen with no user input for 5 seconds.
void change_settings()
{
    //Switch off LEDs whilst in configuration mode 
    out_wide.pulsewidth_us(0);
    out_narrow.pulsewidth_us(0);
    display.clear_display();
    display.set_position(0,0);
    display.write_string("CONFIGURATION",13);
    display.set_position(1,0);
    display.write_string("MODE",4);
    while(button1 == 1);
    char screen = 0;
    char active = 1;
    Timer settings_timer;
    settings_timer.start();
    while(active) {
        display.clear_display();
        display.set_position(0,0);
        char line2[17];
        switch(screen) {
            case 0:
                display.write_string("Set Frequency:",14);
                display.set_position(1,0);
                strcpy(line2,freq_string());
                display.write_string(line2,4);
                break;
            case 1:
                display.write_string("Set Power:    ",14);
                display.set_position(1,0);
                strcpy(line2,power_string());
                display.write_string(line2,4);
                break;
            case 2:
                display.write_string("Set Duty Cycle:",15);
                display.set_position(1,0);
                strcpy(line2,duty_string());
                display.write_string(line2,4);
                break;
            case 3:
                display.write_string("Set Mode:     ",14);
                display.set_position(1,0);
                strcpy(line2,mode_string());
                display.write_string(line2,6);
                break;
            case 4:
                display.write_string("End Setup",9);
                break;
        }
        char button_pressed = 0;
        
        while(button_pressed < 2 && settings_timer.read_ms() < 5000){
            if(button1 == 1 || button2 == 1){
                if(button_pressed == 1){
                    if(button_timer.read_ms() > 50) button_pressed = 2;
                } else {button_pressed = 1; button_timer.reset();}
            }  else button_pressed = 0;
        }
        if(button1==1){
            screen++;
            if(screen == 5)screen=0;
            while(button1 == 1);
        }else{
          if(button2==1){
            switch(screen){
               case 0: frequency ++;
                       if(frequency == 8) frequency = 0;
                       break;
               case 1: power++;
                       if(power == 4) power=0;
                       break;
               case 2: duty++;
                       if(duty == 5) duty=0;
                       break;
               case 3: mode++;
                       if(mode == 3) mode = 0;
                       break;
               case 4: active=0; break;
            }
            while(button2 == 1);   
          }   
        }
        if(settings_timer > 5000) active=0;
        settings_timer.reset();
    }
}

int main()
{
    init();
    display_status();
    char b_p = 0;
    system_timer.start();
    button_timer.start();
    update_cycles();
    out_narrow.period_us(1000);
    out_wide.period_us(1000);
    out_narrow.pulsewidth_us(0);
    out_wide.pulsewidth_us(0);


    while(1) {
        if(phase==0){
          if(system_timer.read_us() > off_period){
            system_timer.reset();
            int pw = 250;
            if(power==1) pw=500;
            if(power==2) pw=750;
            if(power==3) pw=1000;
            if(mode<2){
                out_wide.pulsewidth_us(pw);
            } 
            if(mode!=1){
                out_narrow.pulsewidth_us(pw);
            }
            phase = 1;
          }
        }else{
          if(system_timer.read_us() > on_period){
            system_timer.reset();
            phase = 0;
            out_wide.pulsewidth_us(0);
            out_narrow.pulsewidth_us(0);
          }   
        }
        
        
        if(button1 == 1) {
            if(b_p == 0) {
                b_p=1;
                button_timer.reset();
            }
            if(b_p == 1) {
                if(button_timer.read_ms() > 100) {
                    b_p=2;
                    display.clear_display();
                    display.set_position(0,0);
                    display.write_string("Hold to change",14);
                    display.set_position(1,0);
                    display.write_string("settings",8);
                }
            }
            if(b_p == 2) {
                if(button_timer.read_ms() > 1000) {
                    change_settings();
                    update_cycles();
                    display_status();
                    b_p=0;
                }
            }
        } else {
            if (b_p > 0) {
                if(b_p == 2) display_status();
                b_p=0;
            }
        }
    }
}