repo time

Dependencies:   mbed MAX14720 MAX30205 USBDevice

Committer:
darienf
Date:
Tue Apr 06 06:41:40 2021 +0000
Revision:
20:6d2af70c92ab
another repo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
darienf 20:6d2af70c92ab 1 /*******************************************************************************
darienf 20:6d2af70c92ab 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All rights Reserved.
darienf 20:6d2af70c92ab 3 *
darienf 20:6d2af70c92ab 4 * This software is protected by copyright laws of the United States and
darienf 20:6d2af70c92ab 5 * of foreign countries. This material may also be protected by patent laws
darienf 20:6d2af70c92ab 6 * and technology transfer regulations of the United States and of foreign
darienf 20:6d2af70c92ab 7 * countries. This software is furnished under a license agreement and/or a
darienf 20:6d2af70c92ab 8 * nondisclosure agreement and may only be used or reproduced in accordance
darienf 20:6d2af70c92ab 9 * with the terms of those agreements. Dissemination of this information to
darienf 20:6d2af70c92ab 10 * any party or parties not specified in the license agreement and/or
darienf 20:6d2af70c92ab 11 * nondisclosure agreement is expressly prohibited.
darienf 20:6d2af70c92ab 12 *
darienf 20:6d2af70c92ab 13 * The above copyright notice and this permission notice shall be included
darienf 20:6d2af70c92ab 14 * in all copies or substantial portions of the Software.
darienf 20:6d2af70c92ab 15 *
darienf 20:6d2af70c92ab 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
darienf 20:6d2af70c92ab 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
darienf 20:6d2af70c92ab 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
darienf 20:6d2af70c92ab 19 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
darienf 20:6d2af70c92ab 20 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
darienf 20:6d2af70c92ab 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
darienf 20:6d2af70c92ab 22 * OTHER DEALINGS IN THE SOFTWARE.
darienf 20:6d2af70c92ab 23 *
darienf 20:6d2af70c92ab 24 * Except as contained in this notice, the name of Maxim Integrated
darienf 20:6d2af70c92ab 25 * Products, Inc. shall not be used except as stated in the Maxim Integrated
darienf 20:6d2af70c92ab 26 * Products, Inc. Branding Policy.
darienf 20:6d2af70c92ab 27 *
darienf 20:6d2af70c92ab 28 * The mere transfer of this software does not imply any licenses
darienf 20:6d2af70c92ab 29 * of trade secrets, proprietary technology, copyrights, patents,
darienf 20:6d2af70c92ab 30 * trademarks, maskwork rights, or any other form of intellectual
darienf 20:6d2af70c92ab 31 * property whatsoever. Maxim Integrated Products, Inc. retains all
darienf 20:6d2af70c92ab 32 * ownership rights.
darienf 20:6d2af70c92ab 33 *******************************************************************************
darienf 20:6d2af70c92ab 34 */
darienf 20:6d2af70c92ab 35
darienf 20:6d2af70c92ab 36 using System;
darienf 20:6d2af70c92ab 37 using System.Collections.Generic;
darienf 20:6d2af70c92ab 38 using System.Linq;
darienf 20:6d2af70c92ab 39 using System.Text;
darienf 20:6d2af70c92ab 40
darienf 20:6d2af70c92ab 41 using HealthSensorPlatform.View;
darienf 20:6d2af70c92ab 42 using HealthSensorPlatform.Model;
darienf 20:6d2af70c92ab 43 using HealthSensorPlatform.CustomControls;
darienf 20:6d2af70c92ab 44
darienf 20:6d2af70c92ab 45 using RPCSupport;
darienf 20:6d2af70c92ab 46 using RPCSupport.Streaming;
darienf 20:6d2af70c92ab 47
darienf 20:6d2af70c92ab 48 namespace HealthSensorPlatform.Presenter
darienf 20:6d2af70c92ab 49 {
darienf 20:6d2af70c92ab 50 public class RawFileLogPresenter
darienf 20:6d2af70c92ab 51 {
darienf 20:6d2af70c92ab 52 IRawFileLogView ecgLog;
darienf 20:6d2af70c92ab 53 IRawFileLogView bioZLog;
darienf 20:6d2af70c92ab 54 IRawFileLogView rToRLog;
darienf 20:6d2af70c92ab 55 IRawFileLogView paceLog;
darienf 20:6d2af70c92ab 56 IFormView formView;
darienf 20:6d2af70c92ab 57 IEcgView ecgView;
darienf 20:6d2af70c92ab 58
darienf 20:6d2af70c92ab 59 bool fileLog = false; // user enabled file logging
darienf 20:6d2af70c92ab 60 bool streaming = false; // streaming data or flash log data, only save data from streaming
darienf 20:6d2af70c92ab 61 //bool flashLog = false;
darienf 20:6d2af70c92ab 62
darienf 20:6d2af70c92ab 63 IDataLoggingView dataLogView;
darienf 20:6d2af70c92ab 64
darienf 20:6d2af70c92ab 65 PaceData paceData;
darienf 20:6d2af70c92ab 66
darienf 20:6d2af70c92ab 67 RToRCalculator rToRCalculator;
darienf 20:6d2af70c92ab 68 bool rToRFirst = true; // received first RR value for offset correction
darienf 20:6d2af70c92ab 69
darienf 20:6d2af70c92ab 70 //bool ecgLeadOff; // DC Lead off data for ECG or BioZ Channel
darienf 20:6d2af70c92ab 71 DCLeadOff leadOff; // lead off status bits
darienf 20:6d2af70c92ab 72 ACLeadOff acLeadOff; // bioz lead off status bits
darienf 20:6d2af70c92ab 73
darienf 20:6d2af70c92ab 74 int count = 0;
darienf 20:6d2af70c92ab 75 int bioZCount = 0;
darienf 20:6d2af70c92ab 76 //int ppgCount = 0;
darienf 20:6d2af70c92ab 77 //int accelCount = 0;
darienf 20:6d2af70c92ab 78
darienf 20:6d2af70c92ab 79 string logFileDirectory = null;
darienf 20:6d2af70c92ab 80
darienf 20:6d2af70c92ab 81 View.FileLogView.FileLogHeader fileLogHeader = new View.FileLogView.FileLogHeader();
darienf 20:6d2af70c92ab 82
darienf 20:6d2af70c92ab 83 public RawFileLogPresenter(IRawFileLogView ecg, IRawFileLogView bioZ, IRawFileLogView rToR, IRawFileLogView pace, IFormView formView, RPCClient rpcClient, IEcgView ecgView, IDataLoggingView dataLogView)
darienf 20:6d2af70c92ab 84 {
darienf 20:6d2af70c92ab 85 this.ecgLog = ecg;
darienf 20:6d2af70c92ab 86 this.bioZLog = bioZ;
darienf 20:6d2af70c92ab 87 this.rToRLog = rToR;
darienf 20:6d2af70c92ab 88 this.paceLog = pace;
darienf 20:6d2af70c92ab 89 this.formView = formView;
darienf 20:6d2af70c92ab 90 this.ecgView = ecgView;
darienf 20:6d2af70c92ab 91
darienf 20:6d2af70c92ab 92 this.dataLogView = dataLogView;
darienf 20:6d2af70c92ab 93
darienf 20:6d2af70c92ab 94 formView.FileLogEnable += new EventHandler<EnableEventArgs>(OnLogFileEnable);
darienf 20:6d2af70c92ab 95 ecgView.StreamingStartStop += new EventHandler<StreamingStartStopEventArgs>(OnStreamStart);
darienf 20:6d2af70c92ab 96 //dataLogView.LogDownloadStart += new EventHandler<EventArgs>(OnLogDownloadStart);
darienf 20:6d2af70c92ab 97 rpcClient.streaming.PartialArrayIntAvailable += new EventHandler<PartialArrayIntAvailableEventArgs>(OnStreamData);
darienf 20:6d2af70c92ab 98 }
darienf 20:6d2af70c92ab 99
darienf 20:6d2af70c92ab 100 public void OnLogFileEnable(object sender, EnableEventArgs e)
darienf 20:6d2af70c92ab 101 {
darienf 20:6d2af70c92ab 102 fileLog = e.Enable;
darienf 20:6d2af70c92ab 103
darienf 20:6d2af70c92ab 104 if (e.Enable)
darienf 20:6d2af70c92ab 105 {
darienf 20:6d2af70c92ab 106 bool result = false;
darienf 20:6d2af70c92ab 107 IRawFileLogView log = ecgLog;
darienf 20:6d2af70c92ab 108 string filePrefixName = String.Empty;
darienf 20:6d2af70c92ab 109
darienf 20:6d2af70c92ab 110 switch(e.Stream)
darienf 20:6d2af70c92ab 111 {
darienf 20:6d2af70c92ab 112 case StreamType.Ecg:
darienf 20:6d2af70c92ab 113 log = ecgLog;
darienf 20:6d2af70c92ab 114 filePrefixName = "hsp-ecg";
darienf 20:6d2af70c92ab 115 break;
darienf 20:6d2af70c92ab 116 case StreamType.RToR:
darienf 20:6d2af70c92ab 117 log = rToRLog;
darienf 20:6d2af70c92ab 118 filePrefixName = "hsp-rtor";
darienf 20:6d2af70c92ab 119 break;
darienf 20:6d2af70c92ab 120 case StreamType.Pace:
darienf 20:6d2af70c92ab 121 log = paceLog;
darienf 20:6d2af70c92ab 122 filePrefixName = "hsp-pace";
darienf 20:6d2af70c92ab 123 break;
darienf 20:6d2af70c92ab 124 case StreamType.BioZ:
darienf 20:6d2af70c92ab 125 log = bioZLog;
darienf 20:6d2af70c92ab 126 filePrefixName = "hsp-bioz";
darienf 20:6d2af70c92ab 127 break;
darienf 20:6d2af70c92ab 128 }
darienf 20:6d2af70c92ab 129
darienf 20:6d2af70c92ab 130 if (logFileDirectory != null) // Set starting directory to be the same as the last
darienf 20:6d2af70c92ab 131 log.FileDirectory = logFileDirectory;
darienf 20:6d2af70c92ab 132
darienf 20:6d2af70c92ab 133 result = log.SelectCSVFile(filePrefixName);
darienf 20:6d2af70c92ab 134 log.Enable = result;
darienf 20:6d2af70c92ab 135
darienf 20:6d2af70c92ab 136 if (result) // Save directory if success
darienf 20:6d2af70c92ab 137 logFileDirectory = log.FileDirectory;
darienf 20:6d2af70c92ab 138
darienf 20:6d2af70c92ab 139 formView.LogFileItem(e.Stream, result);
darienf 20:6d2af70c92ab 140 }
darienf 20:6d2af70c92ab 141 else
darienf 20:6d2af70c92ab 142 {
darienf 20:6d2af70c92ab 143 switch (e.Stream)
darienf 20:6d2af70c92ab 144 {
darienf 20:6d2af70c92ab 145 case StreamType.Ecg:
darienf 20:6d2af70c92ab 146 ecgLog.Enable = false;
darienf 20:6d2af70c92ab 147 break;
darienf 20:6d2af70c92ab 148 case StreamType.RToR:
darienf 20:6d2af70c92ab 149 rToRLog.Enable = false;
darienf 20:6d2af70c92ab 150 break;
darienf 20:6d2af70c92ab 151 case StreamType.Pace:
darienf 20:6d2af70c92ab 152 paceLog.Enable = false;
darienf 20:6d2af70c92ab 153 break;
darienf 20:6d2af70c92ab 154 case StreamType.BioZ:
darienf 20:6d2af70c92ab 155 bioZLog.Enable = false;
darienf 20:6d2af70c92ab 156 break;
darienf 20:6d2af70c92ab 157 }
darienf 20:6d2af70c92ab 158
darienf 20:6d2af70c92ab 159 formView.LogFileItem(e.Stream, false);
darienf 20:6d2af70c92ab 160 }
darienf 20:6d2af70c92ab 161 }
darienf 20:6d2af70c92ab 162
darienf 20:6d2af70c92ab 163 public void OnStreamStart(object sender, StreamingStartStopEventArgs e)
darienf 20:6d2af70c92ab 164 {
darienf 20:6d2af70c92ab 165 streaming = e.state;
darienf 20:6d2af70c92ab 166 count = 0;
darienf 20:6d2af70c92ab 167 bioZCount = 0;
darienf 20:6d2af70c92ab 168
darienf 20:6d2af70c92ab 169 if (e.state)
darienf 20:6d2af70c92ab 170 {
darienf 20:6d2af70c92ab 171 leadOff = new DCLeadOff { NegativeHigh = false, NegativeLow = false, PostiveHigh = false, PostiveLow = false };
darienf 20:6d2af70c92ab 172 acLeadOff = new ACLeadOff { BioZOverRange = false, BioZUnderRange = false };
darienf 20:6d2af70c92ab 173
darienf 20:6d2af70c92ab 174 if (ecgLog != null && ecgLog.Enable && ecgView.EnableECG)
darienf 20:6d2af70c92ab 175 {
darienf 20:6d2af70c92ab 176 //ecgLog.WriteLine("% " + ecgView.HspSetting.EcgSettingString()); // TODO: What is the requirement for headers
darienf 20:6d2af70c92ab 177 ecgLog.WriteLine(fileLogHeader.Ecg);
darienf 20:6d2af70c92ab 178 }
darienf 20:6d2af70c92ab 179
darienf 20:6d2af70c92ab 180 if (bioZLog != null && bioZLog.Enable && ecgView.EnableBioZ)
darienf 20:6d2af70c92ab 181 {
darienf 20:6d2af70c92ab 182 //ecgLog.WriteLine("% " + ecgView.HspSetting.BioZSettingString());
darienf 20:6d2af70c92ab 183 bioZLog.WriteLine(fileLogHeader.BioZ);
darienf 20:6d2af70c92ab 184 }
darienf 20:6d2af70c92ab 185
darienf 20:6d2af70c92ab 186 if (rToRLog != null && rToRLog.Enable && ecgView.EnableRToR)
darienf 20:6d2af70c92ab 187 {
darienf 20:6d2af70c92ab 188 rToRLog.WriteLine(fileLogHeader.RToR);
darienf 20:6d2af70c92ab 189 rToRCalculator = new RToRCalculator(ecgView.MasterClockField, ecgView.EcgArgs.Rate, ecgView.EcgArgs.Dlpf, ecgView.RToRArgs.Wndw);
darienf 20:6d2af70c92ab 190 }
darienf 20:6d2af70c92ab 191
darienf 20:6d2af70c92ab 192 if (paceLog != null && paceLog.Enable && ecgView.EnablePace)
darienf 20:6d2af70c92ab 193 {
darienf 20:6d2af70c92ab 194 paceLog.WriteLine(fileLogHeader.Pace);
darienf 20:6d2af70c92ab 195 }
darienf 20:6d2af70c92ab 196 }
darienf 20:6d2af70c92ab 197 else
darienf 20:6d2af70c92ab 198 {
darienf 20:6d2af70c92ab 199 if (ecgLog != null)
darienf 20:6d2af70c92ab 200 ecgLog.Enable = false;
darienf 20:6d2af70c92ab 201
darienf 20:6d2af70c92ab 202 if (bioZLog != null)
darienf 20:6d2af70c92ab 203 bioZLog.Enable = false;
darienf 20:6d2af70c92ab 204
darienf 20:6d2af70c92ab 205 if (rToRLog != null)
darienf 20:6d2af70c92ab 206 rToRLog.Enable = false;
darienf 20:6d2af70c92ab 207
darienf 20:6d2af70c92ab 208 if (paceLog != null)
darienf 20:6d2af70c92ab 209 paceLog.Enable = false;
darienf 20:6d2af70c92ab 210 }
darienf 20:6d2af70c92ab 211 }
darienf 20:6d2af70c92ab 212
darienf 20:6d2af70c92ab 213 void fileLogStop()
darienf 20:6d2af70c92ab 214 {
darienf 20:6d2af70c92ab 215 fileLog = false;
darienf 20:6d2af70c92ab 216 stop();
darienf 20:6d2af70c92ab 217
darienf 20:6d2af70c92ab 218 }
darienf 20:6d2af70c92ab 219
darienf 20:6d2af70c92ab 220 void stop()
darienf 20:6d2af70c92ab 221 {
darienf 20:6d2af70c92ab 222 if (ecgLog != null && ecgLog.Enable)
darienf 20:6d2af70c92ab 223 ecgLog.Enable = false;
darienf 20:6d2af70c92ab 224
darienf 20:6d2af70c92ab 225 if (rToRLog != null && rToRLog.Enable)
darienf 20:6d2af70c92ab 226 rToRLog.Enable = false;
darienf 20:6d2af70c92ab 227
darienf 20:6d2af70c92ab 228 if (paceLog != null && paceLog.Enable)
darienf 20:6d2af70c92ab 229 paceLog.Enable = false;
darienf 20:6d2af70c92ab 230
darienf 20:6d2af70c92ab 231 if (bioZLog != null && bioZLog.Enable)
darienf 20:6d2af70c92ab 232 bioZLog.Enable = false;
darienf 20:6d2af70c92ab 233
darienf 20:6d2af70c92ab 234 formView.LogFileItem(StreamType.Ecg, false);
darienf 20:6d2af70c92ab 235 formView.LogFileItem(StreamType.RToR, false);
darienf 20:6d2af70c92ab 236 formView.LogFileItem(StreamType.Pace, false);
darienf 20:6d2af70c92ab 237 formView.LogFileItem(StreamType.BioZ, false);
darienf 20:6d2af70c92ab 238 }
darienf 20:6d2af70c92ab 239
darienf 20:6d2af70c92ab 240 private void OnStreamData(object sender, PartialArrayIntAvailableEventArgs e)
darienf 20:6d2af70c92ab 241 {
darienf 20:6d2af70c92ab 242 if (streaming)
darienf 20:6d2af70c92ab 243 {
darienf 20:6d2af70c92ab 244 switch (e.reportID)
darienf 20:6d2af70c92ab 245 {
darienf 20:6d2af70c92ab 246 case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_ECG:
darienf 20:6d2af70c92ab 247 if (ecgLog.Enable)
darienf 20:6d2af70c92ab 248 ProcessEcg(e.array1);
darienf 20:6d2af70c92ab 249 break;
darienf 20:6d2af70c92ab 250 case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_BIOZ:
darienf 20:6d2af70c92ab 251 if (bioZLog.Enable)
darienf 20:6d2af70c92ab 252 ProcessBioZ(e.array1);
darienf 20:6d2af70c92ab 253 break;
darienf 20:6d2af70c92ab 254 case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_PACE:
darienf 20:6d2af70c92ab 255 if (paceLog.Enable)
darienf 20:6d2af70c92ab 256 paceData = new PaceData(e.array1);
darienf 20:6d2af70c92ab 257 break;
darienf 20:6d2af70c92ab 258 case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_RTOR:
darienf 20:6d2af70c92ab 259 if (rToRLog.Enable)
darienf 20:6d2af70c92ab 260 ProcessRToR(e.array1[0]);
darienf 20:6d2af70c92ab 261 break;
darienf 20:6d2af70c92ab 262 case PartialArrayIntAvailableEventArgs.PACKET_END_OF_STREAM:
darienf 20:6d2af70c92ab 263 fileLogStop();
darienf 20:6d2af70c92ab 264 break;
darienf 20:6d2af70c92ab 265 case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_LEADOFF_DC:
darienf 20:6d2af70c92ab 266 ProcessLeadOff(e.array1[0]);
darienf 20:6d2af70c92ab 267 break;
darienf 20:6d2af70c92ab 268 case PartialArrayIntAvailableEventArgs.PACKET_MAX30001_LEADOFF_AC:
darienf 20:6d2af70c92ab 269 ProcessACLeadOff(e.array1[0]);
darienf 20:6d2af70c92ab 270 break;
darienf 20:6d2af70c92ab 271 }
darienf 20:6d2af70c92ab 272 }
darienf 20:6d2af70c92ab 273 }
darienf 20:6d2af70c92ab 274
darienf 20:6d2af70c92ab 275 void ProcessBioZ(int[] rawData)
darienf 20:6d2af70c92ab 276 {
darienf 20:6d2af70c92ab 277 BioZFifo[] bioZFifo;
darienf 20:6d2af70c92ab 278 double sampleRate = ecgView.SampleRateBioZ;
darienf 20:6d2af70c92ab 279 double[] time = new double[rawData.Length];
darienf 20:6d2af70c92ab 280
darienf 20:6d2af70c92ab 281 bioZFifo = ConvertBioZ(rawData);
darienf 20:6d2af70c92ab 282
darienf 20:6d2af70c92ab 283 for (int i = 0; i < time.Length; i++)
darienf 20:6d2af70c92ab 284 {
darienf 20:6d2af70c92ab 285 time[i] = bioZCount / sampleRate;
darienf 20:6d2af70c92ab 286 bioZCount++;
darienf 20:6d2af70c92ab 287 }
darienf 20:6d2af70c92ab 288
darienf 20:6d2af70c92ab 289 if (ecgView.EnableDCLeadOff == false && ecgView.EnableBioZOverUnderRange == true)
darienf 20:6d2af70c92ab 290 bioZLog.DisplayBioZ(time, bioZFifo, acLeadOff);
darienf 20:6d2af70c92ab 291 else if (ecgView.EnableDCLeadOff == true && ecgView.EnableEcgDCLeadOff == false && ecgView.EnableBioZOverUnderRange == false) // && ecgLeadOff == false)
darienf 20:6d2af70c92ab 292 bioZLog.DisplayBioZ(time, bioZFifo, leadOff);
darienf 20:6d2af70c92ab 293 else if (ecgView.EnableDCLeadOff == true && ecgView.EnableEcgDCLeadOff == false && ecgView.EnableBioZOverUnderRange == true)
darienf 20:6d2af70c92ab 294 bioZLog.DisplayBioZ(time, bioZFifo, leadOff, acLeadOff);
darienf 20:6d2af70c92ab 295 else if ((ecgView.EnableDCLeadOff == false && ecgView.EnableBioZOverUnderRange == false) ||
darienf 20:6d2af70c92ab 296 ecgView.EnableEcgDCLeadOff == true && ecgView.EnableEcgDCLeadOff == true && ecgView.EnableBioZOverUnderRange == false)
darienf 20:6d2af70c92ab 297 bioZLog.DisplayBioZ(time, bioZFifo);
darienf 20:6d2af70c92ab 298 }
darienf 20:6d2af70c92ab 299
darienf 20:6d2af70c92ab 300 public BioZFifo[] ConvertBioZ(int[] data)
darienf 20:6d2af70c92ab 301 {
darienf 20:6d2af70c92ab 302 BioZFifo[] impedance = new BioZFifo[data.Length];
darienf 20:6d2af70c92ab 303 EcgView.ChartInfo chartInfo = ecgView.BioZInfo;
darienf 20:6d2af70c92ab 304 int dataShift;
darienf 20:6d2af70c92ab 305
darienf 20:6d2af70c92ab 306 for (int i = 0; i < data.Length; i++)
darienf 20:6d2af70c92ab 307 {
darienf 20:6d2af70c92ab 308 dataShift = data[i] >> chartInfo.Shift;
darienf 20:6d2af70c92ab 309
darienf 20:6d2af70c92ab 310 // Two's Complement Conversions
darienf 20:6d2af70c92ab 311 if (dataShift > chartInfo.Threshold)
darienf 20:6d2af70c92ab 312 {
darienf 20:6d2af70c92ab 313 dataShift -= chartInfo.Offset;
darienf 20:6d2af70c92ab 314 }
darienf 20:6d2af70c92ab 315
darienf 20:6d2af70c92ab 316 // 1.9734 = 1/2^19 * 1e-6
darienf 20:6d2af70c92ab 317 impedance[i].Data = dataShift * 1.9073486328125 /
darienf 20:6d2af70c92ab 318 (chartInfo.Gain * ((chartInfo.CurrentGenerator == 0) ? 1 : chartInfo.CurrentGenerator));
darienf 20:6d2af70c92ab 319 impedance[i].Code = data[i];
darienf 20:6d2af70c92ab 320 impedance[i].BioZData = dataShift;
darienf 20:6d2af70c92ab 321 impedance[i].BTag = data[i] & 0x07;
darienf 20:6d2af70c92ab 322 }
darienf 20:6d2af70c92ab 323
darienf 20:6d2af70c92ab 324 return impedance;
darienf 20:6d2af70c92ab 325 }
darienf 20:6d2af70c92ab 326
darienf 20:6d2af70c92ab 327 void ProcessEcg(int[] rawData)
darienf 20:6d2af70c92ab 328 {
darienf 20:6d2af70c92ab 329 EcgFifo[] ecgFifo;
darienf 20:6d2af70c92ab 330 double ecgRate = ecgView.SampleRateEcg;
darienf 20:6d2af70c92ab 331 double[] ecgVoltage = new double[rawData.Length];
darienf 20:6d2af70c92ab 332 double[] timeSecond = new double[rawData.Length];
darienf 20:6d2af70c92ab 333
darienf 20:6d2af70c92ab 334 ecgFifo = ConvertEcg(rawData);
darienf 20:6d2af70c92ab 335
darienf 20:6d2af70c92ab 336 for (int i = 0; i < ecgFifo.Length; i++ )
darienf 20:6d2af70c92ab 337 {
darienf 20:6d2af70c92ab 338 timeSecond[i] = count / ecgRate;
darienf 20:6d2af70c92ab 339
darienf 20:6d2af70c92ab 340 // Look for Pace Events
darienf 20:6d2af70c92ab 341 if (paceLog.Enable)
darienf 20:6d2af70c92ab 342 {
darienf 20:6d2af70c92ab 343 //for (int j = 0; j < ecgFifo.Length; j++)
darienf 20:6d2af70c92ab 344 //{
darienf 20:6d2af70c92ab 345 if (ecgFifo[i].PTag != 7)
darienf 20:6d2af70c92ab 346 {
darienf 20:6d2af70c92ab 347 PaceData.PaceRegister paceRegister = paceData.PaceGroup(ecgFifo[i].PTag);
darienf 20:6d2af70c92ab 348 List<double> timeMillsecondPace = new List<double>();
darienf 20:6d2af70c92ab 349 List<PaceData.PaceEdge> paceEdges = new List<PaceData.PaceEdge>();
darienf 20:6d2af70c92ab 350
darienf 20:6d2af70c92ab 351 for (int k = 0; k < 6; k++)
darienf 20:6d2af70c92ab 352 {
darienf 20:6d2af70c92ab 353 PaceData.PaceEdge edge = paceRegister.Edge[k];
darienf 20:6d2af70c92ab 354
darienf 20:6d2af70c92ab 355 timeMillsecondPace.Add(count / ecgRate + ConvertPace(edge.Data));
darienf 20:6d2af70c92ab 356 paceEdges.Add(edge);
darienf 20:6d2af70c92ab 357
darienf 20:6d2af70c92ab 358 if (edge.Last == true)
darienf 20:6d2af70c92ab 359 break;
darienf 20:6d2af70c92ab 360 }
darienf 20:6d2af70c92ab 361
darienf 20:6d2af70c92ab 362 paceLog.DisplayPace(timeMillsecondPace.ToArray(), paceEdges.ToArray());
darienf 20:6d2af70c92ab 363 System.Diagnostics.Debug.Print("ECG PTag = " + ecgFifo[i].PTag);
darienf 20:6d2af70c92ab 364 }
darienf 20:6d2af70c92ab 365 //}
darienf 20:6d2af70c92ab 366 }
darienf 20:6d2af70c92ab 367
darienf 20:6d2af70c92ab 368 count++;
darienf 20:6d2af70c92ab 369 }
darienf 20:6d2af70c92ab 370
darienf 20:6d2af70c92ab 371 if (ecgView.EnableDCLeadOff && ecgView.EnableEcgDCLeadOff)
darienf 20:6d2af70c92ab 372 ecgLog.DisplayEcg(timeSecond, ecgFifo, leadOff);
darienf 20:6d2af70c92ab 373 else
darienf 20:6d2af70c92ab 374 ecgLog.DisplayEcg(timeSecond, ecgFifo);
darienf 20:6d2af70c92ab 375
darienf 20:6d2af70c92ab 376 }
darienf 20:6d2af70c92ab 377
darienf 20:6d2af70c92ab 378 public EcgFifo[] ConvertEcg(int[] data)
darienf 20:6d2af70c92ab 379 {
darienf 20:6d2af70c92ab 380 EcgFifo[] voltage = new EcgFifo[data.Length];
darienf 20:6d2af70c92ab 381 EcgView.ChartInfo chartInfo = ecgView.EcgInfo;
darienf 20:6d2af70c92ab 382 int dataShift;
darienf 20:6d2af70c92ab 383
darienf 20:6d2af70c92ab 384 for (int i = 0; i < data.Length; i++)
darienf 20:6d2af70c92ab 385 {
darienf 20:6d2af70c92ab 386 dataShift = data[i] >> chartInfo.Shift;
darienf 20:6d2af70c92ab 387
darienf 20:6d2af70c92ab 388 // Two's Complement Conversions
darienf 20:6d2af70c92ab 389 if (dataShift > chartInfo.Threshold)
darienf 20:6d2af70c92ab 390 {
darienf 20:6d2af70c92ab 391 dataShift -= chartInfo.Offset;
darienf 20:6d2af70c92ab 392 }
darienf 20:6d2af70c92ab 393
darienf 20:6d2af70c92ab 394 voltage[i].Data = 1000 * 7.62939453125e-6 * dataShift / chartInfo.Gain;
darienf 20:6d2af70c92ab 395 voltage[i].EcgData = dataShift;
darienf 20:6d2af70c92ab 396 voltage[i].Code = data[i];
darienf 20:6d2af70c92ab 397 voltage[i].PTag = data[i] & 0x07;
darienf 20:6d2af70c92ab 398 voltage[i].ETag = (data[i] >> 3) & 0x07;
darienf 20:6d2af70c92ab 399 }
darienf 20:6d2af70c92ab 400
darienf 20:6d2af70c92ab 401 return voltage;
darienf 20:6d2af70c92ab 402 }
darienf 20:6d2af70c92ab 403
darienf 20:6d2af70c92ab 404 public double ConvertRToR(int data)
darienf 20:6d2af70c92ab 405 {
darienf 20:6d2af70c92ab 406 return ecgView.TimeResolution * 1000 * data * 512;
darienf 20:6d2af70c92ab 407 }
darienf 20:6d2af70c92ab 408
darienf 20:6d2af70c92ab 409 public double ConvertPace(int data)
darienf 20:6d2af70c92ab 410 {
darienf 20:6d2af70c92ab 411 return data * ecgView.TimeResolution;
darienf 20:6d2af70c92ab 412 }
darienf 20:6d2af70c92ab 413
darienf 20:6d2af70c92ab 414 public string PaceRegisterGroupToString(PaceData.PaceRegister paceRegister)
darienf 20:6d2af70c92ab 415 {
darienf 20:6d2af70c92ab 416 StringBuilder paceRegisterLogBuilder = new StringBuilder();
darienf 20:6d2af70c92ab 417 for (int j = 0; j < 6; j++)
darienf 20:6d2af70c92ab 418 {
darienf 20:6d2af70c92ab 419 paceRegisterLogBuilder.Append(paceRegister.Edge[j].Data / (2 * ecgView.MasterClockFrequency));
darienf 20:6d2af70c92ab 420 paceRegisterLogBuilder.Append(", ");
darienf 20:6d2af70c92ab 421 paceRegisterLogBuilder.Append(paceRegister.Edge[j].Polarity ? 'R' : 'F');
darienf 20:6d2af70c92ab 422 paceRegisterLogBuilder.Append(", ");
darienf 20:6d2af70c92ab 423 paceRegisterLogBuilder.Append(paceRegister.Edge[j].Last ? 'Y' : 'N');
darienf 20:6d2af70c92ab 424 paceRegisterLogBuilder.Append(", ");
darienf 20:6d2af70c92ab 425 }
darienf 20:6d2af70c92ab 426
darienf 20:6d2af70c92ab 427 return paceRegisterLogBuilder.ToString();
darienf 20:6d2af70c92ab 428 }
darienf 20:6d2af70c92ab 429
darienf 20:6d2af70c92ab 430 void ProcessLeadOff(int data)
darienf 20:6d2af70c92ab 431 {
darienf 20:6d2af70c92ab 432 /*
darienf 20:6d2af70c92ab 433 if (bitShiftMask(data, 8)) // ECG lead off
darienf 20:6d2af70c92ab 434 ecgLeadOff = true;
darienf 20:6d2af70c92ab 435 else if (bitShiftMask(data, 9)) // BioZ lead off
darienf 20:6d2af70c92ab 436 ecgLeadOff = false;
darienf 20:6d2af70c92ab 437 */
darienf 20:6d2af70c92ab 438
darienf 20:6d2af70c92ab 439 leadOff = new DCLeadOff()
darienf 20:6d2af70c92ab 440 {
darienf 20:6d2af70c92ab 441 PostiveHigh = bitShiftMask(data, 3),
darienf 20:6d2af70c92ab 442 PostiveLow = bitShiftMask(data, 2),
darienf 20:6d2af70c92ab 443 NegativeHigh = bitShiftMask(data, 1),
darienf 20:6d2af70c92ab 444 NegativeLow = bitShiftMask(data, 0)
darienf 20:6d2af70c92ab 445 };
darienf 20:6d2af70c92ab 446
darienf 20:6d2af70c92ab 447 }
darienf 20:6d2af70c92ab 448
darienf 20:6d2af70c92ab 449 void ProcessACLeadOff(int data)
darienf 20:6d2af70c92ab 450 {
darienf 20:6d2af70c92ab 451 acLeadOff = new ACLeadOff()
darienf 20:6d2af70c92ab 452 {
darienf 20:6d2af70c92ab 453 BioZUnderRange = bitShiftMask(data, 1),
darienf 20:6d2af70c92ab 454 BioZOverRange = bitShiftMask(data, 0),
darienf 20:6d2af70c92ab 455 };
darienf 20:6d2af70c92ab 456 }
darienf 20:6d2af70c92ab 457
darienf 20:6d2af70c92ab 458 private static bool bitShiftMask(int data, int index)
darienf 20:6d2af70c92ab 459 {
darienf 20:6d2af70c92ab 460 int state;
darienf 20:6d2af70c92ab 461 int mask = 1 << index;
darienf 20:6d2af70c92ab 462 state = ((data & mask) == mask) ? 1 : 0;
darienf 20:6d2af70c92ab 463 return state == 1;
darienf 20:6d2af70c92ab 464 }
darienf 20:6d2af70c92ab 465
darienf 20:6d2af70c92ab 466 void ProcessRToR(int data)
darienf 20:6d2af70c92ab 467 {
darienf 20:6d2af70c92ab 468 if (rToRFirst)
darienf 20:6d2af70c92ab 469 {
darienf 20:6d2af70c92ab 470 rToRLog.DisplayRToR(data, rToRCalculator.Corrected(data, true) / 1000);
darienf 20:6d2af70c92ab 471 rToRFirst = false;
darienf 20:6d2af70c92ab 472 }
darienf 20:6d2af70c92ab 473 else
darienf 20:6d2af70c92ab 474 rToRLog.DisplayRToR(data, rToRCalculator.Corrected(data, false) / 1000);
darienf 20:6d2af70c92ab 475 }
darienf 20:6d2af70c92ab 476 }
darienf 20:6d2af70c92ab 477 }