![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
repo time
Dependencies: mbed MAX14720 MAX30205 USBDevice
HspGuiSourceV301/HSPGui/MedicalChartHelper.cs@20:6d2af70c92ab, 2021-04-06 (annotated)
- Committer:
- darienf
- Date:
- Tue Apr 06 06:41:40 2021 +0000
- Revision:
- 20:6d2af70c92ab
another repo
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
darienf | 20:6d2af70c92ab | 1 | //using System; |
darienf | 20:6d2af70c92ab | 2 | //using System.Collections; |
darienf | 20:6d2af70c92ab | 3 | //using System.Collections.Generic; |
darienf | 20:6d2af70c92ab | 4 | //using System.ComponentModel; |
darienf | 20:6d2af70c92ab | 5 | //using System.Linq; |
darienf | 20:6d2af70c92ab | 6 | //using System.Text; |
darienf | 20:6d2af70c92ab | 7 | //using System.Windows.Forms; |
darienf | 20:6d2af70c92ab | 8 | //using Microsoft.Win32.SafeHandles; |
darienf | 20:6d2af70c92ab | 9 | |
darienf | 20:6d2af70c92ab | 10 | namespace Maxim.MAX30101 |
darienf | 20:6d2af70c92ab | 11 | { |
darienf | 20:6d2af70c92ab | 12 | #pragma warning disable 1574 |
darienf | 20:6d2af70c92ab | 13 | /// <summary> |
darienf | 20:6d2af70c92ab | 14 | /// MedicalChartHelper class, an invisible "helper" class, |
darienf | 20:6d2af70c92ab | 15 | /// helps manage an existing standard chart object. |
darienf | 20:6d2af70c92ab | 16 | /// |
darienf | 20:6d2af70c92ab | 17 | /// Initializes the standard |
darienf | 20:6d2af70c92ab | 18 | /// System.Windows.Forms.DataVisualization.Charting.Chart chart |
darienf | 20:6d2af70c92ab | 19 | /// with a maximum of 3 chart areas vertically aligned with each other. |
darienf | 20:6d2af70c92ab | 20 | /// |
darienf | 20:6d2af70c92ab | 21 | /// When data is appended to the chart, the chart series data |
darienf | 20:6d2af70c92ab | 22 | /// is initially aligned with the left. Once the X axis reaches the |
darienf | 20:6d2af70c92ab | 23 | /// right side of the screen, the chart begins scrolling so that |
darienf | 20:6d2af70c92ab | 24 | /// newest data is aligned to the right edge. |
darienf | 20:6d2af70c92ab | 25 | /// |
darienf | 20:6d2af70c92ab | 26 | /// </summary> |
darienf | 20:6d2af70c92ab | 27 | #pragma warning restore 1574 |
darienf | 20:6d2af70c92ab | 28 | public class MedicalChartHelper |
darienf | 20:6d2af70c92ab | 29 | { |
darienf | 20:6d2af70c92ab | 30 | private System.Windows.Forms.DataVisualization.Charting.Chart _chart; |
darienf | 20:6d2af70c92ab | 31 | private string _chartArea1Name; |
darienf | 20:6d2af70c92ab | 32 | private string _chartArea2Name; |
darienf | 20:6d2af70c92ab | 33 | private string _chartArea3Name; |
darienf | 20:6d2af70c92ab | 34 | private string _series1Name; |
darienf | 20:6d2af70c92ab | 35 | private string _series2Name; |
darienf | 20:6d2af70c92ab | 36 | private string _series3Name; |
darienf | 20:6d2af70c92ab | 37 | private string _chartArea1AxisYTitle; |
darienf | 20:6d2af70c92ab | 38 | private string _chartArea2AxisYTitle; |
darienf | 20:6d2af70c92ab | 39 | private string _chartArea3AxisYTitle; |
darienf | 20:6d2af70c92ab | 40 | |
darienf | 20:6d2af70c92ab | 41 | /// <summary> |
darienf | 20:6d2af70c92ab | 42 | /// Constructor |
darienf | 20:6d2af70c92ab | 43 | /// </summary> |
darienf | 20:6d2af70c92ab | 44 | /// <param name="chart"></param> |
darienf | 20:6d2af70c92ab | 45 | /// <param name="chartArea1Name"></param> |
darienf | 20:6d2af70c92ab | 46 | /// <param name="series1Name"></param> |
darienf | 20:6d2af70c92ab | 47 | /// <param name="chartArea1AxisYTitle"></param> |
darienf | 20:6d2af70c92ab | 48 | /// <param name="chartArea2Name"></param> |
darienf | 20:6d2af70c92ab | 49 | /// <param name="series2Name"></param> |
darienf | 20:6d2af70c92ab | 50 | /// <param name="chartArea2AxisYTitle"></param> |
darienf | 20:6d2af70c92ab | 51 | /// <param name="chartArea3Name"></param> |
darienf | 20:6d2af70c92ab | 52 | /// <param name="series3Name"></param> |
darienf | 20:6d2af70c92ab | 53 | /// <param name="chartArea3AxisYTitle"></param> |
darienf | 20:6d2af70c92ab | 54 | public MedicalChartHelper(System.Windows.Forms.DataVisualization.Charting.Chart chart, |
darienf | 20:6d2af70c92ab | 55 | string chartArea1Name = "ChartArea1Red", string series1Name = "SeriesRed", string chartArea1AxisYTitle = "Red ADC Code", |
darienf | 20:6d2af70c92ab | 56 | string chartArea2Name = "ChartArea2IR", string series2Name = "SeriesIR", string chartArea2AxisYTitle = "IR ADC Code", |
darienf | 20:6d2af70c92ab | 57 | string chartArea3Name = "ChartArea3Green", string series3Name = "SeriesGreen", string chartArea3AxisYTitle = "Green ADC Code", |
darienf | 20:6d2af70c92ab | 58 | DataFormats dataFormat = DataFormats.FormatUnsigned |
darienf | 20:6d2af70c92ab | 59 | ) |
darienf | 20:6d2af70c92ab | 60 | { |
darienf | 20:6d2af70c92ab | 61 | // implementation: see InitCharting() |
darienf | 20:6d2af70c92ab | 62 | // default X axis length should be 10 seconds of data |
darienf | 20:6d2af70c92ab | 63 | _chart = chart; |
darienf | 20:6d2af70c92ab | 64 | _chartArea1Name = chartArea1Name; |
darienf | 20:6d2af70c92ab | 65 | _chartArea2Name = chartArea2Name; |
darienf | 20:6d2af70c92ab | 66 | _chartArea3Name = chartArea3Name; |
darienf | 20:6d2af70c92ab | 67 | _series1Name = series1Name; |
darienf | 20:6d2af70c92ab | 68 | _series2Name = series2Name; |
darienf | 20:6d2af70c92ab | 69 | _series3Name = series3Name; |
darienf | 20:6d2af70c92ab | 70 | _chartArea1AxisYTitle = chartArea1AxisYTitle; |
darienf | 20:6d2af70c92ab | 71 | _chartArea2AxisYTitle = chartArea2AxisYTitle; |
darienf | 20:6d2af70c92ab | 72 | _chartArea3AxisYTitle = chartArea3AxisYTitle; |
darienf | 20:6d2af70c92ab | 73 | |
darienf | 20:6d2af70c92ab | 74 | DataFormat = dataFormat; |
darienf | 20:6d2af70c92ab | 75 | |
darienf | 20:6d2af70c92ab | 76 | // VERIFY: OS24EVK-75 replace _xCount with _xCount1, _xCount2, _xCount3 |
darienf | 20:6d2af70c92ab | 77 | //_xCount = 0; |
darienf | 20:6d2af70c92ab | 78 | _xCount1 = 0; |
darienf | 20:6d2af70c92ab | 79 | _xCount2 = 0; |
darienf | 20:6d2af70c92ab | 80 | _xCount3 = 0; |
darienf | 20:6d2af70c92ab | 81 | |
darienf | 20:6d2af70c92ab | 82 | _chart.Titles[0].Visible = false; |
darienf | 20:6d2af70c92ab | 83 | |
darienf | 20:6d2af70c92ab | 84 | _chart.ChartAreas[_chartArea2Name].AlignWithChartArea = _chartArea1Name; |
darienf | 20:6d2af70c92ab | 85 | _chart.ChartAreas[_chartArea3Name].AlignWithChartArea = _chartArea1Name; |
darienf | 20:6d2af70c92ab | 86 | |
darienf | 20:6d2af70c92ab | 87 | _chart.ChartAreas[_chartArea1Name].AxisY.Title = chartArea1AxisYTitle; |
darienf | 20:6d2af70c92ab | 88 | _chart.ChartAreas[_chartArea2Name].AxisY.Title = chartArea2AxisYTitle; |
darienf | 20:6d2af70c92ab | 89 | _chart.ChartAreas[_chartArea3Name].AxisY.Title = chartArea3AxisYTitle; |
darienf | 20:6d2af70c92ab | 90 | |
darienf | 20:6d2af70c92ab | 91 | //_chart.ChartAreas[_chartArea1Name].AxisX.LabelStyle.Enabled = !_plotXAxisNoLabels; |
darienf | 20:6d2af70c92ab | 92 | //_chart.ChartAreas[_chartArea2Name].AxisX.LabelStyle.Enabled = !_plotXAxisNoLabels; |
darienf | 20:6d2af70c92ab | 93 | //_chart.ChartAreas[_chartArea3Name].AxisX.LabelStyle.Enabled = !_plotXAxisNoLabels; |
darienf | 20:6d2af70c92ab | 94 | |
darienf | 20:6d2af70c92ab | 95 | _chart.ChartAreas[_chartArea1Name].Visible = true; // valid_Red; |
darienf | 20:6d2af70c92ab | 96 | _chart.ChartAreas[_chartArea2Name].Visible = true; // valid_IR; |
darienf | 20:6d2af70c92ab | 97 | _chart.ChartAreas[_chartArea3Name].Visible = true; // valid_Green; |
darienf | 20:6d2af70c92ab | 98 | |
darienf | 20:6d2af70c92ab | 99 | _chart.Series[_series1Name].MarkerSize = 1; // Charting.Series.MarkerSize=0 makes no points visible |
darienf | 20:6d2af70c92ab | 100 | _chart.Series[_series1Name].BorderWidth = 1; // Charting.Series.BorderWidth is actually the line thickness |
darienf | 20:6d2af70c92ab | 101 | _chart.Series[_series1Name].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.UInt32; |
darienf | 20:6d2af70c92ab | 102 | _chart.Series[_series1Name].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32; |
darienf | 20:6d2af70c92ab | 103 | |
darienf | 20:6d2af70c92ab | 104 | _chart.Series[_series2Name].MarkerSize = 1; // Charting.Series.MarkerSize=0 makes no points visible |
darienf | 20:6d2af70c92ab | 105 | _chart.Series[_series2Name].BorderWidth = 1; // Charting.Series.BorderWidth is actually the line thickness |
darienf | 20:6d2af70c92ab | 106 | _chart.Series[_series2Name].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.UInt32; |
darienf | 20:6d2af70c92ab | 107 | _chart.Series[_series2Name].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32; |
darienf | 20:6d2af70c92ab | 108 | |
darienf | 20:6d2af70c92ab | 109 | _chart.Series[_series3Name].MarkerSize = 1; // Charting.Series.MarkerSize=0 makes no points visible |
darienf | 20:6d2af70c92ab | 110 | _chart.Series[_series3Name].BorderWidth = 1; // Charting.Series.BorderWidth is actually the line thickness |
darienf | 20:6d2af70c92ab | 111 | _chart.Series[_series3Name].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.UInt32; |
darienf | 20:6d2af70c92ab | 112 | _chart.Series[_series3Name].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32; |
darienf | 20:6d2af70c92ab | 113 | } |
darienf | 20:6d2af70c92ab | 114 | |
darienf | 20:6d2af70c92ab | 115 | /// <summary> |
darienf | 20:6d2af70c92ab | 116 | /// Clear chart data, reset _xCount, reset _plotPointsToSkip |
darienf | 20:6d2af70c92ab | 117 | /// </summary> |
darienf | 20:6d2af70c92ab | 118 | public void Clear() |
darienf | 20:6d2af70c92ab | 119 | { |
darienf | 20:6d2af70c92ab | 120 | _chart.Series[_series1Name].Points.Clear(); |
darienf | 20:6d2af70c92ab | 121 | _chart.Series[_series2Name].Points.Clear(); |
darienf | 20:6d2af70c92ab | 122 | _chart.Series[_series3Name].Points.Clear(); |
darienf | 20:6d2af70c92ab | 123 | // VERIFY: OS24EVK-75 replace _xCount with _xCount1, _xCount2, _xCount3 |
darienf | 20:6d2af70c92ab | 124 | //_xCount = 0; |
darienf | 20:6d2af70c92ab | 125 | _xCount1 = 0; |
darienf | 20:6d2af70c92ab | 126 | _xCount2 = 0; |
darienf | 20:6d2af70c92ab | 127 | _xCount3 = 0; |
darienf | 20:6d2af70c92ab | 128 | _plotPointsToSkip = 0; |
darienf | 20:6d2af70c92ab | 129 | // https://jira.maxim-ic.com/browse/OS24EVK-32 replace numPlotTime with menu item Options | Plot Time |
darienf | 20:6d2af70c92ab | 130 | _plotPoints = (int)_plotWindowTime * _SampleRate_Hz / SampleAverage_n; |
darienf | 20:6d2af70c92ab | 131 | if (_plotPoints > _maxPlotPoints) |
darienf | 20:6d2af70c92ab | 132 | { |
darienf | 20:6d2af70c92ab | 133 | _plotPointsToSkip = _plotPoints / _maxPlotPoints - 1; |
darienf | 20:6d2af70c92ab | 134 | _plotPoints = _maxPlotPoints; |
darienf | 20:6d2af70c92ab | 135 | } |
darienf | 20:6d2af70c92ab | 136 | } |
darienf | 20:6d2af70c92ab | 137 | |
darienf | 20:6d2af70c92ab | 138 | /// <summary> |
darienf | 20:6d2af70c92ab | 139 | /// Replacement for plotXAxisNoLabelsToolStripMenuItem.Checked |
darienf | 20:6d2af70c92ab | 140 | /// </summary> |
darienf | 20:6d2af70c92ab | 141 | public bool plotXAxisNoLabels { |
darienf | 20:6d2af70c92ab | 142 | get { return _plotXAxisNoLabels; } |
darienf | 20:6d2af70c92ab | 143 | set |
darienf | 20:6d2af70c92ab | 144 | { |
darienf | 20:6d2af70c92ab | 145 | _plotXAxisNoLabels = value; |
darienf | 20:6d2af70c92ab | 146 | _chart.ChartAreas[_chartArea1Name].AxisX.LabelStyle.Enabled = !_plotXAxisNoLabels; |
darienf | 20:6d2af70c92ab | 147 | _chart.ChartAreas[_chartArea2Name].AxisX.LabelStyle.Enabled = !_plotXAxisNoLabels; |
darienf | 20:6d2af70c92ab | 148 | _chart.ChartAreas[_chartArea3Name].AxisX.LabelStyle.Enabled = !_plotXAxisNoLabels; |
darienf | 20:6d2af70c92ab | 149 | } |
darienf | 20:6d2af70c92ab | 150 | } |
darienf | 20:6d2af70c92ab | 151 | private bool _plotXAxisNoLabels = true; // VERIFY: default plotXAxisNoLabelsToolStripMenuItem.Checked |
darienf | 20:6d2af70c92ab | 152 | |
darienf | 20:6d2af70c92ab | 153 | /// <summary> |
darienf | 20:6d2af70c92ab | 154 | /// Replacement for plotXAxisTimeToolStripMenuItem.Checked |
darienf | 20:6d2af70c92ab | 155 | /// </summary> |
darienf | 20:6d2af70c92ab | 156 | public bool plotXAxisTime |
darienf | 20:6d2af70c92ab | 157 | { |
darienf | 20:6d2af70c92ab | 158 | get { return _plotXAxisTime; } |
darienf | 20:6d2af70c92ab | 159 | set |
darienf | 20:6d2af70c92ab | 160 | { |
darienf | 20:6d2af70c92ab | 161 | _plotXAxisTime = value; |
darienf | 20:6d2af70c92ab | 162 | } |
darienf | 20:6d2af70c92ab | 163 | } |
darienf | 20:6d2af70c92ab | 164 | private bool _plotXAxisTime = true; // VERIFY: default plotXAxisTimeToolStripMenuItem.Checked |
darienf | 20:6d2af70c92ab | 165 | |
darienf | 20:6d2af70c92ab | 166 | private int _SampleRate_Hz = 100; |
darienf | 20:6d2af70c92ab | 167 | /// <summary> |
darienf | 20:6d2af70c92ab | 168 | /// Sample rate. Replacement for int.Parse(cboSampleRate.Text) |
darienf | 20:6d2af70c92ab | 169 | /// </summary> |
darienf | 20:6d2af70c92ab | 170 | public int SampleRate_Hz |
darienf | 20:6d2af70c92ab | 171 | { |
darienf | 20:6d2af70c92ab | 172 | get { return _SampleRate_Hz; } |
darienf | 20:6d2af70c92ab | 173 | set |
darienf | 20:6d2af70c92ab | 174 | { |
darienf | 20:6d2af70c92ab | 175 | _SampleRate_Hz = value; |
darienf | 20:6d2af70c92ab | 176 | |
darienf | 20:6d2af70c92ab | 177 | //_AutoScaleEveryNSamples = 4 * _SampleRate_Hz; // 4 seconds assuming sample rate int.Parse(cboSampleRate.Text) == 100 samples per second |
darienf | 20:6d2af70c92ab | 178 | |
darienf | 20:6d2af70c92ab | 179 | // VERIFY: OS24EVK-73 Sample Avg 2 breaks chart scrolling |
darienf | 20:6d2af70c92ab | 180 | // update _plotPoints which depends on myMAX30101.SampleAverage_n |
darienf | 20:6d2af70c92ab | 181 | _plotPoints = (int)_plotWindowTime * _SampleRate_Hz / SampleAverage_n; |
darienf | 20:6d2af70c92ab | 182 | if (_plotPoints > _maxPlotPoints) |
darienf | 20:6d2af70c92ab | 183 | { |
darienf | 20:6d2af70c92ab | 184 | _plotPointsToSkip = _plotPoints / _maxPlotPoints - 1; |
darienf | 20:6d2af70c92ab | 185 | _plotPoints = _maxPlotPoints; |
darienf | 20:6d2af70c92ab | 186 | } |
darienf | 20:6d2af70c92ab | 187 | } |
darienf | 20:6d2af70c92ab | 188 | } |
darienf | 20:6d2af70c92ab | 189 | |
darienf | 20:6d2af70c92ab | 190 | private int _SampleAverage_n = 1; |
darienf | 20:6d2af70c92ab | 191 | /// <summary> |
darienf | 20:6d2af70c92ab | 192 | /// Replacement for myMAX30101.SampleAverage_n |
darienf | 20:6d2af70c92ab | 193 | /// </summary> |
darienf | 20:6d2af70c92ab | 194 | public int SampleAverage_n |
darienf | 20:6d2af70c92ab | 195 | { |
darienf | 20:6d2af70c92ab | 196 | get { return _SampleAverage_n; } |
darienf | 20:6d2af70c92ab | 197 | set |
darienf | 20:6d2af70c92ab | 198 | { |
darienf | 20:6d2af70c92ab | 199 | _SampleAverage_n = value; |
darienf | 20:6d2af70c92ab | 200 | // VERIFY: OS24EVK-73 Sample Avg 2 breaks chart scrolling |
darienf | 20:6d2af70c92ab | 201 | // update _plotPoints which depends on myMAX30101.SampleAverage_n |
darienf | 20:6d2af70c92ab | 202 | _plotPoints = (int)_plotWindowTime * _SampleRate_Hz / SampleAverage_n; |
darienf | 20:6d2af70c92ab | 203 | if (_plotPoints > _maxPlotPoints) |
darienf | 20:6d2af70c92ab | 204 | { |
darienf | 20:6d2af70c92ab | 205 | _plotPointsToSkip = _plotPoints / _maxPlotPoints - 1; |
darienf | 20:6d2af70c92ab | 206 | _plotPoints = _maxPlotPoints; |
darienf | 20:6d2af70c92ab | 207 | } |
darienf | 20:6d2af70c92ab | 208 | } |
darienf | 20:6d2af70c92ab | 209 | } |
darienf | 20:6d2af70c92ab | 210 | |
darienf | 20:6d2af70c92ab | 211 | // VERIFY: IMPLEMENT OS24EVK-70 Maxim.MAX30101.MedicalChartHelper._xCount int instead of double? |
darienf | 20:6d2af70c92ab | 212 | // VERIFY: OS24EVK-75 replace _xCount with _xCount1, _xCount2, _xCount3 |
darienf | 20:6d2af70c92ab | 213 | //public double _xCount = 0; |
darienf | 20:6d2af70c92ab | 214 | public int _xCount1 = 0; |
darienf | 20:6d2af70c92ab | 215 | public int _xCount2 = 0; |
darienf | 20:6d2af70c92ab | 216 | public int _xCount3 = 0; |
darienf | 20:6d2af70c92ab | 217 | |
darienf | 20:6d2af70c92ab | 218 | /// <summary> |
darienf | 20:6d2af70c92ab | 219 | /// The actual number of points on the plot (<= _maxPlotPoints). The actual number of points may be less than _maxPlotPoints in order to maintain ~numPlotTime.Value of plotted data |
darienf | 20:6d2af70c92ab | 220 | /// </summary> |
darienf | 20:6d2af70c92ab | 221 | public int _plotPoints = 500; |
darienf | 20:6d2af70c92ab | 222 | |
darienf | 20:6d2af70c92ab | 223 | private int _plotWindowTime = 5; // plot window in seconds |
darienf | 20:6d2af70c92ab | 224 | public int plotWindowTime |
darienf | 20:6d2af70c92ab | 225 | { |
darienf | 20:6d2af70c92ab | 226 | get |
darienf | 20:6d2af70c92ab | 227 | { |
darienf | 20:6d2af70c92ab | 228 | return _plotWindowTime; |
darienf | 20:6d2af70c92ab | 229 | } |
darienf | 20:6d2af70c92ab | 230 | set |
darienf | 20:6d2af70c92ab | 231 | { |
darienf | 20:6d2af70c92ab | 232 | _plotWindowTime = value; |
darienf | 20:6d2af70c92ab | 233 | _plotPoints = (int)_plotWindowTime * _SampleRate_Hz / SampleAverage_n; |
darienf | 20:6d2af70c92ab | 234 | if (_plotPoints > _maxPlotPoints) |
darienf | 20:6d2af70c92ab | 235 | { |
darienf | 20:6d2af70c92ab | 236 | _plotPointsToSkip = _plotPoints / _maxPlotPoints - 1; |
darienf | 20:6d2af70c92ab | 237 | _plotPoints = _maxPlotPoints; |
darienf | 20:6d2af70c92ab | 238 | } |
darienf | 20:6d2af70c92ab | 239 | } |
darienf | 20:6d2af70c92ab | 240 | } |
darienf | 20:6d2af70c92ab | 241 | |
darienf | 20:6d2af70c92ab | 242 | private int _maxPlotPoints = 2000; // maximum allowed number of points that can be plotted per series. Higher Fs will have more than 500 pts for a given numPlotTime.Value, so the number of samples per point will need to be increased accordingly to give maximum _maxPlotPoints |
darienf | 20:6d2af70c92ab | 243 | |
darienf | 20:6d2af70c92ab | 244 | public int _plotPointsToSkip = 0; |
darienf | 20:6d2af70c92ab | 245 | |
darienf | 20:6d2af70c92ab | 246 | // https://jira.maxim-ic.com/browse/OS24EVK-34 Autoscale tuning parameters |
darienf | 20:6d2af70c92ab | 247 | // https://jira.maxim-ic.com/browse/OS24EVK-34 Change _AutoScaleTimeInterval to _AutoScaleEveryNSamples and use sampleNumber to measure time |
darienf | 20:6d2af70c92ab | 248 | // https://jira.maxim-ic.com/browse/OS24EVK-42 Autoscale tuning (Larry 2014-11-24) _AutoScaleEveryNSamples |
darienf | 20:6d2af70c92ab | 249 | // - Slow the Autoscale update rate every 4 seconds |
darienf | 20:6d2af70c92ab | 250 | //private int _AutoScaleEveryNSamples = 400; // 4 seconds assuming sample rate int.Parse(cboSampleRate.Text) == 100 samples per second |
darienf | 20:6d2af70c92ab | 251 | |
darienf | 20:6d2af70c92ab | 252 | // private double _AutoScaleMarginXLeft; // ignore old data at left of graph |
darienf | 20:6d2af70c92ab | 253 | // private double _AutoScaleMarginXRight; // ignore new data at right of graph? probably 0 by default |
darienf | 20:6d2af70c92ab | 254 | |
darienf | 20:6d2af70c92ab | 255 | /// <summary> |
darienf | 20:6d2af70c92ab | 256 | /// chartMax empty area above dataMax |
darienf | 20:6d2af70c92ab | 257 | /// </summary> |
darienf | 20:6d2af70c92ab | 258 | private static double _AutoScaleMarginYTop = 0.125; |
darienf | 20:6d2af70c92ab | 259 | |
darienf | 20:6d2af70c92ab | 260 | /// <summary> |
darienf | 20:6d2af70c92ab | 261 | /// chartMin empty area below dataMin |
darienf | 20:6d2af70c92ab | 262 | /// </summary> |
darienf | 20:6d2af70c92ab | 263 | private static double _AutoScaleMarginYBottom = 0.125; |
darienf | 20:6d2af70c92ab | 264 | |
darienf | 20:6d2af70c92ab | 265 | /// <summary> |
darienf | 20:6d2af70c92ab | 266 | /// Minimum Y span: allow up to 10 counts per division (i.e. 50 LSBs) |
darienf | 20:6d2af70c92ab | 267 | /// |
darienf | 20:6d2af70c92ab | 268 | /// (5 * _AutoScaleYmultiples) minimum allowed span of chartMax-chartMin, |
darienf | 20:6d2af70c92ab | 269 | /// to avoid focusing on LSB noise |
darienf | 20:6d2af70c92ab | 270 | /// </summary> |
darienf | 20:6d2af70c92ab | 271 | private static double _AutoScaleMinSpanY = 500; |
darienf | 20:6d2af70c92ab | 272 | |
darienf | 20:6d2af70c92ab | 273 | /// <summary> |
darienf | 20:6d2af70c92ab | 274 | /// Y axis: No decimals. Round to nearest multiple of 100. |
darienf | 20:6d2af70c92ab | 275 | /// </summary> |
darienf | 20:6d2af70c92ab | 276 | private static double _AutoScaleYmultiples = 100; |
darienf | 20:6d2af70c92ab | 277 | |
darienf | 20:6d2af70c92ab | 278 | // Calculated initial default chart limits _AutoscaleInitialChartMaxY .. _AutoscaleInitialChartMinY |
darienf | 20:6d2af70c92ab | 279 | int _AutoscaleInitialChartMaxY = |
darienf | 20:6d2af70c92ab | 280 | ( |
darienf | 20:6d2af70c92ab | 281 | (int) |
darienf | 20:6d2af70c92ab | 282 | ((_AutoScaleMinSpanY * (1.0 + _AutoScaleMarginYTop + _AutoScaleMarginYBottom)) / _AutoScaleYmultiples) |
darienf | 20:6d2af70c92ab | 283 | ) |
darienf | 20:6d2af70c92ab | 284 | * (int)(_AutoScaleYmultiples); |
darienf | 20:6d2af70c92ab | 285 | int _AutoscaleInitialChartMinY = 0; |
darienf | 20:6d2af70c92ab | 286 | |
darienf | 20:6d2af70c92ab | 287 | /// <summary> |
darienf | 20:6d2af70c92ab | 288 | /// Append data to chart area 1 series 1 (Optical: Red. Accelerometer: X) |
darienf | 20:6d2af70c92ab | 289 | /// |
darienf | 20:6d2af70c92ab | 290 | /// @post _xCount1 is updated |
darienf | 20:6d2af70c92ab | 291 | /// </summary> |
darienf | 20:6d2af70c92ab | 292 | /// <param name="rawIntArrayYData"></param> |
darienf | 20:6d2af70c92ab | 293 | /// <param name="firstNewXIndex"></param> |
darienf | 20:6d2af70c92ab | 294 | /// <param name="lastXIndex"></param> |
darienf | 20:6d2af70c92ab | 295 | public void AppendDataChartArea1(int[] rawIntArrayYData, int firstNewXIndex, int lastXIndex) |
darienf | 20:6d2af70c92ab | 296 | { |
darienf | 20:6d2af70c92ab | 297 | // AppendDataChartArea(_chartArea1Name, _series1Name, rawIntArrayYData, firstNewXIndex, lastXIndex); |
darienf | 20:6d2af70c92ab | 298 | string chartAreaName = _chartArea1Name; |
darienf | 20:6d2af70c92ab | 299 | string seriesName = _series1Name; |
darienf | 20:6d2af70c92ab | 300 | |
darienf | 20:6d2af70c92ab | 301 | for (int index = firstNewXIndex; index <= lastXIndex; index++) |
darienf | 20:6d2af70c92ab | 302 | { |
darienf | 20:6d2af70c92ab | 303 | int yData = rawIntArrayYData[index]; |
darienf | 20:6d2af70c92ab | 304 | // VERIFY: OS24EVK-75 replace AutoScaleEvaluate dataFormatIs16bit2sComplement with if (DataFormat == DataFormats.Format16bit2sComplement) |
darienf | 20:6d2af70c92ab | 305 | if (DataFormat == DataFormats.Format16bit2sComplement) |
darienf | 20:6d2af70c92ab | 306 | { |
darienf | 20:6d2af70c92ab | 307 | // VERIFY: OS24EVK-57 interpret rawX rawY rawZ as 16-bit 2's complement |
darienf | 20:6d2af70c92ab | 308 | if (yData > 0x8000) |
darienf | 20:6d2af70c92ab | 309 | { |
darienf | 20:6d2af70c92ab | 310 | yData = yData - 0x10000; |
darienf | 20:6d2af70c92ab | 311 | } |
darienf | 20:6d2af70c92ab | 312 | } |
darienf | 20:6d2af70c92ab | 313 | int count = _chart.Series[seriesName].Points.Count; |
darienf | 20:6d2af70c92ab | 314 | // VERIFY: OS24EVK-75 replace _xCount with _xCount1, _xCount2, _xCount3 |
darienf | 20:6d2af70c92ab | 315 | double xCoord = _xCount1 * (_plotPointsToSkip + 1) * SampleAverage_n / (plotXAxisTime ? SampleRate_Hz : 1); |
darienf | 20:6d2af70c92ab | 316 | |
darienf | 20:6d2af70c92ab | 317 | //_chart.Series[seriesName].Points.AddXY(xCoord, yData); |
darienf | 20:6d2af70c92ab | 318 | _chart.Series[seriesName].Points.AddY(yData); |
darienf | 20:6d2af70c92ab | 319 | _chart.ResetAutoValues(); |
darienf | 20:6d2af70c92ab | 320 | |
darienf | 20:6d2af70c92ab | 321 | while (count > _plotPoints) |
darienf | 20:6d2af70c92ab | 322 | { |
darienf | 20:6d2af70c92ab | 323 | _chart.Series[seriesName].Points.RemoveAt(0); |
darienf | 20:6d2af70c92ab | 324 | count = _chart.Series[seriesName].Points.Count; |
darienf | 20:6d2af70c92ab | 325 | } |
darienf | 20:6d2af70c92ab | 326 | // VERIFY: OS24EVK-75 replace _xCount with _xCount1, _xCount2, _xCount3 |
darienf | 20:6d2af70c92ab | 327 | _xCount1++; |
darienf | 20:6d2af70c92ab | 328 | } |
darienf | 20:6d2af70c92ab | 329 | //AutoScaleEvaluate(e.rawRedData, e.sampleNumberOffset, numSamples - 1, _chart, chartAreaName); |
darienf | 20:6d2af70c92ab | 330 | } |
darienf | 20:6d2af70c92ab | 331 | |
darienf | 20:6d2af70c92ab | 332 | /// <summary> |
darienf | 20:6d2af70c92ab | 333 | /// Append data to chart area 2 series 2 (Optical: IR. Accelerometer: Y) |
darienf | 20:6d2af70c92ab | 334 | /// |
darienf | 20:6d2af70c92ab | 335 | /// @post _xCount2 is updated |
darienf | 20:6d2af70c92ab | 336 | /// </summary> |
darienf | 20:6d2af70c92ab | 337 | /// <param name="rawIntArrayYData"></param> |
darienf | 20:6d2af70c92ab | 338 | /// <param name="firstNewXIndex"></param> |
darienf | 20:6d2af70c92ab | 339 | /// <param name="lastXIndex"></param> |
darienf | 20:6d2af70c92ab | 340 | public void AppendDataChartArea2(int[] rawIntArrayYData, int firstNewXIndex, int lastXIndex) |
darienf | 20:6d2af70c92ab | 341 | { |
darienf | 20:6d2af70c92ab | 342 | // AppendDataChartArea(_chartArea2Name, _series2Name, rawIntArrayYData, firstNewXIndex, lastXIndex); |
darienf | 20:6d2af70c92ab | 343 | string chartAreaName = _chartArea2Name; |
darienf | 20:6d2af70c92ab | 344 | string seriesName = _series2Name; |
darienf | 20:6d2af70c92ab | 345 | |
darienf | 20:6d2af70c92ab | 346 | for (int index = firstNewXIndex; index <= lastXIndex; index++) |
darienf | 20:6d2af70c92ab | 347 | { |
darienf | 20:6d2af70c92ab | 348 | int yData = rawIntArrayYData[index]; |
darienf | 20:6d2af70c92ab | 349 | // VERIFY: OS24EVK-75 replace AutoScaleEvaluate dataFormatIs16bit2sComplement with if (DataFormat == DataFormats.Format16bit2sComplement) |
darienf | 20:6d2af70c92ab | 350 | if (DataFormat == DataFormats.Format16bit2sComplement) |
darienf | 20:6d2af70c92ab | 351 | { |
darienf | 20:6d2af70c92ab | 352 | // VERIFY: OS24EVK-57 interpret rawX rawY rawZ as 16-bit 2's complement |
darienf | 20:6d2af70c92ab | 353 | if (yData > 0x8000) |
darienf | 20:6d2af70c92ab | 354 | { |
darienf | 20:6d2af70c92ab | 355 | yData = yData - 0x10000; |
darienf | 20:6d2af70c92ab | 356 | } |
darienf | 20:6d2af70c92ab | 357 | } |
darienf | 20:6d2af70c92ab | 358 | int count = _chart.Series[seriesName].Points.Count; |
darienf | 20:6d2af70c92ab | 359 | // VERIFY: OS24EVK-75 replace _xCount with _xCount1, _xCount2, _xCount3 |
darienf | 20:6d2af70c92ab | 360 | double xCoord = _xCount2 * (_plotPointsToSkip + 1) * SampleAverage_n / (plotXAxisTime ? SampleRate_Hz : 1); |
darienf | 20:6d2af70c92ab | 361 | |
darienf | 20:6d2af70c92ab | 362 | _chart.Series[seriesName].Points.AddXY(xCoord, yData); |
darienf | 20:6d2af70c92ab | 363 | _chart.ResetAutoValues(); |
darienf | 20:6d2af70c92ab | 364 | |
darienf | 20:6d2af70c92ab | 365 | while (count > _plotPoints) |
darienf | 20:6d2af70c92ab | 366 | { |
darienf | 20:6d2af70c92ab | 367 | _chart.Series[seriesName].Points.RemoveAt(0); |
darienf | 20:6d2af70c92ab | 368 | count = _chart.Series[seriesName].Points.Count; |
darienf | 20:6d2af70c92ab | 369 | } |
darienf | 20:6d2af70c92ab | 370 | // VERIFY: OS24EVK-75 replace _xCount with _xCount1, _xCount2, _xCount3 |
darienf | 20:6d2af70c92ab | 371 | _xCount2++; |
darienf | 20:6d2af70c92ab | 372 | } |
darienf | 20:6d2af70c92ab | 373 | //AutoScaleEvaluate(e.rawRedData, e.sampleNumberOffset, numSamples - 1, _chart, chartAreaName); |
darienf | 20:6d2af70c92ab | 374 | } |
darienf | 20:6d2af70c92ab | 375 | |
darienf | 20:6d2af70c92ab | 376 | /// <summary> |
darienf | 20:6d2af70c92ab | 377 | /// Append data to chart area 3 series 3 (Optical: Green. Accelerometer: Z) |
darienf | 20:6d2af70c92ab | 378 | /// |
darienf | 20:6d2af70c92ab | 379 | /// @post _xCount3 is updated |
darienf | 20:6d2af70c92ab | 380 | /// </summary> |
darienf | 20:6d2af70c92ab | 381 | /// <param name="rawIntArrayYData"></param> |
darienf | 20:6d2af70c92ab | 382 | /// <param name="firstNewXIndex"></param> |
darienf | 20:6d2af70c92ab | 383 | /// <param name="lastXIndex"></param> |
darienf | 20:6d2af70c92ab | 384 | public void AppendDataChartArea3(int[] rawIntArrayYData, int firstNewXIndex, int lastXIndex) |
darienf | 20:6d2af70c92ab | 385 | { |
darienf | 20:6d2af70c92ab | 386 | // AppendDataChartArea(_chartArea3Name, _series3Name, rawIntArrayYData, firstNewXIndex, lastXIndex); |
darienf | 20:6d2af70c92ab | 387 | string chartAreaName = _chartArea3Name; |
darienf | 20:6d2af70c92ab | 388 | string seriesName = _series3Name; |
darienf | 20:6d2af70c92ab | 389 | |
darienf | 20:6d2af70c92ab | 390 | for (int index = firstNewXIndex; index <= lastXIndex; index++) |
darienf | 20:6d2af70c92ab | 391 | { |
darienf | 20:6d2af70c92ab | 392 | int yData = rawIntArrayYData[index]; |
darienf | 20:6d2af70c92ab | 393 | // VERIFY: OS24EVK-75 replace AutoScaleEvaluate dataFormatIs16bit2sComplement with if (DataFormat == DataFormats.Format16bit2sComplement) |
darienf | 20:6d2af70c92ab | 394 | if (DataFormat == DataFormats.Format16bit2sComplement) |
darienf | 20:6d2af70c92ab | 395 | { |
darienf | 20:6d2af70c92ab | 396 | // VERIFY: OS24EVK-57 interpret rawX rawY rawZ as 16-bit 2's complement |
darienf | 20:6d2af70c92ab | 397 | if (yData > 0x8000) |
darienf | 20:6d2af70c92ab | 398 | { |
darienf | 20:6d2af70c92ab | 399 | yData = yData - 0x10000; |
darienf | 20:6d2af70c92ab | 400 | } |
darienf | 20:6d2af70c92ab | 401 | } |
darienf | 20:6d2af70c92ab | 402 | int count = _chart.Series[seriesName].Points.Count; |
darienf | 20:6d2af70c92ab | 403 | // VERIFY: OS24EVK-75 replace _xCount with _xCount1, _xCount2, _xCount3 |
darienf | 20:6d2af70c92ab | 404 | double xCoord = _xCount3 * (_plotPointsToSkip + 1) * SampleAverage_n / (plotXAxisTime ? SampleRate_Hz : 1); |
darienf | 20:6d2af70c92ab | 405 | |
darienf | 20:6d2af70c92ab | 406 | _chart.Series[seriesName].Points.AddXY(xCoord, yData); |
darienf | 20:6d2af70c92ab | 407 | _chart.ResetAutoValues(); |
darienf | 20:6d2af70c92ab | 408 | |
darienf | 20:6d2af70c92ab | 409 | while (count > _plotPoints) |
darienf | 20:6d2af70c92ab | 410 | { |
darienf | 20:6d2af70c92ab | 411 | _chart.Series[seriesName].Points.RemoveAt(0); |
darienf | 20:6d2af70c92ab | 412 | count = _chart.Series[seriesName].Points.Count; |
darienf | 20:6d2af70c92ab | 413 | } |
darienf | 20:6d2af70c92ab | 414 | // VERIFY: OS24EVK-75 replace _xCount with _xCount1, _xCount2, _xCount3 |
darienf | 20:6d2af70c92ab | 415 | _xCount3++; |
darienf | 20:6d2af70c92ab | 416 | } |
darienf | 20:6d2af70c92ab | 417 | //AutoScaleEvaluate(e.rawRedData, e.sampleNumberOffset, numSamples - 1, _chart, chartAreaName); |
darienf | 20:6d2af70c92ab | 418 | } |
darienf | 20:6d2af70c92ab | 419 | |
darienf | 20:6d2af70c92ab | 420 | #if PROFILER |
darienf | 20:6d2af70c92ab | 421 | //// TODO1: OS24EVK-54 profiling: capture max interval, number of intervals, cumulative interval |
darienf | 20:6d2af70c92ab | 422 | System.Diagnostics.Stopwatch _profilingStopwatchAutoScaleEvaluate = new System.Diagnostics.Stopwatch(); // cumulative timing |
darienf | 20:6d2af70c92ab | 423 | int _profilingStopwatchAutoScaleEvaluate_NumIntervals; |
darienf | 20:6d2af70c92ab | 424 | #endif // PROFILER |
darienf | 20:6d2af70c92ab | 425 | |
darienf | 20:6d2af70c92ab | 426 | public void AutoScaleEvaluate1(int[] rawIntArrayYData, int firstNewXIndex, int lastXIndex) |
darienf | 20:6d2af70c92ab | 427 | { |
darienf | 20:6d2af70c92ab | 428 | AutoScaleEvaluate(rawIntArrayYData, firstNewXIndex, lastXIndex, _chartArea1Name); |
darienf | 20:6d2af70c92ab | 429 | } |
darienf | 20:6d2af70c92ab | 430 | |
darienf | 20:6d2af70c92ab | 431 | public void AutoScaleEvaluate2(int[] rawIntArrayYData, int firstNewXIndex, int lastXIndex) |
darienf | 20:6d2af70c92ab | 432 | { |
darienf | 20:6d2af70c92ab | 433 | AutoScaleEvaluate(rawIntArrayYData, firstNewXIndex, lastXIndex, _chartArea2Name); |
darienf | 20:6d2af70c92ab | 434 | } |
darienf | 20:6d2af70c92ab | 435 | |
darienf | 20:6d2af70c92ab | 436 | public void AutoScaleEvaluate3(int[] rawIntArrayYData, int firstNewXIndex, int lastXIndex) |
darienf | 20:6d2af70c92ab | 437 | { |
darienf | 20:6d2af70c92ab | 438 | AutoScaleEvaluate(rawIntArrayYData, firstNewXIndex, lastXIndex, _chartArea3Name); |
darienf | 20:6d2af70c92ab | 439 | } |
darienf | 20:6d2af70c92ab | 440 | |
darienf | 20:6d2af70c92ab | 441 | // TODO1: OS24EVK-57 OS24EVK-54 AutoScaleEvaluate(int[] rawIntArrayYData,...) Calculate autoscale min/max/SampleVariance from the raw integer data. This should be much faster as it doesn't involve arbitrarily converting into floating-point numbers or excessive indexing. |
darienf | 20:6d2af70c92ab | 442 | public void AutoScaleEvaluate(int[] rawIntArrayYData, |
darienf | 20:6d2af70c92ab | 443 | int firstNewXIndex, |
darienf | 20:6d2af70c92ab | 444 | int lastXIndex, |
darienf | 20:6d2af70c92ab | 445 | /*Chart chart,*/ string chartAreaName |
darienf | 20:6d2af70c92ab | 446 | // TODO1: OS24EVK-75 replace AutoScaleEvaluate dataFormatIs16bit2sComplement with if (DataFormat == DataFormats.Format16bit2sComplement) |
darienf | 20:6d2af70c92ab | 447 | //bool dataFormatIs16bit2sComplement = false |
darienf | 20:6d2af70c92ab | 448 | //string seriesName, |
darienf | 20:6d2af70c92ab | 449 | //int sampleNumber, |
darienf | 20:6d2af70c92ab | 450 | //ref int sampleNumberPreviousAutoscale |
darienf | 20:6d2af70c92ab | 451 | ) |
darienf | 20:6d2af70c92ab | 452 | { |
darienf | 20:6d2af70c92ab | 453 | #if PROFILER |
darienf | 20:6d2af70c92ab | 454 | // TODO1: OS24EVK-54 profiling: capture max interval, number of intervals, cumulative interval |
darienf | 20:6d2af70c92ab | 455 | _profilingStopwatchAutoScaleEvaluate.Start(); |
darienf | 20:6d2af70c92ab | 456 | _profilingStopwatchAutoScaleEvaluate_NumIntervals = _profilingStopwatchAutoScaleEvaluate_NumIntervals + 1; |
darienf | 20:6d2af70c92ab | 457 | #endif // PROFILER |
darienf | 20:6d2af70c92ab | 458 | |
darienf | 20:6d2af70c92ab | 459 | // TODO1: OS24EVK-57 OS24EVK-54 Calculate autoscale min/max/SampleVariance from the raw integer data. This should be much faster as it doesn't involve arbitrarily converting into floating-point numbers or excessive indexing. |
darienf | 20:6d2af70c92ab | 460 | |
darienf | 20:6d2af70c92ab | 461 | // https://jira.maxim-ic.com/browse/OS24EVK-34 AutoScaleEvaluate() use _AutoScaleMarginXLeft; // ignore old data at left of graph |
darienf | 20:6d2af70c92ab | 462 | // https://jira.maxim-ic.com/browse/OS24EVK-34 AutoScaleEvaluate() use _AutoScaleMarginXRight; // ignore new data at right of graph? probably 0 by default |
darienf | 20:6d2af70c92ab | 463 | //const int firstPointIndex = 0; |
darienf | 20:6d2af70c92ab | 464 | // advance the left and right X limits |
darienf | 20:6d2af70c92ab | 465 | // https://jira.maxim-ic.com/browse/OS24EVK-48 Graph X axis - Replace hidden chkPlotTime with a menu option plotXAxisTimeToolStripMenuItem.Checked |
darienf | 20:6d2af70c92ab | 466 | // https://jira.maxim-ic.com/browse/OS24EVK-47 Graph scrolling needs to be smooth progression like a paper tape chart even when (plotXAxisTimeToolStripMenuItem.Checked is true) |
darienf | 20:6d2af70c92ab | 467 | // per Larry Skrenes 2014-11-24: graph scrolling needs to be smooth progression like a paper tape chart. |
darienf | 20:6d2af70c92ab | 468 | // When (plotXAxisTimeToolStripMenuItem.Checked is false) graph scrolling is already smooth. |
darienf | 20:6d2af70c92ab | 469 | // When (plotXAxisTimeToolStripMenuItem.Checked is true) graph scrolling moves in staccato 1-second steps. Larry hates this. |
darienf | 20:6d2af70c92ab | 470 | int xWidth = _plotPoints * (_plotPointsToSkip + 1) * SampleAverage_n / (plotXAxisTime ? SampleRate_Hz : 1); |
darienf | 20:6d2af70c92ab | 471 | // VERIFY: OS24EVK-73 Sample Avg 2 breaks chart scrolling -- xLastXIndex = lastXIndex * myMAX30101.SampleAverage_n |
darienf | 20:6d2af70c92ab | 472 | int xLastXIndex = lastXIndex * SampleAverage_n / (plotXAxisTime ? SampleRate_Hz : 1); |
darienf | 20:6d2af70c92ab | 473 | //int xWidth = _plotPoints * (_plotPointsToSkip + 1) * _cboSampleAvg / (false ? int.Parse(cboSampleRate.Text) : 1); |
darienf | 20:6d2af70c92ab | 474 | //int xWidth = _plotPoints * (_plotPointsToSkip + 1) * _cboSampleAvg / (1); |
darienf | 20:6d2af70c92ab | 475 | //int xWidth = _plotPoints * (_plotPointsToSkip + 1) * _cboSampleAvg; |
darienf | 20:6d2af70c92ab | 476 | // https://jira.maxim-ic.com/browse/OS24EVK-15 Fix plot X axis jumping around (_plotWindowTime) |
darienf | 20:6d2af70c92ab | 477 | // 0.0 --> 0 1 2 3 4 5 |
darienf | 20:6d2af70c92ab | 478 | // 0.0 --> 0_ 1 2 3 4 5 |
darienf | 20:6d2af70c92ab | 479 | // 0.0 --> 0__1 2 3 4 5 |
darienf | 20:6d2af70c92ab | 480 | // 0.0 --> 0__1_ 2 3 4 5 |
darienf | 20:6d2af70c92ab | 481 | // 0.0 --> 0__1__2 3 4 5 |
darienf | 20:6d2af70c92ab | 482 | // 0.0 --> 0__1__2_ 3 4 5 |
darienf | 20:6d2af70c92ab | 483 | // 0.0 --> 0__1__2__3 4 5 |
darienf | 20:6d2af70c92ab | 484 | // 0.0 --> 0__1__2__3_ 4 5 |
darienf | 20:6d2af70c92ab | 485 | // 0.0 --> 0__1__2__3__4 5 |
darienf | 20:6d2af70c92ab | 486 | // 0.0 --> 0__1__2__3__4_ 5 |
darienf | 20:6d2af70c92ab | 487 | // 0.0 --> 0__1__2__3__4__5 |
darienf | 20:6d2af70c92ab | 488 | // 0.5 --> 1__2__3__4__5_ 6 |
darienf | 20:6d2af70c92ab | 489 | // 1.0 --> 1__2__3__4__5__6 |
darienf | 20:6d2af70c92ab | 490 | // 1.5 --> 2__3__4__5__6_ 7 |
darienf | 20:6d2af70c92ab | 491 | // 2.0 --> 2__3__4__5__6__7 |
darienf | 20:6d2af70c92ab | 492 | // https://jira.maxim-ic.com/browse/OS24EVK-47 Graph scrolling needs to be smooth progression like a paper tape chart even when (plotXAxisTimeToolStripMenuItem.Checked is true) |
darienf | 20:6d2af70c92ab | 493 | // per Larry Skrenes 2014-11-24: graph scrolling needs to be smooth progression like a paper tape chart. |
darienf | 20:6d2af70c92ab | 494 | // When (plotXAxisTimeToolStripMenuItem.Checked is false) graph scrolling is already smooth. |
darienf | 20:6d2af70c92ab | 495 | // When (plotXAxisTimeToolStripMenuItem.Checked is true) graph scrolling moves in staccato 1-second steps. Larry hates this. |
darienf | 20:6d2af70c92ab | 496 | // VERIFY: OS24EVK-76 Autoscale delay time is affected by Sample Average - firstVisiblePointIndex |
darienf | 20:6d2af70c92ab | 497 | //int firstVisiblePointIndex = lastXIndex - (_plotPoints * (_plotPointsToSkip + 1) * SampleAverage_n); |
darienf | 20:6d2af70c92ab | 498 | int firstVisiblePointIndex = lastXIndex - (_plotPoints * (_plotPointsToSkip + 1)); |
darienf | 20:6d2af70c92ab | 499 | if (firstVisiblePointIndex < 0) { firstVisiblePointIndex = 0; } |
darienf | 20:6d2af70c92ab | 500 | // |
darienf | 20:6d2af70c92ab | 501 | // VERIFY: OS24EVK-73 Sample Avg 2 breaks chart scrolling -- xLastXIndex instead of lastXIndex |
darienf | 20:6d2af70c92ab | 502 | int firstVisiblePointX = xLastXIndex - xWidth; // (int)chart.Series[0].Points[firstPointIndex].XValue; |
darienf | 20:6d2af70c92ab | 503 | if (firstVisiblePointX < 0) { firstVisiblePointX = 0; } |
darienf | 20:6d2af70c92ab | 504 | //int firstPointX = (int)System.Math.Ceiling(chart.Series[seriesName].Points[firstPointIndex].XValue); |
darienf | 20:6d2af70c92ab | 505 | //if ((chart.Series[seriesName].Points[firstPointIndex].XValue) < 0.1) |
darienf | 20:6d2af70c92ab | 506 | //{ |
darienf | 20:6d2af70c92ab | 507 | // firstPointX = (int)System.Math.Floor(chart.Series[seriesName].Points[firstPointIndex].XValue); |
darienf | 20:6d2af70c92ab | 508 | //} |
darienf | 20:6d2af70c92ab | 509 | _chart.ChartAreas[chartAreaName].AxisX.Minimum = firstVisiblePointX; |
darienf | 20:6d2af70c92ab | 510 | // https://jira.maxim-ic.com/browse/OS24EVK-47 Graph scrolling needs to be smooth progression like a paper tape chart even when (plotXAxisTimeToolStripMenuItem.Checked is true) |
darienf | 20:6d2af70c92ab | 511 | //chart.ChartAreas[0].AxisX.Maximum = (int)System.Math.Ceiling((double)firstPointX + xWidth); |
darienf | 20:6d2af70c92ab | 512 | _chart.ChartAreas[chartAreaName].AxisX.Maximum = firstVisiblePointX + xWidth; |
darienf | 20:6d2af70c92ab | 513 | |
darienf | 20:6d2af70c92ab | 514 | if (lastXIndex /* chart.Series[seriesName].Points.Count */ < 1) |
darienf | 20:6d2af70c92ab | 515 | { |
darienf | 20:6d2af70c92ab | 516 | //int iMaxY_chart_default = (_AutoScaleMinSpanY * (1.0 + _AutoScaleMarginYTop + _AutoScaleMarginYBottom)) / _AutoScaleYmultiples; |
darienf | 20:6d2af70c92ab | 517 | //int _AutoscaleInitialChartMaxY = iMaxY_chart_default * _AutoScaleYmultiples; |
darienf | 20:6d2af70c92ab | 518 | //int _AutoscaleInitialChartMaxY = |
darienf | 20:6d2af70c92ab | 519 | // ( |
darienf | 20:6d2af70c92ab | 520 | // (int) |
darienf | 20:6d2af70c92ab | 521 | // ((_AutoScaleMinSpanY * (1.0 + _AutoScaleMarginYTop + _AutoScaleMarginYBottom)) / _AutoScaleYmultiples) |
darienf | 20:6d2af70c92ab | 522 | // ) |
darienf | 20:6d2af70c92ab | 523 | // * (int)(_AutoScaleYmultiples); |
darienf | 20:6d2af70c92ab | 524 | //int _AutoscaleInitialChartMinY = 0; |
darienf | 20:6d2af70c92ab | 525 | _chart.ChartAreas[chartAreaName].AxisY.Maximum = _AutoscaleInitialChartMaxY; |
darienf | 20:6d2af70c92ab | 526 | _chart.ChartAreas[chartAreaName].AxisY.Minimum = _AutoscaleInitialChartMinY; |
darienf | 20:6d2af70c92ab | 527 | #if PROFILER |
darienf | 20:6d2af70c92ab | 528 | // TODO1: OS24EVK-54 profiling: capture max interval, number of intervals, cumulative interval |
darienf | 20:6d2af70c92ab | 529 | _profilingStopwatchAutoScaleEvaluate.Stop(); |
darienf | 20:6d2af70c92ab | 530 | #endif // PROFILER |
darienf | 20:6d2af70c92ab | 531 | return; |
darienf | 20:6d2af70c92ab | 532 | } |
darienf | 20:6d2af70c92ab | 533 | |
darienf | 20:6d2af70c92ab | 534 | // // TODO1: OS24EVK-57 OS24EVK-54 scan new data rawIntArrayYData[firstNewIndex .. lastIndex]. As is this code only triggers if the last point is extreme. |
darienf | 20:6d2af70c92ab | 535 | // int newestPointIndex = lastXIndex; // chart.Series[seriesName].Points.Count - 1; |
darienf | 20:6d2af70c92ab | 536 | // int newestPointY = rawIntArrayYData[lastXIndex]; // (int)chart.Series[seriesName].Points[newestPointIndex].YValues[0]; |
darienf | 20:6d2af70c92ab | 537 | // if ((newestPointY < chart.ChartAreas[chartAreaName].AxisY.Maximum) |
darienf | 20:6d2af70c92ab | 538 | // && (newestPointY > chart.ChartAreas[chartAreaName].AxisY.Minimum) |
darienf | 20:6d2af70c92ab | 539 | // ) |
darienf | 20:6d2af70c92ab | 540 | // { |
darienf | 20:6d2af70c92ab | 541 | // // https://jira.maxim-ic.com/browse/OS24EVK-34 always re-evaluate chart when new data exceeds Minimum or Maximum |
darienf | 20:6d2af70c92ab | 542 | // // But if we just return at this point, then autoscale will never contract to fit smaller data series. |
darienf | 20:6d2af70c92ab | 543 | // // |
darienf | 20:6d2af70c92ab | 544 | // // https://jira.maxim-ic.com/browse/OS24EVK-34 Change _AutoScaleTimeInterval to _AutoScaleEveryNSamples and use sampleNumber to measure time |
darienf | 20:6d2af70c92ab | 545 | // // https://jira.maxim-ic.com/browse/OS24EVK-34 AutoScaleEvaluate() after every _AutoScaleEveryNSamples, re-scan data and fit chart to data |
darienf | 20:6d2af70c92ab | 546 | // // if ( interval has been less than _AutoScaleEveryNSamples ) { return; } |
darienf | 20:6d2af70c92ab | 547 | // if ((sampleNumber - sampleNumberPreviousAutoscale) < _AutoScaleEveryNSamples) |
darienf | 20:6d2af70c92ab | 548 | // { |
darienf | 20:6d2af70c92ab | 549 | //#if PROFILER |
darienf | 20:6d2af70c92ab | 550 | // // TODO1: OS24EVK-54 profiling: capture max interval, number of intervals, cumulative interval |
darienf | 20:6d2af70c92ab | 551 | // _profilingStopwatchAutoScaleEvaluate.Stop(); |
darienf | 20:6d2af70c92ab | 552 | //#endif // PROFILER |
darienf | 20:6d2af70c92ab | 553 | // return; |
darienf | 20:6d2af70c92ab | 554 | // } |
darienf | 20:6d2af70c92ab | 555 | // } |
darienf | 20:6d2af70c92ab | 556 | |
darienf | 20:6d2af70c92ab | 557 | int chartMinYValue = (int)_chart.ChartAreas[chartAreaName].AxisY.Minimum; // rawIntArrayYData[firstVisiblePointX] - 1; |
darienf | 20:6d2af70c92ab | 558 | int chartMaxYValue = (int)_chart.ChartAreas[chartAreaName].AxisY.Maximum; // rawIntArrayYData[firstVisiblePointX] + 1; |
darienf | 20:6d2af70c92ab | 559 | // VERIFY: OS24EVK-73 Sample Avg 2 breaks chart scrolling - firstVisiblePointIndex instead of firstVisiblePointX |
darienf | 20:6d2af70c92ab | 560 | int dataMinYValue = rawIntArrayYData[firstVisiblePointIndex] - 1; |
darienf | 20:6d2af70c92ab | 561 | int dataMaxYValue = rawIntArrayYData[firstVisiblePointIndex] + 1; |
darienf | 20:6d2af70c92ab | 562 | for (int index = firstVisiblePointIndex; index <= lastXIndex; index++) |
darienf | 20:6d2af70c92ab | 563 | { |
darienf | 20:6d2af70c92ab | 564 | int Y = rawIntArrayYData[index]; |
darienf | 20:6d2af70c92ab | 565 | // VERIFY: OS24EVK-57 OS24EVK-54 improve chart throughput: AutoScaleEvaluate() dataFormatIs16bit2sComplement=true for Accelerometer X Y Z data |
darienf | 20:6d2af70c92ab | 566 | // VERIFY: OS24EVK-75 replace AutoScaleEvaluate dataFormatIs16bit2sComplement with if (DataFormat == DataFormats.Format16bit2sComplement) |
darienf | 20:6d2af70c92ab | 567 | if (DataFormat == DataFormats.Format16bit2sComplement) |
darienf | 20:6d2af70c92ab | 568 | { |
darienf | 20:6d2af70c92ab | 569 | // VERIFY: OS24EVK-57 interpret rawX rawY rawZ as 16-bit 2's complement |
darienf | 20:6d2af70c92ab | 570 | if (Y > 0x8000) |
darienf | 20:6d2af70c92ab | 571 | { |
darienf | 20:6d2af70c92ab | 572 | Y = Y - 0x10000; |
darienf | 20:6d2af70c92ab | 573 | } |
darienf | 20:6d2af70c92ab | 574 | } |
darienf | 20:6d2af70c92ab | 575 | //else |
darienf | 20:6d2af70c92ab | 576 | //{ |
darienf | 20:6d2af70c92ab | 577 | // Y = Y + 0; // debug breakpoint for code path verification |
darienf | 20:6d2af70c92ab | 578 | //} |
darienf | 20:6d2af70c92ab | 579 | if (dataMinYValue > Y) |
darienf | 20:6d2af70c92ab | 580 | { |
darienf | 20:6d2af70c92ab | 581 | dataMinYValue = Y; |
darienf | 20:6d2af70c92ab | 582 | } |
darienf | 20:6d2af70c92ab | 583 | if (dataMaxYValue < Y) |
darienf | 20:6d2af70c92ab | 584 | { |
darienf | 20:6d2af70c92ab | 585 | dataMaxYValue = Y; |
darienf | 20:6d2af70c92ab | 586 | } |
darienf | 20:6d2af70c92ab | 587 | } |
darienf | 20:6d2af70c92ab | 588 | // rawIntArrayYData[firstIndex..lastIndex] spans the range from dataMinYValue .. dataMaxYValue |
darienf | 20:6d2af70c92ab | 589 | double dataSpanY = (dataMaxYValue - dataMinYValue); |
darienf | 20:6d2af70c92ab | 590 | double dataCenterY = (dataMaxYValue + dataMinYValue) / 2; |
darienf | 20:6d2af70c92ab | 591 | |
darienf | 20:6d2af70c92ab | 592 | bool isAllDataVisible = ( |
darienf | 20:6d2af70c92ab | 593 | (chartMinYValue < dataMaxYValue) && (dataMaxYValue < chartMaxYValue) |
darienf | 20:6d2af70c92ab | 594 | && |
darienf | 20:6d2af70c92ab | 595 | (chartMinYValue < dataMinYValue) && (dataMinYValue < chartMaxYValue) |
darienf | 20:6d2af70c92ab | 596 | ); |
darienf | 20:6d2af70c92ab | 597 | if (isAllDataVisible) |
darienf | 20:6d2af70c92ab | 598 | { |
darienf | 20:6d2af70c92ab | 599 | // all data is within the chart limits, but is the chart sufficiently zoomed in? |
darienf | 20:6d2af70c92ab | 600 | double relativeDataSpan = (double)dataSpanY / (chartMaxYValue - chartMinYValue); |
darienf | 20:6d2af70c92ab | 601 | if (relativeDataSpan > 0.65) |
darienf | 20:6d2af70c92ab | 602 | { |
darienf | 20:6d2af70c92ab | 603 | // the current chart scale is good enough, do not update |
darienf | 20:6d2af70c92ab | 604 | #if PROFILER |
darienf | 20:6d2af70c92ab | 605 | // TODO1: OS24EVK-54 profiling: capture max interval, number of intervals, cumulative interval |
darienf | 20:6d2af70c92ab | 606 | _profilingStopwatchAutoScaleEvaluate.Stop(); |
darienf | 20:6d2af70c92ab | 607 | #endif // PROFILER |
darienf | 20:6d2af70c92ab | 608 | return; |
darienf | 20:6d2af70c92ab | 609 | } |
darienf | 20:6d2af70c92ab | 610 | } |
darienf | 20:6d2af70c92ab | 611 | // https://jira.maxim-ic.com/browse/OS24EVK-34 AutoScaleEvaluate() use _AutoScaleMinSpanY; // minimum allowed span of chartMax-chartMin, to avoid focusing on LSB noise |
darienf | 20:6d2af70c92ab | 612 | if (dataSpanY < _AutoScaleMinSpanY) |
darienf | 20:6d2af70c92ab | 613 | { |
darienf | 20:6d2af70c92ab | 614 | // https://jira.maxim-ic.com/browse/OS24EVK-34 Autoscale - Minimum span (in case dataMax-dataMin is too small) to avoid focusing on LSB noise |
darienf | 20:6d2af70c92ab | 615 | dataSpanY = _AutoScaleMinSpanY; |
darienf | 20:6d2af70c92ab | 616 | } |
darienf | 20:6d2af70c92ab | 617 | else |
darienf | 20:6d2af70c92ab | 618 | { |
darienf | 20:6d2af70c92ab | 619 | // https://jira.maxim-ic.com/browse/OS24EVK-34 Autoscale - Apply a Top margin - Bottom margin = 12% .. 88% when mapping Chart max-min to Data max-min |
darienf | 20:6d2af70c92ab | 620 | // https://jira.maxim-ic.com/browse/OS24EVK-34 AutoScaleEvaluate() use _AutoScaleMarginYTop; // chartMax empty area above dataMax |
darienf | 20:6d2af70c92ab | 621 | // https://jira.maxim-ic.com/browse/OS24EVK-34 AutoScaleEvaluate() use _AutoScaleMarginYBottom; // chartMin empty area below dataMin |
darienf | 20:6d2af70c92ab | 622 | // dataSpanY = dataSpanY * 1.25; |
darienf | 20:6d2af70c92ab | 623 | // dataSpanY = dataSpanY * (1.0 + 0.125 + 0.125); |
darienf | 20:6d2af70c92ab | 624 | dataSpanY = dataSpanY * (1.0 + _AutoScaleMarginYTop + _AutoScaleMarginYBottom); |
darienf | 20:6d2af70c92ab | 625 | |
darienf | 20:6d2af70c92ab | 626 | // https://jira.maxim-ic.com/browse/OS24EVK-42 Autoscale tuning (Larry 2014-11-24) Round to nearest multiple of 100. |
darienf | 20:6d2af70c92ab | 627 | // - Y axis: No decimals. Round to nearest multiple of 100. |
darienf | 20:6d2af70c92ab | 628 | // private double _AutoScaleYmultiples = 100; |
darienf | 20:6d2af70c92ab | 629 | //int tempdataSpanY = (int)(dataSpanY / _AutoScaleYmultiples); |
darienf | 20:6d2af70c92ab | 630 | //dataSpanY = tempdataSpanY * _AutoScaleYmultiples; |
darienf | 20:6d2af70c92ab | 631 | //dataSpanY = (double)((int)dataSpanY / _AutoScaleYmultiples) * _AutoScaleYmultiples; |
darienf | 20:6d2af70c92ab | 632 | //dataCenterY = (double)((int)dataCenterY / _AutoScaleYmultiples) * _AutoScaleYmultiples; |
darienf | 20:6d2af70c92ab | 633 | } |
darienf | 20:6d2af70c92ab | 634 | // https://jira.maxim-ic.com/browse/OS24EVK-34 Autoscale - There are 5 vertical divisions; keep the minor axis tick values integer |
darienf | 20:6d2af70c92ab | 635 | //int YaxisDivisions = (int)System.Math.Ceiling(dataSpanY / 6.0); |
darienf | 20:6d2af70c92ab | 636 | //dataSpanY = YaxisDivisions * 6; |
darienf | 20:6d2af70c92ab | 637 | // https://jira.maxim-ic.com/browse/OS24EVK-42 Autoscale tuning (Larry 2014-11-24) Round to nearest multiple of 100. |
darienf | 20:6d2af70c92ab | 638 | // - Y axis: No decimals. Round to nearest multiple of 100. |
darienf | 20:6d2af70c92ab | 639 | // private double _AutoScaleYmultiples = 100; |
darienf | 20:6d2af70c92ab | 640 | //int tempdataCenterY = (int)(dataCenterY / (_AutoScaleYmultiples*2)); |
darienf | 20:6d2af70c92ab | 641 | //dataCenterY = tempdataCenterY * (_AutoScaleYmultiples*2); |
darienf | 20:6d2af70c92ab | 642 | |
darienf | 20:6d2af70c92ab | 643 | // chart.ChartAreas[0].AxisY.Maximum = dataMaxYValue; |
darienf | 20:6d2af70c92ab | 644 | // chart.ChartAreas[0].AxisY.Minimum = dataMinYValue; |
darienf | 20:6d2af70c92ab | 645 | //chart.ChartAreas[0].AxisY.Maximum = System.Math.Ceiling(dataCenterY + (dataSpanY / 2)); // dataMaxYValue; |
darienf | 20:6d2af70c92ab | 646 | //chart.ChartAreas[0].AxisY.Minimum = System.Math.Floor(dataCenterY - (dataSpanY / 2)); // dataMinYValue; |
darienf | 20:6d2af70c92ab | 647 | // https://jira.maxim-ic.com/browse/OS24EVK-42 Autoscale tuning (Larry 2014-11-24) Round to nearest multiple of 100. |
darienf | 20:6d2af70c92ab | 648 | // - Y axis: No decimals. Round to nearest multiple of 100. |
darienf | 20:6d2af70c92ab | 649 | // private double _AutoScaleYmultiples = 100; |
darienf | 20:6d2af70c92ab | 650 | int iMaxY_target = (int)((dataCenterY + (dataSpanY / 2)) / _AutoScaleYmultiples); |
darienf | 20:6d2af70c92ab | 651 | int iMinY_target = (int)((dataCenterY - (dataSpanY / 2)) / _AutoScaleYmultiples); |
darienf | 20:6d2af70c92ab | 652 | |
darienf | 20:6d2af70c92ab | 653 | double dampingConstantK = 0.2; |
darienf | 20:6d2af70c92ab | 654 | int iMaxY_damped = iMaxY_target; |
darienf | 20:6d2af70c92ab | 655 | int iMinY_damped = iMinY_target; |
darienf | 20:6d2af70c92ab | 656 | if (double.IsNaN(_chart.ChartAreas[chartAreaName].AxisY.Maximum) == false) |
darienf | 20:6d2af70c92ab | 657 | { |
darienf | 20:6d2af70c92ab | 658 | int iMaxY_chart = (int)(_chart.ChartAreas[chartAreaName].AxisY.Maximum / _AutoScaleYmultiples); |
darienf | 20:6d2af70c92ab | 659 | int iMinY_chart = (int)(_chart.ChartAreas[chartAreaName].AxisY.Minimum / _AutoScaleYmultiples); |
darienf | 20:6d2af70c92ab | 660 | iMaxY_damped = (int)((dampingConstantK * (double)iMaxY_target) + ((1 - dampingConstantK) * (double)iMaxY_chart) + 0.5); |
darienf | 20:6d2af70c92ab | 661 | iMinY_damped = (int)((dampingConstantK * (double)iMinY_target) + ((1 - dampingConstantK) * (double)iMinY_chart)); |
darienf | 20:6d2af70c92ab | 662 | } |
darienf | 20:6d2af70c92ab | 663 | double maxY = iMaxY_target * _AutoScaleYmultiples; |
darienf | 20:6d2af70c92ab | 664 | double minY = iMinY_target * _AutoScaleYmultiples; |
darienf | 20:6d2af70c92ab | 665 | _chart.ChartAreas[chartAreaName].AxisY.Maximum = maxY; |
darienf | 20:6d2af70c92ab | 666 | _chart.ChartAreas[chartAreaName].AxisY.Minimum = minY; |
darienf | 20:6d2af70c92ab | 667 | // if chart.ChartAreas[chartAreaName].AxisY.Maximum is NaN then just assign maxY |
darienf | 20:6d2af70c92ab | 668 | //if (double.IsNaN(chart.ChartAreas[chartAreaName].AxisY.Maximum)) |
darienf | 20:6d2af70c92ab | 669 | //{ |
darienf | 20:6d2af70c92ab | 670 | // chart.ChartAreas[chartAreaName].AxisY.Maximum = maxY; |
darienf | 20:6d2af70c92ab | 671 | // chart.ChartAreas[chartAreaName].AxisY.Minimum = minY; |
darienf | 20:6d2af70c92ab | 672 | //} |
darienf | 20:6d2af70c92ab | 673 | //else |
darienf | 20:6d2af70c92ab | 674 | //{ |
darienf | 20:6d2af70c92ab | 675 | // chart.ChartAreas[chartAreaName].AxisY.Maximum = (dampingConstantK * maxY) + ((1 - dampingConstantK) * chart.ChartAreas[chartAreaName].AxisY.Maximum); |
darienf | 20:6d2af70c92ab | 676 | // chart.ChartAreas[chartAreaName].AxisY.Minimum = (dampingConstantK * minY) + ((1 - dampingConstantK) * chart.ChartAreas[chartAreaName].AxisY.Minimum); |
darienf | 20:6d2af70c92ab | 677 | //} |
darienf | 20:6d2af70c92ab | 678 | |
darienf | 20:6d2af70c92ab | 679 | #if PROFILER |
darienf | 20:6d2af70c92ab | 680 | // TODO1: OS24EVK-54 profiling: capture max interval, number of intervals, cumulative interval |
darienf | 20:6d2af70c92ab | 681 | _profilingStopwatchAutoScaleEvaluate.Stop(); |
darienf | 20:6d2af70c92ab | 682 | #endif // PROFILER |
darienf | 20:6d2af70c92ab | 683 | } |
darienf | 20:6d2af70c92ab | 684 | |
darienf | 20:6d2af70c92ab | 685 | /// <summary> |
darienf | 20:6d2af70c92ab | 686 | /// Raw data format |
darienf | 20:6d2af70c92ab | 687 | /// </summary> |
darienf | 20:6d2af70c92ab | 688 | public DataFormats DataFormat = DataFormats.FormatUnsigned; |
darienf | 20:6d2af70c92ab | 689 | |
darienf | 20:6d2af70c92ab | 690 | public enum DataFormats |
darienf | 20:6d2af70c92ab | 691 | { |
darienf | 20:6d2af70c92ab | 692 | /// <summary> |
darienf | 20:6d2af70c92ab | 693 | /// Interpret raw data as unsigned values |
darienf | 20:6d2af70c92ab | 694 | /// </summary> |
darienf | 20:6d2af70c92ab | 695 | FormatUnsigned, |
darienf | 20:6d2af70c92ab | 696 | |
darienf | 20:6d2af70c92ab | 697 | /// <summary> |
darienf | 20:6d2af70c92ab | 698 | /// Interpret raw data as 16-bit, signed 2's complement values |
darienf | 20:6d2af70c92ab | 699 | /// </summary> |
darienf | 20:6d2af70c92ab | 700 | Format16bit2sComplement, |
darienf | 20:6d2af70c92ab | 701 | } |
darienf | 20:6d2af70c92ab | 702 | |
darienf | 20:6d2af70c92ab | 703 | } // public class MedicalChartHelper |
darienf | 20:6d2af70c92ab | 704 | |
darienf | 20:6d2af70c92ab | 705 | } // namespace Maxim.MAX30101 |