Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: hspguisourcev301/HspGuiSourceV301/HSPGui/Presenter/StreamPresenter.cs
- Revision:
- 3:36de8b9e4b1a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hspguisourcev301/HspGuiSourceV301/HSPGui/Presenter/StreamPresenter.cs Sat Apr 10 03:05:42 2021 +0000
@@ -0,0 +1,265 @@
+/*******************************************************************************
+* Copyright (C) 2016 Maxim Integrated Products, Inc., All rights Reserved.
+*
+* This software is protected by copyright laws of the United States and
+* of foreign countries. This material may also be protected by patent laws
+* and technology transfer regulations of the United States and of foreign
+* countries. This software is furnished under a license agreement and/or a
+* nondisclosure agreement and may only be used or reproduced in accordance
+* with the terms of those agreements. Dissemination of this information to
+* any party or parties not specified in the license agreement and/or
+* nondisclosure agreement is expressly prohibited.
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using RPCSupport;
+using RPCSupport.Streaming;
+using HealthSensorPlatform.CustomControls;
+using HealthSensorPlatform.Model;
+using HealthSensorPlatform.View;
+
+namespace HealthSensorPlatform.Presenter
+{
+ public class StreamPresenter
+ {
+ const double NoData = -5000;
+ const int NoRToR = -1;
+
+ private RPCClient rpcClient;
+ private EcgView ecgView;
+ private IFormView formView;
+ private int rToRRaw = NoRToR;
+ private PaceData paceData;
+ private bool start = false;
+
+ public StreamPresenter()
+ {
+
+ }
+
+ public StreamPresenter(EcgView ecgView)
+ {
+ this.ecgView = ecgView;
+ }
+
+ public StreamPresenter(RPCClient rpcClient, EcgView ecgView, IFormView formView)
+ {
+ this.rpcClient = rpcClient;
+ this.ecgView = ecgView;
+ this.formView = formView;
+
+ ecgView.StreamingStartStop += new EventHandler<StreamingStartStopEventArgs>(OnStreamingStartStop);
+ rpcClient.streaming.PartialArrayIntAvailable += new EventHandler<PartialArrayIntAvailableEventArgs>(OnStreamData);
+ }
+
+ private void OnStreamingStartStop(object sender, StreamingStartStopEventArgs e)
+ {
+ start = e.state;
+
+ if (ecgView.Connected && !start) // Clear Interrupts on stream start and stop, start to prevent RPC Int Assignment freeze
+ {
+ rpcClient.MAX30001.WriteReg(0x02, 0x03); // Stop Interrupts
+ rpcClient.MAX30001.WriteReg(0x03, 0x03); // Stop Interrupts
+ }
+
+ formView.EcgLogFileItem(false);
+ formView.BioZLogFileItem(false);
+ formView.RtoRLogFileItem(false);
+ formView.PaceLogFileItem(false);
+ }
+
+ private void OnStreamData(object sender, PartialArrayIntAvailableEventArgs e)
+ {
+ int leadOffState;
+ if (start && e.array1.Length > 0) // Ignore events unless started (from flash logging)
+ {
+ leadOffState = e.array1[0];
+
+ switch(e.reportID)
+ {
+ case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_LEADOFF_DC:
+ ecgView.SetDCLeadOff(leadOffState);
+ break;
+ case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_LEADOFF_AC:
+ ecgView.SetACLeadOff(leadOffState);
+ break;
+ }
+
+ switch (e.reportID)
+ {
+ case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_ECG:
+ ProcessEcg(e.array1);
+ break;
+ case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_BIOZ:
+ ProcessBioZ(e.array1);
+ break;
+ case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_PACE:
+ ProcessPace(e.array1);
+ break;
+ case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_RTOR:
+ rToRRaw = e.array1[0];
+ ecgView.DisplayRToR(e.array1[0]);
+ break;
+ }
+ }
+ }
+
+ void ProcessBioZ(int[] rawData)
+ {
+ BioZFifo[] bioZFifo;
+ double[] bioZImpedance;
+
+ bioZFifo = ConvertBioZ(rawData);
+
+ bioZImpedance = new double[bioZFifo.Length];
+ for (int i = 0; i < bioZFifo.Length; i++)
+ {
+ bioZImpedance[i] = bioZFifo[i].Data;
+ }
+ ecgView.DisplayBioZ(bioZImpedance);
+ }
+
+ public BioZFifo[] ConvertBioZ(int[] data)
+ {
+ BioZFifo[] impedence = new BioZFifo[data.Length];
+ EcgView.ChartInfo chartInfo = ecgView.BioZInfo;
+ int dataShift;
+
+ for (int i = 0; i < data.Length; i++)
+ {
+ dataShift = data[i] >> chartInfo.Shift;
+
+ // Two's Complement Conversions
+ if (dataShift > chartInfo.Threshold)
+ {
+ dataShift -= chartInfo.Offset;
+ }
+
+ // 1.9734 = 1/2^19 * 1e-6
+ impedence[i].Data = dataShift * 1.9073486328125 /
+ (chartInfo.Gain * ((chartInfo.CurrentGenerator == 0) ? 1 : chartInfo.CurrentGenerator));
+ impedence[i].BTag = data[i] & 0x07;
+ }
+
+ return impedence;
+ }
+
+ public double[] ProcessEcg(int[] rawData)
+ {
+ EcgFifo[] ecgFifo;
+ double[] ecgVoltage = new double[rawData.Length];
+ double[] rToRInterval = null;
+
+ // Pace File Log
+ string[] paceRegisterLog = new string[rawData.Length];
+
+ List<EcgView.PacePoint> pacePoints = new List<EcgView.PacePoint>();
+
+ ecgFifo = ConvertEcg(rawData);
+
+ // ECG
+ for (int i = 0; i < ecgFifo.Length; i++)
+ {
+ ecgVoltage[i] = ecgFifo[i].Data;
+
+ if (ecgFifo[i].PTag != 0x07 && paceData != null) // Pace Event
+ {
+ PaceData.PaceRegister paceRegister = paceData.PaceGroup(ecgFifo[i].PTag); // Register Group
+ PaceData.PaceEdge[] paceEdges = paceRegister.Edge; // Pace Edge
+
+ // Pace Charting Data
+ int k = 0;
+ PaceData.PaceEdge edge;
+ do
+ {
+ edge = paceEdges[k];
+ // Convert Pace into ECG samples
+ // (Pace Raw / (2 * FMSTR )) / (1 / ECG Sample Rate) = Pace Raw * ECG Sample Rate / (2 * FMSTR)
+ pacePoints.Add(new EcgView.PacePoint(i + (edge.Data * ecgView.SampleRateEcg / (2 * ecgView.MasterClockFrequency)), edge.Polarity));
+
+ k++;
+ }
+ while (!(edge.Last == true || k >= 6));
+ }
+ }
+
+ // R to R
+ if (ecgView.EnableRToR)
+ {
+ rToRInterval = new double[rawData.Length];
+ for (int i = 0; i < rToRInterval.Length; i++)
+ {
+ rToRInterval[i] = NoData;
+ }
+
+ if (rToRRaw > 0)
+ {
+ rToRInterval[0] = ecgVoltage[0]; // Plot at height of ECG signal
+ rToRRaw = NoRToR;
+ }
+ }
+
+ ecgView.DisplayEcg(ecgVoltage, pacePoints.ToArray(), rToRInterval);
+
+ return ecgVoltage;
+ }
+
+ public EcgFifo[] ConvertEcg(int[] data)
+ {
+ EcgFifo[] voltage = new EcgFifo[data.Length];
+ EcgView.ChartInfo chartInfo = ecgView.EcgInfo;
+ int dataShift;
+
+ for (int i = 0; i < data.Length; i++)
+ {
+ dataShift = data[i] >> chartInfo.Shift;
+
+ // Two's Complement Conversions
+ if (dataShift > chartInfo.Threshold)
+ {
+ dataShift -= chartInfo.Offset;
+ }
+
+ voltage[i].Data = 1000 * 7.62939453125e-6 * dataShift / chartInfo.Gain;
+ voltage[i].PTag = data[i] & 0x07;
+ voltage[i].ETag = (data[i] >> 3) & 0x07;
+ }
+
+ return voltage;
+ }
+
+ public PaceData ProcessPace(int[] data)
+ {
+ paceData = new PaceData(data);
+
+ return paceData;
+ }
+
+ }
+}