]> git.defcon.no Git - rctxduino/commitdiff
Moved to new value format on model.stick. Used to be float 0..1, is not float -100...
authorJon Langseth <jon.langseth@lilug.no>
Tue, 30 Aug 2011 16:15:28 +0000 (18:15 +0200)
committerJon Langseth <jon.langseth@lilug.no>
Tue, 30 Aug 2011 16:15:28 +0000 (18:15 +0200)
Updated process_inputs() to the new values
Added dual-rate math to process_inputs()
Updated the ISR_Timer to reflect the new value format, and added an extra sanity check
Added raw values to model datastruct for debugging
Added dumping of raw value to serial-dumping.
Tested tuning of PPM timing const's, may still be glitchy..
Moved the calibrate-trigger during startup, it did not get triggered after the change to active low logic
Removed a for-loop-limit-bug causing incorrect/invalid values for input_cal.max[0] and model.stick[0]
Changed the calibrate routine to use one int less, less code space and cycles.

source/RCTXDuino/RCTXDuino.pde

index b6c8d2651a2d36c2adb035054d5e57f0fc942cd9..5d81bc1697a6a4d5b75bfd96ac02ee2bff256980 100644 (file)
@@ -17,6 +17,7 @@ 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.
+       int raw[8];
        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.
@@ -52,10 +53,10 @@ volatile bool do_channel = true;        // Is next operation a channel or a sepa
 // 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...
 
-#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 framelength  21000             // Max length of frame
+#define seplength      300             // Lenght of a channel separator
+#define chmax         1550             // Max lenght of channel pulse
+#define chmin          620             // Min length of channel
 #define chwidht  (chmax - chmin)// Useable time of channel pulse
 
 // ----------------- Menu/IU related stuffs --------------------
