Pathetic initial attempt at CMS50 Live Plethy

This commit is contained in:
Mark Watkins 2011-07-15 20:01:28 +10:00
parent fb13500bee
commit ad8edfc1e7
7 changed files with 113 additions and 46 deletions

View File

@ -27,13 +27,17 @@ gLineChart::~gLineChart()
// Time Domain Line Chart // Time Domain Line Chart
void gLineChart::Plot(gGraphWindow & w,float scrx,float scry) void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
{ {
if (!m_visible) if (!m_visible)
return; return;
if (!data) if (!data)
return; return;
if (!data->IsReady()) if (!data->IsReady())
return; return;
if (w.Title()=="Plethysomogram") {
int q=0;
} else {
// qDebug() << w.Title();
}
int start_px=w.GetLeftMargin(), start_py=w.GetBottomMargin(); int start_px=w.GetLeftMargin(), start_py=w.GetBottomMargin();

View File

@ -21,45 +21,52 @@ public:
gGraphData(int mp,gDataType t=gDT_Point); gGraphData(int mp,gDataType t=gDT_Point);
virtual ~gGraphData(); virtual ~gGraphData();
virtual void Reload(Day *day=NULL) { day=day; }; virtual void Reload(Day *day=NULL) { day=day; }
virtual void Update(Day *day=NULL); virtual void Update(Day *day=NULL);
//inline wxRealPoint & operator [](int i) { return vpoint[seg][i]; }; //inline wxRealPoint & operator [](int i) { return vpoint[seg][i]; }
//inline vector<double> & Vec(int i) { return yaxis[i]; }; //inline vector<double> & Vec(int i) { return yaxis[i]; }
//virtual inline const int & NP(int i) { return vnp[i]; }; //virtual inline const int & NP(int i) { return vnp[i]; }
//virtual inline const int & MP(int i) { return vsize[i]; }; //virtual inline const int & MP(int i) { return vsize[i]; }
inline const gDataType & Type() { return type; }; inline const gDataType & Type() { return type; }
virtual inline double MaxX() { return max_x; }; virtual inline double MaxX() { return max_x; }
virtual inline double MinX() { return min_x; }; virtual inline double MinX() { return min_x; }
virtual inline double MaxY() { return max_y; }; virtual inline double MaxY() { return max_y; }
virtual inline double MinY() { return min_y; }; virtual inline double MinY() { return min_y; }
virtual inline void SetMaxX(double v) { max_x=v; if (max_x>real_max_x) max_x=real_max_x; }; virtual inline void SetMaxX(double v) { max_x=v; if (max_x>real_max_x) max_x=real_max_x; }
virtual inline void SetMinX(double v) { min_x=v; if (min_x<real_min_x) min_x=real_min_x; }; virtual inline void SetMinX(double v) { min_x=v; if (min_x<real_min_x) min_x=real_min_x; }
virtual inline void SetMaxY(double v) { max_y=v; if (max_y>real_max_y) max_y=real_max_y; }; virtual inline void SetMaxY(double v) { max_y=v; if (max_y>real_max_y) max_y=real_max_y; }
virtual inline void SetMinY(double v) { min_y=v; if (min_y<real_min_y) min_y=real_min_y; }; virtual inline void SetMinY(double v) { min_y=v; if (min_y<real_min_y) min_y=real_min_y; }
virtual inline double RealMaxX() { return real_max_x; }; virtual inline double RealMaxX() { return real_max_x; }
virtual inline double RealMinX() { return real_min_x; }; virtual inline double RealMinX() { return real_min_x; }
virtual inline double RealMaxY() { return real_max_y; }; virtual inline double RealMaxY() { return real_max_y; }
virtual inline double RealMinY() { return real_min_y; }; virtual inline double RealMinY() { return real_min_y; }
virtual inline void ForceMinY(double v) { force_min_y=v; }; virtual inline void SetRealMaxX(double v) { real_max_x=v; }
virtual inline void ForceMaxY(double v) { force_max_y=v; }; virtual inline void SetRealMinX(double v) { real_min_x=v; }
virtual inline void SetRealMaxY(double v) { real_max_y=v; }
virtual inline void SetRealMinY(double v) { real_min_y=v; }
inline void ResetX() { min_x=real_min_x; max_x=real_max_x; }; virtual inline void ForceMinY(double v) { force_min_y=v; }
inline void ResetY() { min_y=real_min_y; max_y=real_max_y; }; virtual inline void ForceMaxY(double v) { force_max_y=v; }
virtual inline int VC() { return vc; }; inline void ResetX() { min_x=real_min_x; max_x=real_max_x; }
inline void ResetY() { min_y=real_min_y; max_y=real_max_y; }
virtual inline int VC() { return vc; }
void SetVC(int v) { vc=v; }
vector<int> np; vector<int> np;
vector<int> maxsize; vector<int> maxsize;
bool IsReady() { return m_ready; }; bool IsReady() { return m_ready; }
void SetReady(bool b) { m_ready=b; }
bool isEmpty(); bool isEmpty();
void AddLayer(gLayer *g); void AddLayer(gLayer *g);
protected: protected:
virtual void AddSegment(int max_points) { max_points=max_points; }; virtual void AddSegment(int max_points) { max_points=max_points; }
double real_min_x, real_max_x, real_min_y, real_max_y; double real_min_x, real_max_x, real_min_y, real_max_y;
double min_x, max_x, min_y, max_y; double min_x, max_x, min_y, max_y;

View File

@ -612,10 +612,14 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,qint64
} }
break; break;
case 0x0e: // Unknown case 0x0e: // Unknown
data[0]=buffer[pos++]; // << 8) | buffer[pos]; data[0]=buffer[pos++];
data[1]=buffer[pos++]; data[1]=buffer[pos++]; //(buffer[pos+1] << 8) | buffer[pos];
//data[0]/=10.0;
//pos+=2;
data[2]=buffer[pos++]; data[2]=buffer[pos++];
session->AddEvent(new Event(t,cpapcode, data, 3)); session->AddEvent(new Event(t,cpapcode, data, 3));
//tt-=data[1]*1000;
//session->AddEvent(new Event(t,CPAP_CSR, data, 2));
break; break;
case 0x10: // Unknown case 0x10: // Unknown
data[0]=buffer[pos++]; // << 8) | buffer[pos]; data[0]=buffer[pos++]; // << 8) | buffer[pos];

