From 06e94c007dd14aa2f83afe22a90befa90751ba2f Mon Sep 17 00:00:00 2001 From: mspider65 Date: Sun, 28 Feb 2021 11:07:43 +0100 Subject: [PATCH] Version 2.1.8 - Updated Hall calibration: Hall counter offset calculated for every Hall state --- app/build.gradle | 4 +- .../spider65/ebike/tsdz2_esp32/TSDZConst.java | 6 +- .../activities/HallCalibrationActivity.java | 152 ++++++++++++++---- .../activities/MotorSetupActivity.java | 68 +++----- .../ebike/tsdz2_esp32/data/TSDZ_Config.java | 25 +-- .../ebike/tsdz2_esp32/utils/Cramer.java | 80 +++++++++ .../activity_hal_sensor_calibration.xml | 143 ++++------------ .../main/res/layout/activity_motor_setup.xml | 64 ++------ app/src/main/res/values/strings.xml | 30 ++-- 9 files changed, 295 insertions(+), 277 deletions(-) create mode 100644 app/src/main/java/spider65/ebike/tsdz2_esp32/utils/Cramer.java diff --git a/app/build.gradle b/app/build.gradle index d284df1..5cdf270 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "spider65.ebike.tsdz2_esp32" minSdkVersion 23 targetSdkVersion 28 - versionCode 14 - versionName "2.1.7" + versionCode 15 + versionName "2.1.8" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/spider65/ebike/tsdz2_esp32/TSDZConst.java b/app/src/main/java/spider65/ebike/tsdz2_esp32/TSDZConst.java index 78a6864..7ac788e 100644 --- a/app/src/main/java/spider65/ebike/tsdz2_esp32/TSDZConst.java +++ b/app/src/main/java/spider65/ebike/tsdz2_esp32/TSDZConst.java @@ -54,10 +54,10 @@ public interface TSDZConst { int STATUS_ADV_SIZE = 20; // Default Hall Counter Offset values - int DEFAULT_HALL_DOWN_OFFSET = 23; // Hall counter Offset for counter starting from Hall falling edge - int DEFAULT_HALL_UP_OFFSET = 43; // Hall counter Offset for counter starting from Hall rising edge + int[] DEFAULT_HALL_OFFSET = {44,23,44,23,44,23}; + double DEFAULT_AVG_OFFSET = (double)Math.round(((44*3) + (23*3))/6D * 2) / 2.0; // average rounded to 0.5 // Default motor Phase - int DEFAULT_PHASE_OFFSET = 4; // Phase angle adjust regarding the rotor reference Hall angle + int DEFAULT_ROTOR_OFFSET = 4; // Rotor angle adjust regarding the Hall angle reference int DEFAULT_PHASE_ANGLE = 64; // Phase has 90 deg difference from rotor position } diff --git a/app/src/main/java/spider65/ebike/tsdz2_esp32/activities/HallCalibrationActivity.java b/app/src/main/java/spider65/ebike/tsdz2_esp32/activities/HallCalibrationActivity.java index 02c5a78..df481fa 100644 --- a/app/src/main/java/spider65/ebike/tsdz2_esp32/activities/HallCalibrationActivity.java +++ b/app/src/main/java/spider65/ebike/tsdz2_esp32/activities/HallCalibrationActivity.java @@ -24,6 +24,7 @@ import spider65.ebike.tsdz2_esp32.TSDZBTService; import spider65.ebike.tsdz2_esp32.TSDZConst; import spider65.ebike.tsdz2_esp32.data.TSDZ_Config; +import spider65.ebike.tsdz2_esp32.utils.Cramer; import spider65.ebike.tsdz2_esp32.utils.LinearRegression; import spider65.ebike.tsdz2_esp32.utils.RollingAverage; @@ -35,8 +36,8 @@ public class HallCalibrationActivity extends AppCompatActivity { private static final String TAG = "HallCalibration"; - private static final int SETUP_STEPS = 15; - private static final int AVG_SIZE = 150; + private static final int SETUP_STEPS = 30; + private static final int AVG_SIZE = 100; private final TSDZ_Config cfg = new TSDZ_Config(); private final IntentFilter mIntentFilter = new IntentFilter(); @@ -67,7 +68,7 @@ public class HallCalibrationActivity extends AppCompatActivity { private final LinearRegression[] linearRegression = new LinearRegression[6]; private final int[] phaseAngles = new int[6]; - private int hallUpDnDiff; + private final int[] hallTOffset = new int[6]; @Override @@ -100,7 +101,7 @@ protected void onCreate(Bundle savedInstanceState) { errorTV[5] = findViewById(R.id.err6TV); hallValuesTV = findViewById(R.id.hallValuesTV); hallUpDnDiffTV = findViewById(R.id.hallUpDnDiffTV); - resetBT = findViewById(R.id.defaultBT); + resetBT = findViewById(R.id.resetBT); cancelBT = findViewById(R.id.exitButton); saveBT = findViewById(R.id.saveButton); progressBar = findViewById(R.id.progressBar); @@ -180,11 +181,11 @@ public void onButtonClick(View view) { } else if (view.getId() == R.id.saveButton) { if (TSDZBTService.getBluetoothService() != null) { System.arraycopy(phaseAngles, 0, cfg.ui8_hall_ref_angles, 0, 6); - cfg.ui8_hall_counter_offset_up = cfg.ui8_hall_counter_offset_down + hallUpDnDiff; + System.arraycopy(hallTOffset, 0, cfg.ui8_hall_counter_offset, 0, 6); TSDZBTService.getBluetoothService().writeCfg(cfg); } else showDialog(getString(R.string.error), getString(R.string.connection_error), false); - } else if (view.getId() == R.id.defaultBT) { + } else if (view.getId() == R.id.resetBT) { for (int i=0; i<6; i++) { angleTV[i].setText(R.string.dash); offsetTV[i].setText(R.string.dash); @@ -192,12 +193,12 @@ public void onButtonClick(View view) { } for (int i=0; i<6; i++) { double v = Math.round(((30D + 60D * (double) i) * (256D / 360D) - + TSDZConst.DEFAULT_PHASE_OFFSET + + TSDZConst.DEFAULT_ROTOR_OFFSET - TSDZConst.DEFAULT_PHASE_ANGLE)); if (v < 0) v += 256; phaseAngles[i] = (int)v; } - hallUpDnDiff = TSDZConst.DEFAULT_HALL_UP_OFFSET - TSDZConst.DEFAULT_HALL_DOWN_OFFSET; + System.arraycopy(TSDZConst.DEFAULT_HALL_OFFSET,0,hallTOffset,0,hallTOffset.length); refresValues(); saveBT.setEnabled(true); showDialog("", getString(R.string.defaultLoaded), false); @@ -213,7 +214,14 @@ private void refresValues() { s.append(String.format(Locale.getDefault(), "%d", phaseAngles[i])); } hallValuesTV.setText(s.toString()); - hallUpDnDiffTV.setText(String.format(Locale.getDefault(), "%d", hallUpDnDiff)); + + s = new StringBuilder(); + for (int i=0; i<6; i++) { + if (i > 0) + s.append(" "); + s.append(String.format(Locale.getDefault(), "%d", hallTOffset[i])); + } + hallUpDnDiffTV.setText(s.toString()); } private void updateUI() { @@ -269,42 +277,113 @@ private void showDialog (String title, String message, boolean exit) { builder.show(); } - private void updateResult() { - for (int i=0; i<6; i++) { - linearRegression[i] = new LinearRegression(px[i], py[i]); - angleTV[i].setText(String.format(Locale.getDefault(),"%.1f", linearRegression[i].slope()*360)); - offsetTV[i].setText(String.format(Locale.getDefault(),"%.1f", linearRegression[i].intercept())); - errorTV[i].setText(String.format(Locale.getDefault(),"%.2f", linearRegression[i].R2())); + + /* + * F1=Hall1 Tfall, R1=Hall1 TRise, F2=Hall2 TFall etc.. + * The 6 linear equations calculated with the linear regression are dependant and have + * infinite solutions. + * Lets set F1=0 and then calculate all the other values 6 times for each equation + * combination and then calculate the average for each value. + * At the end add an offset to all values so that the total average value is TSDZConst.DEFAULT_AVG_OFFSET. + */ + private void calculateOffsets() { + final double[][] A1 = { + { 0, 0,-1, 0, 1, 0}, // -F3 + R2 = linearRegression[0].intercept(); + { 1, 0, 0, 0,-1, 0}, // F1 - R2 = linearRegression[1].intercept(); + {-1, 0, 0, 0, 0, 1}, // -F1 + R3 = linearRegression[2].intercept(); + { 0, 1, 0, 0, 0,-1}, // F2 - R3 = linearRegression[3].intercept(); + { 0,-1, 0, 1, 0, 0}, // -F2 + R1 = linearRegression[4].intercept(); + { 0, 0, 1,-1, 0, 0} // F3 - R1 = linearRegression[5].intercept(); + }; + final double[] Ak = {1,0,0,0,0,0}; // F1 = 0 + + double[][] A = new double[6][]; + double[] b = new double[6]; + + double[] result = {0,0,0,0,0,0}; + + for (int i = 0; i < 6; i++) { + for (int j = 0; j < 6; j++) { + if (j == i) { + A[j] = Ak; + b[j] = 0; + } else { + A[j] = A1[j]; + b[j] = linearRegression[j].intercept(); + } + } + Cramer cramer = new Cramer(A, b); + double[] solution = cramer.solve(); + for (int k = 0; k < solution.length; k++) { + result[k] += solution[k]; + } } - if (valuesOK()) { - showDialog("", getString(R.string.calibrationDataValid), false); - saveBT.setEnabled(true); - } else { - showDialog(getString(R.string.error), getString(R.string.calibrationDataNotValid), false); - saveBT.setEnabled(false); + for (int i=0; i<6; i++) + result[i] = result[i] / 6; + + double avgOffset = 0; + for (int i=0; i<6; i++) + avgOffset += result[i]; + avgOffset /= 6; + double diffOffset = TSDZConst.DEFAULT_AVG_OFFSET - avgOffset; + for (int i=0; i<6; i++) { + result[i] += diffOffset; } + hallTOffset[0] = (int)Math.round(result[4]); // R2 - delay for Hall state 6 + hallTOffset[1] = (int)Math.round(result[0]); // F1 - delay for Hall state 2 + hallTOffset[2] = (int)Math.round(result[5]); // R3 - delay for Hall state 3 + hallTOffset[3] = (int)Math.round(result[1]); // F2 - delay for Hall state 1 + hallTOffset[4] = (int)Math.round(result[3]); // R1 - delay for Hall state 5 + hallTOffset[5] = (int)Math.round(result[2]); // F3 - delay for Hall state 4 + } + + private void calculateAngles() { double[] calcRefAngles = {0d,0d,0d,0d,0d,0d}; double value = 0; double error = 0; + // Calculate the Hall incremental angles setting Hall state 6 = 0 degrees. + // Calculate the average offset error in regard to the reference positions. for (int i=1; i<6; i++) { value += linearRegression[i].slope()*256D; error += value - ((double)i*256D/6D); calcRefAngles[i] = value; } error /= 6D; - double offset = 0; + + // Calculate the Phase reference angles applying the error correction and the absolute + // reference position correction. for (int i=0; i<6; i++) { + // add 30 degree and subtract the calculated error calcRefAngles[i] = calcRefAngles[i] - error + 256D/12D; + // Add rotor offset and subtract phase angle (90 degree) int v = (int)Math.round(calcRefAngles[i]) - + TSDZConst.DEFAULT_PHASE_OFFSET + + TSDZConst.DEFAULT_ROTOR_OFFSET - TSDZConst.DEFAULT_PHASE_ANGLE; if (v<0) v += 256; phaseAngles[i] = v; - offset += Math.abs(linearRegression[i].intercept()); } - hallUpDnDiff = (byte)Math.round(offset/6D); + } + + private void updateResult() { + for (int i=0; i<6; i++) { + linearRegression[i] = new LinearRegression(px[i], py[i]); + angleTV[i].setText(String.format(Locale.getDefault(),"%.1f", linearRegression[i].slope()*360)); + offsetTV[i].setText(String.format(Locale.getDefault(),"%.1f", linearRegression[i].intercept())); + errorTV[i].setText(String.format(Locale.getDefault(),"%.2f", linearRegression[i].R2())); + } + + if (valuesOK()) { + showDialog("", getString(R.string.calibrationDataValid), false); + saveBT.setEnabled(true); + } else { + showDialog(getString(R.string.error), getString(R.string.calibrationDataNotValid), false); + saveBT.setEnabled(false); + } + + calculateAngles(); + calculateOffsets(); Log.d(TAG,"ui8_hall_ref_angles:" + (phaseAngles[0] & 0xff) + "," + (phaseAngles[1] & 0xff) @@ -313,7 +392,13 @@ private void updateResult() { + "," + (phaseAngles[4] & 0xff) + "," + (phaseAngles[5] & 0xff) ); - Log.d(TAG, "Hall Up-Down diff:" + hallUpDnDiff); + Log.d(TAG, "hallTOffset:" + (hallTOffset[0] & 0xff) + + "," + (hallTOffset[1] & 0xff) + + "," + (hallTOffset[2] & 0xff) + + "," + (hallTOffset[3] & 0xff) + + "," + (hallTOffset[4] & 0xff) + + "," + (hallTOffset[5] & 0xff) + ); refresValues(); } @@ -357,9 +442,8 @@ public void onReceive(Context context, Intent intent) { } System.arraycopy(cfg.ui8_hall_ref_angles, 0, phaseAngles, 0, 6); - hallUpDnDiff = cfg.ui8_hall_counter_offset_up - cfg.ui8_hall_counter_offset_down; + System.arraycopy(cfg.ui8_hall_counter_offset, 0, hallTOffset, 0, 6); refresValues(); - break; case TSDZBTService.TSDZ_CFG_WRITE_BROADCAST: if (intent.getBooleanExtra(TSDZBTService.VALUE_EXTRA,false)) @@ -389,7 +473,13 @@ public void onReceive(Context context, Intent intent) { break; } } else if (data[0] == CMD_HALL_DATA) { - if (!calibrationRunning || (msgCounter++ < SETUP_STEPS)) { + if (!calibrationRunning) { + return; + } + msgCounter++; + long progress = (100 * (step * (AVG_SIZE + SETUP_STEPS) + msgCounter)) / (4 * (AVG_SIZE + SETUP_STEPS)); + progressTV.setText(String.format(Locale.getDefault(), "%d%%", progress)); + if (msgCounter <= SETUP_STEPS) { return; } long sum = 0; @@ -400,10 +490,6 @@ public void onReceive(Context context, Intent intent) { erpsTV.setText(String.format(Locale.getDefault(), "%.2f", 250000D/sum)); if (avg[0].getIndex() == 0) nextStep(sum); - else { - long progress = (100 * (step * AVG_SIZE + avg[0].getIndex())) / (4 * AVG_SIZE); - progressTV.setText(String.format(Locale.getDefault(), "%d%%", progress)); - } } break; } diff --git a/app/src/main/java/spider65/ebike/tsdz2_esp32/activities/MotorSetupActivity.java b/app/src/main/java/spider65/ebike/tsdz2_esp32/activities/MotorSetupActivity.java index f8a8187..dc8b8ee 100644 --- a/app/src/main/java/spider65/ebike/tsdz2_esp32/activities/MotorSetupActivity.java +++ b/app/src/main/java/spider65/ebike/tsdz2_esp32/activities/MotorSetupActivity.java @@ -9,30 +9,24 @@ import android.view.View; import android.widget.TextView; -import java.util.Locale; - import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import spider65.ebike.tsdz2_esp32.R; import spider65.ebike.tsdz2_esp32.TSDZBTService; -import spider65.ebike.tsdz2_esp32.TSDZConst; import spider65.ebike.tsdz2_esp32.data.TSDZ_Config; public class MotorSetupActivity extends AppCompatActivity { private static final int MAX_ANGLE = 10; - private static final int MIN_OFFSET = 7; - private static final int MAX_OFFSET = 40; - private static final int MAX_DIFF = 30; + private static final int MAX_OFFSET = 10; private final IntentFilter mIntentFilter = new IntentFilter(); - private TextView angleValTV, hall124ValTV, hall356ValTV; + private TextView angleValTV, offsetValTV; private final TSDZ_Config cfg = new TSDZ_Config(); - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -42,8 +36,7 @@ protected void onCreate(Bundle savedInstanceState) { setSupportActionBar(toolbar); angleValTV = findViewById(R.id.angleValTV); - hall124ValTV = findViewById(R.id.hall124ValTV); - hall356ValTV = findViewById(R.id.hall356ValTV); + offsetValTV = findViewById(R.id.offsetValTV); mIntentFilter.addAction(TSDZBTService.TSDZ_CFG_READ_BROADCAST); mIntentFilter.addAction(TSDZBTService.TSDZ_CFG_WRITE_BROADCAST); @@ -56,6 +49,7 @@ protected void onCreate(Bundle savedInstanceState) { showDialog(getString(R.string.warning), getString(R.string.warning_cfg), false); } + @Override protected void onResume() { super.onResume(); @@ -82,15 +76,10 @@ else if (view.getId() == R.id.saveButton) { updated = true; } - int hall124Offset = Integer.parseInt(hall124ValTV.getText().toString()); - if (hall124Offset != cfg.ui8_hall_counter_offset_down) { - cfg.ui8_hall_counter_offset_down = hall124Offset; - updated = true; - } - - int hall356Offset = Integer.parseInt(hall356ValTV.getText().toString()); - if (hall356Offset != cfg.ui8_hall_counter_offset_up) { - cfg.ui8_hall_counter_offset_up = hall356Offset; + int offsetAdj = Integer.parseInt(offsetValTV.getText().toString()); + if (offsetAdj < 0) offsetAdj = (256 + offsetAdj); + if (offsetAdj != cfg.ui8_hall_offset_adj) { + cfg.ui8_hall_offset_adj = offsetAdj; updated = true; } @@ -101,32 +90,22 @@ else if (view.getId() == R.id.saveButton) { } else if (view.getId() == R.id.angleAddBT) { val = Integer.parseInt(angleValTV.getText().toString()); if (val < MAX_ANGLE) - angleValTV.setText(String.valueOf(++val)); + angleValTV.setText(String.valueOf(val + 1)); } else if (view.getId() == R.id.angleSubBT) { val = Integer.parseInt(angleValTV.getText().toString()); if (val > -MAX_ANGLE) - angleValTV.setText(String.valueOf(--val)); - } else if (view.getId() == R.id.hall124AddBT) { - val = Integer.parseInt(hall124ValTV.getText().toString()); - if ((val < MAX_OFFSET) && (val < Integer.parseInt(hall356ValTV.getText().toString()))) - hall124ValTV.setText(String.valueOf(++val)); - } else if (view.getId() == R.id.hall124SubBT) { - val = Integer.parseInt(hall124ValTV.getText().toString()); - if (val > MIN_OFFSET) - hall124ValTV.setText(String.valueOf(--val)); - } else if (view.getId() == R.id.hall356AddBT) { - val = Integer.parseInt(hall356ValTV.getText().toString()); - if (val < MAX_OFFSET+MAX_DIFF) - hall356ValTV.setText(String.valueOf(++val)); - } else if (view.getId() == R.id.hall356SubBT) { - val = Integer.parseInt(hall356ValTV.getText().toString()); - if (val > Integer.parseInt(hall124ValTV.getText().toString())) - hall356ValTV.setText(String.valueOf(--val)); - } else if (view.getId() == R.id.defaultBT) { + angleValTV.setText(String.valueOf(val - 1)); + } else if (view.getId() == R.id.offsetAddBT) { + val = Integer.parseInt(offsetValTV.getText().toString()); + if (val < MAX_OFFSET) + offsetValTV.setText(String.valueOf(val + 1)); + } else if (view.getId() == R.id.offsetSubBT) { + val = Integer.parseInt(offsetValTV.getText().toString()); + if (val > -MAX_OFFSET) + offsetValTV.setText(String.valueOf(val - 1)); + } else if (view.getId() == R.id.resetBT) { angleValTV.setText("0"); - hall124ValTV.setText(String.format(Locale.getDefault(), "%d", TSDZConst.DEFAULT_HALL_DOWN_OFFSET)); - hall356ValTV.setText(String.format(Locale.getDefault(), "%d", TSDZConst.DEFAULT_HALL_UP_OFFSET)); - showDialog("", getString(R.string.defaultLoaded), false); + offsetValTV.setText("0"); } } @@ -156,9 +135,10 @@ public void onReceive(Context context, Intent intent) { } int v = cfg.ui8_phase_angle_adj; if (v >= 128) v-=256; - angleValTV.setText(String.format(Locale.getDefault(),"%d", v)); - hall124ValTV.setText(String.format(Locale.getDefault(), "%d", cfg.ui8_hall_counter_offset_down)); - hall356ValTV.setText(String.format(Locale.getDefault(), "%d", cfg.ui8_hall_counter_offset_up)); + angleValTV.setText(String.valueOf(v)); + v = cfg.ui8_hall_offset_adj; + if (v >= 128) v-=256; + offsetValTV.setText(String.valueOf(v)); findViewById(R.id.saveButton).setEnabled(true); break; case TSDZBTService.TSDZ_CFG_WRITE_BROADCAST: diff --git a/app/src/main/java/spider65/ebike/tsdz2_esp32/data/TSDZ_Config.java b/app/src/main/java/spider65/ebike/tsdz2_esp32/data/TSDZ_Config.java index 1a5defe..723d747 100644 --- a/app/src/main/java/spider65/ebike/tsdz2_esp32/data/TSDZ_Config.java +++ b/app/src/main/java/spider65/ebike/tsdz2_esp32/data/TSDZ_Config.java @@ -6,7 +6,7 @@ public class TSDZ_Config { private static final String TAG = "TSDZ_Config"; - private static final int CFG_SIZE = 64; + private static final int CFG_SIZE = 68; public enum TempControl { none (0), @@ -39,7 +39,7 @@ public int getValue() { public int ui8_motor_temperature_min_value_to_limit; public int ui8_motor_temperature_max_value_to_limit; public int ui8_motor_acceleration; - public int ui8_dummy; + public int ui8_hall_offset_adj; public int ui8_max_speed; public int ui8_street_max_speed; public int ui8_pedal_torque_per_10_bit_ADC_step_x100; @@ -73,8 +73,7 @@ public int getValue() { public boolean torque_offset_fix; public int ui16_torque_offset_ADC; public int[] ui8_hall_ref_angles = new int[6]; - public int ui8_hall_counter_offset_up; - public int ui8_hall_counter_offset_down; + public int[] ui8_hall_counter_offset = new int[6]; /* #pragma pack(1) @@ -83,7 +82,7 @@ public int getValue() { volatile uint8_t ui8_motor_temperature_min_value_to_limit; volatile uint8_t ui8_motor_temperature_max_value_to_limit; volatile uint8_t ui8_motor_acceleration; - volatile uint8_t ui8_dummy; + volatile uint8_t ui8_hall_offset_adj; volatile uint8_t ui8_max_speed; volatile uint8_t ui8_street_max_speed; volatile uint8_t ui8_pedal_torque_per_10_bit_ADC_step_x100; @@ -102,7 +101,7 @@ public int getValue() { volatile uint8_t ui8_li_io_cell_full_bars_x100; volatile uint8_t ui8_li_io_cell_one_bar_x100; volatile uint8_t ui8_li_io_cell_empty_x100; - volatile uint8_t ui8_dummy2; + volatile uint8_t ui8_phase_angle_adj; volatile uint8_t ui8_street_mode_power_limit_enabled; volatile uint8_t ui8_street_mode_throttle_enabled; volatile uint8_t ui8_street_mode_power_limit_div25; @@ -115,6 +114,8 @@ public int getValue() { volatile uint8_t ui8_walk_assist_level[4]; volatile uint8_t ui8_torque_offset_fix; volatile uint16_t ui16_torque_offset_value; + volatile uint8_t ui8_hall_ref_angles[6]; + volatile uint8_t ui8_hall_offsets[6]; } struct_tsdz_cfg; */ @@ -127,7 +128,7 @@ public boolean setData(byte[] data) { ui8_motor_temperature_min_value_to_limit = (data[1] & 255); ui8_motor_temperature_max_value_to_limit = (data[2] & 255); ui8_motor_acceleration = (data[3] & 255); - ui8_dummy = (data[4] & 255 ); // ui8_cadence_sensor_mode + ui8_hall_offset_adj = (data[4] & 255 ); // ui8_cadence_sensor_mode ui8_max_speed = (data[5] & 255); ui8_street_max_speed = (data[6] & 255); ui8_pedal_torque_per_10_bit_ADC_step_x100 = (data[7] & 255); @@ -172,8 +173,8 @@ public boolean setData(byte[] data) { ui16_torque_offset_ADC = (data[54] & 255) + ((data[55] & 255) << 8); for (int i=0;i<6;i++) ui8_hall_ref_angles[i] = (data[56+i] & 255); - ui8_hall_counter_offset_up = (data[62] & 255); - ui8_hall_counter_offset_down = (data[63] & 255); + for (int i=0;i<6;i++) + ui8_hall_counter_offset[i] = (data[62+i] & 255); return true; } @@ -183,7 +184,7 @@ public byte[] toByteArray() { data[1] = (byte)ui8_motor_temperature_min_value_to_limit; data[2] = (byte)ui8_motor_temperature_max_value_to_limit; data[3] = (byte)ui8_motor_acceleration; - data[4] = (byte)ui8_dummy; + data[4] = (byte)ui8_hall_offset_adj; data[5] = (byte)ui8_max_speed; data[6] = (byte)(ui8_street_max_speed); data[7] = (byte)ui8_pedal_torque_per_10_bit_ADC_step_x100; @@ -228,8 +229,8 @@ public byte[] toByteArray() { data[55] = (byte)(ui16_torque_offset_ADC >>> 8); for (int i=0;i<6;i++) data[56+i] = (byte)(ui8_hall_ref_angles[i] & 0xff); - data[62] = (byte)(ui8_hall_counter_offset_up & 0xff); - data[63] = (byte)(ui8_hall_counter_offset_down & 0xff); + for (int i=0;i<6;i++) + data[62+i] = (byte)(ui8_hall_counter_offset[i] & 0xff); return data; } } \ No newline at end of file diff --git a/app/src/main/java/spider65/ebike/tsdz2_esp32/utils/Cramer.java b/app/src/main/java/spider65/ebike/tsdz2_esp32/utils/Cramer.java new file mode 100644 index 0000000..8bdc026 --- /dev/null +++ b/app/src/main/java/spider65/ebike/tsdz2_esp32/utils/Cramer.java @@ -0,0 +1,80 @@ +package spider65.ebike.tsdz2_esp32.utils; + +public class Cramer { + + double [][]A; + double []B; + int size; + + public Cramer() { + A = null; + B = null; + size = 0; + } + + public Cramer (double[][] m2, double[] x) { + this.A = m2; + this.B = x; + this.size = x.length; + } + + public double[] solve () { + double [][]tempMatrix = new double[size][size]; + double []x = new double[size]; + double detCohef = this.calculateCoeficientsMatrixDeterminant(); + for (int i=0;i + android:shrinkColumns="*" + android:stretchColumns="*"> - + @@ -174,188 +144,133 @@ - @@ -401,7 +316,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp" - android:text="@string/hallDiff" /> + android:text="@string/hallOffset" />