Reputation: 1718
I am writing a code that receives heart sound from a hardware device using comports and plots the signal received. I am using OpenGl to plot the signal received. I am able to plot when I receive the complete data. But I want the graph to update with the updating of data received Here is my code:
int num_samples = 100000;
long samples[100000];
DWORD bytes_read = 0; // Number of bytes read from port
/* Function plotting func */
void draw( float x1, float x2, float y1, float y2, int N)
{
float x, dx = 1.0/N;
glPushMatrix(); /* GL_MODELVIEW is default */
glScalef(1.0 / (x2 - x1), 1.0 / (y2 - y1), 1.0);
glTranslatef(-x1, -y1, 0.0);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
int k =0;
for(x = 0; x < num_samples; x += dx)
{
glVertex2f(x, samples[k]);
k=k+1;
}
glEnd();
glPopMatrix();
glFlush();
};
/* Redrawing func */
void redraw(void)
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//long buf = getBuffer(samples);
draw(0, num_samples,-693554432, 693554432, 1);
// draw(func, 0, 1000,0, 5000, 1);
glutSwapBuffers();
//glFlush();
};
/* Idle proc. Redisplays, if called. */
void idle(void)
{
glutPostRedisplay();
};
/* Key press processing */
void key(unsigned char c, int x, int y)
{
if(c == 27) exit(0);
};
/* Window reashape */
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1, 0, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
};
/*
long putBuffer(long[] buffer)
{
return buffer;
}*/
//Main function
int j =0;
unsigned long size = 400000;
int main(int argc, char* argv[])
{
unsigned char INBUFFER[400000];
char OUTBUFFER[20];
DWORD bytes_read = 0; // Number of bytes read from port
DWORD bytes_written = 0; // Number of bytes written to the port
HANDLE comport = NULL; // Handle COM port
int bStatus;
DCB comSettings; // Contains various port settings
COMMTIMEOUTS CommTimeouts;
strcpy(&OUTBUFFER[0], "The quick brown fox jumped over the lazy dog. \n\r\0");
// Open COM port
if ((comport =
CreateFile("\\\\.\\COM44", // open com5:
GENERIC_READ | GENERIC_WRITE, // for reading and writing
0, // exclusive access
NULL, // no security attributes
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
{
// cout<<"Port can't be opened"<<endl;
}
// Set timeouts in milliseconds
// cout<<"Port opened"<<endl;
//DCB dcb;
CommTimeouts.ReadIntervalTimeout = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 100;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 100;
bStatus = SetCommTimeouts(comport,&CommTimeouts);
if (bStatus != 0)
{
// error processing code goes here
}
// Set Port parameters.
// Make a call to GetCommState() first in order to fill
// the comSettings structure with all the necessary values.
// Then change the ones you want and call SetCommState().
GetCommState(comport, &comSettings);
// memset(&dcb,0,sizeof(dcb));
comSettings.fBinary = 1;
comSettings.fDtrControl = DTR_CONTROL_ENABLE;
comSettings.fRtsControl = RTS_CONTROL_ENABLE;
comSettings.fOutxCtsFlow = 1;
comSettings.fRtsControl = DTR_CONTROL_HANDSHAKE;
comSettings.BaudRate = 921600;
comSettings.StopBits = ONESTOPBIT;
comSettings.ByteSize = 8;
comSettings.Parity = NOPARITY;
comSettings.fParity = FALSE;
bStatus = SetCommState(comport, &comSettings);
ofstream outdata;
outdata.open("hsm.txt"); // opens the file
if( !outdata ) { // file couldn't be opened
cerr << "Error: file could not be opened" << endl;
exit(1);
}
if (bStatus == 0)
{
// error processing code goes here
}
int flag = 1;
int fl =1;
glutInit(&argc, argv);
glutInitWindowSize(500,500);
glutInitWindowPosition(500,200);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
//glutMainLoop();
while(flag<120)
{
bStatus = ReadFile(comport, // Handle
&INBUFFER, // Incoming data
size, // Number of bytes to read
&bytes_read, // Number of bytes read
NULL);
if (bStatus != 0)
{
//cout<<"Error receiving"<<endl;
}
// long samples[100000];
for (int i=0; i<bytes_read; i++)
{
if((unsigned char)INBUFFER[i]==0x99&&(unsigned char)INBUFFER[i+4]==0x99)
{
samples[j] = 0x00|(unsigned char)INBUFFER[i+1]<<8|(unsigned char)INBUFFER[i+2]<<16|(unsigned char)INBUFFER[i+3]<<24;
if(samples[j]!=0)
{
outdata << samples[j] <<"\n";
j++;
}
}
}
flag++;
glutCreateWindow("Graph plotter");
glutDisplayFunc(redraw);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutMainLoop();
}
CloseHandle(comport);
outdata.close();
return 0;
}
Basically when the samples buffer gets updated, the graph should also update. But the graph is plotted in first iteration and then nothing happens. Can anyone tell me how to fix it?
Upvotes: 0
Views: 3604
Reputation: 3592
When you call glutMainLoop, it will draw the screen, handle window events, and call the idle function repeatedly. Since all your idle function does now is to ask for the screen to be redrawn, it will not be reading additional samples from your input serial port.
You should try reading from the serial port and populating additional samples when your idle
function is called.
Upvotes: 1