From c41a98ba13cf6e384a62d2e5d24aa2f8fa9f0343 Mon Sep 17 00:00:00 2001
From: Thomas Lambert <t.lambert@uliege.be>
Date: Thu, 13 Jul 2023 22:06:04 +0200
Subject: [PATCH] fix(encoders): multiple issues with encoders

- Issue with interger overlow is no longer a problem. I tried to work it
  out, but as the sensors are all within range for the Q3 2023 campaign,
  I have not gone deeper into it.
- Issue with conversion between bit value and degrees properly solved.

Other changes concern calibration value to display data properly for the
Q3 2023 test campaign.
---
 controller/calibration.ino |  9 ++++++++-
 controller/controller.ino  | 10 +++++-----
 controller/sensors.ino     | 20 ++++++++++++++++++--
 controller/utils.ino       |  4 ++--
 4 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/controller/calibration.ino b/controller/calibration.ino
index 7386153..db8f683 100644
--- a/controller/calibration.ino
+++ b/controller/calibration.ino
@@ -7,8 +7,11 @@
   Then we determine the maximum position so we can make it match the maximum
   angle attainable.
 
+  WARNING: Not sure if this function is working properly or not. The second test
+  campaign (Q3 2023) did not require any special offset as all encoders were
+  staying within 12 bit without overflowing.
  -------------------------------------------------------------------------------
-  (c) Copyright 2022 University of Liege
+  (c) Copyright 2022-2023 University of Liege
   Author: Thomas Lambert <t.lambert@uliege.be>
   ULiege - Aeroelasticity and Experimental Aerodynamics
   MIT License
@@ -96,6 +99,10 @@ void GetAngleOffset(uint32_t calibTime) {
   }
 
   // Determine if offset is needed
+  //   We know that the overall amplitude is approx 60deg -> ENC_PREICSION / 6
+  //   If we measure a difference between the min and max that is more than the
+  //   preicsion/2, we are sure that we have an over/under flow somewhere.
+  //   Therefore, we conclude that we need to offset everything.
   for (int i = 0; i < sizeof(gCSN_PINS); i++) {
     if (maxPos[i] - minPos[i] > ENC_PRECISION / 2) {
       gAngleOffset[i] = 1;
diff --git a/controller/controller.ino b/controller/controller.ino
index 8850336..d6288c7 100644
--- a/controller/controller.ino
+++ b/controller/controller.ino
@@ -7,7 +7,7 @@
   wings flap at the same frequency. The phase between the two sets will be
   adjusted manually by setting their initial positions as desired.
   ------------------------------------------------------------------------------
-  (c) Copyright 2022 University of Liege
+  (c) Copyright 2022-2023 University of Liege
   Author: Thomas Lambert <t.lambert@uliege.be>
   ULiege - Aeroelasticity and Experimental Aerodynamics
   MIT License
@@ -56,9 +56,9 @@
 // Calibration of encoders
 #define ENC_PRECISION 4096  // 12-Bits encoders (nb of points per rot)
 #define ENC_ORIENT \
-  { 1, -1, 1, -1 }  // Encoder orientation
+  { 1, -1, -1, 1 }  // Encoder orientation
 #define MAX_WING_POS \
-  { 4095, 1317, 0, 1494 }     // Maximum wing angle (returned by encoder value)
+  { 3166, 2374, 1290, 1135 }  // Maximum wing angle (returned by encoder value)
 #define TRUE_MAX_ANGLE 38.07  // Maximum wing angle (measured on setup)
 
 
@@ -89,7 +89,7 @@ Servo gEsc2;  // ESC for aft motor
 
 uint8_t gEsc_val = 0;                      // ESC angle (to use with the Servo library) [0-180]
 String gMode;                              // Mode of operation
-uint16_t gAngleOffset[] = { 0, 0, 1, 0 };  // Encoder offset (prevent wrap-around)
+uint16_t gAngleOffset[] = { 0, 0, 0, 0 };  // Encoder offset (prevent wrap-around)
 uint16_t gMaxWingPos[] = MAX_WING_POS;     // Encoder maximum recorder position
 int gStartTime;                            // Loop start time
 
@@ -275,7 +275,7 @@ void SerialPrint(String mode, int potent, int esc_val, unsigned int wing_angles[
   }
   for (int i = 0; i < sizeof(gCSN_PINS); i++) {
     Serial.print(",");
-    Serial.print(PosToDeg((wing_angles[i] - gMaxWingPos[i]) % ENC_PRECISION) + TRUE_MAX_ANGLE - 360);
+    Serial.print(PosToDeg(int(wing_angles[i]) - int(gMaxWingPos[i])) + TRUE_MAX_ANGLE);
   }
   for (int i = 0; i < 2; i++) {
     Serial.print(",");
diff --git a/controller/sensors.ino b/controller/sensors.ino
index 5fb742d..d150649 100644
--- a/controller/sensors.ino
+++ b/controller/sensors.ino
@@ -3,8 +3,12 @@
 
   Functions for sensors and acquisition.
 
+  WARNING: Not sure if the application of an offset to prevent integer overflow
+  is working properly or not. The second test campaign (Q3 2023) did not require
+  any special offset as all encoders were staying within 12 bit without
+  overflowing.
   ------------------------------------------------------------------------------
-  (c) Copyright 2022 University of Liege
+  (c) Copyright 2022-2023 University of Liege
   Author: Thomas Lambert <t.lambert@uliege.be>
   ULiege - Aeroelasticity and Experimental Aerodynamics
   MIT License
@@ -30,7 +34,19 @@ unsigned int ReadSensor(uint8_t csn, int8_t orient, int8_t offset) {
 
   digitalWrite(csn, HIGH);  //deselects the encoder from reading
 
-  return (1 - orient) / 2 * ENC_PRECISION + orient * ret - (offset * ENC_PRECISION / 2);
+  // Flip the function if needed
+  ret = (1 - orient) / 2 * ENC_PRECISION + orient * ret;
+
+  // Apply offset to prevent overflow if needed
+  // FIXME: Check. It is probably not correct
+  if (offset == 1) {
+    if (ret >= 0 and ret < ENC_PRECISION / 2) {
+      ret = ret + ENC_PRECISION / 2;
+    } else {
+      ret = ret - ENC_PRECISION / 2;
+    }
+  }
+  return ret;
 }
 
 // Get the tension and current of a PSU
diff --git a/controller/utils.ino b/controller/utils.ino
index d902aa5..f3fb116 100644
--- a/controller/utils.ino
+++ b/controller/utils.ino
@@ -3,7 +3,7 @@
 
   Miscellaneous utilities.
   ------------------------------------------------------------------------------
-  (c) Copyright 2022 University of Liege
+  (c) Copyright 2022-2023 University of Liege
   Author: Thomas Lambert <t.lambert@uliege.be>
   ULiege - Aeroelasticity and Experimental Aerodynamics
   MIT License
@@ -32,7 +32,7 @@ float RpmToFreq(int rpm) {
 
 
 // Convert encoder position to degree
-float PosToDeg(unsigned int pos) {
+float PosToDeg(int pos) {
   return pos * 360.0 / ENC_PRECISION;
 }
 
-- 
GitLab