I have this code for a comunication between pc-arduino with xbee. The problem is that when I execute this, the program seems to be freezed and doesn't receive nothing from arduino, I don't know why is this happening, but one time the program was showing in the 'terminal' the message that I want to show to see if the communication is happening: 'line:....' But now isn't communicating.
Are any errors in the code, or why is this happening?
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <termios.h> // POSIX terminal control definitions
#include <math.h>
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
double average(int data[],int elem);
double desviation(double m, int data[],int elem);
void normalize(double data[],int elem);
void store(double data[],int ex);
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
struct termios options;
int data[262142];
int tty_fd = open(XBEE , O_RDWR | O_NOCTTY | O_NDELAY);
again:
cfsetospeed(&tio,BAUDRATE);
cfsetispeed(&tio,BAUDRATE); // baudrate is declarated above
tcsetattr(tty_fd,TCSANOW,&tio);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// write(tty_fd,&c,'1');
char o='o';
char a='a';
FILE *f;
char line[100];
f = fopen("/dev/ttyUSB0", "r+");
while(line[0]!='o'){
fgets(line,10,f);
printf("line: %s\n",line);
}
while(line[0]=='o'){
fputc(a,f);
fgets(line,10,f);
printf("line: %s\n",line);
}
int count=0;
int pos=0;
//----------------------
while(1){
printf("dentro: %c\n",line[0]);
int num;
char number[3];
if(line[0]!=' '){
number[count]=line[0];
if(count>3){
count=0;
}
else{
count=count+1;
}
}
if(line[0]==' '){
count=0;
sscanf(number,"%d",&num);
printf("%d\n",num);
data[pos]=num;
}
if(line[0]=='\n'){
printf("\n\nAll the data have been received");
double av=average(data,262142);
double desv=desviation(av,data,262142);
double data2[262142];
int i;
for (i = 0; i < num; i++)
{
data2[i]=(data[i]-av)/desv;
}
normalize(data2,262142);
char ex;
int aux;
printf("It was steps? y/n\n");
scanf ("%c",&ex);
if(ex=='y'){
aux=1;
}
else{
aux=0;
}
store(data2,aux);
fputc(o,f);
line[0]='0';
while(line[0]!='o'){
fgets(line,10,f);
}
break;
}
write(tty_fd,&o,1);
line[0]='0';
while(line[0]!='o'){
fgets(line,10,f);
}
line[0]='x';
while(line[0]=='x'){
fgets(line,10,f);
}
}
goto again;
close(tty_fd);
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
return EXIT_SUCCESS;
}
postdata: I can't use the API mode, need to do this on c.
Update
I have done all you have said to me. Still not working, the debugger is stuck in the first fgets (line 30).
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <termios.h> // POSIX terminal control definitions
#include <math.h>
#define XBEE "/dev/ttyUSB0"
#define BAUDRATE B9600
double average(int data[],int elem);
double desviation(double m, int data[],int elem);
void normalize(double data[],int elem);
void store(double data[],int ex);
int main(int argc,char** argv)
{
int data[262142];
char o='o';
char a='a';
char line[100];
FILE *f;
again:
f = fopen("/dev/ttyUSB0", "r+");
if (f == NULL) {
printf("Error opening the port\n");
}
while(line[0]!='o'){
fgets(line,10,f);
printf("line: %s\n",line);
}
while(line[0]=='o'){
fputc(a,f);
fgets(line,10,f);
printf("line: %s\n",line);
}
int count=0;
int pos=0;
//----------------------
while(1){
printf("dentro: %c\n",line[0]);
int num;
char number[3];
if(line[0]!=' '){
number[count]=line[0];
if(count>3){
count=0;
}
else{
count=count+1;
}
}
if(line[0]==' '){
count=0;
sscanf(number,"%d",&num);
printf("%d\n",num);
data[pos]=num;
}
if(line[0]=='\n'){
printf("\n\nAll the data have been received");
double av=average(data,262142);
double desv=desviation(av,data,262142);
double data2[262142];
int i;
for (i = 0; i < num; i++)
{
data2[i]=(data[i]-av)/desv;
}
normalize(data2,262142);
char ex;
int aux;
printf("It was steps? y/n\n");
scanf ("%c",&ex);
if(ex=='y'){
aux=1;
}
else{
aux=0;
}
store(data2,aux);
fputc(o,f);
line[0]='0';
while(line[0]!='o'){
fgets(line,10,f);
}
break;
}
fputc(o,f);
line[0]='0';
while(line[0]!='o'){
fgets(line,10,f);
}
line[0]='x';
while(line[0]=='x'){
fgets(line,10,f);
}
}
goto again;
fclose(f);
return EXIT_SUCCESS;
}
double average(int data[],int elem){
int i=0;
int sum=0;
for (i = 0; i < elem; i++){
sum+=data[i];
}
return sum/elem;
}
double desviation(double m, int data[],int elem){
int i=0;
int j=0;
double dif=0.0;
for (i = 0; i < elem; i++){
dif=pow(data[i]-m,2);
}
return sqrt(dif/(18000-1));
}
void normalize(double data[],int elem){
int i,j;
double biggest;
double lowest;
double aux;
biggest = 0.0;
lowest = 9999999999999999.999;
for (i = 0; i < elem; i++){
if(data[i]>biggest){
biggest=data[i];
}
if(data[i]<lowest){
lowest=data[i];
}
}
if (abs(biggest)>abs(lowest)){
aux=abs(biggest);}
else{
aux=abs(lowest);}
for (i = 0; i < elem; i++){
data[i]=data[i]/aux;
}
}
void store(double data[],int ex){
FILE *out;
out=fopen("training.data","r");
char line[262142];
fgets(line,262142,out);
char *values;
values=strtok(line," ");
int val;
sscanf(&values[0],"%d",&val);
FILE *out2;
out2=fopen("trainingAux.data","w");
fprintf(out2,"%d 262142 1\n",val+1);
while(fgets(line,262142,out)!=NULL){
fprintf(out2,"%s",line);
}
int i = 0;
for(i;i<262141;i++){
fprintf(out2,"%lf ", data[i]);
}
fprintf(out2,"%lf\n", data[i+1]);
fprintf(out2,"%d\n",ex);
fclose(out2);
fclose(out);
out=fopen("training.data","w");
out2=fopen("trainingAux.data","r");
while(fgets(line,262142,out2)!=NULL){
fprintf(out,"%s",line);
}
fclose(out);
fclose(out2);
}
There are some ways to figure out what's happening when communicating via serial. First of all, why are you using 'fopen' right after using 'open' to the same path (/dev/ttyUSB0)? When you use a handle to estabilish communication like 'tty_fd' you have to be sure that this handle was created sucessfully, you can try:
if ( (tty_fd = open(XBEE , O_RDWR | O_NOCTTY | O_NDELAY)) == -1 ){ IfTraceAvaliable("Error while opening"); return -1; }
In addition, you may be trying to set some attributes on termios struct, like:
options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8;
But after it, you aren't applying it to your connection, like:
ioctl(tty_fd, TCSETA, &options);
Remember you can also test ioctl == 0, if its not equal, than it means you couldn't set it properly.
[Edit] Since you're using open(), you can use read() function to retrieve the answer from arduino, instead of using fgets or fread, that can be an alternative.