View File

@ -518,7 +518,15 @@ void Daily::UpdateEventsTree(QTreeWidget *tree,Day *day)
} }
QStringList a; QStringList a;
QDateTime d=QDateTime::fromMSecsSinceEpoch(t); QDateTime d=QDateTime::fromMSecsSinceEpoch(t);
a.append(QString("#%1: %2").arg((int)++mccnt[code],(int)3,(int)10,QChar('0')).arg(d.toString("HH:mm:ss"))); QString s=QString("#%1: %2").arg((int)++mccnt[code],(int)3,(int)10,QChar('0')).arg(d.toString("HH:mm:ss"));
if ((code==PRS1_Unknown0E) || (code==PRS1_Unknown10) || (code==PRS1_Unknown0B)) {
s.append(" "+QString::number((*(*e))[0]));
s.append(" "+QString::number((*(*e))[1]));
}
if ((code==PRS1_Unknown0E) || (code==PRS1_Unknown10)) {
s.append(" "+QString::number((*(*e))[2]));
}
a.append(s);
a.append(d.toString("yyyy-MM-dd HH:mm:ss")); a.append(d.toString("yyyy-MM-dd HH:mm:ss"));
mcr->addChild(new QTreeWidgetItem(a)); mcr->addChild(new QTreeWidgetItem(a));
} }

View File