@@ -137,9 +138,6 @@ void setup(){
   Serial.println("Starting....");
   delay(500);
   read_settings();
-  scan_keys();
-  if ( keys[KEY_UP])
-    calibrate();
 
   pinMode(A5, OUTPUT);  // PPM output pin  
   do_channel = false;
@@ -154,6 +152,9 @@ void setup(){
   // Unfortunately the interrupt mode is unusable in this scenario, but digital I/O works :P
   pinMode(A2, INPUT); 
   digitalWrite(A2, HIGH);
+  scan_keys();
+  if ( !keys[KEY_UP])
+    calibrate();
   
   // Debugging: how long does the main loop take on avg...  
   t = micros();
@@ -165,7 +166,7 @@ void setup(){
   // 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.channels = 6;
   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;
@@ -251,7 +252,6 @@ void mplx_select(int pin)
 void calibrate()
 {
   int i, r0, r1, r2, adc_in;
-  int calcount = 0;
   int num_calibrations = 200;
 
   lcd.clear();
@@ -260,13 +260,13 @@ void calibrate()
   lcd.print("their extremes..");
   Serial.print("Calibration. Move all controls to their extremes.");
 
-  for (i=0; i< MAX_INPUTS; i++) {
+  for (i=0; i<MAX_INPUTS; i++) {
     input_cal.min[i] = 1024;
     input_cal.max[i] = 0;
   }
-  while ( calcount <= num_calibrations )
+  while ( num_calibrations-- )
   {
-    for (i=0; i<=MAX_INPUTS; i++) {
+    for (i=0; i<MAX_INPUTS; i++) {
       mplx_select(i);
       adc_in = analogRead(0);
 
@@ -279,8 +279,6 @@ void calibrate()
       }
       delay(10);
     }
-
-    calcount++;
   }
 
   // TODO: WILL need to do center-point calibration after min-max...
@@ -330,15 +328,61 @@ void scan_keys ( void )
 
 void process_inputs(void )
 {
-  int current_input, r0, r1, r2, adc_in;
-  for (current_input=0; current_input<=7; current_input++) {
+  int current_input, adc_in, fact;
+  float min, max;
+
+  for (current_input=0; current_input<MAX_INPUTS; current_input++) {
 
     mplx_select(current_input);
     adc_in = analogRead(0);
 
-       // TODO: New format on stick values
+       model.raw[current_input] = adc_in;
+       // New format on stick values
+    if ( adc_in < input_cal.center[current_input] )
+    {
+            max = input_cal.min[current_input];
+            min = input_cal.center[current_input];
+                       fact = -100;
+    } 
+    else 
+    {
+            min = input_cal.center[current_input];
+            max = input_cal.max[current_input];
+                       fact = 100;
+    }
+    model.stick[current_input] =  fact * ((float)adc_in - min ) / (max - min);
+    if ( model.rev[current_input] ) model.stick[current_input] *= -1;
+
+    // Old format on stick values...
+    /*
     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];  
+    */
+
+    // Dual-rate calculation :D
+    // This is very repetitive code. It should be fast, but it may waste code-space.
+    float dr_val;
+    // Test to see if dualrate-switch #1 applies to channel...
+    if ( ( current_input == ( model.dr[0]-1) ) || ( current_input == ( model.dr[1]-1) ) )
+    {
+            if ( !keys[KEY_DR1] )
+                    dr_val = ((float)model.dr[4])/100.0; 
+            else
+                    dr_val = ((float)model.dr[5])/100.0;
+
+            model.stick[current_input] *= dr_val; 
+    }
+    else
+    // Test to see if dualrate-switch #1 applies to channel...
+    if ( ( current_input == ( model.dr[2]-1) ) || ( current_input == ( model.dr[3]-1) ) )
+    {
+            if ( !keys[KEY_DR1] )
+                    dr_val = ((float)model.dr[6])/100.0; 
+            else
+                    dr_val = ((float)model.dr[7])/100.0;
+
+            model.stick[current_input] *= dr_val; 
+    }
   }
 }
 
@@ -371,10 +415,17 @@ void ISR_timer(void)
   if ( do_channel )
   {
     set_ppm_output( HIGH );
-       // TODO: New format on stick values
-    long next_timer = (( chwidht * model.stick[cchannel] ) + chmin);
+
+       // New format on stick values
+    // model.stick contains percentages, -100% to 100% in float. To make the timer-handling
+    // here as simple as possible. We want to calc the channel value as a  "ratio-value",
+    // a float in the range 0..1.0. So, by moving the lower bound to 0, then cutting the
+    // range in half, and finally dividing by 100, we should get the ratio value.
+    // Some loss of presicion occurs, perhaps the algo' should be reconsidered :P
+    long next_timer = (( chwidht * ((model.stick[cchannel]+100)/200) ) + chmin);
     // Do sanity-check of next_timer compared to chmax ...
     while ( chmax < next_timer ) next_timer--;
+    while ( next_timer < chmin ) next_timer++;
     sum += next_timer;
 
     // Done with channel separator and value,
@@ -390,15 +441,13 @@ void serial_debug()
 {
   int current_input;
   for (current_input=0; current_input<=7; current_input++) {
-       // TODO: New format on stick values
-    int v = (int)(model.stick[current_input] * 100);
 
     Serial.print("Input #");
     Serial.print(current_input);
-    Serial.print(" value: ");
-    Serial.print(model.stick[current_input]);
     Serial.print(" pct: ");
-    Serial.print(v);
+    Serial.print(model.stick[current_input]);
+    Serial.print(" raw value: ");
+    Serial.print(model.raw[current_input]);
     Serial.print(" min: ");
     Serial.print(input_cal.min[current_input]);
     Serial.print(" max: ");
@@ -531,9 +580,8 @@ void ui_handler()
         lcd.print("    ");
         lcd.setCursor(col, row);
         // Display uses percents, while PPM uses ratio....
-               // TODO: New format on stick values
-        int v = (int)(model.stick[current_input] * 100);
-        lcd.print(v);
+               // New format on stick values
+               lcd.print( (int)model.stick[current_input] );
       }
       break;