c++ seri port kullanımı yardım...

Başlatan screammm11, 24 Ekim 2011, 21:20:14

screammm11

Arkadaşlar merhabalar,

c biliyorum ancak c++ ile ilgili çok bilgim yok... c++ ile bir haptik kütüphanesini kullanmam ve seri portu kullanarak veri iletişimi sağlamam gerekiyor...

Yaptığımı sanıyordum, yani tek yönlü iletişimde sıkıntı yok ancak çift yönlü haberleşmeyi kontrol ettiğimde veri alımında 3-5 sn'lik geciklemeler yaşıyorum...

Nedenini anlayamadım...  14byte'lık bir veri gönderiyor ve 10 byte'lık veri okuyorum... Thread mi kullanmam gerekiyor? Çeşitli denemeler yaptım ancak başarılı olamadım... Örneğin, microsofta verilen serial port programming in win32 ve codegrue'daki serial class uygulamalırını denedim....

Aşağıda yazdığım kod parçası görülmektedir...

/*****************************************************************************


*******************************************************************************/
// Kütüphaneler..........


# include <stdio.h>
# include <stdlib.h>
# include <assert.h>
# include <windows.h>
# include <conio.h>
#include <tchar.h>








#include <HD/hd.h>
#include <HDU/hduError.h>
#include <HDU/hduVector.h>

/*******************************************************************************/
/* Tanımlamalar */


/*******************************************************************************/
/* Değişkenler */
HDdouble force[3] = {0.0, 0.0, 0.0};
unsigned char pos[8];
unsigned char seriforce[8];
HDdouble position[3];
HDdouble poss[3];
char seribul=0;
char inx=0;
/*******************************************************************************/
// fonksiyonlar..



/*******************************************************************************/
// Schedular işlemleri......

HDSchedulerHandle gCallbackHandle = HD_INVALID_HANDLE;

HDCallbackCode HDCALLBACK ServoSchedulerCallback(void *pUserData)
{
    HDErrorInfo error;

    hdBeginFrame(hdGetCurrentDevice());    
		hdSetDoublev(HD_CURRENT_FORCE,force);
		hdGetDoublev(HD_CURRENT_POSITION,position);
    hdEndFrame(hdGetCurrentDevice());

    if (HD_DEVICE_ERROR(error = hdGetError()))
    {
        hduPrintError(stderr, &error, "Error while commanding DAC values");
        
        if (hduIsSchedulerError(&error))
        {
            return HD_CALLBACK_DONE;
        }
    }

    return HD_CALLBACK_CONTINUE;
}

/*HDCallbackCode HDCALLBACK GetDeviceStateCallback(void *pUserData)
{
    DeviceStateStruct *pState = (DeviceStateStruct *) pUserData;

    hdGetDoublev(HD_CURRENT_POSITION, pState->position);

    return HD_CALLBACK_DONE;
}

/*******************************************************************************/
/*
void PrintDeviceState(HDboolean bContinuous)
{
    int i;
    DeviceStateStruct state;

    memset(&state, 0, sizeof(DeviceStateStruct));

    do
    {
        hdScheduleSynchronous(GetDeviceStateCallback, &state,
            HD_DEFAULT_SCHEDULER_PRIORITY);

        printf("\n");

        printf("Position:");
        for (i = 0; i < 3; i++)
        {
            printf(" %f", state.position[i]);
        }
        printf("\n");

        if (bContinuous)
        {
            Sleep(50);
        }

    } while (!_kbhit() && bContinuous);
}

/*******************************************************************************
 Main function.
*******************************************************************************/
int main(int argc, char* argv[])
{  
    // seri port

TCHAR* currentuser = L"COM1";
		LPCWSTR *lstr = (LPCWSTR *)(&currentuser);

	// open port for I/O
	HANDLE h = CreateFile(*lstr,
	GENERIC_READ|GENERIC_WRITE,
	0,NULL,
	OPEN_EXISTING,0,NULL);

	if(h == INVALID_HANDLE_VALUE) 
		{
		printf("E012_Failed to open port\n");
		} 
	else 
	printf("*Port opened succesfully\n");

	COMMTIMEOUTS cto = { 1, 100, 1000, 0, 0 };
	
	if(!SetCommTimeouts(h,&cto))
	printf("E013_SetCommTimeouts failed");


	DCB dcb;
	DWORD write = 8; // Number of bytes to write to serial port
	DWORD read = 8;


	// set DCB
	memset(&dcb,0,sizeof(dcb));
	dcb.DCBlength = sizeof(dcb);
	dcb.BaudRate = 19200;
	dcb.fBinary = 1;
	dcb.fDtrControl = DTR_CONTROL_ENABLE;
	dcb.fRtsControl = RTS_CONTROL_ENABLE;
	// dcb.fOutxCtsFlow = 1;
	// dcb.fRtsControl = DTR_CONTROL_HANDSHAKE;

	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;
	dcb.ByteSize = 8;

	if(!SetCommState(h,&dcb))
	printf("E014_SetCommState failed");
	

	HDErrorInfo error;
    HDstring model;
    HDboolean bDone = FALSE;


// Initialize Haptic Device

    HHD hHD = hdInitDevice(HD_DEFAULT_DEVICE);
    if (HD_DEVICE_ERROR(error = hdGetError()))
    {
        hduPrintError(stderr, &error, "Failed to initialize haptic device");
        fprintf(stderr, "\nPress any key to quit.\n");
        getch();

        return -1;
    }

    model = hdGetString(HD_DEVICE_MODEL_TYPE);
    printf("Initialized: %s\n", model);

    
   // hdGetIntegerv(HD_INPUT_DOF, &gNumEncoders);

   
    /* Schedule the haptic callback function for continuously monitoring the
       button state and rendering the anchored spring force */
    gCallbackHandle = hdScheduleAsynchronous(
        ServoSchedulerCallback, 0, HD_MAX_SCHEDULER_PRIORITY);
    if (HD_DEVICE_ERROR(error = hdGetError()))
    {
        hduPrintError(stderr, &error, "Failed to schedule servoloop callback");
        fprintf(stderr, "\nPress any key to quit.\n");
        getch();

        hdDisableDevice(hHD);
        return -1;
    }

    hdEnable(HD_FORCE_OUTPUT);

    /* Start the haptic rendering loop */
    hdStartScheduler();
    if (HD_DEVICE_ERROR(error = hdGetError()))
    {
        hduPrintError(stderr, &error, "Failed to start servoloop");
        fprintf(stderr, "\nPress any key to quit.\n");
        getch();

        hdDisableDevice(hHD);
        return -1;        
    }

    
    /* Start the main application loop */
    while (!kbhit())
	{
		pos[0]=0xff;
		pos[1]=0xff;
		pos[2]=floor((position[0]+225)*70/256);
		pos[3]=floor((position[0]+225)*70-pos[0]*256);
		pos[4]=floor((position[1]+225)*70/256);
		pos[5]=floor((position[1]+225)*70-pos[0]*256);
		pos[6]=floor((position[2]+225)*70/256);
		pos[7]=floor((position[2]+225)*70-pos[0]*256);

			WriteFile(h,pos,write,&write,NULL); // write is updated with the number of bytes written

			printf("%f , %f , %f\n",position[0],position[1],position[2]);
			
//Sleep(50);
			ReadFile(h,seriforce,8,&read,NULL);

			if (seribul==0 && inx==2)
			{
					for (inx=0;inx<7;inx++)
					{
						if(seriforce[inx]==255)// && seriforce[inx+1]==255)
							break;
					}
					printf("%u\n",inx);
					seribul=1;
					ReadFile(h,seriforce,inx,&read,NULL);
			}
			inx++;
			//printf("%x , %x , %x, %x , %x , %x\n",seriforce[0],seriforce[1],seriforce[2],seriforce[3],seriforce[4],seriforce[5],seriforce[6],seriforce[7]);

			
			if (seriforce[0]==255 && seriforce[1]==255)
			{
				//printf("asd\n");
				poss[0]= ((double) seriforce[2]*256+seriforce[3])/70-225;
				poss[1]=((double) seriforce[4]*256+seriforce[5])/70-225;
				poss[2]=((double) seriforce[6]*256+seriforce[7])/70-225;
			}
			
			printf("%f , %f , %f\n",poss[0],poss[1],poss[2]);

			printf("----------------------------------------------------------\n");
			//Sleep(200);
			
	}


    hdStopScheduler();
    hdUnschedule(gCallbackHandle);
    hdDisableDevice(hHD);
	CloseHandle(h);

    return 0;
}



/*****************************************************************************/

ern

#1
POSIX tabanlı bir kütüphane kullanmak, size uygun olursa LibSerial'i kullanabilirsiniz.
http://libserial.sourceforge.net/

Tagli

ern, şimdi merak edip baktım, libserial'ın Windows desteği yok gibi gözüküyor. Şöyle yazmışlar:
Alıntı YapLibSerial has received most extensive testing under Linux operating system. It is currently being tested on Mac OS X and version 0.6.0 will support Mac OS X operating system. There are no plans to port this library to Microsoft Windows operating system at this point (including the use of Cygwin).

Ama bilgilendirme için teşekkürler. Özellikle Java bağlantısı ilgimi çekti.

Bu arada, Linux kullanıldığı zaman, ek bir kütüphane olmadan da seri porta erişmek kısmen kolay sayılır. Forumda bir örneğini paylaşmıştım.
Gökçe Tağlıoğlu