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

Committer:
jah128
Date:
Wed Mar 19 15:09:11 2014 +0000
Revision:
0:d88fd55a27a6
Initial Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jah128 0:d88fd55a27a6 1 /* University of York Robot Lab
jah128 0:d88fd55a27a6 2 *
jah128 0:d88fd55a27a6 3 * Programmable IR Beacon with Display Example Code
jah128 0:d88fd55a27a6 4 *
jah128 0:d88fd55a27a6 5 * This file is intended for use exclusively with the high-power IR Beacon with display
jah128 0:d88fd55a27a6 6 *
jah128 0:d88fd55a27a6 7 *
jah128 0:d88fd55a27a6 8 *
jah128 0:d88fd55a27a6 9 * (C) Dr James Hilder, Dept. Electronics & Computer Science, University of York
jah128 0:d88fd55a27a6 10 *
jah128 0:d88fd55a27a6 11 * March 2014
jah128 0:d88fd55a27a6 12 *
jah128 0:d88fd55a27a6 13 */
jah128 0:d88fd55a27a6 14
jah128 0:d88fd55a27a6 15 #include "mbed.h"
jah128 0:d88fd55a27a6 16 #include "display.h" //Display driver for the Midas 16x2 I2C Display
jah128 0:d88fd55a27a6 17
jah128 0:d88fd55a27a6 18 DigitalIn button1(p23); //"SET" Push-button
jah128 0:d88fd55a27a6 19 DigitalIn button2(p24); //"SELECT" Push-button
jah128 0:d88fd55a27a6 20 PwmOut out_narrow(p21); //PWM Output for the narrow (high intensity) LED driver
jah128 0:d88fd55a27a6 21 PwmOut out_wide(p22); //PWM Output for the wide-angle LED driver
jah128 0:d88fd55a27a6 22
jah128 0:d88fd55a27a6 23 Display display;
jah128 0:d88fd55a27a6 24 Timer system_timer; //System timer is used for timer the on-off periods for the LEDs
jah128 0:d88fd55a27a6 25 Timer button_timer; //Button timer is used for debouncing the push buttons and pausing for entering 'SET' mode
jah128 0:d88fd55a27a6 26
jah128 0:d88fd55a27a6 27 char adjust = 0;
jah128 0:d88fd55a27a6 28 char mode = 0;
jah128 0:d88fd55a27a6 29 char power = 1;
jah128 0:d88fd55a27a6 30 char duty = 2;
jah128 0:d88fd55a27a6 31 char frequency = 2;
jah128 0:d88fd55a27a6 32
jah128 0:d88fd55a27a6 33 int on_period;
jah128 0:d88fd55a27a6 34 int off_period;
jah128 0:d88fd55a27a6 35 int total_period;
jah128 0:d88fd55a27a6 36 char phase;
jah128 0:d88fd55a27a6 37
jah128 0:d88fd55a27a6 38 int get_period()
jah128 0:d88fd55a27a6 39 {
jah128 0:d88fd55a27a6 40 switch(frequency) {
jah128 0:d88fd55a27a6 41 case 0:
jah128 0:d88fd55a27a6 42 return 1000000;
jah128 0:d88fd55a27a6 43 case 1:
jah128 0:d88fd55a27a6 44 return 500000;
jah128 0:d88fd55a27a6 45 case 2:
jah128 0:d88fd55a27a6 46 return 200000;
jah128 0:d88fd55a27a6 47 case 3:
jah128 0:d88fd55a27a6 48 return 100000;
jah128 0:d88fd55a27a6 49 case 4:
jah128 0:d88fd55a27a6 50 return 50000;
jah128 0:d88fd55a27a6 51 case 5:
jah128 0:d88fd55a27a6 52 return 33333;
jah128 0:d88fd55a27a6 53 case 6:
jah128 0:d88fd55a27a6 54 return 25000;
jah128 0:d88fd55a27a6 55 case 7:
jah128 0:d88fd55a27a6 56 return 20000;
jah128 0:d88fd55a27a6 57 }
jah128 0:d88fd55a27a6 58 return 0;
jah128 0:d88fd55a27a6 59 }
jah128 0:d88fd55a27a6 60
jah128 0:d88fd55a27a6 61 void update_cycles()
jah128 0:d88fd55a27a6 62 {
jah128 0:d88fd55a27a6 63 total_period = get_period();
jah128 0:d88fd55a27a6 64 switch(duty){
jah128 0:d88fd55a27a6 65 case 0: on_period=total_period/10;break;
jah128 0:d88fd55a27a6 66 case 1: on_period=total_period/4;break;
jah128 0:d88fd55a27a6 67 case 2: on_period=total_period/2;break;
jah128 0:d88fd55a27a6 68 case 3: on_period=(total_period*3)/4;break;
jah128 0:d88fd55a27a6 69 case 4: on_period=total_period-(total_period/10);break;
jah128 0:d88fd55a27a6 70 }
jah128 0:d88fd55a27a6 71 off_period = total_period - on_period;
jah128 0:d88fd55a27a6 72 phase = 0;
jah128 0:d88fd55a27a6 73 system_timer.reset();
jah128 0:d88fd55a27a6 74 }
jah128 0:d88fd55a27a6 75
jah128 0:d88fd55a27a6 76 void init()
jah128 0:d88fd55a27a6 77 {
jah128 0:d88fd55a27a6 78 display.init_display();
jah128 0:d88fd55a27a6 79 display.set_position(0,2);
jah128 0:d88fd55a27a6 80 display.write_string("YORK ROBOTICS",13);
jah128 0:d88fd55a27a6 81 display.set_position(1,3);
jah128 0:d88fd55a27a6 82 display.write_string("LABORATORY",10);
jah128 0:d88fd55a27a6 83 wait(0.45);
jah128 0:d88fd55a27a6 84 display.clear_display();
jah128 0:d88fd55a27a6 85 display.set_position(0,2);
jah128 0:d88fd55a27a6 86 display.write_string("Programmable",12);
jah128 0:d88fd55a27a6 87 display.set_position(1,3);
jah128 0:d88fd55a27a6 88 display.write_string("IR Beacon",9);
jah128 0:d88fd55a27a6 89 wait(0.45);
jah128 0:d88fd55a27a6 90 }
jah128 0:d88fd55a27a6 91
jah128 0:d88fd55a27a6 92 char * mode_string()
jah128 0:d88fd55a27a6 93 {
jah128 0:d88fd55a27a6 94 switch(mode) {
jah128 0:d88fd55a27a6 95 case 1:
jah128 0:d88fd55a27a6 96 return "WIDE ";
jah128 0:d88fd55a27a6 97 case 2:
jah128 0:d88fd55a27a6 98 return "NARROW";
jah128 0:d88fd55a27a6 99 }
jah128 0:d88fd55a27a6 100 return "BOTH ";
jah128 0:d88fd55a27a6 101 }
jah128 0:d88fd55a27a6 102
jah128 0:d88fd55a27a6 103 char * duty_string()
jah128 0:d88fd55a27a6 104 {
jah128 0:d88fd55a27a6 105 switch(duty) {
jah128 0:d88fd55a27a6 106 case 0:
jah128 0:d88fd55a27a6 107 return " 10%";
jah128 0:d88fd55a27a6 108 case 1:
jah128 0:d88fd55a27a6 109 return " 25%";
jah128 0:d88fd55a27a6 110 case 2:
jah128 0:d88fd55a27a6 111 return " 50%";
jah128 0:d88fd55a27a6 112 case 3:
jah128 0:d88fd55a27a6 113 return " 75%";
jah128 0:d88fd55a27a6 114 case 4:
jah128 0:d88fd55a27a6 115 return " 90%";
jah128 0:d88fd55a27a6 116 }
jah128 0:d88fd55a27a6 117 return"???";
jah128 0:d88fd55a27a6 118 }
jah128 0:d88fd55a27a6 119
jah128 0:d88fd55a27a6 120 char * power_string()
jah128 0:d88fd55a27a6 121 {
jah128 0:d88fd55a27a6 122 switch(power) {
jah128 0:d88fd55a27a6 123 case 0:
jah128 0:d88fd55a27a6 124 return " 25%";
jah128 0:d88fd55a27a6 125 case 1:
jah128 0:d88fd55a27a6 126 return " 50%";
jah128 0:d88fd55a27a6 127 case 2:
jah128 0:d88fd55a27a6 128 return " 75%";
jah128 0:d88fd55a27a6 129 case 3:
jah128 0:d88fd55a27a6 130 return "100%";
jah128 0:d88fd55a27a6 131 }
jah128 0:d88fd55a27a6 132 return"????";
jah128 0:d88fd55a27a6 133 }
jah128 0:d88fd55a27a6 134
jah128 0:d88fd55a27a6 135 char * freq_string()
jah128 0:d88fd55a27a6 136 {
jah128 0:d88fd55a27a6 137 switch(frequency) {
jah128 0:d88fd55a27a6 138 case 0:
jah128 0:d88fd55a27a6 139 return " 1Hz";
jah128 0:d88fd55a27a6 140 case 1:
jah128 0:d88fd55a27a6 141 return " 2Hz";
jah128 0:d88fd55a27a6 142 case 2:
jah128 0:d88fd55a27a6 143 return " 5Hz";
jah128 0:d88fd55a27a6 144 case 3:
jah128 0:d88fd55a27a6 145 return "10Hz";
jah128 0:d88fd55a27a6 146 case 4:
jah128 0:d88fd55a27a6 147 return "20Hz";
jah128 0:d88fd55a27a6 148 case 5:
jah128 0:d88fd55a27a6 149 return "30Hz";
jah128 0:d88fd55a27a6 150 case 6:
jah128 0:d88fd55a27a6 151 return "40Hz";
jah128 0:d88fd55a27a6 152 case 7:
jah128 0:d88fd55a27a6 153 return "50Hz";
jah128 0:d88fd55a27a6 154 }
jah128 0:d88fd55a27a6 155 return "????";
jah128 0:d88fd55a27a6 156 }
jah128 0:d88fd55a27a6 157
jah128 0:d88fd55a27a6 158 // The normal mode display output: shows the frequency, power, duty-cycle and output mode (ie wide, narrow or both)
jah128 0:d88fd55a27a6 159 void display_status()
jah128 0:d88fd55a27a6 160 {
jah128 0:d88fd55a27a6 161 display.clear_display();
jah128 0:d88fd55a27a6 162 display.set_position(0,0);
jah128 0:d88fd55a27a6 163 char line1[15] ;
jah128 0:d88fd55a27a6 164 strcpy(line1, "F:");
jah128 0:d88fd55a27a6 165 strcat(line1, freq_string());
jah128 0:d88fd55a27a6 166 strcat(line1, " P:");
jah128 0:d88fd55a27a6 167 strcat(line1, power_string());
jah128 0:d88fd55a27a6 168 display.write_string(line1,13);
jah128 0:d88fd55a27a6 169 char line2[17];
jah128 0:d88fd55a27a6 170 strcpy(line2, "D:");
jah128 0:d88fd55a27a6 171 strcat(line2, duty_string());
jah128 0:d88fd55a27a6 172 strcat(line2, " M:");
jah128 0:d88fd55a27a6 173 strcat(line2, mode_string());
jah128 0:d88fd55a27a6 174 display.set_position(1,0);
jah128 0:d88fd55a27a6 175 display.write_string(line2,16);
jah128 0:d88fd55a27a6 176 }
jah128 0:d88fd55a27a6 177
jah128 0:d88fd55a27a6 178 // The configuration mode; entered by holding the 'set' button for one second. In this mode the user can through the options
jah128 0:d88fd55a27a6 179 // by pressing 'set' and change a setting by pressing 'select'. The final screen in the loop allows the user to return to
jah128 0:d88fd55a27a6 180 // normal operation, this will also happen with no user input for 5 seconds.
jah128 0:d88fd55a27a6 181 void change_settings()
jah128 0:d88fd55a27a6 182 {
jah128 0:d88fd55a27a6 183 //Switch off LEDs whilst in configuration mode
jah128 0:d88fd55a27a6 184 out_wide.pulsewidth_us(0);
jah128 0:d88fd55a27a6 185 out_narrow.pulsewidth_us(0);
jah128 0:d88fd55a27a6 186 display.clear_display();
jah128 0:d88fd55a27a6 187 display.set_position(0,0);
jah128 0:d88fd55a27a6 188 display.write_string("CONFIGURATION",13);
jah128 0:d88fd55a27a6 189 display.set_position(1,0);
jah128 0:d88fd55a27a6 190 display.write_string("MODE",4);
jah128 0:d88fd55a27a6 191 while(button1 == 1);
jah128 0:d88fd55a27a6 192 char screen = 0;
jah128 0:d88fd55a27a6 193 char active = 1;
jah128 0:d88fd55a27a6 194 Timer settings_timer;
jah128 0:d88fd55a27a6 195 settings_timer.start();
jah128 0:d88fd55a27a6 196 while(active) {
jah128 0:d88fd55a27a6 197 display.clear_display();
jah128 0:d88fd55a27a6 198 display.set_position(0,0);
jah128 0:d88fd55a27a6 199 char line2[17];
jah128 0:d88fd55a27a6 200 switch(screen) {
jah128 0:d88fd55a27a6 201 case 0:
jah128 0:d88fd55a27a6 202 display.write_string("Set Frequency:",14);
jah128 0:d88fd55a27a6 203 display.set_position(1,0);
jah128 0:d88fd55a27a6 204 strcpy(line2,freq_string());
jah128 0:d88fd55a27a6 205 display.write_string(line2,4);
jah128 0:d88fd55a27a6 206 break;
jah128 0:d88fd55a27a6 207 case 1:
jah128 0:d88fd55a27a6 208 display.write_string("Set Power: ",14);
jah128 0:d88fd55a27a6 209 display.set_position(1,0);
jah128 0:d88fd55a27a6 210 strcpy(line2,power_string());
jah128 0:d88fd55a27a6 211 display.write_string(line2,4);
jah128 0:d88fd55a27a6 212 break;
jah128 0:d88fd55a27a6 213 case 2:
jah128 0:d88fd55a27a6 214 display.write_string("Set Duty Cycle:",15);
jah128 0:d88fd55a27a6 215 display.set_position(1,0);
jah128 0:d88fd55a27a6 216 strcpy(line2,duty_string());
jah128 0:d88fd55a27a6 217 display.write_string(line2,4);
jah128 0:d88fd55a27a6 218 break;
jah128 0:d88fd55a27a6 219 case 3:
jah128 0:d88fd55a27a6 220 display.write_string("Set Mode: ",14);
jah128 0:d88fd55a27a6 221 display.set_position(1,0);
jah128 0:d88fd55a27a6 222 strcpy(line2,mode_string());
jah128 0:d88fd55a27a6 223 display.write_string(line2,6);
jah128 0:d88fd55a27a6 224 break;
jah128 0:d88fd55a27a6 225 case 4:
jah128 0:d88fd55a27a6 226 display.write_string("End Setup",9);
jah128 0:d88fd55a27a6 227 break;
jah128 0:d88fd55a27a6 228 }
jah128 0:d88fd55a27a6 229 char button_pressed = 0;
jah128 0:d88fd55a27a6 230
jah128 0:d88fd55a27a6 231 while(button_pressed < 2 && settings_timer.read_ms() < 5000){
jah128 0:d88fd55a27a6 232 if(button1 == 1 || button2 == 1){
jah128 0:d88fd55a27a6 233 if(button_pressed == 1){
jah128 0:d88fd55a27a6 234 if(button_timer.read_ms() > 50) button_pressed = 2;
jah128 0:d88fd55a27a6 235 } else {button_pressed = 1; button_timer.reset();}
jah128 0:d88fd55a27a6 236 } else button_pressed = 0;
jah128 0:d88fd55a27a6 237 }
jah128 0:d88fd55a27a6 238 if(button1==1){
jah128 0:d88fd55a27a6 239 screen++;
jah128 0:d88fd55a27a6 240 if(screen == 5)screen=0;
jah128 0:d88fd55a27a6 241 while(button1 == 1);
jah128 0:d88fd55a27a6 242 }else{
jah128 0:d88fd55a27a6 243 if(button2==1){
jah128 0:d88fd55a27a6 244 switch(screen){
jah128 0:d88fd55a27a6 245 case 0: frequency ++;
jah128 0:d88fd55a27a6 246 if(frequency == 8) frequency = 0;
jah128 0:d88fd55a27a6 247 break;
jah128 0:d88fd55a27a6 248 case 1: power++;
jah128 0:d88fd55a27a6 249 if(power == 4) power=0;
jah128 0:d88fd55a27a6 250 break;
jah128 0:d88fd55a27a6 251 case 2: duty++;
jah128 0:d88fd55a27a6 252 if(duty == 5) duty=0;
jah128 0:d88fd55a27a6 253 break;
jah128 0:d88fd55a27a6 254 case 3: mode++;
jah128 0:d88fd55a27a6 255 if(mode == 3) mode = 0;
jah128 0:d88fd55a27a6 256 break;
jah128 0:d88fd55a27a6 257 case 4: active=0; break;
jah128 0:d88fd55a27a6 258 }
jah128 0:d88fd55a27a6 259 while(button2 == 1);
jah128 0:d88fd55a27a6 260 }
jah128 0:d88fd55a27a6 261 }
jah128 0:d88fd55a27a6 262 if(settings_timer > 5000) active=0;
jah128 0:d88fd55a27a6 263 settings_timer.reset();
jah128 0:d88fd55a27a6 264 }
jah128 0:d88fd55a27a6 265 }
jah128 0:d88fd55a27a6 266
jah128 0:d88fd55a27a6 267 int main()
jah128 0:d88fd55a27a6 268 {
jah128 0:d88fd55a27a6 269 init();
jah128 0:d88fd55a27a6 270 display_status();
jah128 0:d88fd55a27a6 271 char b_p = 0;
jah128 0:d88fd55a27a6 272 system_timer.start();
jah128 0:d88fd55a27a6 273 button_timer.start();
jah128 0:d88fd55a27a6 274 update_cycles();
jah128 0:d88fd55a27a6 275 out_narrow.period_us(1000);
jah128 0:d88fd55a27a6 276 out_wide.period_us(1000);
jah128 0:d88fd55a27a6 277 out_narrow.pulsewidth_us(0);
jah128 0:d88fd55a27a6 278 out_wide.pulsewidth_us(0);
jah128 0:d88fd55a27a6 279
jah128 0:d88fd55a27a6 280
jah128 0:d88fd55a27a6 281 while(1) {
jah128 0:d88fd55a27a6 282 if(phase==0){
jah128 0:d88fd55a27a6 283 if(system_timer.read_us() > off_period){
jah128 0:d88fd55a27a6 284 system_timer.reset();
jah128 0:d88fd55a27a6 285 int pw = 250;
jah128 0:d88fd55a27a6 286 if(power==1) pw=500;
jah128 0:d88fd55a27a6 287 if(power==2) pw=750;
jah128 0:d88fd55a27a6 288 if(power==3) pw=1000;
jah128 0:d88fd55a27a6 289 if(mode<2){
jah128 0:d88fd55a27a6 290 out_wide.pulsewidth_us(pw);
jah128 0:d88fd55a27a6 291 }
jah128 0:d88fd55a27a6 292 if(mode!=1){
jah128 0:d88fd55a27a6 293 out_narrow.pulsewidth_us(pw);
jah128 0:d88fd55a27a6 294 }
jah128 0:d88fd55a27a6 295 phase = 1;
jah128 0:d88fd55a27a6 296 }
jah128 0:d88fd55a27a6 297 }else{
jah128 0:d88fd55a27a6 298 if(system_timer.read_us() > on_period){
jah128 0:d88fd55a27a6 299 system_timer.reset();
jah128 0:d88fd55a27a6 300 phase = 0;
jah128 0:d88fd55a27a6 301 out_wide.pulsewidth_us(0);
jah128 0:d88fd55a27a6 302 out_narrow.pulsewidth_us(0);
jah128 0:d88fd55a27a6 303 }
jah128 0:d88fd55a27a6 304 }
jah128 0:d88fd55a27a6 305
jah128 0:d88fd55a27a6 306
jah128 0:d88fd55a27a6 307 if(button1 == 1) {
jah128 0:d88fd55a27a6 308 if(b_p == 0) {
jah128 0:d88fd55a27a6 309 b_p=1;
jah128 0:d88fd55a27a6 310 button_timer.reset();
jah128 0:d88fd55a27a6 311 }
jah128 0:d88fd55a27a6 312 if(b_p == 1) {
jah128 0:d88fd55a27a6 313 if(button_timer.read_ms() > 100) {
jah128 0:d88fd55a27a6 314 b_p=2;
jah128 0:d88fd55a27a6 315 display.clear_display();
jah128 0:d88fd55a27a6 316 display.set_position(0,0);
jah128 0:d88fd55a27a6 317 display.write_string("Hold to change",14);
jah128 0:d88fd55a27a6 318 display.set_position(1,0);
jah128 0:d88fd55a27a6 319 display.write_string("settings",8);
jah128 0:d88fd55a27a6 320 }
jah128 0:d88fd55a27a6 321 }
jah128 0:d88fd55a27a6 322 if(b_p == 2) {
jah128 0:d88fd55a27a6 323 if(button_timer.read_ms() > 1000) {
jah128 0:d88fd55a27a6 324 change_settings();
jah128 0:d88fd55a27a6 325 update_cycles();
jah128 0:d88fd55a27a6 326 display_status();
jah128 0:d88fd55a27a6 327 b_p=0;
jah128 0:d88fd55a27a6 328 }
jah128 0:d88fd55a27a6 329 }
jah128 0:d88fd55a27a6 330 } else {
jah128 0:d88fd55a27a6 331 if (b_p > 0) {
jah128 0:d88fd55a27a6 332 if(b_p == 2) display_status();
jah128 0:d88fd55a27a6 333 b_p=0;
jah128 0:d88fd55a27a6 334 }
jah128 0:d88fd55a27a6 335 }
jah128 0:d88fd55a27a6 336 }
jah128 0:d88fd55a27a6 337 }