]> git.defcon.no Git - rctxduino/commitdiff
Mainly data-structure changes:
authorJon Langseth <jon.langseth@lilug.no>
Mon, 29 Aug 2011 16:38:35 +0000 (18:38 +0200)
committerJon Langseth <jon.langseth@lilug.no>
Mon, 29 Aug 2011 16:38:35 +0000 (18:38 +0200)
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 <jon.langseth@lilug.no>
source/RCTXDuino/RCTXDuino.pde

index cf711bb4700d7789d8cb07855862cb55e8baa59b..134526e76780d63e880c1a93521df7e7606d8a98 100644 (file)
@@ -1,23 +1,35 @@
 #include <LiquidCrystal.h>
 #include <TimerOne.h>
 
+#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;