From 32134b415f1e9a3fb927c85d2347169ec4eafb8d Mon Sep 17 00:00:00 2001 From: Jon Langseth Date: Mon, 29 Aug 2011 18:38:35 +0200 Subject: [PATCH] Mainly data-structure changes: Restructured global variables, actively using structs Changed a bunch of constants stored in variables to #defines Added a bit of quasi-sane initialization of model settings Saved about 800 bytes of memory use. Signed-off-by: Jon Langseth --- source/RCTXDuino/RCTXDuino.pde | 191 +++++++++++++++++++-------------- 1 file changed, 111 insertions(+), 80 deletions(-) diff --git a/source/RCTXDuino/RCTXDuino.pde b/source/RCTXDuino/RCTXDuino.pde index cf711bb..134526e 100644 --- a/source/RCTXDuino/RCTXDuino.pde +++ b/source/RCTXDuino/RCTXDuino.pde @@ -1,23 +1,35 @@ #include #include +#define MAX_INPUTS 8 + // --------------- ADC related stuffs.... -------------------- -int maxval[8]; // Stores maximum values read during calibration, setup() sets 1024 -int minval[8]; // Stores minimum values read during calibration, setup() sets 0 -int rev[8]; -int dr[8]; // The Dual-rate array uses magic numbers :P -/* dr[0] = Input channel #1 of 2 for D/R switch #1. 0 means off, 1-4 valid values. - dr[1] = Input channel #2 of 2 for D/R switch #1. 0 means off, 1-4 valid values. - dr[2] = Input channel #1 of 2 for D/R switch #2. 0 means off, 1-4 valid values. - dr[3] = Input channel #2 of 2 for D/R switch #2. 0 means off, 1-4 valid values. - dr[4] = D/R value for switch # 1 LOW(off). Value -100 to 100 in steps of 5. - dr[5] = D/R value for switch # 1 HIGH(on). Value -100 to 100 in steps of 5. - dr[6] = D/R value for switch # 1 LOW(off). Value -100 to 100 in steps of 5. - dr[7] = D/R value for switch # 1 HIGH(on). Value -100 to 100 in steps of 5. -*/ - -volatile float channel[8]; +struct input_cal_t // Struct type for input calibration values +{ + int min[MAX_INPUTS]; + int max[MAX_INPUTS]; + int center[MAX_INPUTS]; +} ; +input_cal_t input_cal; + +struct model_t +{ + int channels; // How many channels should PPM generate for this model ... + float stick[8]; // The (potentially recalc'ed) value of stick/input channel. + boolean rev[8]; + int dr[8]; // The Dual-rate array uses magic numbers :P + /* dr[0] = Input channel #1 of 2 for D/R switch #1. 0 means off, 1-4 valid values. + dr[1] = Input channel #2 of 2 for D/R switch #1. 0 means off, 1-4 valid values. + dr[2] = Input channel #1 of 2 for D/R switch #2. 0 means off, 1-4 valid values. + dr[3] = Input channel #2 of 2 for D/R switch #2. 0 means off, 1-4 valid values. + dr[4] = D/R value for switch # 1 LOW(off). Value -100 to 100 in steps of 5. + dr[5] = D/R value for switch # 1 HIGH(on). Value -100 to 100 in steps of 5. + dr[6] = D/R value for switch # 1 LOW(off). Value -100 to 100 in steps of 5. + dr[7] = D/R value for switch # 1 HIGH(on). Value -100 to 100 in steps of 5. + */ +}; +volatile model_t model; // ----------------- Display related stuffs -------------------- LiquidCrystal lcd( 12, 11, 10, 6, 7, 8, 9); @@ -26,20 +38,25 @@ LiquidCrystal lcd( 12, 11, 10, 6, 7, 8, 9); // ----------------- PPM related stuffs ------------------------ // The PPM generation is handled by Timer0 interrupts, and needs // all modifiable variables to be global and volatile... -int max_channels = 6; // How many channels should PPM generate ... + +//int max_channels = 6; // How many channels should PPM generate ... +// Moved to model_t struct... + volatile long sum = 0; // Frame-time spent so far volatile int cchannel = 0; // Current channnel volatile bool do_channel = true; // Is next operation a channel or a separator + // All time values in usecs // TODO: // The timing here (and/or in the ISR) needs to be tweaked to provide valid // RC PPM signals accepted by standard RC RX'es and the Microcopter... -long framelength = 21500; // Max length of frame -long seplength = 400; // Lenght of a channel separator -long chmax = 1700; // Max lenght of channel pulse -long chmin = 600; // Min length of channel -long chwidht = (chmax - chmin); // Useable time of channel pulse (1000) + +#define framelength 21500 // Max length of frame +#define seplength 400 // Lenght of a channel separator +#define chmax 1700 // Max lenght of channel pulse +#define chmin 600 // Min length of channel +#define chwidht (chmax - chmin)// Useable time of channel pulse // ----------------- Menu/IU related stuffs -------------------- @@ -88,10 +105,13 @@ int battery_val; #define UI_INTERVAL 250 unsigned long last = 0; -unsigned long timer_start = 0; -unsigned long timer_init = 0; -unsigned long timer_value = 0; -boolean timer_running = false; +struct clock_timer_t +{ + unsigned long start; + unsigned long init; + unsigned long value; + boolean running; +} clock_timer; // ----------------- DEBUG-STUFF -------------------- unsigned long prev_loop_time; @@ -138,10 +158,20 @@ void setup(){ t = micros(); avg_loop_time = t; prev_loop_time = t; - - dr[0] = dr[1] = dr[2] = dr[3] = 0; - dr[4] = dr[5] = dr[6] = dr[7] = 100; + // Setting this here to be sure I do not forget to init' it.... + // These initializations should be done by read_settings from eeprom, + // and this "default model values" should probably be moved + // out to a section of read_settings when handling "new model", or + // to a separate model_defaults function... + model.channels = 8; + model.rev[0] = model.rev[1] = model.rev[2] = model.rev[3] = + model.rev[4] = model.rev[5] = model.rev[6] = model.rev[7] = false; + model.dr[0] = model.dr[1] = model.dr[2] = model.dr[3] = 0; + model.dr[4] = model.dr[5] = model.dr[6] = model.dr[7] = 100; + + // Initializing the stopwatch timer/clock values... + clock_timer = (clock_timer_t){0, 0, 0, false}; } // ---------- Arduino main loop ----------------------- @@ -229,22 +259,22 @@ void calibrate() lcd.print("their extremes.."); Serial.print("Calibration. Move all controls to their extremes."); - for (i=0; i<=7; i++) { - minval[i] = 1024; - maxval[i] = 0; + for (i=0; i< MAX_INPUTS; i++) { + input_cal.min[i] = 1024; + input_cal.max[i] = 0; } while ( calcount <= num_calibrations ) { - for (i=0; i<=7; i++) { + for (i=0; i<=MAX_INPUTS; i++) { mplx_select(i); adc_in = analogRead(0); // Naive min/max calibration - if ( adc_in < minval[i] ) { - minval[i] = adc_in; + if ( adc_in < input_cal.min[i] ) { + input_cal.min[i] = adc_in; } - if ( adc_in > maxval[i] ) { - maxval[i] = adc_in; + if ( adc_in > input_cal.max[i] ) { + input_cal.max[i] = adc_in; } delay(10); } @@ -265,8 +295,9 @@ void read_settings(void) { // Dummy. Will be modified to read model settings from EEPROM for (int i=0; i<=7; i++) { - minval[i] = 0; - maxval[i] = 1024; + input_cal.min[i] = 0; + input_cal.center[i] = 512; + input_cal.max[i] = 1024; } } @@ -304,8 +335,8 @@ void process_inputs(void ) mplx_select(current_input); adc_in = analogRead(0); - channel[current_input] = ((float)adc_in - (float)minval[current_input]) / (float)(maxval[current_input]-minval[current_input]); - if ( rev[current_input] ) channel[current_input] = 1.0f - channel[current_input]; + model.stick[current_input] = ((float)adc_in - (float)input_cal.min[current_input]) / (float)(input_cal.max[current_input]-input_cal.min[current_input]); + if ( model.rev[current_input] ) model.stick[current_input] = 1.0f - model.stick[current_input]; } } @@ -323,7 +354,7 @@ void ISR_timer(void) return; } - if ( cchannel >= max_channels ) + if ( cchannel >= model.channels ) { set_ppm_output( HIGH ); long framesep = framelength - sum; @@ -338,7 +369,7 @@ void ISR_timer(void) if ( do_channel ) { set_ppm_output( HIGH ); - long next_timer = (( chwidht * channel[cchannel] ) + chmin); + long next_timer = (( chwidht * model.stick[cchannel] ) + chmin); // Do sanity-check of next_timer compared to chmax ... while ( chmax < next_timer ) next_timer--; sum += next_timer; @@ -356,18 +387,18 @@ void serial_debug() { int current_input; for (current_input=0; current_input<=7; current_input++) { - int v = (int)(channel[current_input] * 100); + int v = (int)(model.stick[current_input] * 100); Serial.print("Input #"); Serial.print(current_input); Serial.print(" value: "); - Serial.print(channel[current_input]); + Serial.print(model.stick[current_input]); Serial.print(" pct: "); Serial.print(v); Serial.print(" min: "); - Serial.print(minval[current_input]); + Serial.print(input_cal.min[current_input]); Serial.print(" max: "); - Serial.print(maxval[current_input]); + Serial.print(input_cal.max[current_input]); Serial.println(); } Serial.print("Battery level is: "); @@ -380,8 +411,8 @@ void serial_debug() } void dr_inputselect( int no, int in ) { - if ( dr[menu_substate] < 0 ) dr[menu_substate] = 4; - if ( dr[menu_substate] > 4 ) dr[menu_substate] = 0; + if ( model.dr[menu_substate] < 0 ) model.dr[menu_substate] = 4; + if ( model.dr[menu_substate] > 4 ) model.dr[menu_substate] = 0; lcd.setCursor(0 , 0); lcd.print("D/R switch "); @@ -392,15 +423,15 @@ void dr_inputselect( int no, int in ) lcd.print(in+1); lcd.print(": "); - if ( ! dr[menu_substate] ) lcd.print("Off"); - else lcd.print(dr[menu_substate]); + if ( ! model.dr[menu_substate] ) lcd.print("Off"); + else lcd.print(model.dr[menu_substate]); if ( check_key(KEY_INC) ) { - dr[menu_substate]++; + model.dr[menu_substate]++; return; } else if ( check_key(KEY_DEC) ) { - dr[menu_substate]--; + model.dr[menu_substate]--; return; } // Wrap around. @@ -427,14 +458,14 @@ void dr_value() lcd.print( state ? "HI" : "LO" ); lcd.print(" Value :"); - lcd.print( dr[pos] ); + lcd.print( model.dr[pos] ); if ( keys[KEY_INC] ) { - if ( dr[pos] < 100) dr[pos] += 5; + if ( model.dr[pos] < 100) model.dr[pos] += 5; return; } else if ( keys[KEY_DEC] ) { - if ( dr[pos] > -100) dr[pos] -= 5; + if ( model.dr[pos] > -100) model.dr[pos] -= 5; return; } @@ -496,7 +527,7 @@ void ui_handler() lcd.print(" "); lcd.setCursor(col, row); // Display uses percents, while PPM uses ratio.... - int v = (int)(channel[current_input] * 100); + int v = (int)(model.stick[current_input] * 100); lcd.print(v); } break; @@ -522,16 +553,16 @@ void ui_handler() lcd.clear(); lcd.print("Timer: "); - lcd.print( timer_running ? "Running" : "Stopped" ); + lcd.print( clock_timer.running ? "Running" : "Stopped" ); lcd.setCursor(5 , 1); - if ( timer_running ) + if ( clock_timer.running ) { - timer_value = millis() - (timer_start + timer_init); + clock_timer.value = millis() - (clock_timer.start + clock_timer.init); } - hours = ( timer_value / 1000 ) / 3600; - timer_value = timer_value % 3600000; - minutes = ( timer_value / 1000 ) / 60; - seconds = ( timer_value / 1000 ) % 60; + hours = ( clock_timer.value / 1000 ) / 3600; + clock_timer.value = clock_timer.value % 3600000; + minutes = ( clock_timer.value / 1000 ) / 60; + seconds = ( clock_timer.value / 1000 ) % 60; if ( hours ) { lcd.print(hours); lcd.print(":"); @@ -543,23 +574,23 @@ void ui_handler() lcd.print( seconds ); if ( check_key(KEY_INC) ) { - if ( !timer_running && !timer_start ) + if ( !clock_timer.running && !clock_timer.start ) { - timer_start = millis(); - timer_value = 0; - timer_running = true; - } else if ( !timer_running && timer_start ) { - timer_start = millis() - timer_value; - timer_running = true; - } else if ( timer_running ) { - timer_running = false; + clock_timer.start = millis(); + clock_timer.value = 0; + clock_timer.running = true; + } else if ( !clock_timer.running && clock_timer.start ) { + clock_timer.start = millis() - clock_timer.value; + clock_timer.running = true; + } else if ( clock_timer.running ) { + clock_timer.running = false; } return; } else if ( check_key(KEY_DEC) ) { - if ( !timer_running && timer_start ) { - timer_value = 0; - timer_start = 0; - timer_init = 0; + if ( !clock_timer.running && clock_timer.start ) { + clock_timer.value = 0; + clock_timer.start = 0; + clock_timer.init = 0; } return; } @@ -586,13 +617,13 @@ void ui_handler() case INVERTS: - if ( menu_substate >= max_channels ) menu_substate = 0; - if ( menu_substate < 0) menu_substate = (max_channels - 1); + if ( menu_substate >= model.channels ) menu_substate = 0; + if ( menu_substate < 0) menu_substate = (model.channels - 1); lcd.print("Channel invert"); lcd.setCursor(0 , 1); lcd.print("Ch "); lcd.print(menu_substate+1); - lcd.print( (rev[menu_substate] ? ": Invert" : ": Normal")); + lcd.print( (model.rev[menu_substate] ? ": Invert" : ": Normal")); if ( check_key(KEY_UP) ) { menu_mainstate = TOP; @@ -612,7 +643,7 @@ void ui_handler() return; } else if ( check_key(KEY_INC) || check_key(KEY_DEC) ) { - rev[menu_substate] ^= 1; + model.rev[menu_substate] ^= 1; return; } break; -- 2.39.2