ECG Monitor – Software Revision, Hardware Revision, Firmware Revision and Mechanical Design Revision
Software Revision
ECG Monitor – Software Revision, Hardware Revision, Firmware Revision and Mechanical Design Revision / Research & Development
//=========================================================
// Format of Status
// S0000, S0001, S0010, S0011
// Last TWO bits are the status of LOD+ and LOD-
//=========================================================
// Data Capture
// Comment: Try to save data in HEXDEC format. It is not easy to read.
// Final : Using double precision format to save the data.
//=========================================================
// Modified: 31 Aug 2016 8:35:00 AM
// (Description 1.0.0.2)
// Put All the bluetooth module to uChatManager.pas and create two threads
// (TReadThread and TWriteThread) for handling the Read/Write process during
// communication between Android host and ECG client.
// =============================
// Bluetooth Module Modification
// =============================
// Create uChatManager.pas unit with following:-
// 1) TChatManager
// 2) TReadThread
// 3) TWriteThread
//
// Comment:
// Using the System.Bluetooth unit, there is I/O exception,
// There is an error when the android try to connect with the bluetooth
// HC-06. The socket is closed or timeout.
// “java.io.ioexception read failed socket might closed or timeout read ret -1”
//
// LServerSocket.Accept(60000);
// LReadSocket.Connect;
// LWriteSocket.Connect;
//
// The above socket DOES NOT work. Bugggggy!!!!
//
// Solution:
// Using the AndroidApi instead. See below.
//=========================================================
// Modified: 20 Oct 2016 3:00:00 PM
// (Description 1.0.0.3)
// ECGBTMain v26a working.rar <<< This apps is working but bug!!!!
//
// Read Thread has error to read automatically.
// Read Thread has error to read automatically.
//
// Using uAndroidChatManager.pas and create two threads
// (TReadThread and TWriteThread) for handling the Read/Write process during
// communication between Android host and ECG client.
// =============================
// Bluetooth Module Modification
// =============================
// Create uAndroidChatManager.pas unit with following:-
// 1) TAndroidChatManager
// 2) TReadThread
// 3) TWriteThread
// Comment: uChatManager cannot communicate between Android and BlueTooth Module.
// Create uAndroidChatManager to do the job. The unit is using
// AndroidApi to call BlueTooth module.
//=========================================================
// Modified: 26 Oct 2016 10:00:00 AM
// (Description 1.0.0.4)
//
// Using uAndroidChatManager.pas and create one timer to read the receiving text
// to communicate between Android host and ECG client.
// =============================
// Bluetooth Module Modification
// =============================
// Create uAndroidChatManager.pas unit with following:-
// 1) TAndroidChatManager
// 2) receiveThd : TReceiveThread;
// Comment: uAndroidChatManager can communicate between Android and BlueTooth Module.
// Using receiveThd: TReceiveThread to receive the incoming text automatically.
//=========================================================
// Modified: 3 Dec 2016 10:43:00 AM
// (Description 1.0.0.5)
//
// Using BluetoothLE unit to communicate with Bluetooth 4.0 version
// Using uBT4ChatManager.pas and create to read the receiving text
// to communicate between Android, MAC OSX & iOS, host and ECG client.
// =============================
// Bluetooth Module Modification
// =============================
// Create uBT4ChatManager.pas unit with following:-
// 1) TBT4ChatClass
// 2) fbGetServiceAndCharacteristics
// 3) fbBTCharacteristicWrite
// 4) fbBTCharacteristicRead
// Comment: uBT4ChatManager can communicate between Android, MAC OSX & iOS and BlueTooth 4.0 module.
//
// ===========================
// ===========================
// ===========================
//
// Result: Testing Bluetooth 4 version 3.0.6
// *****************************************
// Procedure
// {$Define BT4} Change in ECGctrl.inc
// The module of BT4 is working but very very slow.
// The BT4 need to transmitted the Characteristic String each time together with the data variable.
// It will take a significant amount of time to transmit “Characteristic String” and “Data Variable”.
// Further Development
// *******************
// Baud rate is increased to certain amount to deduce the Characteristic String. It will have this improvement.
// ===========================
// ===========================
// ===========================
//=========================================================
// 32-bit Windows and 64-bit Windows are using for DEBUG only.
// They don’t have Bluetooth wireless Enable!
//=========================================================
// Comment:
// There is a problem at the pcrParserBytes to calculate the heartTimer.Interval.
// pcrParserBytes is a thread. There is a conflict between timer and pcrParserBytes thread.
// Set heartTimer.Interval here is more stable sound pulse than that
// at the pcrParserBytes
//
// It is the best location to put the fbBeepSound and reset timer.
// Reset heartTimer after each of the fbBeepSound when the interval is changed.
//
// Create: TTimeThread.pas
// This unit is used a thread to control the time interval (eRate).
// The time interval is more precise than that of the system timer.
//=========================================================
// Capture data in HexDec format at pcrParserBytes here
// OR
// Capture data in float point format at fbSetUpOneBTData
//=========================================================
// Modified: 20 Dec 2016 11:43:00 PM
// (Description 1.0.0.6)
// Extra Function:
// 1) Auto Phone Dialer – Monitor ecg If too high or too low, it will call the preset phone number.
// 2) eMail infoormation – email ecg information, location to the preset email address
// 3) Current Location – get the current location from GPS
// 4) SMS – send ecg information, location to the preset SMS number
//=========================================================
// Research Paper – “InTech-A_mobile_device_based_ecg_analysis_system.pdf”
// School of Electrical and Computer Engineering, RMIT University of Australia
//
// Description of “Procedure pcrMonitor”
// The following code is to calculate the
// 1)First Derivative
// 2)Second Derivative
// 3)Check or Monitor FDBT
// 4)Check or Monitor SDBT
//
// Parameters:
// eFrequency (pulse per second) is used to calculate SDBT
//=========================================================
// Research Paper – “Dynamic Time Warp Visualizer by Aleksei Loos”
// Research Paper – “Dynamic Time Warping by Quim Llimona Torras / Jounal Club 2011. MTG-UPF”
//
// Description
// In time series analysis, dynamic time warping (DTW) is
// an algorithm for measuring similarity between two temporal sequences
// which may vary in speed. For instance, similarities in walking
// could be detected using DTW, even if one person was walking
// faster than the other, or if there were accelerations and decelerations
// during the course of an observation.
// DTW has been applied to temporal sequences of video, audio, and graphics data
// — indeed, any data which can be turned into a linear sequence can be
// analyzed with DTW.
// A well known application has been automatic speech recognition,
// to cope with different speaking speeds.
// Other applications include speaker recognition and online signature recognition.
// Also it is seen that it can be used in partial shape matching application.
//
//=========================================================
// Usage: function TPlotClass.fbCalculateDistance(aObsChartValues: TChartValues; //obs
// aExpChartValues: TChartValues; //exp or Standard
// var dDisDataSet: dMultiArray): Boolean;
// fbCalculateDistance is used to calculate the Dynamic Time Warping(DTW).
// Input : There are two dataset of ChartValues (aObsChartValues & aExpChartValues).
// Output: dDisDataSet will be generated by the function.
//=========================================================
// Usage: function TPlotClass.fbCalculatePath(dDisDataSet: dMultiArray;
// var dPathDataSet: dArray): Boolean;
// fbCalculatePath is used to calculate the shortest distance.
// Constant: giDTWConstant & gdDTWCoefficient
// Adjust two constants, the output will generate the result changing accordingly.
// Output: dPathDataSet will be generated by the fbCalculatePath.
//=========================================================
// Further Development
// Discrete Frechet Distance
// For person identification, Dynamic Time Warping (DTW) and
// Fisher’s Linear Discriminant Analysis (FLDA)
// with K-Nearest Neighbor Classifier (NNC) as Single stage classification
// yielded a recognition accuracy of 96% and 97% respectively.
// To further improve the performance of the system, two stage classification techniques
// have been adapted.
// In two stage classifications FLDA is used with k-NNC at the first stage followed by
// DTW classifier at the second stage which yielded 100% recognition accuracy.
//=========================================================
//=========================================================
// Special Feature #001
// ecg Frequency Function
// Description: If the capture Amplitude is too low to be detected Threshold,
// it is better to make the frequency to ZERO and then pulse/sec and pulse/min to zero.
//=========================================================
// 43) Add LogAppErr on fbSetUpOneBTData and fbZeroCrossFreq
//=========================================================
// 44) Add FLAG_KEEP_SCREEN_ON to keep the screen awake
//=========================================================
// 45) Initialization
// TFastLineSeries(ecgChart[0]).DrawAllPoints := False;
// TFastLineSeries(ecgChart[0]).FastPen := True;
// ecgChart.Axes.FastCalc := True;
// ecgFastLine.AutoRepaint := False;
// ecgChart.AutoRepaint := False;
//=========================================================
// Modified: 2 Jul 2018 11:53:00 PM
// (Description: 1.0.0.12)
// 46) Change giDefaultFreq and giDefaultAmp to value of 10.
// Sound of the beep when there is invalid frequency will be 600 pulse per sec.
// It more make sense of invalid frequency on bpm or bps.
// The lblPulseMin will be ‘888 bpm’ or ’88 bpm’.
// lblPulseSec will be ‘8.88 bps’.
//
// Verify the fbDCAC and fbHRT functions.
// fbDCAC and fbHRT are depending on eFrequency.
// It is OK to use ‘ZeroCross discrete frequency’ to get the frequency whenever
// there is a valid frequency available from fbZeroCrossFreq.
//=========================================================
// Modified: 5 Jul 2018 07:13:00 AM
// (Description: 1.0.0.15)
// 47) Add Directive at ECGctrl.inc
//
// For IOS Device – 32 bit, there is no problems on AnsiChar.
// For IOS Device – 64 bit, there is an exception on
// ‘No mapping for the Unicode character exists in the target multi-byte code page’
//
// Change the following code.
// {$HIGHCHARUNICODE ON}
// {$EXCESSPRECISION OFF}
// sValue := ACharacteristic.GetValueAsString(0, True);
//=========================================================
// Modified: 23 Jul 2018 09:26:00 PM
// (Description: 1.0.0.19)
// 48) Low Battery Operation:
// If the battery is operated below 3.3v, the wave form will have a BIG distoration.
// There will be a 0.2Hz-0.5Hz wave superimposed on the ECG wave,
// It should be re-charged the battery again!!!
//
// The BLE also received better signal when the battery is enough.
//
//=========================================================
// Modified: 26 Aug 2018 12:00:00 PM
// (See Description 1.0.0.24)
// Reinstallation on Delphi 10.2.3
// Recompile the project on Delphi 10.2.3
//=========================================================
// Modified: 27 Aug 2018 08:38:00 AM
// (See Description 1.0.0.25)
//
// There is NO change on the code of ecgMain.
//
// 1) Samsung S9 Issue
// Samsung can be seen by the Delphi. Still it cannot be link with debugger.
// The issue is same as 10.2.1 and 10.2.3.
// The debugger cannot link with Delphi. The problem is coming from the Google side.
// The OS Android Oreo is tested on Nexus. This problem will be solved.
// Samsung S9 is waiting for the update…
//
// 2) IOS Simulator – OS 11 or Later.
// For OS 11 or later, the simulator also cannot be compiled.
// Delphi said the new version of 10.3 will have 64-bit os. The problem will be solved.
// The current simulator on 10.2.3 is still working on 32-bit os.
// The simulator is waiting for the update…
//
// 3) Samsung Galaxy Note Edge
// The apps is running un-stable in 10.2.1.
// After about 1-day running, the apps will suddenly closed.
// The apps is running more stable in 10.2.3.
// After about 2-day running, the apps is still running without closed.
//
// 4) Nexus 7 in 10.2.3
// The apps is running with more fast respond. The is NO delay in real time capture.
// There is NO issue in iPhone and iPad.
//=========================================================
// Modified: 09 Sep 2018 10:20:00 PM
// (See Description 1.0.0.27)
// Add ‘D.P.F. Component IOS’ to the library. DPF Component is native IOS component.
//
// 1) This DPF Component IOS library has to major usage on ‘eMail and iMessage compose’.
// The component of dpfMailCompose and dpfMessageCompose are using in IOS to
// send email and iMessage to another mobile device.
//
// Before the apps is only enchanced for Android. With this DPF Component IOS,
// the app can be used for IOS device.
//
// Comment: There is a ‘root.PList’ in XML format for IOS.
// This ‘root.PList’ is using to hold informations:-
// – Application, Developer or version information
// – Preference/Boolean of SMS, Email, Location and Phone Call.
// Some library components are added to $(SDKROOT)/System/Library/Frameworks
//=========================================================
// Modified: 17 Sep 2018 03:30:00 PM
// (See Description 1.0.0.28)
// Add ‘KastriFree-master’ to the library. KastriFree-master is Android component
//=========================================================
// Modified: 25 Sep 2018 01:10:00 AM
// (See Description 1.0.0.29)
// Using rectPageControl to replace the Delphi PageControl component.
// The graphic interface is look colorful than PageControl.
//
// We are using the following rectPageControl components.
// rectPageControl : TRectangle;
// rectPageAbout : TRectangle;
// rectPageBTChat : TRectangle;
// rectPageBT4Chat : TRectangle;
// rectPageECGMonitor : TRectangle;
// rectPageSetup : TRectangle;
// rectPageFiles : TRectangle;
// rectPageTheme : TRectangle;
// rectPageMemo : TRectangle;
// rectPageLocation : TRectangle;
//
// Comments:
// 1) pcrUpdateKBBounds is removed from FormFocusChanged.
// 2) There is a bug in pcrSetLabelsCoordinate of ecgChart.Height.
// ecgChart.Height is changing and cannot be validated before calling pcrSetLabelsCoordinate
//=========================================================
// Modified: 29 Sep 2018 10:00:00 PM
// (See Description 1.0.0.31)
// Remove public variable in TPlotClass. Modularize the procedure and function call.
//=========================================================
// Modified: 04 Oct 2018 10:00:00 PM
// (See Description 1.0.0.32)
// Function: fbPeakBin, fbQuadratic & fbStirling are used to estimate the PeakBin Frequency and Amplitude.
// Function: fbLogPeakBin, fbExpQuadratic is used to estimate the PeakBin Frequency and Amplitude.
//
// Comment: -dResolution <= dp <= dResolution, Where dResolution = half of the interval of VFreq
// Result almost the same: (fbLogPeakBin & fbExpQuadratic) and (fbPeakBin & fbQuadratic)!!!
// Result almost the same: (fbLogPeakBin & fbExpQuadratic) and (fbPeakBin & fbQuadratic)!!!
// Result almost the same: (fbLogPeakBin & fbExpQuadratic) and (fbPeakBin & fbQuadratic)!!!
//
// vFreqs[i] Frequency Resolution:-
// eFreq := i*iSampleRate/iNBRPoints/32;
// vFreqs[i] := eFreq*iTimeBase/iTimeBaseConstant;
// vFreqs[i] := i*iSampleRate/iNBRPoints/32 * iTimeBase/iTimeBaseConstant;
//
// vFreqs[i] Frequency Resolution is given by the above equation.
// example: eFreqs := 8192/2048/32 = 1/8;
// vFreqs[i] := 1/8 * 256 / 256 = 1/8;
// The resolution will be improved by using fbPeakBin & fbStirling.
// They are second and third order iteration.
// The result vFreqs[i] Frequency Resolution is improved a lot.
//
// dx[0] := 0.75;
// dx[1] := 0.875;
// dx[2] := 1;
// dx[3] := 1.125;
// dx[4] := 1.25;
// dfx[0] := 0;
// dfx[1] := 0.0;
// dfx[2] := 8.0;
// dfx[3] := 0.0000005; //<<< Here is the error term!!!
// dfx[4] := 0.0;
// //Freq original = 60 bpm
// //Freq estimated = 60.00000100 bpm //<<< Here is the estimation!!!
//
// fbPeakBin, fbQuadratic & fbStirling are tested!!!
//
// 1) fbPeakBin is converted
// applsci-06-00306.pdf
// www.mdpi.com/2076-3417/6/10/306/pdf
//
// 2) fbStirling is converted from C++ to pascal
// https://www.geeksforgeeks.org/program-stirling-interpolation-formula/
//
// We use PeakBin (fbPeakBin) and Stirling Interpolation (fbStirling) to
// calculate the frequency and amplitude.
// Stirling is third order iteration. PeakBin is second order iteration.
//
// 3) we use fbQuadratic to estimate Amplitude from PeakBin Frequency
// https://ccrma.stanford.edu/~jos/parshl/Peak_Detection_Steps_3.html
// y(x) app. = a (x – p) * (x – p) + b
//
// p = 0.25 * (alpha – gamma) / (alpha – 2beta + gamma)
// which is given by dResult of fbPeakBin
//
// y(p) = beta – 0.25 * (alpha – gamma) * p
//
// where:-
// alpha := dfx[1];
// beta := dfx[2];
// gamma := dfx[3];
// p := 0.25 * (alpha – gamma) / (alpha – 2beta + gamma)
//
// Comments:-
// fbStirling is more accurate but slower.
// fbQuadratic is less accurate but faster.
//=========================================================
// Modified: 04 Oct 2018 10:00:00 PM
// (See Description 1.0.0.32)
// 1) Array modified: ecgStd, ECG_Wave & ECGReal_wave
// 2) Re-define lbxGpHeader and lbxItem of lbxMultiView and re-define margin, Font, Size and Family
// 3) Add DSP Resolution switch to select Stirling or Quadratic Interpolation
// 4) Add color to buttons on rectPageSetup
//=========================================================
// Modified: 11 Oct 2018 10:50:00 PM
// (See Description 1.0.0.34)
// 1) Modifed: bt4ECGCharacteristicRead, bt4ECGDiscoverLEDevice & bt4ECGEndDiscoverDevices
// 2) Filter only for all ‘ecgMon’ devices and list on the drop down list.
// It will not show up other BLE devices without ‘ecgMon’ characters.
// 3) It will or will not start pcrBTEndDevice automatically after bt4ECGEndDiscoverDevices.
//=========================================================
// Modified: 16 Mar 2019 10:00:00 PM
// (See Description 1.0.0.37)
// Android version
// After certain time the apps will be killed by the OS of Android,
// if the user switch off the screen after certain time.
// Killing apps time is depending on setting arround 5-10 minutes.
//
// After Android OS 8 Oreo, Google adding Power Manager to Optimize the battery life.
//
// ================================================================================
// We want to keep the screen on by ‘FLAG_KEEP_SCREEN_ON’ when the apps is running.
// OR
// If press ‘Power Off’ button with screen and keyboard off,
// we still want to keep the CPU in running mode.
// ================================================================================
// BUT, after the user press the power button, Android will KILL the apps if the screen off
// at certain time.
//
// IOS version
// There is no such issue in IOS.
//
// Attention: The wake lock doesn’t work in debug mode.
// It only work in release mode.
// ================================================================================
// Stable Version by Delphi-Emotiv-EPOC-master.zip of PowerViewer
//
// TApplicationEvent are using the original event handler!!!
// TApplicationEvent.FinishedLaunching : fbAcquireWakeLock(jprWakeLock);
// TApplicationEvent.BecameActive : fbAcquireWakeLock(jprWakeLock);
// TApplicationEvent.WillBecomeInactive : pcrReleaseWakeLock(jprWakeLock);
// TApplicationEvent.EnteredBackground : pcrReleaseWakeLock(jprWakeLock);
// TApplicationEvent.WillBecomeForeground: fbAcquireWakeLock(jprWakeLock);
// TApplicationEvent.WillTerminate : pcrReleaseWakeLock(jprWakeLock);
//
// Comment: ScreenCtrl: Off (Always Screen Off) is not always working!!!
// ================================================================================
// Reference: [How to prevent FireMonkey app / service stop working while in background?]
// https://stackoverflow.com/questions/52504808/how-to-prevent-firemonkey-app-service-stop-working-while-in-background
//
// [Guide to background processing]
// https://developer.android.com/guide/background#js
//
// [how to keep app running when screen off?]
// https://stackoverflow.com/questions/44743265/how-to-keep-app-running-when-screen-off-or-open-another-app
//
// [Delphi XE5 Android. How to use PowerManager.WakeLock?]
// https://stackoverflow.com/questions/19021647/delphi-xe5-android-how-to-use-powermanager-wakelock
//
// [How to keep an Activity running while screen off?]
// https://stackoverflow.com/questions/11978742/how-to-keep-an-activity-running-while-screen-off
//
// [PowerManager]
// https://developer.android.com/reference/android/os/PowerManager
//=========================================================
// Modified: 04 May 2019 05:00:00 AM
// (See Description 1.0.0.42)
// OLD Library U_FFT.pas and U_FFT2.pas is replaced by new U_FFT.pas.
// fbFourierTransform from fourier.pas – Don Cross <dcross@intersrv.com>
//
// Updated version of Kastri library from Delphiworld/Dave Nottage is using with DW.Android.Helpers.
// TAndroidHelperEx.RestartIfNotIgnoringBatteryOptimizations is to make sure the app
// is running in ‘IgnoringBatteryOptimization’ mode.
//
// In iPad and iPhone, there are no such issue to ‘Keep_Screen_ON’.
// Background runmning is OK in IOS.
//=========================================================
// Modified: 10 May 2019 10:00:00 PM
// (See Description 1.0.0.43)
//
// Introduce the below ‘Performance Mode’ for Android
// 1) High Performance – Screen On
// 2) Normal Mode – Screen Off/Background Mode
// 3) Low Battery Mode – Screen Off
//
// Description of ‘Performance Mode’
// 1) High Performance – Screen On is the mode that CPU is always running and Screen is always ON.
// The user can do any activities such as phone call, browsing, gaming,
// video and audio … etc together. The apps is ALWAYS working.
// The ‘High Performance Mode’ is that the battery will be drain for performance.
// 2) Low Battery Mode – Screen Off/Background mode is that CPU is always running in the background and
// Screen is auto off in doze mode.
// The user can do any activities such as phone call, browsing, gaming,
// video and audio … etc together. CPU can be kept running in the background
// for 1hr-8hrs. The apps will be killed by the system when the user has no
// activities.
//=========================================================
//
// ALPHA TEST with bug report
//
//=========================================================
//
//
//=========================================================
//
// Bug Report!!!
//
//=========================================================
// Bug#001
// Fixed
// Disable the function when the time is running(Start Event)
//
//=========================================================
// Bug#002 FIXED
// Fixed
// Here for giWaveType > giCaptureMode
// Do one more time of setup chart scale
// Change Axes Time Scale
// Code is removed.
//
//=========================================================
// Bug#003
// Fixed
// Only enable the function when the time is not running(Pause Event)
//
// Bug#004
// Fixed
// Only save the capture data when capture is enabled.
//
//=========================================================
// Bug#005
// Fixed
// Same as Bug#004. Only save the capture data when capture is enabled.
//
//=========================================================
// Bug#006
// Fixed
// Make sure CALLING the pcrMonitor after the first page. Try 5 Times!!!
// If there is no delay, it will araise access violation.
//
//=========================================================
// Bug#007
// Fixed
// This bug is due to the tmrECG thread still running in the background.
// fbCalculatePath is not finished the calculation and quit the exe.
// It will come out the Exception.
// Waiting 2s to end the fbCalculatePath calculation, Threads, Timers
//
//=========================================================
// Bug#008
// Fixed
// Quiting the Apps need to wait until the fbCalculatePath is finished!!!
// It cannot free the array or waiting these calculation to be finished.
// Checking the fbCalculatePath is still finished or not?
//
//=========================================================
// Bug#009
// Fixed
// while bpuMonStatus do
// begin
// Do something
// end;
//
// =============================================================================
// Bug#010
// Fixed. See Bug#022
// Android OS 4.4.2
// Comment: Different iResolution will give different NumBufPoints.
// This is because the phase and the capture data difference.
// Solution: Result := Trunc(iScbTrigger+iTimeBase*XXX) > 3072, it must be greater than 3072.
// =============================================================================
// iWaveType = giReadMode, different i Resolution will give different Bluepoints
// Pl see the description of the function disfigurements
// If the capture data size is NOT multiple of 256, it will appear
// the join of the graph during looping of playing record.
// Result := Trunk(outrigger+Sebastian*XXX) > 3072, it must be greater than 3072.
//
//=========================================================
// Bug#011
// Fixed
// Casting the format extended or double into single.
//
//=========================================================
// Bug#012
// Fixed
// Make sure CALLING the pcrMonitor after the first page (not bpu1stPlot)
//
//=========================================================
// Bug#013
// Here, length of vXReal & vXImag must be the same of two multiple
//
//=========================================================
// Bug#014
// Fixed
// Fill the original chart with NO Gain and NO Offset
// Save dy to the aOrgChartValues
// No need to have this statement here and comment it out
// aOrgChartValues[indexI] := dy; //<<<<< Comment it out!!! //
//=========================================================
// Bug#024
// Checking the Bluetooth is connected or not
// If bluetooth connection is broken, reconnect it again
//=========================================================
// Bug!!! Bug#025
// Fixed
// Comment out the pcrcbxResolution0to1
// Let the demo have the resolution 128sps
//=========================================================
// Bug!!! Bug#026
// Fixed Minor bug
// sSend := edtBT4NewText.Text;
// sSend := edtNewText.Text;
//=========================================================
// Bug!!! Bug#027
// Fixed Minor bug
// Comment out the below code. Focus something wrong with bottom screen
// pcrUpdateKBBounds;
//=========================================================
// Bug!!! Bug#028
// Fixed
// It is a MUST that (vFreqs[i] < iBPMHighLimit/60)!!! // It is a MUST that (vFreqs[i] > iBPMLowLimit/60)!!!
// If (vFreqs[i] <= iBPMHighLimit/60) and (vFreqs[i] > iBPMLowLimit/60) then
// to Keep track of the 2 highest amplitudes.
//=========================================================
// Bug!!! Bug#029
// if frmECG.epuFrequency = 0, the fbTimerOnTime is NOT working.
// We need to check the dFreqThreshold frequency.
//=========================================================
// Bug!!! Bug#030
// if frmECG.epuFrequency = 0, the fdOptimizeFrequency is NOT working.
// We need to check the dFreqThreshold frequency.
//=========================================================
// Bug!!! Bug#031
// Add the below code to optimize the frequency below 0.01 dAmplitudeThreshold
// If the eFrequency >= 2, we will use fdOptimizeFrequency to get the better frequency instead.
//
// If efMax1 and efMax2 are BOTH >= 2, the eFrequency will be greater than 2!!!
// The client will have the abnormal bpm!!!
//=========================================================
// Bug!!! Bug#036
// Freq = 786, 1152
// Adjust the eFrequency for giWavetype = giReadMode
// Comment: Because there is NO time clock to run the reading signal.
// Base on the cpu clock, the reading of ECG graph is running with cpu clock.
// It will variate will the system clock.
// Solution: By Bug#037, reading (TimeBase number of data per second by fbPrnFrame.
// The FFT calculation is more more stable and accurate.
//=========================================================
// Bug!!! Bug#037
// Before the method is just reading any data per second and to calculate FFT.
// The result is very very unstable and inaccurate.
//
// Fixed.
// Now is reading (TimeBase) number of data per second by fbPrnFrame.
// This fbPrnFrame is tmeECG operated per second.
// When tmeECG time on time, it will come to here to prepare a frame.
// Let say the iTimeBase = 384. It will read 384 number of data per second
// to prepare a chart for printing.
//=========================================================
// Bug!!! Bug#038
// fbMakeSpectrum add this condition(iWaveType <> iCaptureMode)
//=========================================================
// Bug!!! Bug#039
// Adding EOF a file ending number ‘1,’ and ‘-1’ to slData.
//=========================================================
// Bug!!! Bug#040
// Don’t put fbDoConnection into the applog
// LogAppErr(‘TAndroidChatManager.fbDoConnection: ‘ + E.classname, ‘general’, E.message);
//=========================================================
// Bug!!! Bug#041
// Comment: Num Point is using 16384 instead of 2048
// More accuracy and precise of Frequency and Amplitude!!!
// More accuracy and precise of Frequency and Amplitude!!!
// More accuracy and precise of Frequency and Amplitude!!!
// bpm is more precise and accuracy.
// giNumPoints : integer = 16384; //Instead of 2048, Number of Point of Chart Value
// giObsNumPoints : integer = 8192; //Instead of 1024, Half Number of Point of Chart Value
// giNumBufPoints : integer = 16384; //Instead of 3072, Is to define the Plot Graph Width.
//=========================================================
// Bug!!! Bug#042
// giNumPoints : integer = 8192;
// Number of Point of Chart Value. Default = 8192. [min 1024, 2048, 4096, 8192, 16384 max]
// If using 16384 for giNumPoints, sound pitch output will have the distortion
//=========================================================
// Bug!!! Bug#043
// Check Android version below 4.4.x
// Set giNumPoints = 2048
// If Android version on or after 5.0
// Set giNumPoints = 4096
// If you want to set giNumPoints = 8192 or 16384, the sound frequency will have the distortion!!!
// If you want to set giNumPoints = 8192 or 16384, the sound frequency will have the distortion!!!
// If you want to set giNumPoints = 8192 or 16384, the sound frequency will have the distortion!!!
//=========================================================
// Bug!!! Bug#044
// Add 1 to iSTBufPoints for buffer. There is an exception for 4.4.2
//=========================================================
// Bug!!! Bug#045
// Need to add below code to control the lblTWA Visible at fbTAnalysis
// frmECG.lblTWA.Visible := frmECG.cbxZeroCross.IsChecked and frmECG.cbxMonitor.IsChecked;
//=========================================================
// Bug!!! Bug#046
// Comment:
// Now, put the dAllowLtd at the if condition check for Local Maxima R-Complex!!!
// dAllowance:= abs(dMaxima1 – dMaxima2)*dAllowLtd;
// dAllowLtd = 1.5 is good for QT Analysis
// dAllowLtd = 0.5 is good for RR Interval
//
// There is no significant difference to increase the value dAllowLtd2 = 1.5 to 3.
//
// These TWO if conditions is applied.
// The output RR-Interval and QT-Complex calculation are More More accurate!!!
// The output RR-Interval and QT-Complex calculation are More More accurate!!!
// The results are under expectation.
//
// There are TWO if conditions for Local Maxima
// (1) if (dDY0 <> 0) and (dDY1 <> 0) and (dDY2 <> 0) and (dMaxima1 <> 0) and (dMinima2 <> 0) and (not bMaxima) and
// (dDY0 < dDY1) and (dDY1 > dDY2) and (dDY1 > dMaxima1 – dAllowance*dAllowLtd1)
// (2) if (dDY0 <> 0) and (dDY1 <> 0) and (dDY2 <> 0) and (dMaxima1 <> 0) and (dMinima2 <> 0) and (not bMaxima) and
// (dDY0 < dDY1) and (dDY1 > dDY2) and (dDY1 > dMaxima1 – dAllowance*dAllowLtd2) then
//
// There are TWO if conditions for Local Mimima
// (1) if (dDY0 <> 0) and (dDY1 <> 0) and (dDY2 <> 0) and bMaxima and (dDY0 > dDY1) and (dDY1 < dDY2) and
// (iTrs1 < iTimeBase * dRTimeWidth) and //(iTimeBase * dRTimeWidth / 2 < iTrs1) and
// (dDY1 < dMaxima1 – dAmp + dAllowance*dAllowLtd2) and (dMaxima1 – dAmp – dAllowance*dAllowLtd2 < dDY1) then
// (2) if (dDY0 <> 0) and (dDY1 <> 0) and (dDY2 <> 0) and bMaxima and (dDY0 > dDY1) and (dDY1 < dDY2) and
// (iTrs1 < iTimeBase * dRTimeWidth) and //(iTimeBase * dRTimeWidth / 2 < iTrs1) and
// (dDY1 < dMaxima1 – dAmp + dAllowance*dAllowLtd1) and (dMaxima1 – dAmp – dAllowance*dAllowLtd1 < dDY1) then
//=========================================================
// Bug!!! Bug#047
// Need to re-test these two statements!!!
// Comment out these two lines. The Plot will run faster!!!
// ecgFastLine.Repaint;
// ecgChart.Invalidate;
//=========================================================
// Bug!!! Bug#048 Done
// Fixed FormVirtualKeyboardShown
// Keyboard is hiding the edit.text in Android
//
// Hard code. We don’t have better solution to get the virtual keyboard size Height and Width.
// Once we have the virtual keyboard size, we can relocate the select text or focus.
// Now, we just use screen size to recalculate the keyboard size.
//=========================================================
// Bug!!! Bug#049
// ‘Pause’ click
// We cannot stop the ecgMonitor to right away.
// We send a stop command to ecgMonitor. The internal thread is keep on running.
// ecgMonitor need to pause to process the stop command. This action not working properly!!!
//
// //Using fbBTCharacteristicWrite to send gsCMD to ECG Client
// if not BT4ChatClass.fbBTCharacteristicWrite(btLowEnergy,
// btDevice,
// sCMD,
// slLine,
// btGattCharacteristic,
// sErrMsg) then
// begin
// slLine.Add(sErrMsg);
// {$IFDEF ctrlBT_Log}
//
// We can try to change the ‘app.log and ecgFile.ini’ to ‘apps.log and ecgFile.ini’
// We can use ‘com.pqrst.$(ModuleName)’ or other name ‘com.PQRST.ca’ (Case Sensitive). The problem will be solved.
// Android debug version package name = ‘com.pqrst.$(ModuleName).debug’ or ‘com.PQRST.ca’ …
// Android release version package name = ‘com.pqrst.$(ModuleName)’ or ‘com.pqrst.ca’ …
//=========================================================
// Bug!!! Bug#091
// Minor Bug fix at swZeroCrossClick. Add pcrSetupHRMonitor to event click.
//=========================================================
// Bug!!! Bug#092
// IOS Cannot start the BT connection automatically!!!
// Abdroid start BT connection – OK.
// It is better let the user to activate from drop down list!!!
//=========================================================
// Bug!!! Bug#093
// BT5 cannot search Bluetooth device if the location have too many Bluetooth transmitter source.
//=========================================================
// Bug!!! Bug#094
// For RIO1030:-
// ecgWebBrowser/TWebBrowser will raise up exception with TForm.
// frmECG.BorderStyle := TFmxFormBorderStyle.None will crash with the TForm!!!
// Solution: frmECG.BorderStyle := TFmxFormBorderStyle.Sizeable; <<< This one must be worked in MSWINDOWS!!!
// Solution: frmECG.BorderStyle := TFmxFormBorderStyle.NONE; <<< This one must be worked for OTHER OS!!!
// For Toyko1023:-
// Solution: frmECG.BorderStyle := TFmxFormBorderStyle.NONE; <<< This one must be worked for ALL OS!!!
//=========================================================
// Bug!!! Bug#095
// 1023-v1-AndroidSDK25.2.5_32bit.sdk is working sdk in delphi 1023!!!
// C:UsersPublicDocumentsEmbarcaderoStudio20.0PlatformSDKsandroid-sdk-windows where 20.0 is working!!!
// C:UsersPublicDocumentsEmbarcaderoStudio17.0PlatformSDKsandroid-ndk-r9c where 17.0 is working!!!
// C:Program FilesJavajdk1.7.0_71binkeytool.exe is working!!!
//
// Comment: C:UsersPublicDocumentsEmbarcaderoStudio20.0PlatformSDKsandroid-ndk-r17b is NOT working!!!
// It only works in Delphi 10.3!!! It does NOT working in 10.2.3!!!
//
// 1030-AndroidSDK25.2.5_32bit.sdk is working sdk in delphi 1030!!!
// C:UsersPublicDocumentsEmbarcaderoStudio20.0PlatformSDKsandroid-sdk-windows where 20.0 is working!!!
// C:UsersPublicDocumentsEmbarcaderoStudio20.0PlatformSDKsandroid-ndk-r17b where 20.0 is working!!!
// C:Program FilesJavajdk1.7.0_71binkeytool.exe is working!!!
//=========================================================
// Bug!!! Bug#096
// TWebBrowser has a bug!!!
// Status: Bug Fixed
// RIO1030 uLocation.pas/TWebBrowser/ecgWebBrowser does NOT work in RIO1030!!!
// Toyko1023 uLocation.pas/TWebBrowser/ecgWebBrowser WORK in Toyko1023!!!
//
// https://quality.embarcadero.com/browse/RSP-21834
// Comment out the below statement. IOSSensor problem will be fixed on triggering OnLocationChanged event.
// [MethodName(‘locationManager:didUpdateLocations:’)]
// The problem can be worked around by copying the unit to the project folder, and commenting out line 151
// (the MethodName attribute for locationManagerDidUpdateLocations)
// Just copy the file from C:Program Files (x86)EmbarcaderoStudio20.0sourcertlcommonSystem.iOS.Sensors.pas,
// to the folder your project is in.
//=========================================================
// Bug!!! Bug#097
// Solution: WORKED from Dave N, DelphiWorlds
// Status: Bug Fixed
//
// TWebBrowser has a bug in RIO1030!!!
// There is no problems in Tokyo1023!!!
// Align: Client in Samsung S9 NOT work after minimize!!!
//
// Comment: Detect on Samsung S8 & S9 making Align: FitLeft
//=========================================================
// Bug!!! Bug#098
// Android version
// After certain time the apps will be killed by the OS of Android,
// if the user switch off the screen after certain time.
// Killing apps time is depending on setting arround 5-10 minutes.
// =============================
// Attention: PARTIAL_WAKE_LOCK
// It doesn’t work!!! with any combination with IgnoringBatteryOptimization.
// Android will kill the background apps after API 26.
// We only use JavaClass.FLAG_KEEP_SCREEN_ON to enable the CPU and Screen on.
// =============================
//
// IOS Version
// There is no such issue the apps will be killed by the IOS.
//
// Mode: PARTIAL_WAKE_LOCK
//
// Reference: [How to prevent FireMonkey app / service stop working while in background?]
// https://stackoverflow.com/questions/52504808/how-to-prevent-firemonkey-app-service-stop-working-while-in-background
//
// [Guide to background processing]
// https://developer.android.com/guide/background#js
//
// [how to keep app running when screen off?]
// https://stackoverflow.com/questions/44743265/how-to-keep-app-running-when-screen-off-or-open-another-app
//
// [Delphi XE5 Android. How to use PowerManager.WakeLock?]
// https://stackoverflow.com/questions/19021647/delphi-xe5-android-how-to-use-powermanager-wakelock
//
// [How to keep an Activity running while screen off?]
// https://stackoverflow.com/questions/11978742/how-to-keep-an-activity-running-while-screen-off
//
// [PowerManager]
// https://developer.android.com/reference/android/os/PowerManager
//
// [GlassLevel example by Embarcardero]
// is using wake lock to keep the apps continue running in background
//
// [Optimize for Doze and App Standby]
// https://developer.android.com/training/monitoring-device-state/doze-standby
//
// Comment:
// There are few solutions to solve this problems by ‘Background Processing’.
// DownloadManager, sync adapter, JobScheduler, Firebase Cloud Messaging and Wake Lock.
// Please See ‘Modified: 16 Mar 2019 10:00:00 PM’
//=========================================================
// Bug!!! Bug#099
// Android version
// There is a bug when the Wake Lock acquire at the frmCreate.
// Once the user wake up the system, it will go through below statement and release the wake lock.
// TApplicationEvent.WillBecomeInactive : pcrRelease_WakeLock(jprWakeLock);
// If the user keep on/off the power button, the apps will pass through WillBecomeInactive.
// Release_WakeLock will be release.
//
// Therefore, the apps sometime work and sometime NOT work of the wake lock particularly
// at the long sleeping!!! The apps will be killed by the system when background running.
//
// Comment: We try to remove the pcrRelease_WakeLock when the app is still running
// for long time and wake up by user by press power button.
// Solution: Finally, it is working!!! Testing about 5hr long sleeping, it is working!!!
//=========================================================
// Bug!!! Bug#100
// IOS for iPhone
// There is a bug “Cannot begin rendering scene for ‘TContextIOS'”.
// When the TForm change the exception will be raised.
//
// Comment:
// 1) Try to include FMX.Context.GLES.IOS.pas in the project.
// 2) rectPageAbout, rectPageBT4Chat, rectPageBTChat, rectTabECGMonitorClick & rectPageLocation
// there will be pcrSetLandscapeOrientation with NO pcrSetALLOrientation.
// 3) rectPageSetup, rectPageFile & rectPageTheme
// there will be pcrSetALLOrientation instead.
//=========================================================
// Bug!!! Bug#101
// Solution: WORKED from Dave N, DelphiWorlds
// Status: Bug Fixed
//
// For Samsung S9, Change Orientation is not work on Location Page!!!
// For Android, All Orientation is work. But Landscape and Inverted Landscape are not worked.
// Bug!!! Bug#097
//
// TWebBrowser has a bug in RIO1030!!!
// There is no problems in Tokyo1023!!!
//
// Solution: WORKED from Dave N, DelphiWorlds
//=============================
// Tokyo1023
// FMX.FORMS is NOT added.
// RIO1030
// FMX.FORMS is added to the project folder ‘ECG Bluetooth App’.
// Rename ‘1030FMX.Forms.pas’ to ‘FMX.Forms.pas’ when project compiled in RIO1030.
//=============================
//
// Comment:
// 1) Try to include FMX.Context.GLES.IOS.pas in the project.
// 2) rectPageAbout, rectPageBT4Chat, rectPageBTChat, rectTabECGMonitorClick & rectPageLocation
// there will be pcrSetLandscapeOrientation with NO pcrSetALLOrientation.
// 3) rectPageSetup, rectPageFile & rectPageTheme
// there will be pcrSetALLOrientation instead.
//=========================================================
// Bug!!! Bug#102
// OLD library of U_FFT.pas from Pascal has error on REALFFT2.
// It will crash with ‘Doze’ mode in Android 8.0 or above.
// It must be Keep_Screen_ON to let the apps run.
// Issue: The client let Android to sleep or go to ‘Doze’ mode,
// sleeping for long time without activities, the app will crach when switch on again.
// The bug is at the REALFFT2 library.
//
// Solution: Using fbFourierTransform from fourier.pas – Don Cross <dcross@intersrv.com>
// http://www.intersrv.com/~dcross/fft.html#pascal
// or
// https://github.com/neurolabusc/MRIcron
//
// Function fbFourierTransform is rewriten to replace the REALFFT2.
// There is an error of calculate the daAmps[i] amplitude array after using fbFourierTransform.
// daAmps[i] := eAmplitude/sqrt(iNBRPoints); //<<<< After using fbFourierTransform, here need to divide sqrt(iNBRPoints);
//=========================================================
// Bug!!! Bug#103
// lblBatOpt.Text:= FormatDateTime(‘hh:nn:ss’, tmrBatOpt.Tag / SecsPerDay);
//=========================================================
// Important Notes:-
// To reinstall the apps with the newer version:-
// 1) Goto storage to clear the data and/or clear the cached data.
//
// 2) For ‘Release Version’
// All system folder: Android,
// IOSDevice32,
// IOSDevice64,
// IOSSimulator,
// OSX32,
// Win32,
// Win64
// We need to delete all the above folders and rebuild a clean apps!!!
// We need to delete all the above folders and rebuild a clean apps!!!
// We need to delete all the above folders and rebuild a clean apps!!!
//
// Comment: iPad Mini 2 test run: This machine does not support ‘UIBackgroundModes’.
// When the iPad switch off and the system will kill all the apps running
// in the background. The apps will restart after coming back.
//=========================================================
// Alpha Test
// Comment: All TApplicationEvent are Original. PARTIAL_WAKE_LOCK and Default Screen ON
//
// v1.0.0.A – Apply DelphiWorld RestartIfNotIgnoringBatteryOptimizations.
// Optimize the code in fbMakeSpectrum and fbQuadratic
// v1.0.0.F – FFT Don Cross – Fast Fourier Transformation / Fourier.pas
// MUST RESET Android!!!
// v1.0.0.2 – kastri updated library, move to H:ProjectECG Bluetooth ProjectECG Bluetooth AppAndroidManifest.template.xml
// v1.0.0.3 – Delete and cleanup unnecessary files in project folder.
// Verify Kastri library
// AndroidManifest.template.xml //
//
//
// v1.0.0.4 – AndroidManifest.template.xml //
// android:allowTaskReparenting=”true”
// android:launchMode=”standard”
// v1.0.0.5 – Apply Band Pass Filter after (Fast Fourier Transformation) fbFourierTransform to make the iteration faster.
// Apply Band Pass Filter for frequency = 0.5Hz to 360Hz = 30 bpm to 360 bpm
// AndroidManifest.template.xml //
// android:allowTaskReparenting=”true” //Remove this statement
// android:launchMode=”standard” //Change this statement back to “singleTask”
// The Doze mode bug may be here below!!!
// There is unnecessary to check this statement here. For loop is a band pass filter!!!
// if ((daFreqs[i] <= iBPMHighLimit*cdDiv60) and (daFreqs[i] >= iBPMLowLimit*cdDiv60)) then
// v1.0.0.6 – Remove READ_PHONE_STATUS in AndroidManifest.Template.xml
// Modified Label lblScreenCtrl for gsHighPerformanceMode, gsLowBatteryMode1 & gsLowBatteryMode2
// v1.0.0.7 – Modified: 17 May 2019 01:00:00 AM
// Disable below functions: for Android and IOS!!!
// They are not the MAJOR functions. Otherwise, Google and Apple will ban or not allow to publish the app.
// 1) READ_SMS and SEND_SMS
// 2) CALL_PHONE
// 3) Email
// 4) REQUEST_IGNORE_BATTERY_OPTIMIZATIONS and WAKE_LOCK
// Google Play will not approve the above function. They will ban or subspend the account!!!
// Change the Splash Screen accordingly.
// For Android, Screen Ctrl – Keep Screen On/Allow to do any activities until press ‘Power’ button.
// – Keep Screen Off/Single App/Can last for more than 4 hrs
// For IOS, Screen Ctrl – Keep Screen On/Allow to do any activities/No such issue!!!
// – Keep Screen Off/Allow to do any activities/No such issue!!!
// Default: KEEP_SCREEN_OFF. Keep Screen On will draw so many battery!
// v1.0.7.1 – Modified: 07 Jun 2019 07:00:00 AM
// Minor bug fix on lblBatOpt format hh:nn:ss
//=========================================================
// Testing: Apps ecgMonitor v1.0.0.5.apk
//
// Model Options Doze Mode/Sleep Resolution Result Status
// Samsung S9 FFT+ZeroCross+ScreenON Always WakeUP 256sps Any Activity OK
//
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 1Hr+NO Activity 256sps ?
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 2Hr+NO Activity 256sps ?
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 3Hr+NO Activity 256sps ?
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 4Hr+NO Activity+NO Power 256sps XXX
//
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 1Hr+NO Activity+NO Power 128sps OK
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 2Hr+With Activity+NO Power 128sps OK
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 3Hr+with Activity+NO Power 128sps OK
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 4Hr+with Activity+NO Power 128sps OK
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 5Hr+with Activity+NO Power 128sps OK
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 6Hr+with Activity+NO Power 128sps OK
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 7Hr+with Activity+NO Power 128sps OK
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 8Hr+with Activity+NO Power 128sps OK
// Samsung S9 FFT+ZeroCross+ScreenAutoOFF 9Hr+with Activity+NO Power 128sps OK
//
// Comment:
// with Activity = background with two or more games, wifi phone calling, browsing, camera photo activities…etc.
// NO Power = usb power cable is unplug.
//=========================================================
Hardware Revision
//=========================================================
// Hardware Revision
//=========================================================
// 1st prototype of ECG Monitor
// ADS8866 ADC converter is deleted.
// BT2 is used for communication with Android.
//=========================================================
// 2nd prototype of ECG Monitor
// BT2 is used for communication with Android.
// 50Hz/60Hz Notch Filter are added to filter out the noise from AC.
// MAX4624 is used for control and is deleted.
//=========================================================
// 3rd prototype of ECG Monitor
// BT4 is used for communication with Android.
//=========================================================
// 4th prototype of ECG Monitor
// BT4 is used for communication with Android and iPhone
// Add USB power charging unit.
// Re-design the hardware layout.
//=========================================================
// 5th prototype of ECG Monitor
// Re-design the hardware layout and minimize the size of the case.
// Use 0.6mm pcb for the manufacturing.
// Checking the layout for the Surface Mount Technology.
//=========================================================
Firmware Revision
//=========================================================
// THREE modes of Heart Rate Monitor
//=========================================================
// Description:
// There are three modes of Heart Rate Monitor.
//
// Function:
// Mode 1: ECG Waveform Monitoring
// Mode 2: Heart Rate Measurement Next to Heart
// Mode 3: HEART RATE MEASUREMENT AT HANDS (Trial Mode)
//
//=========================================================
// Mode 1: ECG Waveform Monitoring
//=========================================================
// This configuration is designed for monitoring the shape
// of the ECG waveform. It assumes that the patient remains
// relatively still during the measurement, and therefore,
// motion artifacts are less of an issue.
//
// To obtain an ECG waveform with minimal distortion, the
// AD8232 is configured with a 0.5 Hz two-pole high-pass
// filter followed by a two-pole, 40 Hz, low-pass filter.
// A third electrode is driven for optimum common-mode
// rejection.
//
// In addition to 40 Hz filtering, the op amp stage
// is configured for a gain of 11, resulting in a
// total system gain of 1100.
//=========================================================
// Mode 2: HEART RATE MEASUREMENT NEXT TO THE HEART
//=========================================================
// For wearable exercise devices, the AD8232 is typically
// placed in a pod near the heart. The two sense electrodes
// are placed under-neath the pectoral muscles; no driven
// electrode is used. Because the distance from the heart
// to the AD8232 is small, the heart signal is strong and
// there is less muscle artifact interference.
//
// To obtain an ECG waveform with minimal distortion, the
// AD8232 is configured with a 0.5 Hz two-pole high-pass
// filter followed by a two-pole, 40 Hz, low-pass filter.
// No gain is used on the output op amp.
// Total system gain is 100.
//=========================================================
// Mode 3: HEART RATE MEASUREMENT AT HANDS (Trial Mode)
//=========================================================
// The heart rate signal is measured at the hands with
// stainless steel electrodes. The user’s arm and upper body
// movement create large motion artifacts and the long lead
// length makes the system susceptible to common-mode
// interference.
//
// To obtain an ECG waveform with minimal distortion, the
// AD8232 is configured with a 0.5 Hz two-pole high-pass
// filter followed by a two-pole, 40 Hz, low-pass filter.
//
// In addition to 40 Hz filtering, the op amp stage
// is configured for a gain of 11, resulting in a
// total system gain of 1100.
//=========================================================
//=========================================================
// Heart Mode
// There are two electrode underneath the equipment. User can place the equipment next to your heart
// to carry out the ecg monitor function.
// BUT there is NO detection of two electrodes which is connected or disconnected with the user body of the heart.
//
// Comparsion with Cardiac Mode.
// There is a detection of two electrodes which is connected or disconnected with the user body of the heart.
// There will have an indications of the connection with the user body.
//=========================================================
//=========================================================
//=========================================================
// COMMENT: Cardiac Mode & Heart Mode
// There is NO significant difference between Cardiac Mode & Heart Mode in hardware.
// Two units of MAX4626 switches are deleted. Now, the firmware of Cardiac Mode & Heart Mode are the same.
// Even though the instruction CMD command ?a and ?b is to change the PD3 and PD7 logic. Actually, there
// is NO change of the hardware of AD8232. It only config as Cardiac Mode with gain = 1100.
//
// LO+ and LO- are connected to CPU port PD5 and PD6. Software detection algorithm is used to detect the LO+ and LO-.
// In Cardiac Mode, it will detect the connectivity of LA and RA electrodes to the body.
// In Heart Mode, LO+ and LO- are disable by software. The two electrodes are directly connected to the body
// next to the heart.
//=========================================================
Mechanical Design Revision
//=========================================================
// Mechanical Design Revision
//=========================================================
// Description: CAD design
//=========================================================
// 1st prototype of ECG Monitor
// Use 18650 6000mAh Li-ion 3.7v Battery.
// Use external usb power charging unit.
// Generate the STL file for 3D printing.
//=========================================================
// 2nd prototype of ECG Monitor
// Use PN523450 1000mAh Li-ion 3.7v Battery.
// Rebuild usb power charging unit.
// Generate the STL file for 3D printing.
//=========================================================
// 3rd prototype of ECG Monitor
// Re-design 0.6mm PCB for manufacturing.
// Build the firmware programmer for the ECG Monitor.
// Generate the STL file for 3D printing.
//=========================================================
// 4th prototype of ECG Monitor
// Re-design elastic belt and clip to hold the ECG Monitor.
// Re-design the ECG Monitor case.
// Generate the STL file for 3D printing.
//=========================================================
// 5th prototype of ECG Monitor
// Re-design elastic belt and clip to hold the ECG Monitor.
// Re-design the ECG Monitor case.
// Generate the STL file for 3D printing.
//=========================================================
// 6th prototype of ECG Monitor
// Re-design elastic belt and clip to hold the ECG Monitor.
// Re-design the ECG Monitor case.
// Generate the STL file for 3D printing.
//=========================================================