@ -15,6 +15,7 @@ p,a,td,body { font-size: 14px }
<li>Philips Respironics System One (Including ASV models)</li> <li>Philips Respironics System One (Including ASV models)</li>
<li>ResMed S9 models (AutoSet and lower)</li> <li>ResMed S9 models (AutoSet and lower)</li>
<li>Contec CMS50 Oximeters</li> <li>Contec CMS50 Oximeters</li>
<p>This is a developer preview, features are missing and bugs will be plentyful.
<p><b>Project Website:</b> <a href='http://sleepyhead.sourceforge.net'>http://sleepyhead.sourceforge.net</a><br> <p><b>Project Website:</b> <a href='http://sleepyhead.sourceforge.net'>http://sleepyhead.sourceforge.net</a><br>
<b>About Sleep Apnea:</b> <a href='http://en.wikipedia.org/wiki/Sleep_apnea'>http://en.wikipedia.org/wiki/Sleep_apnea</a><br> <b>About Sleep Apnea:</b> <a href='http://en.wikipedia.org/wiki/Sleep_apnea'>http://en.wikipedia.org/wiki/Sleep_apnea</a><br>
<b>CPAPTalk Forum:</b> <a href='http://www.cpaptalk.com'>http://www.cpaptalk.com</a></p> <b>CPAPTalk Forum:</b> <a href='http://www.cpaptalk.com'>http://www.cpaptalk.com</a></p>
@ -27,8 +28,8 @@ p,a,td,body { font-size: 14px }
<td colspan=2> <td colspan=2>
<hr> <hr>
<p><b>Copyright:</b> &copy;2011 Mark Watkins (jedimark)</p> <p><b>Copyright:</b> &copy;2011 Mark Watkins (jedimark)</p>
<p><b>License:</b> This software is released freely under the GNU Public License.</p> <p><b>License:</b> This software is released freely under the GNU Public License.
<p><b>It would very unwise to rely solely on this software when making medical decisions. Talk to your doctor.</b></p> <p><b>Do NOT rely on this softwares accuracy when making medical decisions. Talk to your doctor.</b></p>
</td></tr> </td></tr>
</table> </table>
</body> </body>

View File

