A Jedi light saber controller program with the following "features": - Using RGB LEDs - User can change light colors with a button - Motion dependent (PWM) sounds with a MPU6050 motion sensor - Low voltage detection

Dependencies:   L152RE_USBDevice STM32_USB48MHz Watchdog mbed

Committer:
nightmechanic
Date:
Tue Mar 22 10:30:16 2016 +0000
Revision:
0:0bb3687e39da
Child:
2:59a7d4677474
First and not so stable version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nightmechanic 0:0bb3687e39da 1 #include "mbed.h"
nightmechanic 0:0bb3687e39da 2 #include "MPU6050.h"
nightmechanic 0:0bb3687e39da 3 #ifdef __SERIAL_DEBUG__
nightmechanic 0:0bb3687e39da 4 #include "USBSerial.h"
nightmechanic 0:0bb3687e39da 5 #include "STM32_USB48MHz.h"
nightmechanic 0:0bb3687e39da 6 #endif
nightmechanic 0:0bb3687e39da 7 #include "Watchdog.h"
nightmechanic 0:0bb3687e39da 8 #include "LightSaber.h"
nightmechanic 0:0bb3687e39da 9 #include "LightSaber_sounds.h"
nightmechanic 0:0bb3687e39da 10
nightmechanic 0:0bb3687e39da 11
nightmechanic 0:0bb3687e39da 12
nightmechanic 0:0bb3687e39da 13 // Light Controls: (Timer 3, ch 1-3)
nightmechanic 0:0bb3687e39da 14 PwmOut Red_LED(PA_6);
nightmechanic 0:0bb3687e39da 15 PwmOut Green_LED(PA_7);
nightmechanic 0:0bb3687e39da 16 PwmOut Blue_LED(PB_0);
nightmechanic 0:0bb3687e39da 17
nightmechanic 0:0bb3687e39da 18 //Speaker drive (Timer 2 ch 2)
nightmechanic 0:0bb3687e39da 19 PwmOut Speaker_OUT(PA_1);
nightmechanic 0:0bb3687e39da 20
nightmechanic 0:0bb3687e39da 21 //Color change button
nightmechanic 0:0bb3687e39da 22 DigitalIn Color_Button(PA_3, PullUp);
nightmechanic 0:0bb3687e39da 23
nightmechanic 0:0bb3687e39da 24 //startup config IOs
nightmechanic 0:0bb3687e39da 25 DigitalIn Startup_Config_IN1(PB_5, PullDown);
nightmechanic 0:0bb3687e39da 26 DigitalIn Startup_Config_IN2(PB_7, PullDown);
nightmechanic 0:0bb3687e39da 27 DigitalOut Startup_Config_OUT(PB_6, 0);
nightmechanic 0:0bb3687e39da 28
nightmechanic 0:0bb3687e39da 29 //Spare Buttons
nightmechanic 0:0bb3687e39da 30 //DigitalIn Spare1_Button(PB_12);
nightmechanic 0:0bb3687e39da 31 //DigitalIn Spare2_Button(PB_13);
nightmechanic 0:0bb3687e39da 32 //DigitalIn Spare3_Button(PB_14);
nightmechanic 0:0bb3687e39da 33
nightmechanic 0:0bb3687e39da 34 //Watchdog
nightmechanic 0:0bb3687e39da 35 //Watchdog wd;
nightmechanic 0:0bb3687e39da 36
nightmechanic 0:0bb3687e39da 37 bool color_button_released = TRUE;
nightmechanic 0:0bb3687e39da 38 volatile int Color_Button_Count = 0;
nightmechanic 0:0bb3687e39da 39
nightmechanic 0:0bb3687e39da 40 //sounds
nightmechanic 0:0bb3687e39da 41 int sound_to_play;
nightmechanic 0:0bb3687e39da 42 volatile int sound_count = 1;
nightmechanic 0:0bb3687e39da 43 volatile int sound_line = 0;
nightmechanic 0:0bb3687e39da 44 volatile int next_sound_time = 0;
nightmechanic 0:0bb3687e39da 45 volatile bool sound_is_playing_flag = FALSE;
nightmechanic 0:0bb3687e39da 46
nightmechanic 0:0bb3687e39da 47 //Battery voltage monitor
nightmechanic 0:0bb3687e39da 48 AnalogIn V_bat(PA_2);
nightmechanic 0:0bb3687e39da 49
nightmechanic 0:0bb3687e39da 50 //Ticker
nightmechanic 0:0bb3687e39da 51 Ticker button_ticker, sound_ticker;
nightmechanic 0:0bb3687e39da 52
nightmechanic 0:0bb3687e39da 53 //MPU 6050
nightmechanic 0:0bb3687e39da 54 float sum = 0;
nightmechanic 0:0bb3687e39da 55 uint32_t sumCount = 0;
nightmechanic 0:0bb3687e39da 56
nightmechanic 0:0bb3687e39da 57 //Set up I2C, (SDA,SCL)
nightmechanic 0:0bb3687e39da 58 //I2C MPU_i2c(PB_9, PB_8); //defined in MPU6050.h...
nightmechanic 0:0bb3687e39da 59
nightmechanic 0:0bb3687e39da 60 //MPU interrupt line
nightmechanic 0:0bb3687e39da 61 DigitalIn MPU_Intr(PB_1);
nightmechanic 0:0bb3687e39da 62
nightmechanic 0:0bb3687e39da 63 MPU6050 mpu6050;
nightmechanic 0:0bb3687e39da 64
nightmechanic 0:0bb3687e39da 65 Timer t;
nightmechanic 0:0bb3687e39da 66
nightmechanic 0:0bb3687e39da 67 void button_inth()
nightmechanic 0:0bb3687e39da 68 {
nightmechanic 0:0bb3687e39da 69 int Color_Button_state;
nightmechanic 0:0bb3687e39da 70
nightmechanic 0:0bb3687e39da 71 Color_Button_state = Color_Button.read(); //pressed = 0, released = 1
nightmechanic 0:0bb3687e39da 72
nightmechanic 0:0bb3687e39da 73 if (color_button_released) {
nightmechanic 0:0bb3687e39da 74 Color_Button_state = (~Color_Button_state) & 0x01;
nightmechanic 0:0bb3687e39da 75 }
nightmechanic 0:0bb3687e39da 76 Color_Button_Count = Color_Button_state*(Color_Button_Count + 1);
nightmechanic 0:0bb3687e39da 77
nightmechanic 0:0bb3687e39da 78 }
nightmechanic 0:0bb3687e39da 79
nightmechanic 0:0bb3687e39da 80 bool sound_player(const int sound_table[][6], int table_lines)
nightmechanic 0:0bb3687e39da 81 {
nightmechanic 0:0bb3687e39da 82 int sound_period;
nightmechanic 0:0bb3687e39da 83 int sound_pulse_width_us;
nightmechanic 0:0bb3687e39da 84 if (sound_count > sound_table[sound_line][NUM_STEPS_IDX])
nightmechanic 0:0bb3687e39da 85 {
nightmechanic 0:0bb3687e39da 86 sound_count = 1;
nightmechanic 0:0bb3687e39da 87 sound_line++;
nightmechanic 0:0bb3687e39da 88 if (sound_line >= table_lines)
nightmechanic 0:0bb3687e39da 89 {
nightmechanic 0:0bb3687e39da 90 return FALSE;
nightmechanic 0:0bb3687e39da 91 }
nightmechanic 0:0bb3687e39da 92 }
nightmechanic 0:0bb3687e39da 93
nightmechanic 0:0bb3687e39da 94 sound_period = sound_table[sound_line][INIT_PERIOD_IDX] + ((sound_count-1) * sound_table[sound_line][STEP_PERIOD_IDX]);
nightmechanic 0:0bb3687e39da 95 sound_pulse_width_us = ( sound_period * (sound_table[sound_line][INIT_VOL_IDX] + ((sound_count-1) * sound_table[sound_line][STEP_VOL_IDX])) )/ 200;
nightmechanic 0:0bb3687e39da 96
nightmechanic 0:0bb3687e39da 97 // there are no checks for 0/negative values of the above - need to make sure that tables are valid.
nightmechanic 0:0bb3687e39da 98 // set PWM parameters for current step
nightmechanic 0:0bb3687e39da 99
nightmechanic 0:0bb3687e39da 100 Speaker_OUT.period_us(sound_period);
nightmechanic 0:0bb3687e39da 101 Speaker_OUT.pulsewidth_us(sound_pulse_width_us);
nightmechanic 0:0bb3687e39da 102
nightmechanic 0:0bb3687e39da 103 //update next_sound_time, step count
nightmechanic 0:0bb3687e39da 104
nightmechanic 0:0bb3687e39da 105 next_sound_time = t.read_ms() + sound_table[sound_line][STEP_DUR_IDX];
nightmechanic 0:0bb3687e39da 106 sound_count++;
nightmechanic 0:0bb3687e39da 107
nightmechanic 0:0bb3687e39da 108 return TRUE;
nightmechanic 0:0bb3687e39da 109 }
nightmechanic 0:0bb3687e39da 110
nightmechanic 0:0bb3687e39da 111 void sound_inth()
nightmechanic 0:0bb3687e39da 112 {
nightmechanic 0:0bb3687e39da 113 if ((t.read_ms() >= next_sound_time) && sound_is_playing_flag )
nightmechanic 0:0bb3687e39da 114 {
nightmechanic 0:0bb3687e39da 115 switch (sound_to_play) {
nightmechanic 0:0bb3687e39da 116
nightmechanic 0:0bb3687e39da 117 case STARTUP_SOUND:
nightmechanic 0:0bb3687e39da 118 sound_is_playing_flag = sound_player(startup_sound_table, STARTUP_TBL_N_LINES);
nightmechanic 0:0bb3687e39da 119 break;
nightmechanic 0:0bb3687e39da 120 case MOVEMENT_SOUND:
nightmechanic 0:0bb3687e39da 121 sound_is_playing_flag = sound_player(movement_sound_table, MOVEMENT_TBL_N_LINES);
nightmechanic 0:0bb3687e39da 122 break;
nightmechanic 0:0bb3687e39da 123 case CLASH_SOUND:
nightmechanic 0:0bb3687e39da 124 sound_is_playing_flag = sound_player(clash_sound_table, CLASH_TBL_N_LINES);
nightmechanic 0:0bb3687e39da 125 break;
nightmechanic 0:0bb3687e39da 126 default:
nightmechanic 0:0bb3687e39da 127 break;
nightmechanic 0:0bb3687e39da 128 }
nightmechanic 0:0bb3687e39da 129 }
nightmechanic 0:0bb3687e39da 130 }
nightmechanic 0:0bb3687e39da 131 int main()
nightmechanic 0:0bb3687e39da 132 {
nightmechanic 0:0bb3687e39da 133 bool motion_is_init = FALSE;
nightmechanic 0:0bb3687e39da 134 bool new_data = FALSE;
nightmechanic 0:0bb3687e39da 135
nightmechanic 0:0bb3687e39da 136 int current_color;
nightmechanic 0:0bb3687e39da 137 int light_intensity = NORM_LIGHT_INTENS;
nightmechanic 0:0bb3687e39da 138
nightmechanic 0:0bb3687e39da 139 int v_bat_avg_mem[VBAT_AVG_LEN];
nightmechanic 0:0bb3687e39da 140 int v_bat_avg_value;
nightmechanic 0:0bb3687e39da 141 int v_bat_avg_pointer = 0;
nightmechanic 0:0bb3687e39da 142 bool v_bat_ready = FALSE;
nightmechanic 0:0bb3687e39da 143 bool vbat_low_flag = FALSE;
nightmechanic 0:0bb3687e39da 144 int t_vbat_count = 0;
nightmechanic 0:0bb3687e39da 145 int t_vbat_start = 0;
nightmechanic 0:0bb3687e39da 146
nightmechanic 0:0bb3687e39da 147 MPU_data_type MPU_data[MPU_BUFFER_LEN];
nightmechanic 0:0bb3687e39da 148 MPU_data_type MPU_avg_data;
nightmechanic 0:0bb3687e39da 149 int mpu_pointer = 0;
nightmechanic 0:0bb3687e39da 150 int mpu_data_count = 0;
nightmechanic 0:0bb3687e39da 151 bool accel_thr_crossed = FALSE;
nightmechanic 0:0bb3687e39da 152 bool ypr_thr_crossed = FALSE;
nightmechanic 0:0bb3687e39da 153 int count = 0;
nightmechanic 0:0bb3687e39da 154
nightmechanic 0:0bb3687e39da 155 int temp_diff;
nightmechanic 0:0bb3687e39da 156
nightmechanic 0:0bb3687e39da 157 int i = 0;
nightmechanic 0:0bb3687e39da 158 #ifdef __SERIAL_DEBUG__
nightmechanic 0:0bb3687e39da 159 STM32_HSI_USB48MHz(); // HSI,USB48MHz,SYSCLK32MHz
nightmechanic 0:0bb3687e39da 160
nightmechanic 0:0bb3687e39da 161 // serial port for debug etc.
nightmechanic 0:0bb3687e39da 162 USBSerial serial;
nightmechanic 0:0bb3687e39da 163
nightmechanic 0:0bb3687e39da 164 //USBSerial serial;
nightmechanic 0:0bb3687e39da 165
nightmechanic 0:0bb3687e39da 166 serial.printf("Initializing main");
nightmechanic 0:0bb3687e39da 167 #endif
nightmechanic 0:0bb3687e39da 168
nightmechanic 0:0bb3687e39da 169 //initialize LEDs : set rate, intensity, and startup color (according to jumper settings)
nightmechanic 0:0bb3687e39da 170
nightmechanic 0:0bb3687e39da 171 init_color(&current_color,light_intensity);
nightmechanic 0:0bb3687e39da 172
nightmechanic 0:0bb3687e39da 173 //Set up I2C
nightmechanic 0:0bb3687e39da 174 MPU_i2c.frequency(300000); // use fast (400 kHz) I2C
nightmechanic 0:0bb3687e39da 175
nightmechanic 0:0bb3687e39da 176 // start "clock"
nightmechanic 0:0bb3687e39da 177 t.start();
nightmechanic 0:0bb3687e39da 178
nightmechanic 0:0bb3687e39da 179 // attach and set sound interrupt handler (every 10msec)
nightmechanic 0:0bb3687e39da 180 sound_ticker.attach(&sound_inth, 0.01);
nightmechanic 0:0bb3687e39da 181 // play startup sound
nightmechanic 0:0bb3687e39da 182 sound_to_play = STARTUP_SOUND;
nightmechanic 0:0bb3687e39da 183 sound_line = 0;
nightmechanic 0:0bb3687e39da 184 sound_count = 1;
nightmechanic 0:0bb3687e39da 185 next_sound_time = t.read_ms();
nightmechanic 0:0bb3687e39da 186 sound_is_playing_flag = TRUE;
nightmechanic 0:0bb3687e39da 187
nightmechanic 0:0bb3687e39da 188 // initialize the motion sensor
nightmechanic 0:0bb3687e39da 189 motion_is_init = motion_sensor_init();
nightmechanic 0:0bb3687e39da 190
nightmechanic 0:0bb3687e39da 191 button_ticker.attach(&button_inth, 0.025);
nightmechanic 0:0bb3687e39da 192
nightmechanic 0:0bb3687e39da 193 wait_ms(1000); //from MPU example
nightmechanic 0:0bb3687e39da 194
nightmechanic 0:0bb3687e39da 195 //Initialize watchdog with a 2 second interval
nightmechanic 0:0bb3687e39da 196 // wd.Configure(2.0);
nightmechanic 0:0bb3687e39da 197
nightmechanic 0:0bb3687e39da 198 //main loop
nightmechanic 0:0bb3687e39da 199 while(1) {
nightmechanic 0:0bb3687e39da 200
nightmechanic 0:0bb3687e39da 201
nightmechanic 0:0bb3687e39da 202
nightmechanic 0:0bb3687e39da 203 if (vbat_low_flag) //low battery
nightmechanic 0:0bb3687e39da 204 {
nightmechanic 0:0bb3687e39da 205 light_intensity = LOW_LIGHT_INTENS; //lower light intensity save some battery
nightmechanic 0:0bb3687e39da 206 if (t_vbat_start == 0) //starting a new cycle
nightmechanic 0:0bb3687e39da 207 {
nightmechanic 0:0bb3687e39da 208 t_vbat_start = t.read_ms();
nightmechanic 0:0bb3687e39da 209 if (t_vbat_count < 3) //flash only in first 3 cycles
nightmechanic 0:0bb3687e39da 210 {
nightmechanic 0:0bb3687e39da 211 change_color(RED , light_intensity);
nightmechanic 0:0bb3687e39da 212 }
nightmechanic 0:0bb3687e39da 213 } else if ( ((t.read_ms() - t_vbat_start) > 1000) && (t_vbat_count < 3)) // dark period and flash only in first 3 cycles
nightmechanic 0:0bb3687e39da 214 {
nightmechanic 0:0bb3687e39da 215 change_color(RED, 0);
nightmechanic 0:0bb3687e39da 216 } else // after first 3 cycles return to normal operation (with lower light intensity)
nightmechanic 0:0bb3687e39da 217 {
nightmechanic 0:0bb3687e39da 218 change_color((color_type) current_color, light_intensity);
nightmechanic 0:0bb3687e39da 219 }
nightmechanic 0:0bb3687e39da 220 if ( (t.read_ms() - t_vbat_start) > 2000) //end of cycle
nightmechanic 0:0bb3687e39da 221 {
nightmechanic 0:0bb3687e39da 222 t_vbat_start = 0;
nightmechanic 0:0bb3687e39da 223 t_vbat_count ++;
nightmechanic 0:0bb3687e39da 224 }
nightmechanic 0:0bb3687e39da 225 if (t_vbat_count > 30) // once a minute, starting over
nightmechanic 0:0bb3687e39da 226 {
nightmechanic 0:0bb3687e39da 227 t_vbat_count = 0;
nightmechanic 0:0bb3687e39da 228 }
nightmechanic 0:0bb3687e39da 229
nightmechanic 0:0bb3687e39da 230 }
nightmechanic 0:0bb3687e39da 231 //battery ok or between low bat flashes, check if button was pressed or released
nightmechanic 0:0bb3687e39da 232 if (!vbat_low_flag || (t_vbat_count >=3))
nightmechanic 0:0bb3687e39da 233 {
nightmechanic 0:0bb3687e39da 234 if ( (Color_Button_Count >= BUTTON_PRESS_THR) && color_button_released )
nightmechanic 0:0bb3687e39da 235 {
nightmechanic 0:0bb3687e39da 236 __disable_irq();
nightmechanic 0:0bb3687e39da 237 color_button_released = FALSE;
nightmechanic 0:0bb3687e39da 238 Color_Button_Count = 0;
nightmechanic 0:0bb3687e39da 239 __enable_irq();
nightmechanic 0:0bb3687e39da 240 current_color++;
nightmechanic 0:0bb3687e39da 241 if (current_color >= NUM_OF_COLORS)
nightmechanic 0:0bb3687e39da 242 {
nightmechanic 0:0bb3687e39da 243 current_color = BLUE;
nightmechanic 0:0bb3687e39da 244 }
nightmechanic 0:0bb3687e39da 245 #ifdef __SERIAL_DEBUG__
nightmechanic 0:0bb3687e39da 246 serial.printf("Color Button pressed");
nightmechanic 0:0bb3687e39da 247 #endif
nightmechanic 0:0bb3687e39da 248 change_color((color_type) current_color, light_intensity);
nightmechanic 0:0bb3687e39da 249 }
nightmechanic 0:0bb3687e39da 250
nightmechanic 0:0bb3687e39da 251 if ((Color_Button_Count >= BUTTON_RELEASE_THR) && !color_button_released)
nightmechanic 0:0bb3687e39da 252 {
nightmechanic 0:0bb3687e39da 253 __disable_irq();
nightmechanic 0:0bb3687e39da 254 color_button_released = TRUE;
nightmechanic 0:0bb3687e39da 255 Color_Button_Count = 0;
nightmechanic 0:0bb3687e39da 256 __enable_irq();
nightmechanic 0:0bb3687e39da 257 #ifdef __SERIAL_DEBUG__
nightmechanic 0:0bb3687e39da 258 serial.printf("Color Button released");
nightmechanic 0:0bb3687e39da 259 #endif
nightmechanic 0:0bb3687e39da 260 }
nightmechanic 0:0bb3687e39da 261 }
nightmechanic 0:0bb3687e39da 262
nightmechanic 0:0bb3687e39da 263
nightmechanic 0:0bb3687e39da 264
nightmechanic 0:0bb3687e39da 265 if (motion_is_init)
nightmechanic 0:0bb3687e39da 266 {
nightmechanic 0:0bb3687e39da 267 new_data = motion_update_data(&MPU_data[mpu_pointer]);
nightmechanic 0:0bb3687e39da 268 }
nightmechanic 0:0bb3687e39da 269
nightmechanic 0:0bb3687e39da 270 if (new_data)
nightmechanic 0:0bb3687e39da 271 {
nightmechanic 0:0bb3687e39da 272
nightmechanic 0:0bb3687e39da 273 if ((mpu_data_count > MPU_DATA_STABLE) && !sound_is_playing_flag )
nightmechanic 0:0bb3687e39da 274 {
nightmechanic 0:0bb3687e39da 275 //calculate new average
nightmechanic 0:0bb3687e39da 276 mpu_calc_avg(MPU_data, mpu_pointer, &MPU_avg_data, MPU_AVG_LEN);
nightmechanic 0:0bb3687e39da 277
nightmechanic 0:0bb3687e39da 278 //check if any thresholds are crossed
nightmechanic 0:0bb3687e39da 279 //acceleration
nightmechanic 0:0bb3687e39da 280 if ((abs(MPU_avg_data.ax - MPU_data[mpu_pointer].ax) > ACCEL_THR)
nightmechanic 0:0bb3687e39da 281 || (abs(MPU_avg_data.ay - MPU_data[mpu_pointer].ay) > ACCEL_THR)
nightmechanic 0:0bb3687e39da 282 || (abs(MPU_avg_data.az - MPU_data[mpu_pointer].az) > ACCEL_THR))
nightmechanic 0:0bb3687e39da 283 {
nightmechanic 0:0bb3687e39da 284 accel_thr_crossed = TRUE;
nightmechanic 0:0bb3687e39da 285 }
nightmechanic 0:0bb3687e39da 286 // YPR
nightmechanic 0:0bb3687e39da 287 temp_diff = abs(MPU_avg_data.yaw - MPU_data[mpu_pointer].yaw);
nightmechanic 0:0bb3687e39da 288 if ((temp_diff > YPR_THR) && (temp_diff < (3600-YPR_THR)))
nightmechanic 0:0bb3687e39da 289 {
nightmechanic 0:0bb3687e39da 290 ypr_thr_crossed = TRUE;
nightmechanic 0:0bb3687e39da 291 }
nightmechanic 0:0bb3687e39da 292
nightmechanic 0:0bb3687e39da 293 temp_diff = abs(MPU_avg_data.pitch - MPU_data[mpu_pointer].pitch);
nightmechanic 0:0bb3687e39da 294 if ((temp_diff > YPR_THR) && (temp_diff < (3600-YPR_THR)))
nightmechanic 0:0bb3687e39da 295 {
nightmechanic 0:0bb3687e39da 296 ypr_thr_crossed = TRUE;
nightmechanic 0:0bb3687e39da 297 }
nightmechanic 0:0bb3687e39da 298
nightmechanic 0:0bb3687e39da 299 temp_diff = abs(MPU_avg_data.roll - MPU_data[mpu_pointer].roll);
nightmechanic 0:0bb3687e39da 300 if ((temp_diff > YPR_THR) && (temp_diff < (3600-YPR_THR)))
nightmechanic 0:0bb3687e39da 301 {
nightmechanic 0:0bb3687e39da 302 ypr_thr_crossed = TRUE;
nightmechanic 0:0bb3687e39da 303 }
nightmechanic 0:0bb3687e39da 304
nightmechanic 0:0bb3687e39da 305 if (accel_thr_crossed)
nightmechanic 0:0bb3687e39da 306 {
nightmechanic 0:0bb3687e39da 307 //play clash sound
nightmechanic 0:0bb3687e39da 308 sound_to_play = CLASH_SOUND;
nightmechanic 0:0bb3687e39da 309 sound_line = 0;
nightmechanic 0:0bb3687e39da 310 sound_count = 1;
nightmechanic 0:0bb3687e39da 311 next_sound_time = t.read_ms();
nightmechanic 0:0bb3687e39da 312 sound_is_playing_flag = TRUE;
nightmechanic 0:0bb3687e39da 313
nightmechanic 0:0bb3687e39da 314 }
nightmechanic 0:0bb3687e39da 315 if (ypr_thr_crossed && !accel_thr_crossed)
nightmechanic 0:0bb3687e39da 316 {
nightmechanic 0:0bb3687e39da 317 //play movement sound
nightmechanic 0:0bb3687e39da 318 sound_to_play = MOVEMENT_SOUND;
nightmechanic 0:0bb3687e39da 319 sound_line = 0;
nightmechanic 0:0bb3687e39da 320 sound_count = 1;
nightmechanic 0:0bb3687e39da 321 next_sound_time = t.read_ms();
nightmechanic 0:0bb3687e39da 322 sound_is_playing_flag = TRUE;
nightmechanic 0:0bb3687e39da 323 }
nightmechanic 0:0bb3687e39da 324
nightmechanic 0:0bb3687e39da 325 accel_thr_crossed = FALSE;
nightmechanic 0:0bb3687e39da 326 ypr_thr_crossed = FALSE;
nightmechanic 0:0bb3687e39da 327
nightmechanic 0:0bb3687e39da 328 } else {
nightmechanic 0:0bb3687e39da 329 mpu_data_count++;
nightmechanic 0:0bb3687e39da 330 }
nightmechanic 0:0bb3687e39da 331
nightmechanic 0:0bb3687e39da 332 mpu_pointer++;
nightmechanic 0:0bb3687e39da 333
nightmechanic 0:0bb3687e39da 334 if (mpu_pointer >= MPU_BUFFER_LEN)
nightmechanic 0:0bb3687e39da 335 {
nightmechanic 0:0bb3687e39da 336 mpu_pointer = 0;
nightmechanic 0:0bb3687e39da 337 }
nightmechanic 0:0bb3687e39da 338
nightmechanic 0:0bb3687e39da 339 new_data = FALSE;
nightmechanic 0:0bb3687e39da 340 }
nightmechanic 0:0bb3687e39da 341
nightmechanic 0:0bb3687e39da 342 delt_t = t.read_ms() - count;
nightmechanic 0:0bb3687e39da 343 if (delt_t > 1000)
nightmechanic 0:0bb3687e39da 344 { // update serial port once per second independent of read rate
nightmechanic 0:0bb3687e39da 345
nightmechanic 0:0bb3687e39da 346 #ifdef __SERIAL_DEBUG__
nightmechanic 0:0bb3687e39da 347 //serial.printf("Yaw, Pitch, Roll: %f %f %f\n\r", (float) (yaw / 16384.0f), (float) (pitch/16384.0f), (float) (roll/16384.0f));
nightmechanic 0:0bb3687e39da 348 serial.printf("Yaw, Pitch, Roll: %i %i %i\n\r", (int)(yaw * 10), (int)(pitch * 10), (int)(roll * 10));
nightmechanic 0:0bb3687e39da 349 serial.printf("Yaw, Pitch, Roll (average): %i %i %i\n\r", MPU_avg_data.yaw, MPU_avg_data.pitch, MPU_avg_data.roll);
nightmechanic 0:0bb3687e39da 350
nightmechanic 0:0bb3687e39da 351 serial.printf("Ax, Ay, Az : %i %i %i\n\r", (int)(ax * 1000), (int)(ay * 1000), (int)(az * 1000));
nightmechanic 0:0bb3687e39da 352 serial.printf("Ax, Ay, Az (average): %i %i %i\n\r", MPU_avg_data.ax , MPU_avg_data.ay, MPU_avg_data.az);
nightmechanic 0:0bb3687e39da 353
nightmechanic 0:0bb3687e39da 354 serial.printf("average rate = %f\n\r", (float) sumCount/sum);
nightmechanic 0:0bb3687e39da 355
nightmechanic 0:0bb3687e39da 356 if (sound_is_playing_flag)
nightmechanic 0:0bb3687e39da 357 {
nightmechanic 0:0bb3687e39da 358 serial.printf("Sound is playing! \n\r", (float) sumCount/sum);
nightmechanic 0:0bb3687e39da 359 }
nightmechanic 0:0bb3687e39da 360 #endif
nightmechanic 0:0bb3687e39da 361 count = t.read_ms();
nightmechanic 0:0bb3687e39da 362 sum = 0;
nightmechanic 0:0bb3687e39da 363 sumCount = 0;
nightmechanic 0:0bb3687e39da 364
nightmechanic 0:0bb3687e39da 365 // Battery voltage monitor
nightmechanic 0:0bb3687e39da 366 v_bat_avg_mem[v_bat_avg_pointer] = V_bat.read_u16();
nightmechanic 0:0bb3687e39da 367 v_bat_avg_pointer++;
nightmechanic 0:0bb3687e39da 368 if (v_bat_avg_pointer >= VBAT_AVG_LEN)
nightmechanic 0:0bb3687e39da 369 {
nightmechanic 0:0bb3687e39da 370 v_bat_avg_pointer = 0;
nightmechanic 0:0bb3687e39da 371 v_bat_ready = TRUE;
nightmechanic 0:0bb3687e39da 372 }
nightmechanic 0:0bb3687e39da 373 if (v_bat_ready)
nightmechanic 0:0bb3687e39da 374 {
nightmechanic 0:0bb3687e39da 375 //calculate the average
nightmechanic 0:0bb3687e39da 376 v_bat_avg_value = 0;
nightmechanic 0:0bb3687e39da 377 for (i = 0 ; i < VBAT_AVG_LEN ; i++)
nightmechanic 0:0bb3687e39da 378 {
nightmechanic 0:0bb3687e39da 379 v_bat_avg_value += v_bat_avg_mem[i];
nightmechanic 0:0bb3687e39da 380 }
nightmechanic 0:0bb3687e39da 381
nightmechanic 0:0bb3687e39da 382 v_bat_avg_value = v_bat_avg_value/VBAT_AVG_LEN;
nightmechanic 0:0bb3687e39da 383 #ifdef __SERIAL_DEBUG__
nightmechanic 0:0bb3687e39da 384 serial.printf("Battery average voltage: %i \n\r", v_bat_avg_value);
nightmechanic 0:0bb3687e39da 385 #endif
nightmechanic 0:0bb3687e39da 386 //check voltage
nightmechanic 0:0bb3687e39da 387 if (v_bat_avg_value < VBAT_THR)
nightmechanic 0:0bb3687e39da 388 {
nightmechanic 0:0bb3687e39da 389 vbat_low_flag = TRUE;
nightmechanic 0:0bb3687e39da 390 } else if ((vbat_low_flag == TRUE) && (v_bat_avg_value > (VBAT_THR+VBAT_HYST)))
nightmechanic 0:0bb3687e39da 391 {
nightmechanic 0:0bb3687e39da 392 vbat_low_flag = FALSE;
nightmechanic 0:0bb3687e39da 393 }
nightmechanic 0:0bb3687e39da 394 }
nightmechanic 0:0bb3687e39da 395
nightmechanic 0:0bb3687e39da 396
nightmechanic 0:0bb3687e39da 397 }
nightmechanic 0:0bb3687e39da 398 //handle timer overflow - even if a sound is playing there are 5 minutes before overflow
nightmechanic 0:0bb3687e39da 399 if ((t.read_ms() > (30*60*1000)) && !sound_is_playing_flag)
nightmechanic 0:0bb3687e39da 400 {
nightmechanic 0:0bb3687e39da 401 t.reset();
nightmechanic 0:0bb3687e39da 402 // reset mpu statistics as well
nightmechanic 0:0bb3687e39da 403 count = t.read_ms();
nightmechanic 0:0bb3687e39da 404 sum = 0;
nightmechanic 0:0bb3687e39da 405 sumCount = 0;
nightmechanic 0:0bb3687e39da 406 //reset the low battery variables
nightmechanic 0:0bb3687e39da 407 t_vbat_start = 0;
nightmechanic 0:0bb3687e39da 408 t_vbat_count = 0;
nightmechanic 0:0bb3687e39da 409 }
nightmechanic 0:0bb3687e39da 410 // kick the dog before the timeout
nightmechanic 0:0bb3687e39da 411 // wd.Service();
nightmechanic 0:0bb3687e39da 412 }
nightmechanic 0:0bb3687e39da 413 }
nightmechanic 0:0bb3687e39da 414
nightmechanic 0:0bb3687e39da 415
nightmechanic 0:0bb3687e39da 416 bool motion_sensor_init()
nightmechanic 0:0bb3687e39da 417 {
nightmechanic 0:0bb3687e39da 418
nightmechanic 0:0bb3687e39da 419
nightmechanic 0:0bb3687e39da 420 // Read the WHO_AM_I register, this is a good test of communication
nightmechanic 0:0bb3687e39da 421 uint8_t whoami = mpu6050.readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050); // Read WHO_AM_I register for MPU-6050
nightmechanic 0:0bb3687e39da 422 //serial.printf("I AM 0x%x\n\r", whoami);
nightmechanic 0:0bb3687e39da 423 //serial.printf("I SHOULD BE 0x68\n\r");
nightmechanic 0:0bb3687e39da 424
nightmechanic 0:0bb3687e39da 425 if (whoami == 0x68) { // WHO_AM_I should always be 0x68
nightmechanic 0:0bb3687e39da 426 // serial.printf("MPU6050 is online...");
nightmechanic 0:0bb3687e39da 427 wait(1);
nightmechanic 0:0bb3687e39da 428
nightmechanic 0:0bb3687e39da 429
nightmechanic 0:0bb3687e39da 430 mpu6050.MPU6050SelfTest(SelfTest); // Start by performing self test and reporting values
nightmechanic 0:0bb3687e39da 431 /*
nightmechanic 0:0bb3687e39da 432 serial.printf("x-axis self test: acceleration trim within : ");
nightmechanic 0:0bb3687e39da 433 serial.printf("%f", SelfTest[0]);
nightmechanic 0:0bb3687e39da 434 serial.printf("% of factory value \n\r");
nightmechanic 0:0bb3687e39da 435 serial.printf("y-axis self test: acceleration trim within : ");
nightmechanic 0:0bb3687e39da 436 serial.printf("%f", SelfTest[1]);
nightmechanic 0:0bb3687e39da 437 serial.printf("% of factory value \n\r");
nightmechanic 0:0bb3687e39da 438 serial.printf("z-axis self test: acceleration trim within : ");
nightmechanic 0:0bb3687e39da 439 serial.printf("%f", SelfTest[2]);
nightmechanic 0:0bb3687e39da 440 serial.printf("% of factory value \n\r");
nightmechanic 0:0bb3687e39da 441 serial.printf("x-axis self test: gyration trim within : ");
nightmechanic 0:0bb3687e39da 442 serial.printf("%f", SelfTest[3]);
nightmechanic 0:0bb3687e39da 443 serial.printf("% of factory value \n\r");
nightmechanic 0:0bb3687e39da 444 serial.printf("y-axis self test: gyration trim within : ");
nightmechanic 0:0bb3687e39da 445 serial.printf("%f", SelfTest[4]);
nightmechanic 0:0bb3687e39da 446 serial.printf("% of factory value \n\r");
nightmechanic 0:0bb3687e39da 447 serial.printf("z-axis self test: gyration trim within : ");
nightmechanic 0:0bb3687e39da 448 serial.printf("%f", SelfTest[5]);
nightmechanic 0:0bb3687e39da 449 serial.printf("% of factory value \n\r");
nightmechanic 0:0bb3687e39da 450 */
nightmechanic 0:0bb3687e39da 451 wait(1);
nightmechanic 0:0bb3687e39da 452
nightmechanic 0:0bb3687e39da 453 if(SelfTest[0] < 1.0f && SelfTest[1] < 1.0f && SelfTest[2] < 1.0f && SelfTest[3] < 1.0f && SelfTest[4] < 1.0f && SelfTest[5] < 1.0f) {
nightmechanic 0:0bb3687e39da 454 mpu6050.resetMPU6050(); // Reset registers to default in preparation for device calibration
nightmechanic 0:0bb3687e39da 455 mpu6050.calibrateMPU6050(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers
nightmechanic 0:0bb3687e39da 456 mpu6050.initMPU6050();
nightmechanic 0:0bb3687e39da 457 //serial.printf("MPU6050 initialized for active data mode....\n\r"); // Initialize device for active mode read of acclerometer, gyroscope, and temperature
nightmechanic 0:0bb3687e39da 458
nightmechanic 0:0bb3687e39da 459 return TRUE;
nightmechanic 0:0bb3687e39da 460 } else {
nightmechanic 0:0bb3687e39da 461 //serial.printf("Device did not the pass self-test!\n\r");
nightmechanic 0:0bb3687e39da 462 return FALSE;
nightmechanic 0:0bb3687e39da 463
nightmechanic 0:0bb3687e39da 464 }
nightmechanic 0:0bb3687e39da 465 } else {
nightmechanic 0:0bb3687e39da 466 //serial.printf("Could not connect to MPU6050: \n\r");
nightmechanic 0:0bb3687e39da 467 //serial.printf("%#x \n", whoami);
nightmechanic 0:0bb3687e39da 468
nightmechanic 0:0bb3687e39da 469 return FALSE;
nightmechanic 0:0bb3687e39da 470 }
nightmechanic 0:0bb3687e39da 471
nightmechanic 0:0bb3687e39da 472
nightmechanic 0:0bb3687e39da 473 }
nightmechanic 0:0bb3687e39da 474
nightmechanic 0:0bb3687e39da 475 bool motion_update_data(MPU_data_type *new_data)
nightmechanic 0:0bb3687e39da 476 {
nightmechanic 0:0bb3687e39da 477 if(mpu6050.readByte(MPU6050_ADDRESS, INT_STATUS) & 0x01) {
nightmechanic 0:0bb3687e39da 478 mpu6050.readAccelData(accelCount); // Read the x/y/z adc values
nightmechanic 0:0bb3687e39da 479 mpu6050.getAres();
nightmechanic 0:0bb3687e39da 480
nightmechanic 0:0bb3687e39da 481 // Now we'll calculate the accleration value into actual g's
nightmechanic 0:0bb3687e39da 482 ax = (float)accelCount[0]*aRes - accelBias[0]; // get actual g value, this depends on scale being set
nightmechanic 0:0bb3687e39da 483 ay = (float)accelCount[1]*aRes - accelBias[1];
nightmechanic 0:0bb3687e39da 484 az = (float)accelCount[2]*aRes - accelBias[2];
nightmechanic 0:0bb3687e39da 485
nightmechanic 0:0bb3687e39da 486 mpu6050.readGyroData(gyroCount); // Read the x/y/z adc values
nightmechanic 0:0bb3687e39da 487 mpu6050.getGres();
nightmechanic 0:0bb3687e39da 488
nightmechanic 0:0bb3687e39da 489 // Calculate the gyro value into actual degrees per second
nightmechanic 0:0bb3687e39da 490 gx = (float)gyroCount[0]*gRes; // - gyroBias[0]; // get actual gyro value, this depends on scale being set
nightmechanic 0:0bb3687e39da 491 gy = (float)gyroCount[1]*gRes; // - gyroBias[1];
nightmechanic 0:0bb3687e39da 492 gz = (float)gyroCount[2]*gRes; // - gyroBias[2];
nightmechanic 0:0bb3687e39da 493
nightmechanic 0:0bb3687e39da 494 tempCount = mpu6050.readTempData(); // Read the x/y/z adc values
nightmechanic 0:0bb3687e39da 495 temperature = (tempCount) / 340. + 36.53; // Temperature in degrees Centigrade
nightmechanic 0:0bb3687e39da 496
nightmechanic 0:0bb3687e39da 497
nightmechanic 0:0bb3687e39da 498 Now = t.read_us();
nightmechanic 0:0bb3687e39da 499 deltat = (float)((Now - lastUpdate)/1000000.0f) ; // set integration time by time elapsed since last filter update
nightmechanic 0:0bb3687e39da 500 lastUpdate = Now;
nightmechanic 0:0bb3687e39da 501
nightmechanic 0:0bb3687e39da 502 sum += deltat;
nightmechanic 0:0bb3687e39da 503 sumCount++;
nightmechanic 0:0bb3687e39da 504
nightmechanic 0:0bb3687e39da 505 if(lastUpdate - firstUpdate > 10000000.0f) {
nightmechanic 0:0bb3687e39da 506 beta = 0.04; // decrease filter gain after stabilized
nightmechanic 0:0bb3687e39da 507 zeta = 0.015; // increase bias drift gain after stabilized
nightmechanic 0:0bb3687e39da 508 }
nightmechanic 0:0bb3687e39da 509
nightmechanic 0:0bb3687e39da 510 // Pass gyro rate as rad/s
nightmechanic 0:0bb3687e39da 511 mpu6050.MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f);
nightmechanic 0:0bb3687e39da 512
nightmechanic 0:0bb3687e39da 513
nightmechanic 0:0bb3687e39da 514
nightmechanic 0:0bb3687e39da 515
nightmechanic 0:0bb3687e39da 516 // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation.
nightmechanic 0:0bb3687e39da 517 // In this coordinate system, the positive z-axis is down toward Earth.
nightmechanic 0:0bb3687e39da 518 // Yaw is the angle between Sensor x-axis and Earth magnetic North (or true North if corrected for local declination, looking down on the sensor positive yaw is counterclockwise.
nightmechanic 0:0bb3687e39da 519 // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative.
nightmechanic 0:0bb3687e39da 520 // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll.
nightmechanic 0:0bb3687e39da 521 // These arise from the definition of the homogeneous rotation matrix constructed from quaternions.
nightmechanic 0:0bb3687e39da 522 // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be
nightmechanic 0:0bb3687e39da 523 // applied in the correct order which for this configuration is yaw, pitch, and then roll.
nightmechanic 0:0bb3687e39da 524 // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links.
nightmechanic 0:0bb3687e39da 525 yaw = atan2(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]);
nightmechanic 0:0bb3687e39da 526 pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
nightmechanic 0:0bb3687e39da 527 roll = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);
nightmechanic 0:0bb3687e39da 528 pitch *= 180.0f / PI;
nightmechanic 0:0bb3687e39da 529 yaw *= 180.0f / PI;
nightmechanic 0:0bb3687e39da 530 roll *= 180.0f / PI;
nightmechanic 0:0bb3687e39da 531 /*
nightmechanic 0:0bb3687e39da 532 new_data->ax = (int) (ax / 16384.0f);
nightmechanic 0:0bb3687e39da 533 new_data->ay = (int) (ay / 16384.0f);
nightmechanic 0:0bb3687e39da 534 new_data->az = (int) (az / 16384.0f);
nightmechanic 0:0bb3687e39da 535 new_data->yaw = (int) (yaw / 16384.0f);
nightmechanic 0:0bb3687e39da 536 new_data->pitch = (int) (pitch / 16384.0f);
nightmechanic 0:0bb3687e39da 537 new_data->roll = (int) (roll / 16384.0f);
nightmechanic 0:0bb3687e39da 538 */
nightmechanic 0:0bb3687e39da 539 new_data->ax = (int) (ax * 1000);
nightmechanic 0:0bb3687e39da 540 new_data->ay = (int) (ay * 1000);
nightmechanic 0:0bb3687e39da 541 new_data->az = (int) (az * 1000);
nightmechanic 0:0bb3687e39da 542 new_data->yaw = (int) (yaw * 10);
nightmechanic 0:0bb3687e39da 543 new_data->pitch = (int) (pitch * 10);
nightmechanic 0:0bb3687e39da 544 new_data->roll = (int) (roll * 10);
nightmechanic 0:0bb3687e39da 545 return TRUE;
nightmechanic 0:0bb3687e39da 546
nightmechanic 0:0bb3687e39da 547 } else {
nightmechanic 0:0bb3687e39da 548 return FALSE;
nightmechanic 0:0bb3687e39da 549 }
nightmechanic 0:0bb3687e39da 550
nightmechanic 0:0bb3687e39da 551 }
nightmechanic 0:0bb3687e39da 552
nightmechanic 0:0bb3687e39da 553 void mpu_calc_avg(MPU_data_type * MPU_data,int mpu_pointer, MPU_data_type * MPU_avg_data, int avg_len)
nightmechanic 0:0bb3687e39da 554 {
nightmechanic 0:0bb3687e39da 555 int i = 0;
nightmechanic 0:0bb3687e39da 556 //MPU_data_type MPU_avg_data;
nightmechanic 0:0bb3687e39da 557
nightmechanic 0:0bb3687e39da 558 MPU_avg_data->ax = 0;
nightmechanic 0:0bb3687e39da 559 MPU_avg_data->ay = 0;
nightmechanic 0:0bb3687e39da 560 MPU_avg_data->az = 0;
nightmechanic 0:0bb3687e39da 561 MPU_avg_data->yaw = 0;
nightmechanic 0:0bb3687e39da 562 MPU_avg_data->pitch = 0;
nightmechanic 0:0bb3687e39da 563 MPU_avg_data->roll = 0;
nightmechanic 0:0bb3687e39da 564
nightmechanic 0:0bb3687e39da 565 for (i=0 ; i < avg_len ; i++)
nightmechanic 0:0bb3687e39da 566 {
nightmechanic 0:0bb3687e39da 567 mpu_pointer++;
nightmechanic 0:0bb3687e39da 568 if (mpu_pointer >= MPU_BUFFER_LEN)
nightmechanic 0:0bb3687e39da 569 {
nightmechanic 0:0bb3687e39da 570 mpu_pointer = 0;
nightmechanic 0:0bb3687e39da 571 }
nightmechanic 0:0bb3687e39da 572 MPU_avg_data->ax += MPU_data[mpu_pointer].ax;
nightmechanic 0:0bb3687e39da 573 MPU_avg_data->ay += MPU_data[mpu_pointer].ay;
nightmechanic 0:0bb3687e39da 574 MPU_avg_data->az += MPU_data[mpu_pointer].az;
nightmechanic 0:0bb3687e39da 575 MPU_avg_data->yaw += MPU_data[mpu_pointer].yaw;
nightmechanic 0:0bb3687e39da 576 MPU_avg_data->pitch += MPU_data[mpu_pointer].pitch;
nightmechanic 0:0bb3687e39da 577 MPU_avg_data->roll += MPU_data[mpu_pointer].roll;
nightmechanic 0:0bb3687e39da 578 }
nightmechanic 0:0bb3687e39da 579
nightmechanic 0:0bb3687e39da 580 MPU_avg_data->ax = MPU_avg_data->ax / avg_len;
nightmechanic 0:0bb3687e39da 581 MPU_avg_data->ay = MPU_avg_data->ay / avg_len;
nightmechanic 0:0bb3687e39da 582 MPU_avg_data->az = MPU_avg_data->az / avg_len;
nightmechanic 0:0bb3687e39da 583 MPU_avg_data->yaw = MPU_avg_data->yaw / avg_len;
nightmechanic 0:0bb3687e39da 584 MPU_avg_data->pitch = MPU_avg_data->pitch / avg_len;
nightmechanic 0:0bb3687e39da 585 MPU_avg_data->roll = MPU_avg_data->roll / avg_len;
nightmechanic 0:0bb3687e39da 586
nightmechanic 0:0bb3687e39da 587 //return MPU_avg_data;
nightmechanic 0:0bb3687e39da 588 }
nightmechanic 0:0bb3687e39da 589
nightmechanic 0:0bb3687e39da 590 void init_color(int *color, int pulsewidth)
nightmechanic 0:0bb3687e39da 591 {
nightmechanic 0:0bb3687e39da 592 Startup_Config_OUT.write(1);
nightmechanic 0:0bb3687e39da 593 wait(1);
nightmechanic 0:0bb3687e39da 594 if (Startup_Config_IN1.read() == 1)
nightmechanic 0:0bb3687e39da 595 {
nightmechanic 0:0bb3687e39da 596 *color = GREEN;
nightmechanic 0:0bb3687e39da 597 }else if (Startup_Config_IN2.read() == 1)
nightmechanic 0:0bb3687e39da 598 {
nightmechanic 0:0bb3687e39da 599 *color = PURPLE;
nightmechanic 0:0bb3687e39da 600 }else
nightmechanic 0:0bb3687e39da 601 {
nightmechanic 0:0bb3687e39da 602
nightmechanic 0:0bb3687e39da 603 *color = BLUE;
nightmechanic 0:0bb3687e39da 604 }
nightmechanic 0:0bb3687e39da 605 Startup_Config_OUT.write(0);
nightmechanic 0:0bb3687e39da 606
nightmechanic 0:0bb3687e39da 607 Blue_LED.period_ms(LED_PWM_PERIOD);
nightmechanic 0:0bb3687e39da 608
nightmechanic 0:0bb3687e39da 609 change_color((color_type)*color, pulsewidth);
nightmechanic 0:0bb3687e39da 610 }
nightmechanic 0:0bb3687e39da 611
nightmechanic 0:0bb3687e39da 612
nightmechanic 0:0bb3687e39da 613 void change_color(color_type new_color, int new_pulsewidth)
nightmechanic 0:0bb3687e39da 614 {
nightmechanic 0:0bb3687e39da 615 Blue_LED.pulsewidth_us(0);
nightmechanic 0:0bb3687e39da 616 Green_LED.pulsewidth_us(0);
nightmechanic 0:0bb3687e39da 617 Red_LED.pulsewidth_us(0);
nightmechanic 0:0bb3687e39da 618
nightmechanic 0:0bb3687e39da 619 switch (new_color) {
nightmechanic 0:0bb3687e39da 620 case BLUE:
nightmechanic 0:0bb3687e39da 621 Blue_LED.pulsewidth_us(new_pulsewidth);
nightmechanic 0:0bb3687e39da 622 break;
nightmechanic 0:0bb3687e39da 623
nightmechanic 0:0bb3687e39da 624 case GREEN:
nightmechanic 0:0bb3687e39da 625 Green_LED.pulsewidth_us(new_pulsewidth);
nightmechanic 0:0bb3687e39da 626 break;
nightmechanic 0:0bb3687e39da 627
nightmechanic 0:0bb3687e39da 628 case PURPLE:
nightmechanic 0:0bb3687e39da 629 Blue_LED.pulsewidth_us(new_pulsewidth);
nightmechanic 0:0bb3687e39da 630 Red_LED.pulsewidth_us(new_pulsewidth);
nightmechanic 0:0bb3687e39da 631 break;
nightmechanic 0:0bb3687e39da 632
nightmechanic 0:0bb3687e39da 633 case RED:
nightmechanic 0:0bb3687e39da 634 Red_LED.pulsewidth_us(new_pulsewidth);
nightmechanic 0:0bb3687e39da 635 break;
nightmechanic 0:0bb3687e39da 636
nightmechanic 0:0bb3687e39da 637 default:
nightmechanic 0:0bb3687e39da 638 break;
nightmechanic 0:0bb3687e39da 639 }
nightmechanic 0:0bb3687e39da 640 }
nightmechanic 0:0bb3687e39da 641