0

I took temperature data from the Arduino serial port. Temperature data coming out of the Arduino serial monitor are:

21.48
21.97
21.48
21.00
21.97
21.97

By using the C program to read the serial port as below code:

char TempChar;
DWORD NoBytesRead;
do{
    ReadFile(hComm,&TempChar,sizeof(TempChar),&NoBytesRead,NULL);
    printf("%c",TempChar);                            }
while(!kbhit());

Then it will appear like this.

21.48
21.97
21.48
21.00
21.97
21.97

Now I want to add and display hours, minutes and seconds using the c program like the code below:

char TempChar;
DWORD NoBytesRead;

SYSTEMTIME str_t;
GetSystemTime(&str_t);

do{
   ReadFile(hComm,&TempChar,sizeof(TempChar),&NoBytesRead,NULL);
    printf("%c, %d:%d:%d ",TempChar,str_t.wHour+7,str_t.wMinute,str_t.wSecond);
 }while(!kbhit());

but the result is like this :

, 18:9:38  1, 18:9:38 ., 18:9:38 ., 18:9:38 0, 18:9:38 0, 18:9:38
, 18:9:38 2, 18:9:38 1, 18:9:38 ., 18:9:38 0, 18:9:38 0, 18:9:38
, 18:9:38 2, 18:9:38 1, 18:9:38 ., 18:9:38 0, 18:9:38 0, 18:9:38

I actually want the result is

21.48,18:9:38
21.97,18:9:38
21.48,18:9:38
21.00,18:9:38
21.97,18:9:38
21.97,18:9:38

What should I fix from the C language program code?

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
Zacknov
  • 21
  • 8

3 Answers3

2

You are reading temperature data character by character. So you need to detect, within this character stream, where the bounds of each data packet are. Obviously, there are line breaking characters contained, so you need to detect them:

if(tempChar == '\n')
{
    // print separator and date/time
}
printf("%c", TempChar)

Depends now which line separator is used, above works with \n, if you have \r\n or only \r you'll need to adjust...

Seems as if there's a leading line break in your data, so you might need special handling for very first line break.

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
  • Thank you for the advice, and I have tried with the code is `if(TempChar=='\r'){ printf(",%d:%d:%d ",str_t.wHour+7,str_t.wMinute,str_t.wSecond); } printf("%c",TempChar);` and the output is | 28.,19:23:36 | | 28.32,19:23:36 | | 28.32,19:23:36 | | 28.32,19:23:36 | | 28.32,19:23:36 | | 28.32,19:23:36 | | 28.32,19:23:36 | – Zacknov Nov 11 '19 at 14:22
  • What do I do if I want to save in a file with the fprintf syntax? – Zacknov Nov 12 '19 at 01:59
  • @Zacknov That wouldn't differ – solely that you'd provide an additional file parameter: `FILE* file = fopen("path/to/file/", "w"); fprintf(file, "%c", tmpChar);` – you'd need to check the file parameter (is NULL, if opening the file fails), or maybe you rather want to append instead of overwrite (then use `"a"` as second parameter). – Aconcagua Nov 12 '19 at 08:51
  • I think is how to combine hours, minutes, seconds with data from the serial. Data hours, minutes, seconds can be made in 1 variable, then what about the serial data that comes out per character and save in a file? – Zacknov Nov 13 '19 at 01:28
  • @Zacknov Can't really follow. Do you want to store the same output you printed to console in a file? Then you can go on as before, write character by character to file and on receiving `\r`, you append time information, just as you did before. Or do you want to actually *work* with the data received, e. g. calculate an average over some duration? – Aconcagua Nov 13 '19 at 08:33
  • I want to store the output my printed to console in a file, like this 28.32,19:23:36. Only store, no calculate, – Zacknov Nov 13 '19 at 10:49
  • @Zacknov Then back at my original comment, just replace your calls to `printf` with those to `fprintf` and don't forget the additional parameter... – Aconcagua Nov 13 '19 at 15:10
  • Finally successfully write in the file by following your instructions and suggestions. It's been 2 days of try and error to be able to save in a file. The next step I will try to input the data into MySQL. – Zacknov Nov 13 '19 at 16:07
  • @Zacknov In databases don't store numeric data as strings, use the types provided. I personally would prefer integral data types, storing 100th of degrees (you can add in the decimal point later when printing again). Additionally, there should be some appropriate timestamp type. Should even be possible to [let database determine the timestamp automatically](https://stackoverflow.com/questions/4411311/getting-timestamp-using-mysql). That way, you'd need to calculate date/time into the format you desire later, but that's not too much of an issue... – Aconcagua Nov 13 '19 at 17:04
  • Yes, changing the TempChar temperature data from from arduino in the string to float to match the mysql data type has not been successful. – Zacknov Nov 14 '19 at 06:38
  • @Zacknov Do you have a fix number of decimals (looks so at least) – if so, write all digits into a character array of sufficent length (I'd assume 8 or 16 characters always should be enough). Skip the decimal point. If number of digits after decimal point is variable, then when passing it, start counting digits and append zeros if you didn't get enough digits. Then convert to number, e. g. using `strtoul` – and you have already a nice number to store, depending on the number of decimal places in 10th, 100th or 1000th of degrees (I'd assume you'd use 100th of). – Aconcagua Nov 14 '19 at 12:16
  • Fixed point numbers (e. g. 100ths of degrees) usually are superior to floating point numbers, provided you do not need variable precision. The floating point data types cannot represent precisely even such simple numbers like 0.1 (periodic in binary...). – Aconcagua Nov 14 '19 at 12:19
1

So the Arduino sends a newline? Then collect the characters you read into a string and display (with time) when you have read the newline.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • .Thank you. My arduino program code is `float temperature; int a=0; void setup() { Serial.begin(9600); } void loop() { temperature=analogRead(a); temperature=temperature*(5.0*100.0/1024.0); Serial.println(temperature); delay(1000); } ` – Zacknov Nov 11 '19 at 14:32
1

This error is coming because of how you have written the print statement.

printf("%c, %d:%d:%d ",TempChar,str_t.wHour+7,str_t.wMinute,str_t.wSecond);

So, Here TempChar stores the current character value which is printing at every character of your temp data. Hence first print all your temp data and then print the date.

do{
   ReadFile(hComm,&TempChar,sizeof(TempChar),&NoBytesRead,NULL);
   if(TempChar!='\n'){printf("%c",TempChar);}
   else{
        printf(", %d:%d:%d \n",str_t.wHour+7,str_t.wMinute,str_t.wSecond);}
}while(!kbhit());
em_bis_me
  • 388
  • 1
  • 8
  • Thank you. I have tried the code you gave, the temperature data did not appear and the results were: | , 19:43:25 | | , 19:43:25 | | , 19:43:25 | | , 19:43:25 | | , 19:43:25 | | , 19:43:25 | | , 19:43:25 | – Zacknov Nov 11 '19 at 14:35
  • Check for the line breaks properly once. The code snippet I have provided is according to my understanding of the data. The idea though remains what I proposed - " First print the temperature data and as soon as you reach the end of it, print the current time". You might have to modify the code according to the data. – em_bis_me Nov 12 '19 at 04:21
  • It has been successful, apparently by replacing TempChar!='\n' with TempChar!='\r' – Zacknov Nov 13 '19 at 16:11
  • Ohkay! Cool. If the answer helped you to solve the problem, you can accept it. – em_bis_me Nov 13 '19 at 16:15