From bd806cf739d098896463971c6a512426619e5230 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Sat, 19 Feb 2022 21:12:33 +0100 Subject: [PATCH 01/21] keep activity screen on always, no screensaver --- app/src/main/AndroidManifest.xml | 1 + .../java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f171d25..d14b842 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ + Date: Sun, 20 Feb 2022 09:58:08 +0100 Subject: [PATCH 02/21] fix connect issue with new BT Module in Witmotion for unknown reasons device.fetchUuidsWithSdp() interferes binding --- .../pitchgauge/BluetoothBaseActivity.java | 12 +++-------- .../j9pr/pitchgauge/BluetoothService.java | 20 +++++++++---------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothBaseActivity.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothBaseActivity.java index fde7f24..9048c5b 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothBaseActivity.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothBaseActivity.java @@ -49,16 +49,17 @@ public void onServiceConnected(ComponentName componentName, IBinder iBinder) { if (!mBluetoothPipe.isBluetoothEnabled()) { mBluetoothPipe.enable(); } else if (!mBluetoothPipe.isServiceAvailable()) { + // create a bluetooth server socket mBluetoothPipe.setupService(mBluetoothService, mHandler); mBluetoothPipe.startService(); mBluetoothPipe.autoConnect("yoyo"); } - + // connect as a bluetooth device new Handler().postDelayed(new Runnable() { public void run() { connectDevices(); } - }, 4000); + }, 100); } else { Log.w(TAG, "Service is not setup, data handler is null"); } @@ -262,15 +263,8 @@ public void run() { } }, 100); } - - new Handler().postDelayed(new Runnable() { - public void run() { - connectDevicesFromKeyring(); - } - }, 4000); } } - } diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java index 7459df3..b21c6b1 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java @@ -30,7 +30,9 @@ import static com.pitchgauge.j9pr.pitchgauge.BluetoothPipe.DEVICE_POS; public class BluetoothService extends Service { - private static UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); + // well-known Bluetooth serial board SPP UUID + private static final UUID MY_UUID = UUID.fromString((String)"00001101-0000-1000-8000-00805F9B34FB"); + private static final String NAME = "BluetoothData"; private short IDNow; @@ -359,7 +361,6 @@ public int getAvailablePosIndexForNewConnection(BluetoothDevice device) { return -1; } - public void Send(byte[] out) { // When writing, try to write out to all connected threads Log.d(TAG, "Start Writing..." + mConnThreads.size()); @@ -388,11 +389,14 @@ public synchronized int getState() { } public synchronized void start() { + + // Cancel any thread attempting to make a connection if (this.mConnectThread != null) { this.mConnectThread.cancel(); this.mConnectThread = null; } + // Cancel any thread currently running a connection if (mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null; @@ -430,16 +434,10 @@ public synchronized void connect(BluetoothDevice device, int pos) { } try { + // using the well-known Bluetooth serial board SPP UUID + Log.d(TAG, "BluetoothService connect(): Connect device UUID===" + MY_UUID); - boolean temp = device.fetchUuidsWithSdp(); - UUID uuid = null; - if( temp ){ - uuid = device.getUuids()[0].getUuid(); - } - - Log.d(TAG, "BluetoothService connect(): Connect device UUID===" + uuid); - - ConnectThread mConnectThread = new ConnectThread(device, uuid, pos); + ConnectThread mConnectThread = new ConnectThread(device, MY_UUID, pos); mConnectThread.start(); setState(BluetoothState.STATE_CONNECTING); From 24d7e6ba18ad8d1bbb2adf1612e27d45a9a34658 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Sun, 20 Feb 2022 11:41:14 +0100 Subject: [PATCH 03/21] ensure proper Witmotion sensor configuration --- .../j9pr/pitchgauge/ThrowActivity.java | 30 +++++++++++++++++++ .../j9pr/pitchgauge/ThrowGaugeViewModel.java | 11 +++++++ 2 files changed, 41 insertions(+) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java index cb440c3..dd55ea9 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java @@ -76,9 +76,17 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { } } + boolean firstMessage = true; + class DataHandler extends Handler { public void handleMessage(Message msg) { + + // send sensor configuration at startup once + if (firstMessage) { + firstMessage = false; + mGaugeViewModel.sendConfigMessage(); + } switch (msg.what) { case BluetoothState.MESSAGE_READ: @@ -183,6 +191,28 @@ public void run() { } }).start(); } + + // ensure proper sensor configuration setting + if (command.getString("Reset sensor") == "Configure sensor") { + new Thread(new Runnable() { + @Override + public void run() { + // horizontal installation + byte[] cmdString1 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x65}; + ThrowActivity.this.mBluetoothService.Send(cmdString1); + try { Thread.sleep(100); } catch(InterruptedException e) { } + // bandwidth 256 Hz + byte[] cmdString2 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; + ThrowActivity.this.mBluetoothService.Send(cmdString2); + try { Thread.sleep(100); } catch(InterruptedException e) { } + // statisc detextion 0.122 deg/sec + byte[] cmdString3 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x71}; + ThrowActivity.this.mBluetoothService.Send(cmdString3); + try { Thread.sleep(100); } catch(InterruptedException e) { } + } + }).start(); + } + } break; default: diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java index c892c93..d216197 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java @@ -553,6 +553,17 @@ public void onCalibrateClicked() { this.mHandler.sendMessage(msg); } + + public void sendConfigMessage() { + + Message msg = this.mHandler.obtainMessage(BluetoothState.MESSAGE_STATE_CHANGE); + Bundle bundle = new Bundle(); + bundle.putString("Reset sensor", "Configure sensor"); + msg.setData(bundle); + this.mHandler.sendMessage(msg); + } + + public boolean isNumeric(String str){ return str.matches("-?\\d+(.\\d+)?"); } From 48d4e042640094ebc159468b9e6201b148bdfa06 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Sun, 20 Feb 2022 11:47:10 +0100 Subject: [PATCH 04/21] send keep alive message fixes delayed instream issue with witmotion HC-02 root cause is still unknown. --- .../j9pr/pitchgauge/ThrowActivity.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java index dd55ea9..310b856 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java @@ -76,6 +76,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { } } + int frameCount = 0; boolean firstMessage = true; class DataHandler extends Handler { @@ -87,6 +88,13 @@ public void handleMessage(Message msg) { firstMessage = false; mGaugeViewModel.sendConfigMessage(); } + // send a regular keep alive message, fixes the delayed instream issue with witmotion HC-02 + if (frameCount==3) { + mGaugeViewModel.sendAliveMessage(); + frameCount = 0; + } else { + frameCount++; + } switch (msg.what) { case BluetoothState.MESSAGE_READ: @@ -191,6 +199,16 @@ public void run() { } }).start(); } + // for unknown reasons an outgoing message avoids stalling of the incoming data stream + if (command.getString("Reset sensor") == "Send alive") { + new Thread(new Runnable() { + @Override + public void run() { + byte[] cmdString = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; // bandwidth = 256Hz + ThrowActivity.this.mBluetoothService.Send(cmdString); + } + }).start(); + } // ensure proper sensor configuration setting if (command.getString("Reset sensor") == "Configure sensor") { From 5f72b4e2ef30aa60529fc102f5a882beeb97c25a Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Sun, 20 Feb 2022 14:26:14 +0100 Subject: [PATCH 05/21] german text correction --- app/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 773d836..13d6825 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -26,8 +26,8 @@ Ausschlag Werkzeuge Voreinstellungen - Verwende XY Axen (default) - Verwende XYZ Axen + Verwende XY Achsen (default) + Verwende XYZ Achsen Anzeige Sensor Einstellungen Ausschalten der WitMotion Sensor(en) nicht vergessen! From cc338682ca0b6b93c0afde977789ba5ba73503c5 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Thu, 24 Feb 2022 08:28:48 +0100 Subject: [PATCH 06/21] fix bluetooth closing issues --- .../j9pr/pitchgauge/BluetoothService.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java index b21c6b1..38f85ba 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java @@ -281,6 +281,7 @@ public void run() { } } + } catch (IOException e) { Log.e(TAG, "got disconnected " + mmSocket.getRemoteDevice(), e); connectionLost(mmSocket.getRemoteDevice()); @@ -297,11 +298,16 @@ public void write(byte[] buffer) { try { this.mmOutStream.write(buffer); BluetoothService.this.mDataHandler.obtainMessage(BluetoothState.MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); + mmOutStream.flush(); + } catch (IOException e) { } } public void cancel() { + try {this.mmInStream.close();} catch (Exception e) {} + try {this.mmOutStream.close();} catch (Exception e) {} + try {this.mmSocket.close();} catch (Exception e) {} isRunningConnectedThread = false; } } @@ -374,10 +380,12 @@ public void Send(byte[] out) { r = mConnThreads.get(i); } // Perform the write unsynchronized - if(r.isAlive()) - r.write(out); - else - r.cancel(); + if (r != null) { + if (r.isAlive()) + r.write(out); + else + r.cancel(); + } } catch (Exception e) { } } @@ -657,7 +665,8 @@ public void CopeSerialData(int acceptedLen, byte[] tempInputBuffer, int pos) { this.iError++; } long lTimeNow = System.currentTimeMillis(); - if (lTimeNow - this.lLastTime > 80) { + long delta = lTimeNow - this.lLastTime; + if (delta > 80) { this.lLastTime = lTimeNow; if (mDataHandler != null) { Message msg = this.mDataHandler.obtainMessage(BluetoothState.MESSAGE_READ); From 28d4928f252a1e2d57e0346a7e076306ad7f0043 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Thu, 24 Feb 2022 08:29:52 +0100 Subject: [PATCH 07/21] avoid blocking in while loop at send --- .../j9pr/pitchgauge/ThrowActivity.java | 71 ++++++++++++------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java index 310b856..6397534 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java @@ -16,6 +16,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.annotation.Nullable; import android.text.InputType; + import android.view.View; import android.widget.Button; import android.widget.EditText; @@ -76,25 +77,27 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { } } - int frameCount = 0; - boolean firstMessage = true; - class DataHandler extends Handler { + long lLastTime = 0; + boolean firstMessage = true; + public void handleMessage(Message msg) { // send sensor configuration at startup once - if (firstMessage) { - firstMessage = false; + if (this.firstMessage) { + this.firstMessage = false; mGaugeViewModel.sendConfigMessage(); } + // send a regular keep alive message, fixes the delayed instream issue with witmotion HC-02 - if (frameCount==3) { + long lTimeNow = System.currentTimeMillis(); + long delta = lTimeNow - this.lLastTime; + if (delta > 1000) { + this.lLastTime = lTimeNow; mGaugeViewModel.sendAliveMessage(); - frameCount = 0; - } else { - frameCount++; } + switch (msg.what) { case BluetoothState.MESSAGE_READ: @@ -146,13 +149,16 @@ public void handleMessage(Message msg) { default: return; } + } catch (Exception e) { return; } default: return; + } + } } @@ -162,6 +168,9 @@ class SendSensor extends Handler { public void handleMessage(Message msg) { + // ensure time gap between sensor messages, otherwise BT connection breaks occasionally + try { Thread.sleep(300); } catch(InterruptedException e) { } + switch (msg.what) { case BluetoothState.MESSAGE_STATE_CHANGE: if (ThrowActivity.this.mBluetoothPipe.isServiceAvailable()) { @@ -175,12 +184,13 @@ public void run() { ThrowActivity.this.mBluetoothService.Send(ResetZaxis); try { Thread.sleep(1000); } catch(InterruptedException e) { } ThrowActivity.this.resetSensor(); - while (!ThrowActivity.this.hasResumed()) ; + while (!ThrowActivity.this.hasResumed()) { // do not block in while loop + try { Thread.sleep(1); } catch(InterruptedException e) {}; + } ThrowActivity.this.resetNeutral(); ThrowActivity.this.busyReset = false; } }).start(); - } if (command.getString("Reset sensor") == "Calibrate") { new Thread(new Runnable() { @@ -193,7 +203,13 @@ public void run() { ThrowActivity.this.resetSensor(); try { Thread.sleep(1000); } catch(InterruptedException e) { } ThrowActivity.this.resetSensor(); - while (!ThrowActivity.this.hasResumed()) ; + byte[] ResetZaxis = {(byte) 0xFF, (byte) 0xAA, (byte) 0x52}; + ThrowActivity.this.mBluetoothService.Send(ResetZaxis); + try { Thread.sleep(1000); } catch(InterruptedException e) { } + ThrowActivity.this.resetSensor(); + while (!ThrowActivity.this.hasResumed()) { // do not block in while loop + try { Thread.sleep(1); } catch(InterruptedException e) {}; + } ThrowActivity.this.resetNeutral(); ThrowActivity.this.busyCalibration = false; } @@ -204,7 +220,8 @@ public void run() { new Thread(new Runnable() { @Override public void run() { - byte[] cmdString = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; // bandwidth = 256Hz + // use a dummy command, bandwidth=256Hz + byte[] cmdString = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; ThrowActivity.this.mBluetoothService.Send(cmdString); } }).start(); @@ -216,17 +233,17 @@ public void run() { @Override public void run() { // horizontal installation - byte[] cmdString1 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x65}; - ThrowActivity.this.mBluetoothService.Send(cmdString1); - try { Thread.sleep(100); } catch(InterruptedException e) { } - // bandwidth 256 Hz - byte[] cmdString2 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; - ThrowActivity.this.mBluetoothService.Send(cmdString2); - try { Thread.sleep(100); } catch(InterruptedException e) { } - // statisc detextion 0.122 deg/sec - byte[] cmdString3 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x71}; - ThrowActivity.this.mBluetoothService.Send(cmdString3); - try { Thread.sleep(100); } catch(InterruptedException e) { } +// byte[] cmdString1 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x65}; +// ThrowActivity.this.mBluetoothService.Send(cmdString1); +// try { Thread.sleep(100); } catch(InterruptedException e) { } +// // bandwidth 256 Hz +// byte[] cmdString2 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; +// ThrowActivity.this.mBluetoothService.Send(cmdString2); +// try { Thread.sleep(100); } catch(InterruptedException e) { } +// // statisc detextion 0.122 deg/sec +// byte[] cmdString3 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x71}; +// ThrowActivity.this.mBluetoothService.Send(cmdString3); +// try { Thread.sleep(100); } catch(InterruptedException e) { } } }).start(); } @@ -355,15 +372,15 @@ public void onChanged(@Nullable ThrowGauge user) { btWatcher.start(); } - public void resetNeutral(){ + public void resetNeutral() { mGaugeViewModel.resetNeutral(); } - public void resetSensor(){ + public void resetSensor() { mGaugeViewModel.resetSensorPosition(); } - public boolean hasResumed(){ + public boolean hasResumed() { return mGaugeViewModel.HasResumed(); } From 29ed177db2645ae31030435ba48d88783ba40a47 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Thu, 24 Feb 2022 08:30:43 +0100 Subject: [PATCH 08/21] add low pass for angle and thresholds for min/max --- .../j9pr/pitchgauge/ThrowGauge.java | 69 ++++++++++++++++--- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java index 7b8306a..c7f173e 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java @@ -13,13 +13,24 @@ public class ThrowGauge { double mChord = 0; double mAngle = 0; double mQuatAngle = 0; - double mOffsetAngle = 0; double mMaxThrow = 0; double mMinThrow = 0; double mTemperature = 0; double mMaxTravelAlarm = 0; double mMinTravelAlarm = 0; double mCurrentTravel = 0; + + // low pass filter + long t0 = 0; + long t1 = 0; + double mQuatAngleFiltered = 0.0; + double mAngleFiltered = 0.0; + double tauLP = 0.3; // time constant tau in seconds + + // min/max thresholds + int iMin = 0; + int iMax = 0; + Vector3d mAcceleration = new Vector3d(); Vector3d mAngularVelocity = new Vector3d(); @@ -42,7 +53,6 @@ public void SetNeutral() mMaxThrow = 0; mResetArmed = false; /*** simple method ***/ - mOffsetAngle = mAngle; mAngle = 0; /*** quaternion method ***/ toQuaternion(mQBoardNeutral, mEulerYaw, mEulerPitch, mEulerRoll); @@ -167,7 +177,22 @@ public double GetNeutralQuatW(){ } public double ResolveSimpleThrow() { - mCurrentTravel = - mChord * Math.sin( Math.toRadians(mAngle)); + + // get delta T + t1 = System.currentTimeMillis(); + long deltaT = t1 - t0; + t0 = t1; + + // low pass filter mAngleFiltered + if (t0 != 0) { + double kLP = tauLP / (tauLP + deltaT / 1000.0); + mAngleFiltered = mAngleFiltered + ( 1 - kLP) * (mAngle - mAngleFiltered); + } else { + mAngleFiltered = 0.0; + } + + mCurrentTravel = - mChord * Math.sin( Math.toRadians(mAngleFiltered)); + if(mCurrentTravel < mMinThrow) mMinThrow = mCurrentTravel; if(mCurrentTravel > mMaxThrow) @@ -210,11 +235,39 @@ public double ResolveQuatsThrow() { mQuatAngle = 0; } - mCurrentTravel = mChord * Math.sin(mQuatAngle); - if(mCurrentTravel < mMinThrow) - mMinThrow = mCurrentTravel; - if(mCurrentTravel > mMaxThrow) - mMaxThrow = mCurrentTravel; + // get delta T + t1 = System.currentTimeMillis(); + long deltaT = t1 - t0; + t0 = t1; + + // low pass filter mQuatAngle + if (t0 != 0) { + double kLP = tauLP / (tauLP + deltaT / 1000.0); + mQuatAngleFiltered = mQuatAngleFiltered + ( 1 - kLP) * (mQuatAngle - mQuatAngleFiltered); + } else { + mQuatAngleFiltered = 0.0; + } + + mCurrentTravel = mChord * Math.sin(mQuatAngleFiltered); + + if(mCurrentTravel < mMinThrow) { + iMin++; + if (iMin > 5) { + mMinThrow = mCurrentTravel; + iMin = 0; + } + } else { + iMin = 0; + } + if(mCurrentTravel > mMaxThrow) { + iMax++; + if (iMax > 5) { + mMaxThrow = mCurrentTravel; + iMax = 0; + } + } else { + iMax = 0; + } return mCurrentTravel; } From 4a934570b2af635dcdc9655e0a2d566031cc98ec Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Thu, 24 Feb 2022 08:31:21 +0100 Subject: [PATCH 09/21] alive message for HC-02 --- .../pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java index d216197..2b323c7 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java @@ -553,6 +553,14 @@ public void onCalibrateClicked() { this.mHandler.sendMessage(msg); } + public void sendAliveMessage() { + + Message msg = this.mHandler.obtainMessage(BluetoothState.MESSAGE_STATE_CHANGE); + Bundle bundle = new Bundle(); + bundle.putString("Reset sensor", "Send alive"); + msg.setData(bundle); + this.mHandler.sendMessage(msg); + } public void sendConfigMessage() { From 6a30fa575a8049cbfaf4dfcd47940c1dfbe2a4e9 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Fri, 25 Feb 2022 19:43:59 +0100 Subject: [PATCH 10/21] fixed issue with keep-alive message overlap reset commands --- .../j9pr/pitchgauge/ThrowActivity.java | 165 +++++++++--------- 1 file changed, 87 insertions(+), 78 deletions(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java index 6397534..a4cb643 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java @@ -79,8 +79,8 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { class DataHandler extends Handler { - long lLastTime = 0; - boolean firstMessage = true; + private long lLastTime = 0; + private boolean firstMessage = true; public void handleMessage(Message msg) { @@ -93,7 +93,7 @@ public void handleMessage(Message msg) { // send a regular keep alive message, fixes the delayed instream issue with witmotion HC-02 long lTimeNow = System.currentTimeMillis(); long delta = lTimeNow - this.lLastTime; - if (delta > 1000) { + if (delta > 500) { this.lLastTime = lTimeNow; mGaugeViewModel.sendAliveMessage(); } @@ -168,93 +168,102 @@ class SendSensor extends Handler { public void handleMessage(Message msg) { - // ensure time gap between sensor messages, otherwise BT connection breaks occasionally - try { Thread.sleep(300); } catch(InterruptedException e) { } + if (!(ThrowActivity.this.busyReset | ThrowActivity.this.busyCalibration)) { + switch (msg.what) { + case BluetoothState.MESSAGE_STATE_CHANGE: + if (ThrowActivity.this.mBluetoothPipe.isServiceAvailable()) { + Bundle command = msg.getData(); - switch (msg.what) { - case BluetoothState.MESSAGE_STATE_CHANGE: - if (ThrowActivity.this.mBluetoothPipe.isServiceAvailable()) { - Bundle command = msg.getData(); - if (command.getString("Reset sensor") == "New neutral") { - new Thread(new Runnable() { - @Override - public void run() { + // reset button + if (command.getString("Reset sensor") == "New neutral") { ThrowActivity.this.busyReset = true; - byte[] ResetZaxis = {(byte) 0xFF, (byte) 0xAA, (byte) 0x52}; - ThrowActivity.this.mBluetoothService.Send(ResetZaxis); - try { Thread.sleep(1000); } catch(InterruptedException e) { } - ThrowActivity.this.resetSensor(); - while (!ThrowActivity.this.hasResumed()) { // do not block in while loop - try { Thread.sleep(1); } catch(InterruptedException e) {}; - } - ThrowActivity.this.resetNeutral(); - ThrowActivity.this.busyReset = false; + new Thread(new Runnable() { + @Override + public void run() { + byte[] ResetZaxis = {(byte) 0xFF, (byte) 0xAA, (byte) 0x52}; + ThrowActivity.this.mBluetoothService.Send(ResetZaxis); + try { Thread.sleep(300); } catch(InterruptedException e) {}; + ThrowActivity.this.resetSensor(); + while (!ThrowActivity.this.hasResumed()) { // do not block in while loop + try { Thread.sleep(100); } catch(InterruptedException e) {}; + } + try { Thread.sleep(300); } catch(InterruptedException e) {}; + ThrowActivity.this.resetNeutral(); + ThrowActivity.this.busyReset = false; + } + }).start(); } - }).start(); - } - if (command.getString("Reset sensor") == "Calibrate") { - new Thread(new Runnable() { - @Override - public void run() { + + // calibrate button + if (command.getString("Reset sensor") == "Calibrate") { ThrowActivity.this.busyCalibration = true; - byte[] CalibrationCmd = {(byte) 0xFF, (byte) 0xAA, (byte) 0x67}; - ThrowActivity.this.mBluetoothService.Send(CalibrationCmd); - try { Thread.sleep(10000); } catch(InterruptedException e) { } - ThrowActivity.this.resetSensor(); - try { Thread.sleep(1000); } catch(InterruptedException e) { } - ThrowActivity.this.resetSensor(); - byte[] ResetZaxis = {(byte) 0xFF, (byte) 0xAA, (byte) 0x52}; - ThrowActivity.this.mBluetoothService.Send(ResetZaxis); - try { Thread.sleep(1000); } catch(InterruptedException e) { } - ThrowActivity.this.resetSensor(); - while (!ThrowActivity.this.hasResumed()) { // do not block in while loop - try { Thread.sleep(1); } catch(InterruptedException e) {}; - } - ThrowActivity.this.resetNeutral(); - ThrowActivity.this.busyCalibration = false; + new Thread(new Runnable() { + @Override + public void run() { + ThrowActivity.this.busyCalibration = true; + byte[] CalibrationCmd = {(byte) 0xFF, (byte) 0xAA, (byte) 0x66}; + //ThrowActivity.this.mBluetoothService.Send(CalibrationCmd); + try { Thread.sleep(10000); } catch(InterruptedException e) {}; + ThrowActivity.this.resetSensor(); + byte[] ResetZaxis = {(byte) 0xFF, (byte) 0xAA, (byte) 0x52}; + ThrowActivity.this.mBluetoothService.Send(ResetZaxis); + try { Thread.sleep(1000); } catch(InterruptedException e) {}; + ThrowActivity.this.resetSensor(); + while (!ThrowActivity.this.hasResumed()) { // do not block in while loop + try { Thread.sleep(100); } catch(InterruptedException e) {}; + } + try { Thread.sleep(300); } catch(InterruptedException e) {}; + ThrowActivity.this.resetNeutral(); + ThrowActivity.this.busyCalibration = false; + } + }).start(); } - }).start(); - } - // for unknown reasons an outgoing message avoids stalling of the incoming data stream - if (command.getString("Reset sensor") == "Send alive") { - new Thread(new Runnable() { - @Override - public void run() { - // use a dummy command, bandwidth=256Hz - byte[] cmdString = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; - ThrowActivity.this.mBluetoothService.Send(cmdString); + + // for unknown reasons an outgoing message avoids stalling of the incoming data stream + if (command.getString("Reset sensor") == "Send alive") { + new Thread(new Runnable() { + @Override + public void run() { + // send a dummy sequence + byte[] cmdString = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; + ThrowActivity.this.mBluetoothService.Send(cmdString); + } + }).start(); } - }).start(); - } - // ensure proper sensor configuration setting - if (command.getString("Reset sensor") == "Configure sensor") { - new Thread(new Runnable() { - @Override - public void run() { - // horizontal installation -// byte[] cmdString1 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x65}; -// ThrowActivity.this.mBluetoothService.Send(cmdString1); -// try { Thread.sleep(100); } catch(InterruptedException e) { } -// // bandwidth 256 Hz -// byte[] cmdString2 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; -// ThrowActivity.this.mBluetoothService.Send(cmdString2); -// try { Thread.sleep(100); } catch(InterruptedException e) { } -// // statisc detextion 0.122 deg/sec -// byte[] cmdString3 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x71}; -// ThrowActivity.this.mBluetoothService.Send(cmdString3); -// try { Thread.sleep(100); } catch(InterruptedException e) { } + // ensure proper sensor configuration setting + if (command.getString("Reset sensor") == "Configure sensor") { + ThrowActivity.this.busyCalibration = true; + new Thread(new Runnable() { + @Override + public void run() { + try { Thread.sleep(500); } catch(InterruptedException e) { } + // horizontal installation + byte[] cmdString1 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x65}; + ThrowActivity.this.mBluetoothService.Send(cmdString1); + try { Thread.sleep(100); } catch(InterruptedException e) { } + // bandwidth 256 Hz + byte[] cmdString2 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; + ThrowActivity.this.mBluetoothService.Send(cmdString2); + try { Thread.sleep(100); } catch(InterruptedException e) { } + // static detection 0.122 deg/sec + byte[] cmdString3 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x71}; + ThrowActivity.this.mBluetoothService.Send(cmdString3); + try { Thread.sleep(100); } catch(InterruptedException e) { } + ThrowActivity.this.busyCalibration = false; + } + }).start(); } - }).start(); - } + } + break; + default: + return; } - break; - default: - return; + } } } - } + @Override From 4c6c35a4e36aaf7858718692eb4b59aa3df47491 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Mon, 28 Feb 2022 22:53:45 +0100 Subject: [PATCH 11/21] fix LP bug --- .../main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java index c7f173e..b562ae9 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java @@ -25,7 +25,7 @@ public class ThrowGauge { long t1 = 0; double mQuatAngleFiltered = 0.0; double mAngleFiltered = 0.0; - double tauLP = 0.3; // time constant tau in seconds + double tauLP = 0.05; // time constant tau in seconds // min/max thresholds int iMin = 0; @@ -56,6 +56,8 @@ public void SetNeutral() mAngle = 0; /*** quaternion method ***/ toQuaternion(mQBoardNeutral, mEulerYaw, mEulerPitch, mEulerRoll); + mQuatAngle = 0; + mQuatAngleFiltered = 0; } public boolean HasResumed() { @@ -248,6 +250,7 @@ public double ResolveQuatsThrow() { mQuatAngleFiltered = 0.0; } + mQuatAngle = mQuatAngleFiltered; mCurrentTravel = mChord * Math.sin(mQuatAngleFiltered); if(mCurrentTravel < mMinThrow) { From af39d15e0d71a74d0178838d76193fb271dad413 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Mon, 28 Feb 2022 22:54:31 +0100 Subject: [PATCH 12/21] configuration issues, reset killed BT connection on old sensors --- .../j9pr/pitchgauge/ThrowActivity.java | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java index a4cb643..0e55d61 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java @@ -93,7 +93,7 @@ public void handleMessage(Message msg) { // send a regular keep alive message, fixes the delayed instream issue with witmotion HC-02 long lTimeNow = System.currentTimeMillis(); long delta = lTimeNow - this.lLastTime; - if (delta > 500) { + if (delta > 2000) { this.lLastTime = lTimeNow; mGaugeViewModel.sendAliveMessage(); } @@ -166,9 +166,10 @@ class SendSensor extends Handler { SendSensor() { } + private boolean txBusy = false; public void handleMessage(Message msg) { - if (!(ThrowActivity.this.busyReset | ThrowActivity.this.busyCalibration)) { + if (!(txBusy)) { switch (msg.what) { case BluetoothState.MESSAGE_STATE_CHANGE: if (ThrowActivity.this.mBluetoothPipe.isServiceAvailable()) { @@ -177,9 +178,11 @@ public void handleMessage(Message msg) { // reset button if (command.getString("Reset sensor") == "New neutral") { ThrowActivity.this.busyReset = true; + txBusy = true; new Thread(new Runnable() { @Override public void run() { + ThrowActivity.this.busyReset = true; byte[] ResetZaxis = {(byte) 0xFF, (byte) 0xAA, (byte) 0x52}; ThrowActivity.this.mBluetoothService.Send(ResetZaxis); try { Thread.sleep(300); } catch(InterruptedException e) {}; @@ -190,6 +193,7 @@ public void run() { try { Thread.sleep(300); } catch(InterruptedException e) {}; ThrowActivity.this.resetNeutral(); ThrowActivity.this.busyReset = false; + txBusy = false; } }).start(); } @@ -197,12 +201,13 @@ public void run() { // calibrate button if (command.getString("Reset sensor") == "Calibrate") { ThrowActivity.this.busyCalibration = true; + txBusy = true; new Thread(new Runnable() { @Override public void run() { ThrowActivity.this.busyCalibration = true; byte[] CalibrationCmd = {(byte) 0xFF, (byte) 0xAA, (byte) 0x66}; - //ThrowActivity.this.mBluetoothService.Send(CalibrationCmd); + ThrowActivity.this.mBluetoothService.Send(CalibrationCmd); try { Thread.sleep(10000); } catch(InterruptedException e) {}; ThrowActivity.this.resetSensor(); byte[] ResetZaxis = {(byte) 0xFF, (byte) 0xAA, (byte) 0x52}; @@ -215,42 +220,57 @@ public void run() { try { Thread.sleep(300); } catch(InterruptedException e) {}; ThrowActivity.this.resetNeutral(); ThrowActivity.this.busyCalibration = false; + txBusy = false; } }).start(); } // for unknown reasons an outgoing message avoids stalling of the incoming data stream if (command.getString("Reset sensor") == "Send alive") { + txBusy = true; new Thread(new Runnable() { @Override public void run() { + try { Thread.sleep(100); } catch(InterruptedException e) {}; // send a dummy sequence - byte[] cmdString = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; - ThrowActivity.this.mBluetoothService.Send(cmdString); + byte[] CommandZero = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; + ThrowActivity.this.mBluetoothService.Send(CommandZero); + txBusy = false; } }).start(); } // ensure proper sensor configuration setting if (command.getString("Reset sensor") == "Configure sensor") { - ThrowActivity.this.busyCalibration = true; + txBusy = true; new Thread(new Runnable() { @Override public void run() { - try { Thread.sleep(500); } catch(InterruptedException e) { } + try { Thread.sleep(100); } catch(InterruptedException e) { } + byte[] CommandZero = {(byte) 0xFF, (byte) 0xAA, (byte) 0x00}; + // horizontal installation byte[] cmdString1 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x65}; ThrowActivity.this.mBluetoothService.Send(cmdString1); + try { Thread.sleep(250); } catch(InterruptedException e) { } + ThrowActivity.this.mBluetoothService.Send(CommandZero); try { Thread.sleep(100); } catch(InterruptedException e) { } + // bandwidth 256 Hz byte[] cmdString2 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; ThrowActivity.this.mBluetoothService.Send(cmdString2); + try { Thread.sleep(250); } catch(InterruptedException e) { } + ThrowActivity.this.mBluetoothService.Send(CommandZero); try { Thread.sleep(100); } catch(InterruptedException e) { } + // static detection 0.122 deg/sec byte[] cmdString3 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x71}; ThrowActivity.this.mBluetoothService.Send(cmdString3); + try { Thread.sleep(250); } catch(InterruptedException e) { } + ThrowActivity.this.mBluetoothService.Send(CommandZero); try { Thread.sleep(100); } catch(InterruptedException e) { } - ThrowActivity.this.busyCalibration = false; + + txBusy = false; } }).start(); } From edd6ea9a6c409b4fddf871e1b5d78af1ad972aa6 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Wed, 2 Mar 2022 20:29:18 +0100 Subject: [PATCH 13/21] minor change in lowpass time constant --- .../main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java index b562ae9..d4c62c2 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGauge.java @@ -25,7 +25,7 @@ public class ThrowGauge { long t1 = 0; double mQuatAngleFiltered = 0.0; double mAngleFiltered = 0.0; - double tauLP = 0.05; // time constant tau in seconds + double tauLP = 0.07; // time constant tau in seconds // min/max thresholds int iMin = 0; From 402ac81cd55077eb0c7e2299f96fdf8d48339c68 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Wed, 2 Mar 2022 20:30:42 +0100 Subject: [PATCH 14/21] removed unused readThread, with zero-delay endless loop. --- .../pitchgauge/BluetoothBaseActivity.java | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothBaseActivity.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothBaseActivity.java index 9048c5b..53b119d 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothBaseActivity.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothBaseActivity.java @@ -267,7 +267,6 @@ public void run() { } } - @Override protected void onDestroy() { doUnbind(); @@ -276,28 +275,8 @@ protected void onDestroy() { private boolean SerialPortOpen() { this.isOpen = true; - new readThread().start(); + //new readThread().start(); // note by AHa: readThread not used return true; } - private class readThread extends Thread { - - public void run() { - byte[] buffer = new byte[4096]; - while (true) { - Message msg = Message.obtain(); - if (BluetoothBaseActivity.this.isOpen) { - //ThrowActivity.this.handler.sendMessage(msg); - } - else { - try { - Thread.sleep(50); - return; - } catch (Exception e) { - return; - } - } - } - } - } } From f30f09f5d93e15036098def5825c710f08778886 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Wed, 2 Mar 2022 20:31:52 +0100 Subject: [PATCH 15/21] bug fix in time calculation for update time limit in dual-mode --- .../pitchgauge/j9pr/pitchgauge/BluetoothService.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java index 38f85ba..7ea2b56 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/BluetoothService.java @@ -41,7 +41,7 @@ public class BluetoothService extends Service { private int ar = 16; private int av = 2000; private int iError = 0; - long lLastTime = System.currentTimeMillis(); + long[] lLastTime = {System.currentTimeMillis(), System.currentTimeMillis()}; private AcceptThread mAcceptThread; private final BluetoothAdapter mAdapter; private ConnectThread mConnectThread; @@ -664,10 +664,12 @@ public void CopeSerialData(int acceptedLen, byte[] tempInputBuffer, int pos) { } this.iError++; } + long lTimeNow = System.currentTimeMillis(); - long delta = lTimeNow - this.lLastTime; - if (delta > 80) { - this.lLastTime = lTimeNow; + long delta = lTimeNow - this.lLastTime[pos]; + if (delta > 10) { // avoid short update intervals + this.lLastTime[pos] = lTimeNow; + //Log.e(TAG, "pos=" + pos + " inputBuffer delta(ms)=" + delta); if (mDataHandler != null) { Message msg = this.mDataHandler.obtainMessage(BluetoothState.MESSAGE_READ); Bundle bundle = new Bundle(); From 1f909ef52c1b3f7b0bf853badaa6f63e26ce4c7e Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Wed, 2 Mar 2022 20:33:16 +0100 Subject: [PATCH 16/21] avoid command transmission overlaps, fix witmotion configuration and reset commands --- .../j9pr/pitchgauge/ThrowActivity.java | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java index 0e55d61..5abab88 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java @@ -206,7 +206,7 @@ public void run() { @Override public void run() { ThrowActivity.this.busyCalibration = true; - byte[] CalibrationCmd = {(byte) 0xFF, (byte) 0xAA, (byte) 0x66}; + byte[] CalibrationCmd = {(byte) 0xFF, (byte) 0xAA, (byte) 0x67}; ThrowActivity.this.mBluetoothService.Send(CalibrationCmd); try { Thread.sleep(10000); } catch(InterruptedException e) {}; ThrowActivity.this.resetSensor(); @@ -243,10 +243,11 @@ public void run() { // ensure proper sensor configuration setting if (command.getString("Reset sensor") == "Configure sensor") { txBusy = true; + ThrowActivity.this.busyReset = true; new Thread(new Runnable() { @Override public void run() { - try { Thread.sleep(100); } catch(InterruptedException e) { } + try { Thread.sleep(2000); } catch(InterruptedException e) { } byte[] CommandZero = {(byte) 0xFF, (byte) 0xAA, (byte) 0x00}; // horizontal installation @@ -256,20 +257,41 @@ public void run() { ThrowActivity.this.mBluetoothService.Send(CommandZero); try { Thread.sleep(100); } catch(InterruptedException e) { } - // bandwidth 256 Hz - byte[] cmdString2 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; + try { Thread.sleep(2000); } catch(InterruptedException e) { } + + // Update rate 100Hz (115200 baudrate) + byte[] cmdString2 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x64}; ThrowActivity.this.mBluetoothService.Send(cmdString2); try { Thread.sleep(250); } catch(InterruptedException e) { } ThrowActivity.this.mBluetoothService.Send(CommandZero); try { Thread.sleep(100); } catch(InterruptedException e) { } - // static detection 0.122 deg/sec - byte[] cmdString3 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x71}; + // bandwidth 256 Hz + byte[] cmdString3 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x81}; ThrowActivity.this.mBluetoothService.Send(cmdString3); try { Thread.sleep(250); } catch(InterruptedException e) { } ThrowActivity.this.mBluetoothService.Send(CommandZero); try { Thread.sleep(100); } catch(InterruptedException e) { } + // static detection 0.122 deg/sec + byte[] cmdString4 = {(byte) 0xFF, (byte) 0xAA, (byte) 0x71}; + ThrowActivity.this.mBluetoothService.Send(cmdString4); + try { Thread.sleep(250); } catch(InterruptedException e) { } + ThrowActivity.this.mBluetoothService.Send(CommandZero); + try { Thread.sleep(100); } catch(InterruptedException e) { } + +// // do an initial reset at startup +// byte[] ResetZaxis = {(byte) 0xFF, (byte) 0xAA, (byte) 0x52}; +// ThrowActivity.this.mBluetoothService.Send(ResetZaxis); +// try { Thread.sleep(300); } catch(InterruptedException e) {}; +// ThrowActivity.this.resetSensor(); +// while (!ThrowActivity.this.hasResumed()) { // do not block in while loop +// try { Thread.sleep(100); } catch(InterruptedException e) {}; +// } +// try { Thread.sleep(300); } catch(InterruptedException e) {}; +// ThrowActivity.this.resetNeutral(); + + ThrowActivity.this.busyReset = false; txBusy = false; } }).start(); From 289717ea4010177f98f53807fa2edf575fcd39ef Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Wed, 2 Mar 2022 21:57:44 +0100 Subject: [PATCH 17/21] use gradient up/down for min/max red color --- .../j9pr/pitchgauge/ThrowGaugeViewModel.java | 18 ++++++++++++------ .../res/drawable/layout_range_red_down.xml | 19 +++++++++++++++++++ .../main/res/drawable/layout_range_red_up.xml | 19 +++++++++++++++++++ app/src/main/res/values/colors.xml | 2 ++ 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 app/src/main/res/drawable/layout_range_red_down.xml create mode 100644 app/src/main/res/drawable/layout_range_red_up.xml diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java index 2b323c7..634c105 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowGaugeViewModel.java @@ -437,18 +437,24 @@ public String getMinTravelSetNum() { @Bindable public Drawable getTravelColor() { - if(getThrowGauge().getValue().IsBelowTravelMin() || getThrowGauge().getValue().IsAboveTravelMax()) - return ResourcesCompat.getDrawable(getApplication().getResources(), R.drawable.layout_range_red, null); - else + if (getThrowGauge().getValue().IsBelowTravelMin()) { + return ResourcesCompat.getDrawable(getApplication().getResources(), R.drawable.layout_range_red_down, null); + } else if (getThrowGauge().getValue().IsAboveTravelMax()) { + return ResourcesCompat.getDrawable(getApplication().getResources(), R.drawable.layout_range_red_up, null); + } else { return ResourcesCompat.getDrawable(getApplication().getResources(), R.drawable.layout_range_green, null); + } } @Bindable public Drawable getTravelColor2() { - if(getThrowGauge2().getValue().IsBelowTravelMin() || getThrowGauge2().getValue().IsAboveTravelMax()) - return ResourcesCompat.getDrawable(getApplication().getResources(), R.drawable.layout_range_red, null); - else + if (getThrowGauge2().getValue().IsBelowTravelMin()) { + return ResourcesCompat.getDrawable(getApplication().getResources(), R.drawable.layout_range_red_down, null); + } else if (getThrowGauge2().getValue().IsAboveTravelMax()) { + return ResourcesCompat.getDrawable(getApplication().getResources(), R.drawable.layout_range_red_up, null); + } else { return ResourcesCompat.getDrawable(getApplication().getResources(), R.drawable.layout_range_green, null); + } } @Bindable diff --git a/app/src/main/res/drawable/layout_range_red_down.xml b/app/src/main/res/drawable/layout_range_red_down.xml new file mode 100644 index 0000000..37ebee9 --- /dev/null +++ b/app/src/main/res/drawable/layout_range_red_down.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/layout_range_red_up.xml b/app/src/main/res/drawable/layout_range_red_up.xml new file mode 100644 index 0000000..ae2650d --- /dev/null +++ b/app/src/main/res/drawable/layout_range_red_up.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 37804ca..e8cb249 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -4,6 +4,8 @@ #00574B #D81B60 #f07c68 + #f8c3b9 + #ba2b12 #7ccf69 #A8A8A8 #FFC107 From 04a194a3e33cce0c655ec5f803b64f2b791437ef Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Wed, 2 Mar 2022 22:35:02 +0100 Subject: [PATCH 18/21] 1.5 documentation --- ...-your-own-BlueTooth-RC-Throwmeter-V2.0.htm | 739 +++++++++++------- 1 file changed, 443 insertions(+), 296 deletions(-) diff --git a/app/src/main/assets/Make-your-own-BlueTooth-RC-Throwmeter-V2.0.htm b/app/src/main/assets/Make-your-own-BlueTooth-RC-Throwmeter-V2.0.htm index 73fbbd0..023fc06 100644 --- a/app/src/main/assets/Make-your-own-BlueTooth-RC-Throwmeter-V2.0.htm +++ b/app/src/main/assets/Make-your-own-BlueTooth-RC-Throwmeter-V2.0.htm @@ -67,612 +67,759 @@ - +

+line-height:normal'>

Make your own Bluetooth RC Throwmeter

+color:black;mso-ansi-language:EN-US'>Make your own Bluetooth RC Throwmeter

by Yannick Selles, Pierre Rondel, Vitaliy Ryumshyn and Alois Hahn

+color:black;mso-ansi-language:FR'>by Yannick Selles, Pierre Rondel, Vitaliy +Ryumshyn and Alois Hahn

 

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:FR'> 

Introduction

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Introduction

This mobile application allows you to "build" your own -Bluetooth throw-meter for a very reasonable cost. It doesn't require any soldering -or cabling. You just need to have access to a 3D printer and that is all!

+color:black;mso-ansi-language:EN-US'>This mobile application allows you to +"build" your own Bluetooth throw-meter for a very reasonable cost. It +doesn't require any soldering or cabling. You just need to have access to a 3D +printer and that is all!

 

+color:black;mso-ansi-language:EN-US'> 

Features of version 1.4

+color:black;mso-ansi-language:EN-US'>Features of version 1.5

 

+color:black;mso-ansi-language:EN-US'> 

·        Support two sensors simultaneously

+color:black;mso-ansi-language:EN-US'>·        +Can bind and use 2022 WitMotion modules +(with other HC-06 inside)

·        Calibration support, no need for manufacturer app

+color:black;mso-ansi-language:EN-US'>·        +Prevent screensaver to lock Throw Meter +screen

·        Bluetooth status bar

+color:black;mso-ansi-language:EN-US'>·        +Improved reliability of Bluetooth binding

·        More stable Bluetooth connection, and reconnection when exiting of -standby/sleeping mode

+color:black;mso-ansi-language:EN-US'>·        +Prevent max UP/DOWN to catch fast travel +glitches

·        Clearer separation between max travel feature and limit setting -with alarm feature

+color:black;mso-ansi-language:EN-US'>·        +Fast and smooth screen update in Dual-Mode

·        ·        +Ensure proper Witmotion configuration at +startup

+ +

 

+ +

Localization

+color:black;mso-ansi-language:EN-US'>Features of version 1.4

+ +

 

·        German language support

+color:black;mso-ansi-language:EN-US'>·        +Support two sensors simultaneously

·        Sensor option to chose more robust X/Y only calculation

+color:black;mso-ansi-language:EN-US'>·        +Calibration support, no need for +manufacturer app

·        Compacter screen layout for small displays

+color:black;mso-ansi-language:EN-US'>·        +Bluetooth status bar

·        Reminder to power off sensor when App is left

+color:black;mso-ansi-language:EN-US'>·        +More stable Bluetooth connection, and +reconnection when exiting of standby/sleeping mode

+ +

·        +Clearer separation between max travel +feature and limit setting with alarm feature

+ +

·        +Localization

+ +

·        +German language support

+ +

·        +Sensor option to chose more robust X/Y +only calculation

+ +

·        +Compacter screen layout for small displays

+ +

·        +Reminder to power off sensor when App is +left

 

+color:black;mso-ansi-language:EN-US'> 

 

The -component

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:FR'>The component

+line-height:normal'>

The component is the BWT61CL from WitMotion, a six axis -Bluetooth attitude angle sensor with battery incorporated. You can buy it on -AliExpress or Amazon US and amazon EU and cost around 20~25 Euros, free -shipping.

+color:black;mso-ansi-language:EN-US'>The component is the BWT61CL from +WitMotion, a six axis Bluetooth attitude angle sensor with battery +incorporated. You can buy it on AliExpress or Amazon US and amazon EU and cost +around 20~25 Euros, free shipping.

 

+color:black;mso-ansi-language:EN-US'> 

It is based on the JY61 sensor, has Bluetooth or serial -connectivity, integrates a dynamic Kalman filter algorithm, an internal voltage -stabilizing circuit module, voltage 3.3v~5v. The only drawback is, that the -Bluetooth BLE is only compatible with android. The battery has a 150mA -capacity so it lasts for a long operation time.

+color:black;mso-ansi-language:EN-US'>It is based on the JY61 sensor, has +Bluetooth or serial connectivity, integrates a dynamic Kalman filter algorithm, +an internal voltage stabilizing circuit module, voltage 3.3v~5v. The only +drawback is, that the Bluetooth BLE is only compatible with android. The +battery has a 150mA capacity so it lasts for a long operation time.

Characteristics

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:FR'>Characteristics

    -
  •     - Voltage: 3.3V-5V
  • -
  •     - Current: <40mA
  • -
  •     - Size : 51.3mm x 36mm X 15mm
  • -
  •     - Weight - : 16gr
  • -
  •     - Dimension: Accelerated speed -3d Angular speed -3d Magnetic field-3d - Angle-3d
  • -
  •     - Air - pressure 1d
  • -
  •     - Range : Accelerated speed -±16g Angular speed -±2000°/s Angle---±180°
  • -
  •     - Stability: Accelerated speed -0.01g Angular speed -0.05°/s
  • -
  •     - Attitude - measurement stability: 0.05°
  • -
  •     - Output content: Time, Accelerated speed, Angular speed, Angel.
  • -
  •     - Output - frequency100Hz
  • -
  •     - Date interface: Serial TTL level, Bitrate 115200 (default and can’t be - changed)
  • -
  •     - Bluetooth - transmission distance : >10m
  • -
  •     - Support for Android
  • -
  •     - Working time: 2 to 3 hours (full charge)
  • +
  •     Voltage: 3.3V-5V
  • +
  •     Current: <40mA
  • +
  •     Size : 51.3mm x 36mm X 15mm
  • +
  •     Weight : 16gr
  • +
  •     Dimension: Accelerated speed -3d + Angular speed -3d Magnetic field-3d Angle-3d
  • +
  •     Air pressure 1d
  • +
  •     Range : Accelerated speed -±16g + Angular speed -±2000°/s Angle---±180°
  • +
  •     Stability: Accelerated speed -0.01g + Angular speed -0.05°/s
  • +
  •     Attitude measurement stability: + 0.05°
  • +
  •     Output content: Time, Accelerated + speed, Angular speed, Angel.
  • +
  •     Output frequency100Hz
  • +
  •     Date interface: Serial TTL level, + Bitrate 115200 (default and can’t be changed)
  • +
  •     Bluetooth transmission distance : + >10m
  • +
  •     Support for Android
  • +
  •     Working time: 2 to 3 hours (full + charge)

Documentation  

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Documentation  

http://wiki.wit-motion.com/english/lib/exe/fetch.php?media=bluetooth_inclinometer:bwt61cl:docs:bwt61cl_user_manual_v1.pdf

+lang=EN-US style='font-size:12.0pt;font-family:"Times New Roman",serif; +mso-ansi-language:EN-US'>http://wiki.wit-motion.com/english/lib/exe/fetch.php?media=bluetooth_inclinometer:bwt61cl:docs:bwt61cl_user_manual_v1.pdf

 

+color:black;mso-ansi-language:EN-US'> 

Building -your RC Throw-meter

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Building your RC Throw-meter

As said in the introduction, the work is limited to the 3D -printing of the clips that allow to fix the device on the trailing edge of the -glider. It has been designed on DesignSpark (As said in the introduction, the work is +limited to the 3D printing of the clips that allow to fix the device on the +trailing edge of the glider. It has been designed on DesignSpark (original -file .rsdoc), and I'm providing the .rsdoc original -file in addition to the STL file.

+target="_blank">original file .rsdoc), and I'm providing the .rsdoc original file in +addition to the STL file.

 

+color:black;mso-ansi-language:EN-US'> 

STL -file is here

+target="_blank">STL file is here

+line-height:normal'>

 

The clips are removable, so the device, its clips and the charging -cable can be carried/stored in the plastic box it was received in.

+color:black;mso-ansi-language:EN-US'>The clips are removable, so the device, +its clips and the charging cable can be carried/stored in the plastic box it +was received in.

 

+color:black;mso-ansi-language:EN-US'> 

Just print the part, in PLA or PETG or ABS, 100% infill for me. -The dimension is optimised for F3x plane wings and tailplanes. To protect the -surface of the control surface and avoid the clips to slide/shift, I added a -piece of rubber (a small piece of bicycle inner tube) on the clips surfaces, -with double side tape.

+color:black;mso-ansi-language:EN-US'>Just print the part, in PLA or PETG or +ABS, 100% infill for me. The dimension is optimised for F3x plane wings and +tailplanes. To protect the surface of the control surface and avoid the clips +to slide/shift, I added a piece of rubber (a small piece of bicycle inner tube) +on the clips surfaces, with double side tape.

 

+color:black;mso-ansi-language:EN-US'> 

 

 

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:FR'> 

 

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:FR'> 

Print the sticker using the .pdf provided. Prior to apply it, -don't forget to remove the other stiker. Protect the printed paper with -transparent tape at the top, and double side tape on the other side, and -position it on the top of the case, respecting the correct orientation (Charge, -On/Off). This will give you the orientation when using pointing where is the -hinge

+color:black;mso-ansi-language:EN-US'>Print the sticker using the .pdf provided. +Prior to apply it, don't forget to remove the other sticker. Protect the +printed paper with transparent tape at the top, and double side tape on the +other side, and position it on the top of the case, respecting the correct +orientation (Charge, On/Off). This will give you the orientation when using +pointing where is the hinge

 

+color:black;mso-ansi-language:EN-US'> 

The -App

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:FR'>The App

The Android App has been developed by Yannick and Vitaliy. The App -is divided in several screens, the start screen giving access to the top left -menu, the "Sensor BT" screen to bind the App with the throwmeter, and -finally the "Throw Meter" screen where everything happens once -binded.

+color:black;mso-ansi-language:EN-US'>The Android App has been developed by +Yannick and Vitaliy. The App is divided in several screens, the start screen +giving access to the top left menu, the "Sensor BT" screen to bind +the App with the throwmeter, and finally the "Throw Meter" screen +where everything happens once binded.

 

+color:black;mso-ansi-language:EN-US'> 

Using -your RC Throw-meter(s)

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Using your RC Throw-meter(s)

Charging -the battery 

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Charging the battery 

Connect the cable provided to the balancer Plug. On newer versions -just connect the USB cable. The red LED is ON during the charge and switches to -OFF once charged.

+color:black;mso-ansi-language:EN-US'>Connect the cable provided to the balancer +Plug. On newer versions just connect the USB cable. The red LED is ON during +the charge and switches to OFF once charged.

 

+color:black;mso-ansi-language:EN-US'> 

Switching -on your Throwmeter(s)

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Switching on your Throwmeter(s)

Move the sliding switch from right to left. The blue LED is -blinking which indicates that the device is waiting for the binding.

+color:black;mso-ansi-language:EN-US'>Move the sliding switch from right to +left. The blue LED is blinking which indicates that the device is waiting for +the binding.

 

+color:black;mso-ansi-language:EN-US'> 

Binding -your Android smartphone for the first time

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Binding your Android smartphone for the first time

On your smartphone navigate to the parameter/bluetooth menu and -scan for new devices. The BWT61CL will show as HC-06. When asked, enter the -code “1234”. The sensor is now binded and you are ready to open the App.

+color:black;mso-ansi-language:EN-US'>On your smartphone navigate to the +parameter/bluetooth menu and scan for new devices. The BWT61CL will show as +HC-06. When asked, enter the code “1234”. The sensor is now binded and you are +ready to open the App.

 

+color:black;mso-ansi-language:EN-US'> 

Binding -with the App

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Binding with the App

Select the menu on the top left, then open "BT Sensors" -and select one (or two) HC-06 sensors or click on SCAN if the device doesn't -appear. Once selected you can return on the start page. Open the menu on the -top left and select "Throw meter"

+color:black;mso-ansi-language:EN-US'>Select the menu on the top left, then open +"BT Sensors" and select one (or two) HC-06 sensors. Once selected you +can return on the start page. Open the menu on the top left and select +"Throw meter"

+line-height:normal'>

 

+color:black;mso-ansi-language:EN-US'> 

 

+color:black;mso-ansi-language:EN-US'> 

 

-

 

+

 

 

+lang=EN-US style='font-size:10.0pt;font-family:"Arial",sans-serif;mso-fareast-font-family: +"Times New Roman";color:#222222;mso-ansi-language:EN-US'> 

 

+lang=EN-US style='font-size:10.0pt;font-family:"Arial",sans-serif;mso-fareast-font-family: +"Times New Roman";color:#222222;mso-ansi-language:EN-US'> 

Calibration

+style='font-size:13.5pt;mso-fareast-font-family:"Times New Roman";color:#222222; +mso-ansi-language:EN-US'>Calibration

 

+style='font-size:13.5pt;mso-fareast-font-family:"Times New Roman";color:#222222; +mso-ansi-language:EN-US'> 

If the -device is providing inconsistent or weird measures, it probably needs a full -calibration. Level the sensor(s) horizontally and do not move. To activate -Calibration long press the “Reset/Calib” button, confirm dialog -and wait until calibration completes.

+font-family:"Times New Roman",serif;color:#222222;background:white;mso-ansi-language: +EN-US'>If the device is providing inconsistent or weird measures, it probably +needs a full calibration. Level the sensor(s) horizontally and do not move. To +activate Calibration long press the “Reset/Calib” button, confirm +dialog and wait until calibration completes.

-

 

+

 

 

+color:#888888;mso-ansi-language:EN-US'> 

+style='color:black;mso-color-alt:windowtext'>

+style='color:black;mso-color-alt:windowtext'>

 

+color:#222222;mso-ansi-language:EN-US'> 

Reset -Angle

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Reset Angle

The device is supposed to do a calibration at startup. It is -recommended to do it with the device installed on a horizontal surface. Once -done, you can clip the device on the leading edge of control surface -you want to measure. When your control surface is at its neutral position, -proceed to a new "Reset" in order for the device to know its -spacial position and be ready to measure the angle.

+color:black;mso-ansi-language:EN-US'>The device is supposed to do a calibration +at startup. It is recommended to do it with the device installed on a +horizontal surface. Once done, you can clip the device on the leading +edge of control surface you want to measure. When your control surface is +at its neutral position, proceed to a new "Reset" in order for +the device to know its spacial position and be ready to measure the angle.

 

+color:black;mso-ansi-language:EN-US'> 

 

 

+color:black;mso-ansi-language:EN-US'> 

Travel -setup 

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Travel setup 

Measure the chord of you control surface and click on the chord -field at the top of the screen to enter the value. There is no unit, so it can -be “mm” or “inches”. Travel will be shown in the same unit.

+color:black;mso-ansi-language:EN-US'>Measure the chord of you control surface +and click on the chord field at the top of the screen to enter the value. There +is no unit, so it can be “mm” or “inches”. Travel will be shown in the same +unit.

 

+color:black;mso-ansi-language:EN-US'> 

+line-height:normal'>

 

+color:black;mso-ansi-language:EN-US'> 

Max UP -and Max DOWN

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Max UP and Max DOWN

This is a very useful feature that allows you to quickly measure -the maximum up and down travels of a control surface. Use “Reset” to clear the -Max UP/DOWN values for a new measurement.

+color:black;mso-ansi-language:EN-US'>This is a very useful feature that allows +you to quickly measure the maximum up and down travels of a control surface. +Use “Reset” to clear the Max UP/DOWN values for a new measurement.

 

+color:black;mso-ansi-language:EN-US'> 

+line-height:normal'>

 

+color:black;mso-ansi-language:EN-US'> 

Set -Max UP and Max DOWN Thresholds

+style='font-size:13.5pt;font-family:"Times New Roman",serif;color:black; +mso-ansi-language:EN-US'>Set Max UP and Max DOWN Thresholds

If your objective is to do settings, not to measure, you can enter -a “Max positiv travel” and a “Min negativ travel” separately. This instructs -the App to display an alarm (in RED color instead GREEN) when the travel value -exceeds a threshold, either above the “Max positiv travel” or below the “Min -negativ travel”.

+color:black;mso-ansi-language:EN-US'>If your objective is to do settings, not +to measure, you can enter a “Max positiv travel” and a “Min negativ travel” +separately. This instructs the App to display an alarm (in RED color instead +GREEN) when the travel value exceeds a threshold, either above the “Max positiv +travel” or below the “Min negativ travel”.

 

+color:black;mso-ansi-language:EN-US'> 

+line-height:normal'>

 

+line-height:normal'>

 

+color:black;mso-ansi-language:EN-US'> 

 

 

+color:black;mso-ansi-language:EN-US'> 

 

+color:black;mso-ansi-language:EN-US'> 

 

-

 

+

 

Sensor Options

+115%;font-family:"Times New Roman",serif;color:black;mso-ansi-language:EN-US'>Sensor +Options

The App computes its spatial -position upon the rotation measurements of the WitMotion sensor. The most -precise method uses all three axes X,Y and Z. It turned out, that the WitMotion -sensor can lose the correct Z value when moved fast and irregularly. This may -add significant error to the measured angle, specifically around zero. The user -has to use “Reset” if this occurs.

+font-family:"Times New Roman",serif;color:black;mso-ansi-language:EN-US'>The +App computes its spatial position upon the rotation measurements of the +WitMotion sensor. The most precise method uses all three axes X,Y and Z. It +turned out, that the WitMotion sensor can lose the correct Z value when moved +fast and irregularly. This may add significant error to the measured angle, +specifically around zero. The user has to use “Reset” if this occurs.

As an alternative, the App may -ignore the vertical Z axis. This method is much more robust, but might add some -absolute measurement error. In real life context this can be accepted for the -comfort of robustness, thus it is the default setting.

+font-family:"Times New Roman",serif;color:black;mso-ansi-language:EN-US'>As an +alternative, the App may ignore the vertical Z axis. This method is much more +robust, but might add some absolute measurement error. In real life context +this can be accepted for the comfort of robustness, thus it is the default +setting.

Sensor setting options are -provided to allow the user to choose the preferred mode.

+font-family:"Times New Roman",serif;color:black;mso-ansi-language:EN-US'>Sensor +setting options are provided to allow the user to choose the preferred mode.

-

+

Calibration with the manufacturer App

+style='font-size:13.5pt;mso-fareast-font-family:"Times New Roman";color:#222222; +mso-ansi-language:EN-US'>Calibration with the manufacturer +App

 

+style='font-size:13.5pt;mso-fareast-font-family:"Times New Roman";color:#222222; +mso-ansi-language:EN-US'> 

Alternatively, -instead using the “Calibrate” Button as described above, the calibration can be -done with the manufacturer App as well. You can download the manufacturer -App Alternatively, instead using the “Calibrate” Button as described above, +the calibration can be done with the manufacturer App as well. You can +download the manufacturer App here.  To do a full calibration, once selected -the correct chipset model WT601, click on SET (top left) and then +font-family:"Times New Roman",serif;color:#0070C0;background:white;mso-ansi-language: +EN-US'>here.  To do a full calibration, once selected the +correct chipset model WT601, click on SET (top left) and then "Acceleration calibration".

-

 

+

 

+style='color:black;mso-color-alt:windowtext'>

+style='color:black;mso-color-alt:windowtext'>

 

+color:black;mso-ansi-language:EN-US'> 

Once calibrated the App can be closed and the -user can run the RC Throw-meter Application.

+color:#222222;background:white;mso-ansi-language:EN-US'>Once calibrated the App +can be closed and the user can run the RC Throw-meter Application.

-

 

+

 

Hope you will enjoy this Bluetooth RC Throw-meter!

+color:black;mso-ansi-language:EN-US'>Hope you will enjoy this Bluetooth RC +Throw-meter!

-

 

+

 

From ce734d2b33f9461397f15bad68c2620a02fca170 Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Wed, 2 Mar 2022 22:36:11 +0100 Subject: [PATCH 19/21] version update 1.5 --- app/build.gradle | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f5ac4c6..3297650 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,8 +2,8 @@ apply plugin: 'com.android.application' android { defaultConfig { - versionCode 4 - versionName "1.4" + versionCode 5 + versionName "1.5" resValue "string", "app_version", "$versionName" applicationId "com.pitchgauge.j9pr.pitchgauge" minSdkVersion 21 @@ -11,7 +11,6 @@ android { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } compileSdkVersion 30 - buildToolsVersion "30.0.0" buildTypes { release { minifyEnabled false From 51070f238d985be99730b50fb03076be6cc72b3c Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Thu, 3 Mar 2022 23:22:22 +0100 Subject: [PATCH 20/21] minimum timing change at dummy command, reduce change that reset causes (old) sensor restart --- .../main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java index 5abab88..bed33cd 100644 --- a/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java +++ b/app/src/main/java/com/pitchgauge/j9pr/pitchgauge/ThrowActivity.java @@ -231,10 +231,10 @@ public void run() { new Thread(new Runnable() { @Override public void run() { - try { Thread.sleep(100); } catch(InterruptedException e) {}; // send a dummy sequence byte[] CommandZero = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; ThrowActivity.this.mBluetoothService.Send(CommandZero); + try { Thread.sleep(350); } catch(InterruptedException e) {}; txBusy = false; } }).start(); From 914c901fb09d88c2c638576682490225de3e640a Mon Sep 17 00:00:00 2001 From: Alois Hahn Date: Thu, 3 Mar 2022 23:23:28 +0100 Subject: [PATCH 21/21] new gradle version strings --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index c21f9bb..03fe89d 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.3' + classpath 'com.android.tools.build:gradle:7.1.2' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f9c6866..3bdc60a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip