You are using "void main" - Have you seen Salem's avatar? Change it to "int main" and return 0 at the end.
You are using "void main" - Have you seen Salem's avatar? Change it to "int main" and return 0 at the end.
Fact - Beethoven wrote his first symphony in C
Where are you clearing your buffer? I'm not talking about your character buffer, I'm talking about the "hardware" buffer. You do know that both the operating system and the hardware usually buffer this port, right? To clear these buffers after you initialize the port you call tcflush().The way i clear my buffer, is that a good way?
Code:tcflush(fd, TCIOFUSH); // Clear both the input and output buffers.What's new to comment about? You haven't changed anything. You're still not checking if read() actually read anything. Please note this quote from this tutorial: Serial Programming Guide for Linuxcomment on my code below:
Reading Data from the Port
Reading data from a port is a little trickier. When you operate the port in raw data mode, each read(2) system call will return the number of characters that are actually available in the serial input buffers. If no characters are available, the call will block (wait) until characters come in, an interval timer expires, or an error occurs. The read function can be made to return immediately by doing the following:
fcntl(fd, F_SETFL, FNDELAY);
The FNDELAY option causes the read function to return 0 if no characters are available on the port. To restore normal (blocking) behavior, call fcntl() without the FNDELAY option:
fcntl(fd, F_SETFL, 0);
What is this supposed to mean? You'll need to provide much more information. Does your external hardware have a method of outputting a predetermined string so you can check the communications? Can you tell us what type of hardware your trying to interface to? The manufacturer, and if the board is mass produced the model and part number of the device you're using?Changed it already but still the output data i get sometimes correct and sometimes not correct. hmm.
Jim
Hello jim, the problem seems to be solved already. I did the input and output clear buffer and its settled. Now i have another problem, below is my code to print the output from the device into a text file:
Problem is the result i get is below:Code:fp = fopen("results_eigenvalue.txt", "w"); /*open and write into existing file*/ for(i=0;i<207;i++) { result = read(mainfd, &chout, sizeof(chout)); /* Read character from ABU (Auto buffering Unit) */ if ( result == -1 ) { perror("error: read"); } if ( i >= 8){ fprintf(fp,"%02x ",chout); } }
f5 23 00 c4 00 00 e7 f5 f5 00 00 00 29 (for example)
What i need is some thing like below:
\xf5\x23\xc4\x00\x00\xe7\xf5\xf5\x00\x00\x00\x29
==> I tried to do this "fprintf(fp,"\x%02x ",chout);", but i get this error below:
error: \x used with no following hex digits
Any suggestion?
The '\' is considered a special character, called the escape character. To print this special character you must use the escape character to tell the compiler you mean the character '\' not this special character so you need to use two '\' characters to print this character "\\".
Jim
Where did I say anything like that. You need to re-read my last post. You need to escape this escape character.So basically i cant have this kind of output? \xf5\x23\xc4\x00\x00\xe7\xf5\xf5\x00\x00\x00\x29?
Jim
Hello Jim, now i have a big problem, hope you'll bear with me to solve this.
1.) i'm sending hex command to my device/port like the code below:
2.) Above example is a hex command which have length of 8byte. The problem now is i have a .txt file which content below data:Code:result2 = write(mainfd,"\xF5\x23\x00\x00\x00\x00\x23\xF5",8); if ( result2 == -1 ) { perror("error: write"); } if ( result2 != 8 ) { fprintf(stderr,"error in write, result = %d\n", result2); }
\xf5\x00\x00\x00\x17\x0a\x16\x01\x61\x0e\x1d\x1a\x 01\x16\x95\x00\xc1\x1f\x26\x44\xa1\x1f\x88\x95\xe1 \x24\x1f\xda\x41\x26\x92\x00\x01\x35\x90\x00\x81\x 43\x22\x44\x21\x53\x16\x01\x61\x57\xa2\x44\x81\x65 \x92\xab\x01\x69\x89\xa6\xa1\x79\x29\xc8\x01\x7d\x 2c\x09\x01\x7e\x8e\x22\xe1\x82\xa5\x47\x21\x84\xab \x02\x01\x8a\xac\x2b\x21\x09\x1c\x03\x82\x2b\x8f\x 97\x82\x2e\x1a\x59\xc2\x6e\x95\x40\x02\x01\x00\x00 \x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\xf5 <==(207 byte data)
==>In the same c file where i need to send the hex command, i called the above data and put it into an array. The problem now is i need to combine the data in that particular array with the hex command which i gave in (1) before i send it to the port. How can i do that? Below is my current code which have error:
p/s: just ignore any unuseful function in the code. abit mess.Code:/* Include files */ #include<stdio.h> #include<string.h> #include <stdlib.h> //------------------------------------------------------------// #include <unistd.h> /* UNIX standard function definitions */ #include <fcntl.h> /* File control definitions */ #include <errno.h> /* Error number definitions */ #include <termios.h> /* POSIX terminal control definitions */ //------------------------------------------------------------// #define VIN_FILE 2 /* Constants to define position in file */ #define BEGIN 0 #define CURRENT 1 #define VIN_RECLEN 30 FILE *fpVin; /* Function declarations */ int fnOpenFile ( int iFile ); int fnReadFile ( char acLine[], int iFile, int ipos); int fnReadFile ( char acLine[], int iFile, int ipos) { if( iFile==VIN_FILE) { if (ipos == BEGIN) { if (fseek(fpVin, 0L, SEEK_SET)) { return 1; } } if ( NULL == fgets (acLine, VIN_RECLEN, fpVin) ) { return 1; } } return 0; } int fnOpenFile ( int iFile ) { char acFileName[20]; if(iFile==VIN_FILE) { strcpy (acFileName, "eigen_from_database.txt"); fpVin = fopen(acFileName, "r+"); if (NULL == fpVin) { return 1; } } return 0; } int open_port(void) { int fd; /* File descriptor for the port */ fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { /* Could not open the port */ fprintf(stderr, "open_port: Unable to open /dev/ttyUSB0 - %s\n", strerror(errno)); } return (fd); } int main() { int iRet,count, int_1, int_2, mainfd=0, i; /*data row*/ char acVinRecord[900], cnt, result2, temp_final[800]; unsigned char result,chout; struct termios options; FILE *fp; //===========================Open port and set configuration=========================================// mainfd = open_port(); fcntl(mainfd, F_SETFL, FNDELAY); /* Configure port reading */ /* Get the current options for the port */ tcgetattr(mainfd, &options); cfsetispeed(&options, B19200); /* Set the baud rates to 19200 */ cfsetospeed(&options, B19200); /* Enable the receiver and set local mode */ options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; /* Mask the character size to 8 bits, no parity */ options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; /* Select 8 data bits */ options.c_cflag &= ~CRTSCTS; /* Disable hardware flow control */ /* Enable data to be processed as raw input */ options.c_lflag &= ~(ICANON | ECHO | ISIG); /* Set the new options for the port */ //============Take the 207 byte data and put it in an array (temp_string)============================// /* Open the Policy file to start with */ iRet = fnOpenFile (VIN_FILE); /* Unable to open file results ? */ if (iRet != 0) { printf ("\t\t\tERROR: Unable to open the file results\n"); exit (1); } /* Read the first record */ iRet = fnReadFile (acVinRecord, VIN_FILE, BEGIN); count=0; /* Read further till the last record */ while (0 == iRet) { count=count+1; int_1 = 0; int_2= 0; switch (count) { case 1: for (int_1=0, int_2=0; int_1<29,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 2: for (int_1=29, int_2=0; int_1<58,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } //temp_final[58]= '\0'; break; case 3: for (int_1=58, int_2=0; int_1<87,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 4: for (int_1=87, int_2=0; int_1<116,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 5: for (int_1=116, int_2=0; int_1<145,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 6: for (int_1=145, int_2=0; int_1<174,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 7: for (int_1=174, int_2=0; int_1<203,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 8: for (int_1=203, int_2=0; int_1<232,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 9: for (int_1=232, int_2=0; int_1<261,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 10: for (int_1=261, int_2=0; int_1<290,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 11: for (int_1=290, int_2=0; int_1<319,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 12: for (int_1=319, int_2=0; int_1<348,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 13: for (int_1=348, int_2=0; int_1<377,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 14: for (int_1=377, int_2=0; int_1<406,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 15: for (int_1=406, int_2=0; int_1<435,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 16: for (int_1=435, int_2=0; int_1<464,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 17: for (int_1=464, int_2=0; int_1<493,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 18: for (int_1=493, int_2=0; int_1<522,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 19: for (int_1=522, int_2=0; int_1<551,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 20: for (int_1=551, int_2=0; int_1<580,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 21: for (int_1=580, int_2=0; int_1<609,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 22: for (int_1=609, int_2=0; int_1<638,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 23: for (int_1=638, int_2=0; int_1<667,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 24: for (int_1=667, int_2=0; int_1<696,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 25: for (int_1=696, int_2=0; int_1<725,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 26: for (int_1=725, int_2=0; int_1<754,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 27: for (int_1=754, int_2=0; int_1<783,int_2<29;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } break; case 28: for (int_1=783, int_2=0; int_1<797,int_2<14;int_1++,int_2++) { temp_final[int_1] = acVinRecord[int_2]; } temp_final[797]= '\0'; break; } iRet = fnReadFile (acVinRecord, VIN_FILE, CURRENT); } printf("%s\n",temp_final); //====This is where i need to combine data in array with the existing hex command==========// tcsetattr(mainfd, TCSANOW, &options); tcflush(mainfd, TCIOFLUSH); // Clear both the input and output buffers. result2 = write(mainfd,"\xF5\x41\x00\x00\x00\x00\x41\xF5\xF5\x00\x01\x01\\%s\",211,temp_final); if ( result2 == -1 ) { perror("error: write"); } if ( result2 != 8 ) { fprintf(stderr,"error in write, result = %d\n", result2); } close(mainfd); /* Close the serial port */ //==========================================================================================// }
Last edited by Marvin Gorres; 04-18-2013 at 02:17 PM.
I really don't understand your problem. But I do see a couple of problems:
In the above snippet you have an out of bounds array access. You allocated 20 bytes to your array, how many characters are in that string constant? Why are you even doing the strcpy()? Why not just use the string constant for the fopen parameter?Code:char acFileName[20]; if(iFile==VIN_FILE) { strcpy (acFileName, "eigen_from_database.txt"); fpVin = fopen(acFileName, "r+");
Next: What's with all the case statements?
Are you sure your reading your file correctly? Have you printed out the values of that array to insure it is correct?
Please post the exact contents of your input file.
Jim
Yes Jim, i printed out the correct data from the .txt file. The problem is how to combine the hex data in array(temp_final) with the existing hex data in here ==> "result2 = write(mainfd,"\xF5\x23\x00\x00\x00\x00\x23\xF5",8) ;"
I've posted the content of the input file #69
Last edited by Marvin Gorres; 04-18-2013 at 11:23 PM.
> 2.) Above example is a hex command which have length of 8byte. The problem now is i have a .txt file which content below data:
> \xf5\x00\x00\x00\x17\x0a
When you're writing bytes using \xnn in C code, then the compiler is responsible for stripping off the \x and interpreting nn as a single byte.
When you're reading from a file, it's your responsibility to read 4 chars, strip off the \x and assign the conversion of "nn" to nn.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
I can read the file exactly as it is in .txt file n it looks like this:
\xf5\x00\x00\x00\x17\x0a\x16\x01\x61\x0e\x1d\x1a\x 01\x16\x95\x00\xc1\x1f\x26\x44\xa1\x1f\x88\x95\xe1 \x24\x1f\xda\x41\x26\x92\x00\x01\x35\x90\x00\x81\x 43\x22\x44\x21\x53\x16\x01\x61\x57\xa2\x44\x81\x65 \x92\xab\x01\x69\x89\xa6\xa1\x79\x29\xc8\x01\x7d\x 2c\x09\x01\x7e\x8e\x22\xe1\x82\xa5\x47\x21\x84\xab \x02\x01\x8a\xac\x2b\x21\x09\x1c\x03\x82\x2b\x8f\x 97\x82\x2e\x1a\x59\xc2\x6e\x95\x40\x02\x01\x00\x00 \x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\xf5 <==(207 byte data)
So, in order to send the hex command using this:
result2 = write(mainfd,"\xF5\x23\x00\x00\x00\x00\x23\xF5",8) ;
The problem is how do i insert the data i read into the coding above??
To make a quick understanding, i have one example:
The code above explained that there's a two array which both have been assigned a string content, and then combine it using strcat. After that i tried to write to the port but failed, because what i'm writing to the port is STRING, it required HEX. That's the problem. the data need to be sent is correct but it's in string format.Code:char get[1000] = {"\\xF5\\x01\\x00\\x00"}, get_2[1000] = {"\\x00\\x00\\x01\\xF5"}; strcat(get,get_2); printf("%s",get); //output is \xf5\x01\x00\x00\x00\x00\x01\xf5 (string) result2 = write(mainfd,get,8);
Your program will only send the first 8 characters of that string and this isCode:result2 = write(mainfd,get,8);
\xF5\x00
you need to find a way to convert the string \xF5\x01\x00\x00\x00\x00\x01\xF5
into an array of unsigned characters that contains
And note. there isn't anything like hex data. There exists only hex representation of dataCode:unsigned char buff[] = { 245, 1, 0, 0, 0, 0, 1, 245 };
Kurt
Last edited by ZuK; 04-19-2013 at 02:33 AM.