@ -218,12 +218,12 @@ void MainWindow::on_webView_loadProgress(int progress)
void MainWindow::on_action_About_triggered() void MainWindow::on_action_About_triggered()
{ {
QString msg=tr("<html><body><div align='center'><h2>SleepyHead v0.8.0</h2><hr>\ QString msg=tr("<html><body><div align='center'><h2>SleepyHead v0.8.0</h2><hr>"
Copyright &copy;2011 Mark Watkins (jedimark) <br> \n\ "Copyright &copy;2011 Mark Watkins (jedimark) <br> \n"
<a href='http://sleepyhead.sourceforge.net'>http://sleepyhead.sourceforge.net</a> <hr>\ "<a href='http://sleepyhead.sourceforge.net'>http://sleepyhead.sourceforge.net</a> <hr>"
This software is released under the GNU Public License <hr> \ "This software is released under the GNU Public License <br>"
<i>This software comes with absolutely no warranty, either express of implied. It comes with no guarantee of fitness for any particular purpose. No guarantees are made regarding the accuracy of any data this program displays.\ "<i>This software comes with absolutely no warranty, either express of implied. It comes with no guarantee of fitness for any particular purpose. No guarantees are made regarding the accuracy of any data this program displays."
</div></body></html>"); "</div></body></html>");
QMessageBox msgbox(QMessageBox::Information,tr("About SleepyHead"),"",QMessageBox::Ok,this); QMessageBox msgbox(QMessageBox::Information,tr("About SleepyHead"),"",QMessageBox::Ok,this);
msgbox.setTextFormat(Qt::RichText); msgbox.setTextFormat(Qt::RichText);
msgbox.setText(msg); msgbox.setText(msg);

View File

@ -38,7 +38,7 @@ Oximetry::Oximetry(QWidget *parent) :
PULSE->setMinimumHeight(150); PULSE->setMinimumHeight(150);
AddData(spo2=new WaveData(OXI_SPO2)); AddData(spo2=new WaveData(OXI_SPO2));
SPO2=new gGraphWindow(gSplitter,tr("SPO2"),(QGLWidget *)NULL); SPO2=new gGraphWindow(gSplitter,tr("SPO2"),PULSE);
SPO2->AddLayer(new gXAxis()); SPO2->AddLayer(new gXAxis());
SPO2->AddLayer(new gYAxis()); SPO2->AddLayer(new gYAxis());
SPO2->AddLayer(new gFooBar()); SPO2->AddLayer(new gFooBar());
@ -46,18 +46,23 @@ Oximetry::Oximetry(QWidget *parent) :
SPO2->setMinimumHeight(150); SPO2->setMinimumHeight(150);
AddData(plethy=new WaveData(OXI_Plethy)); AddData(plethy=new WaveData(OXI_Plethy));
PLETHY=new gGraphWindow(gSplitter,tr("Plethysomogram"),(QGLWidget *)NULL); plethy->AddSegment(1000000);
PLETHY->AddLayer(new gXAxis()); plethy->np[0]=0;
plethy->SetMaxY(100);
plethy->SetMinY(0);
PLETHY=new gGraphWindow(gSplitter,tr("Plethysomogram"),PULSE);
//PLETHY->AddLayer(new gXAxis());
PLETHY->AddLayer(new gYAxis()); PLETHY->AddLayer(new gYAxis());
PLETHY->AddLayer(new gFooBar()); PLETHY->AddLayer(new gFooBar());
PLETHY->AddLayer(new gLineChart(plethy,Qt::red,65536,false,false,false)); PLETHY->AddLayer(new gLineChart(plethy,Qt::red,65536,true,false,false));
PLETHY->setMinimumHeight(150); PLETHY->setMinimumHeight(150);
PLETHY->SetBlockZoom(true);
portname=""; portname="";
gSplitter->addWidget(PLETHY);
gSplitter->addWidget(PULSE); gSplitter->addWidget(PULSE);
gSplitter->addWidget(SPO2); gSplitter->addWidget(SPO2);
gSplitter->addWidget(PLETHY);
on_RefreshPortsButton_clicked(); on_RefreshPortsButton_clicked();
} }
@ -151,6 +156,44 @@ void Oximetry::onReadyRead()
int a = port->bytesAvailable(); int a = port->bytesAvailable();
bytes.resize(a); bytes.resize(a);
port->read(bytes.data(), bytes.size()); port->read(bytes.data(), bytes.size());
static qint64 starttime=0;
static qint64 lasttime=0;
static int idx=0;
if (!lasttime) {
lasttime=QDateTime::currentMSecsSinceEpoch();
starttime=lasttime;
plethy->SetRealMinX(double(lasttime)/86400000.0);
plethy->SetRealMaxX(double(lasttime+1800000)/86400000.0);
plethy->SetMinX(double(lasttime)/86400000.0);
plethy->SetMaxX(double(lasttime+600000)/86400000.0);
plethy->SetRealMinY(0);
plethy->SetRealMaxY(120);
plethy->SetMaxY(120);
plethy->SetMinY(0);
PLETHY->MinX();
PLETHY->MaxX();
PLETHY->RealMinX();
PLETHY->RealMaxX();
PLETHY->MinY();
PLETHY->MaxY();
plethy->SetReady(true);
plethy->SetVC(1);
plethy->np[0]=600;
}
if (bytes.size()==3) {
EventDataType d=bytes[1] & 0x7f;
plethy->point[0][idx].setX(double(lasttime)/86400000.0);
plethy->point[0][idx++].setY(d);
lasttime+=1000;
if (idx>600) {
idx=0;
lasttime=starttime;
}
PLETHY->updateGL();
}
/*if (portmode!=PM_RECORDING) { /*if (portmode!=PM_RECORDING) {
return; return;
} }
@ -169,11 +212,11 @@ void Oximetry::onReadyRead()
lastspo2=bytes[1]; lastspo2=bytes[1];
} else { } else {
qDebug() << "bytes read:" << bytes.size(); */ qDebug() << "bytes read:" << bytes.size(); */
QString aa; //QString aa;
for (int i=0;i<bytes.size();i++) //for (int i=0;i<bytes.size();i++)
aa+=QString::number((unsigned char)bytes[i],16)+" "; // aa+=QString::number((unsigned char)bytes[i],16)+" ";
qDebug() << hex << aa; //qDebug() << hex << aa;
/*QByteArray b; /*QByteArray b;
b.resize(3); b.resize(3);
b[0]=0xf6; b[0]=0xf6;