Problemas com Arduino + C, comunicação serial [Resolvido]

Então, desisti de usar PHP pra pegar os dados da porta serial e agora tô usando C.

O sistema consiste num programa em C que envia um caracter pra porta serial, e quando o Arduino detecta esse caracter, ele envia as leituras analógicas.

Código do Arduino:

#define ANALOG_PIN_0 0
#define ANALOG_PIN_1 1
#define ANALOG_PIN_2 2
#define ANALOG_PIN_3 3
#define ANALOG_PIN_4 4
#define ANALOG_PIN_5 5
#define ANALOG_PIN_6 6
#define ANALOG_PIN_7 7
#define ANALOG_PIN_8 8
#define ANALOG_PIN_9 9

void setup()
{
  Serial.begin(9600);
  pinMode(2, INPUT);
}
void loop()
{
  if (Serial.available() > 0) {
    if (Serial.read() == '1') {
      int n;
      float temp_circ = 0, temp_agua = 0;
      for (n = 0; n < 8; n++) {
        temp_circ = temp_circ + analogRead(ANALOG_PIN_0);
        temp_agua = temp_agua + analogRead(ANALOG_PIN_1);
      }
      temp_circ = temp_circ / 8;
      temp_agua = temp_agua / 8;
      int tensao_motor_1 = analogRead(ANALOG_PIN_2);
      int tensao_motor_2 = analogRead(ANALOG_PIN_3);
      int tensao_motor_3 = analogRead(ANALOG_PIN_4);
      int tensao_bateria = analogRead(ANALOG_PIN_5);
      int corr_motor_1 = analogRead(ANALOG_PIN_6);
      int corr_motor_2 = analogRead(ANALOG_PIN_7);
      int corr_motor_3 = analogRead(ANALOG_PIN_8);
      int umidade = analogRead(ANALOG_PIN_9);
      int inundacao = digitalRead(2);
      Serial.print(temp_circ);
      Serial.print(" ");
      Serial.print(temp_agua);
      Serial.print(" ");
      Serial.print(tensao_motor_1);
      Serial.print(" ");
      Serial.print(tensao_motor_2);
      Serial.print(" ");
      Serial.print(tensao_motor_3);
      Serial.print(" ");
      Serial.print(tensao_bateria);
      Serial.print(" ");
      Serial.print(corr_motor_1);
      Serial.print(" ");
      Serial.print(corr_motor_2);
      Serial.print(" ");
      Serial.print(corr_motor_3);
      Serial.print(" ");
      Serial.print(umidade);
      Serial.print(" ");
      Serial.print(inundacao);
      Serial.println(" ");
    }
  }
}

Código do C:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

const int tamanho = 70;
int main()
{
    int n;
    int valor;
    for (n=1;;n++)
    {
     FILE *porta = fopen("/dev/ttyUSB0", "w+");
     char caracter[1] = "1";
     fwrite(&caracter, sizeof(caracter), 1, porta);
     usleep(1000000);
     char valores[tamanho];
     fgets(valores, tamanho, porta);
     fclose(porta);
     printf("%s", valores);
     FILE *sensores = fopen("sensores.log", "w");
     fputs(valores, sensores);
     fclose(sensores);
     }
}

O problema é que às vezes, quando o programa C recebe os dados, alguns caracteres do início somem, eu quera saber o que causa isso.

Você testou pelo serial monitor e recebeu sempre os dados completos??
Aparentemente você está rodando em linux, no código que postou você não está setado o baund rate do dev\ttyUSB0, tente setar para 9600 antes de rodar seu programa.

Eu sempre usei este site para perceber isso.

http://www.easysw.com/~mike/serial/serial.html

Eu tenho este programinha a rodar em Macosx para sincronizar a hora com um Arduino.

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/select.h>
#include <fcntl.h>


#define INTERVAL	(60*60*12)
#define MINUTE		60
#define TEN_MINUTES	600
#define HALF_HOUR	(60 * 30)
#define ONE_HOUR	3600


int conf_port()
{
	int fd, n; /* File descriptor for the port */
	struct termios iniConfig, myConfig;//serial port
	char myStr[21]; 
	
	fd = open("/dev/cu.usbserial-A400g2JR", O_RDWR | O_NOCTTY | O_NDELAY);
	if (fd == -1)
	{
		printf("Erro ao abrir porta");
		return fd;
	}
	else
		//ioctl(fd, F_SETFL, FNDELAY);//come back after read if no bits present
	
		fcntl(fd, F_SETFL, 0);
//configure port	
	tcgetattr(fd, &iniConfig);
	tcgetattr(fd, &myConfig); 
	
	//set speeds
	cfsetispeed(&myConfig, B19200);
	cfsetospeed(&myConfig, B19200);
	printf("set speeds\n");
	
	//character parity and checking
	myConfig.c_cflag &= ~PARENB;
	myConfig.c_cflag &= ~CSTOPB;
	myConfig.c_cflag &= ~CSIZE;//mask the character size bits
	myConfig.c_cflag |= CS8;//8 data bits
	printf("set char\n");
	
	myConfig.c_cflag &= ~HUPCL;//no DTR going down on last close
	myConfig.c_cflag &= ~CRTSCTS;//no hardware control			
	printf("set DTR off\n");
	
	myConfig.c_lflag = ICANON;//needs an end of line to return anything. :) Yeay
	
	//set everything				
	tcsetattr(fd, TCSANOW, &myConfig);
	printf("apply changes\n");	
	return (fd);
}

int main (int argc, const char * argv[]) {

	time_t then, now;
	struct tm *myTime;
	double time_then=0, time_diff = 0;
	FILE *Log;
	
	int port, n=0;
	char myStr[20];
	
	then = time(NULL);// starting time
	myTime = localtime(&then);// making this a bit more presentable
	
	printf("it's %d:%d:%d\n", myTime->tm_hour, myTime->tm_min, myTime->tm_sec);
	
	//open serial port ?!?!? 
	port = conf_port();
	
	//open log file.
	Log = fopen("TempLog.csv", "w");	
	fprintf(Log, "Living room temperature measurement\n");
	fprintf(Log, "%s \n", asctime(myTime));
		
	n = read(port, myStr, 20);
	
	printf("returned %d bytes - %s\n",n, myStr);
		/*
    while (time_diff <= INTERVAL) {
		now = time(NULL);//time now...
		myTime = localtime(&now);
		time_diff = difftime(now, then);
		if (time_diff-time_then >=60 ) //minuto a minuto
		{
			time_then = time_diff;//so we can come in again.
			//ask for temperature. 
			//wait for reply.
			//print reply to file. :)	
			fprintf(Log, "it's %d,%d,%d\n", myTime->tm_hour, myTime->tm_min, myTime->tm_sec);
		
		//printf("time diff is: %d\n", (int)time_diff);
		}	
	}*/
	fclose(Log);//tidy up... 	
	close(port);

    return 0;
}

E aparentemente fazer um log da temperatura. Mas deve dar-te uma ideia de como fazer o teu programa para rodar em Linux (ambos os programas assentam em POSIX, logo deve compilar sem erros).

Era a baud rate mesmo... Inseri as seguintes linhas no código e até agora não deu problema.

int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(fd, TCSANOW, &options);

Que bom que funcionou, será que você consegue mudar o titulo para algo do tipo "Problemas com Arduino + C, comunicação serial (resolvido)", assim, alguém que for procurar, vai achar mais fácil.

Valeu.