Módulo GPS + microSD + DHT11 + Sensor barométrico

Buenas,
Imlementé un código para mi Arduino MEGA2560 en el que incluyo un módulo GPS con un sensor de temperatura y otro barómetrico, los valores que me devuelven quiero que me los grabe en una tarjeta microSD. El problema es que no me devuelve los datos del GPS y además imprime varias veces los mismos datos. La relación de componentes es la siguiente:
-Temperatura DHT11
-Sensor barométrico BMP085
-Módulo microSD
-GPS

El código es el siguiente:

#define DEBUG 1 //Permite imprimir el código de depuración en caso de error si lo ponemos a 0 dejará de hacerlo
#if DEBUG==1
  #define TRACE(x) Serial.println(x)
#else
  #define TRACE(x)
#endif

#include <SPI.h>
#include <SD.h>
#include <DHT11.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>

#define pindht 2 //pinDigital DHT11



Adafruit_BMP085 bmp;//SDA->A20,SCL->A21
DHT11 dht11(pindht); 
 
const int chipSelect=53; //pinD 53(pin SS),D51->MOSI,D50->MISO,D52->SCK
File myFile;
char fileName[]="test.txt";

typedef struct{
 float presion;
 float altitud;
 float temp;
 float humi;
}t_s;

t_s s;

typedef enum{INICIO, LEYENDO, PROCESANDO}t_estado;

typedef struct{
  byte hora;
  byte minutos;
  byte segundos;
  byte dia;
  byte mes;
  byte anyo;
}t_fecha;
char NMEA[255];
t_fecha fecha;


float longitud;
float latitud;
float nudos;
float direccion;

void setup() {
  char c[]="ESTACIÓN METEOROLÓGICA"; //cabecera
  Serial.begin(9600);
  Serial3.begin(9600);
  
  TRACE(__FUNCTION__);
  pinMode(chipSelect,OUTPUT); //pin CS de la memoria
  if(!SD.begin(chipSelect)){  //iniciar memoria
   TRACE("Error inicializando la memoria");
    return;
  }

  myFile=SD.open(fileName, FILE_WRITE);
  if(myFile){
   TRACE("Fichero OK");
    myFile.println(c); //cabecera
    myFile.flush();
  }else {
   TRACE("Error al abrir el fichero");
  }

  Wire.begin();
  
  if (!bmp.begin()) {//SENSOR BARÓMETRICO 
    myFile.println("Error Sensor BMP");
    myFile.flush();
   return;
 }

}

void loop() {
  TRACE(__FUNCTION__);
  //GPS
  leer();

  
 // BMP PRESION ALTITUD
  myFile.println("---------Sensor BMP Presion y altitud----------");
  s.presion=bmp.readPressure();
  myFile.print(s.presion);
  myFile.println(" Pa");
  TRACE(s.presion);
  TRACE(" Pa");

  s.altitud=bmp.readAltitude(101800);//Presion a nivel del mar cambia con el tiempo
  myFile.print(s.altitud);
  myFile.println(" m");
  myFile.flush();
  TRACE(s.altitud);
  TRACE(" m");

 // DHT11 HUM TEMP
  int err;
  float temp, humi;
  if((err=dht11.read(humi, temp))==0){
    myFile.println("----------Sensor DHT11 Temperatura y humedad----------");
    myFile.print("Temperatura: ");
    myFile.print(temp);
    myFile.print(" C");
    myFile.print("  Humedad:");
    myFile.print(humi);
    myFile.print(" %");
    myFile.println();}
  else{
    TRACE("Error No :");
    TRACE(err);}
  
}

void leer(){
  char caracter;
  static int indice=0;
  static t_estado estado=INICIO;

  if(!Serial3.available()){
    return;
  }
  switch(estado){
    case INICIO:
      caracter=Serial3.read();
      if(caracter=='

Y el texto que me imprime es este otro:

ESTACIÓN METEOROLÓGICA
---------Sensor BMP Presion y altitud----------
101614.00 Pa
15.34 m
----------Sensor DHT11 Temperatura y humedad----------
Temperatura: 27.00 C  Humedad:53.00 %
---------Sensor BMP Presion y altitud----------
101607.00 Pa
15.92 m
---------Sensor BMP Presion y altitud----------
101604.00 Pa
16.42 m
---------Sensor BMP Presion y altitud----------
101607.00 Pa
16.01 m
---------Sensor BMP Presion y altitud----------
101607.00 Pa
15.59 m
---------Sensor BMP Presion y altitud----------
101605.00 Pa
15.51 m
---------Sensor BMP Presion y altitud----------
101605.00 Pa
16.01 m
---------Sensor BMP Presion y altitud----------
101614.00 Pa
15.34 m
---------Sensor BMP Presion y altitud----------
101612.00 Pa
15.51 m
---------Sensor BMP Presion y altitud----------
101607.00 Pa
16.17 m
---------Sensor BMP Presion y altitud----------
101608.00 Pa
15.51 m
---------Sensor BMP Presion y altitud----------
101608.00 Pa
15.84 m
---------Sensor BMP Presion y altitud----------
101614.00 Pa
15.92 m
----------Sensor DHT11 Temperatura y humedad----------
Temperatura: 26.00 C  Humedad:48.00 %
---------Sensor BMP Presion y altitud----------
101609.00 Pa
15.34 m
---------Sensor BMP Presion y altitud----------
101606.00 Pa
16.01 m
---------Sensor BMP Presion y altitud----------
101609.00 Pa
15.43 m
---------Sensor BMP Presion y altitud----------
101608.00 Pa
15.26 m
---------Sensor BMP Presion y altitud----------
101607.00 Pa
15.43 m
---------Sensor BMP Presion y altitud----------
101613.00 Pa
16.17 m
---------Sensor BMP Presion y altitud----------
101609.00 Pa
15.92 m
---------Sensor BMP Presion y altitud----------
101608.00 Pa
16.01 m
---------Sensor BMP Presion y altitud----------
101606.00 Pa
15.84 m
---------Sensor BMP Presion y altitud----------
101614.00 Pa
16.34 m
---------Sensor BMP Presion y altitud----------
101615.00 Pa
15.59 m
---------Sensor BMP Presion y altitud----------
101613.00 Pa
15.43 m
----------Sensor DHT11 Temperatura y humedad----------
Temperatura: 27.00 C  Humedad:47.00 %
---------Sensor BMP Presion y altitud----------
101617.00 Pa
16.09 m
---------GPS--------
0.000000, 0.000000
---------Sensor BMP Presion y altitud----------
101609.00 Pa
16.42 m
---------Sensor BMP Presion y altitud----------
101608.00 Pa
15.84 m
---------Sensor BMP Presion y altitud----------
101614.00 Pa
16.17 m
---------Sensor BMP Presion y altitud----------
101609.00 Pa
14.93 m
---------Sensor BMP Presion y altitud----------
101614.00 Pa
14.93 m
---------Sensor BMP Presion y altitud----------
101613.00 Pa
15.43 m
---------Sensor BMP Presion y altitud----------
101608.00 Pa
15.84 m
---------Sensor BMP Presion y altitud----------
101614.00 Pa
15.26 m
---------Sensor BMP Presion y altitud----------
101614.00 Pa
15.51 m
---------Sensor BMP Presion y altitud----------
101612.00 Pa
15.84 m
---------Sensor BMP Presion y altitud----------
101602.00 Pa
15.84 m

Puede ser de la frecuencia de trabajo de los sensores? Alguna otra posibilidad? Gracias.
){
        estado=LEYENDO;
        NMEA[0]=caracter;
        indice=1;
      }
    break;
    case LEYENDO:
      caracter=Serial3.read();
      NMEA[indice]=caracter;
      indice++;
      if(caracter=='\n'){
        estado=PROCESANDO;
      }
    break;
    case PROCESANDO:
      String aux=NMEA;
      if(aux.substring(1,6).equals("GPRMC")){
        parserRMC(aux);
      }
      estado=INICIO;
    break;
  }
}

void parserRMC(String trama){
  int i=0;
  String aux;
  char aux2[9];

i=trama.indexOf(',',i)+1;
  aux=trama.substring(i,i+6); //hora
  fecha.hora=aux.substring(0,2).toInt();
  fecha.minutos=aux.substring(2,4).toInt();
  fecha.segundos=aux.substring(4,6).toInt();

i=trama.indexOf(',',i)+1;
  aux=trama.substring(i,i+1); //estado

i=trama.indexOf(',',i)+1;
  aux=trama.substring(i,i+7); //latitud
  aux.toCharArray(aux2,9);
  latitud=atof(aux2);
  latitud=convCoord(latitud);

i=trama.indexOf(',',i)+1;
  aux=trama.substring(i,i+1); //N/S
  if(aux=="S") latitud=-latitud;

i=trama.indexOf(',',i)+1;
  aux=trama.substring(i,i+7);
  aux.toCharArray(aux2,9);  //longitud
  longitud=atof(aux2);
  longitud=convCoord(longitud);

i=trama.indexOf(',',i)+1;
  aux=trama.substring(i,i+1); //E/O
  if(aux=="W") longitud=-longitud;

i=trama.indexOf(',',i)+1;
  aux=trama.substring(i,i+5); //velocidad
  aux.toCharArray(aux2,9);
  nudos=atof(aux2);

i=trama.indexOf(',',i)+1;
  aux=trama.substring(i,i+5); //direccion
  aux.toCharArray(aux2,9);
  direccion=atof(aux2);           
 
  i=trama.indexOf(',',i)+1;
  aux=trama.substring(i,i+6); //fecha
  fecha.dia=aux.substring(0,2).toInt();
  fecha.mes=aux.substring(2,4).toInt();
  fecha.anyo=aux.substring(4,6).toInt();
  enviarPosicion();
}

void enviarPosicion(){
  myFile.println("---------GPS--------");
  char msg[30];
  sprintf(msg,"%d/%d/%d %d:%d:%d -> ",fecha.dia,fecha.mes,fecha.anyo,fecha.hora,fecha.minutos,fecha.segundos);
  Serial.print(msg);
  myFile.print(longitud,6);
  myFile.print(", ");
  myFile.println(latitud,6);
  myFile.flush();
}

float convCoord(float coord){
  int x;
  float aux;
  float grados;

x=(int)(coord/100);  //coord=4033.4-->x=40
  aux=coord-x*100;    //aux=33.4
  grados=x+aux/60;    //minutos a decimas de grados

return grados;
}


Y el texto que me imprime es este otro:

§DISCOURSE_HOISTED_CODE_1§


Puede ser de la frecuencia de trabajo de los sensores? Alguna otra posibilidad? Gracias.

Buenas sueco.

Ufffff... veras ese tipo de lector microSD te dará problemas. Tengo 2 idénticos y lo mismo pasan a mejor vida tirándolos a la basura. Ayer recibí este y va de maravilla:

Si te sirve esta es la tienda

Gracias por tu ayuda lightcalamar. Llevo peleandome toda la semana con esto y te daba los mismos problemas que a mi? Un saludo

Ese loop esta hecho de forma de mostrar datos a lo loco..
Porque no le pones un control usando millis() para presentar los datos cada 1 segundo algo como

if (millis() - t_start > 1000UL) {
   //muestras los datos
   TRACE(LO QUE QUIERAS);   
   t_start = millis();
}

Si quieres lee los datos con alguna frecuencia menor digamos 500 mseg o no. Y presentas cada 1 segundo o mas.
Lo mismo para salvarlos en la SD.
Ahora tu problema con el GPS yo lo separaría y vería que ocurre por separado. Si se comunica, etc etc.
Esta claro que por cada lectura de humedad (Mucho mas lento) hay muchas lecturas del sensor de presión.
Asi que si los lees 1 vez cada uno y luego los presentas todos juntos, tendras ordenada la salida.

Buenas surbyte,
Consigo que me imprima ordenada los valores de presion y temperatura pero el GPS no me envía nada.
Probando a conectar solo el GPS con ese mismo código al módulo SD tampòco me funciona.
Pero cuando conecto el GPS solo con la parte de código que se refiere al GPS me imprime perfectamente los valores por el puerto serie.
Voy a probar a cambiar de modulo SD y ya os contaré.

La conclusion que saco es que debe ser algun problema con el sketch. Porque imprimiendo por el puerto serie con unicamente el GPS conectado si que recibo datos por el puerto serie.
Pero luego cuando le conecto el resto de sensores, el GPS no me devuelve nada (o como mucho una vez) por el puerto serie mientras que los valores del resto de sensores si que me los imprime.

Solo como pregunta, estas usando el GPS conectado a RX y TX del Arduino directamente o lo haces usando la librería "SoftwareSerial.h"?, porque cuando usas el RX y TX del Arduino siempre da problemas ya que se marea al intentar mandar y recibir de una u otra cosa la data hacia el Puerto Serial o con un TTL conectado.

Dale por ejemplo:

SoftwareSerial ss(8, 9);//Asignar Pines GPS (8=RX,9=TX)

Considerando que los Pines se cruzan y prueba... a mi me solucionó la vida ese detallito.

Litto:
Solo como pregunta, estas usando el GPS conectado a RX y TX del Arduino directamente o lo haces usando la librería "SoftwareSerial.h"?, porque cuando usas el RX y TX del Arduino siempre da problemas ya que se marea al intentar mandar y recibir de una u otra cosa la data hacia el Puerto Serial o con un TTL conectado.

Dale por ejemplo:

SoftwareSerial ss(8, 9);//Asignar Pines GPS (8=RX,9=TX)

Considerando que los Pines se cruzan y prueba... a mi me solucionó la vida ese detallito.

SoftwareSerial con un MEGA que tiene 4 puertos? De que hablas Willies?

A pesar de eso te sugiero que pruebes con la librería indicada, ya que me ha pasado con Shields que marean los Duinos por el tema del RX/TX y al usar librería se corrige... por qué?... ni idea... solo me ha pasado con ciertos Shield.

Estos son los cambios que te propongo.
Primero: DHT no puede leerse mas rápido que 2 segundos y tu lo tienes en cada ciclo. MAL!!
Estas grabando en la SD a cada momento: MAL
las lecturas en tu máquina de estados estas desde mi punto de vista mal hechas, veamos si esto funciona..

void loop() {
  TRACE(__FUNCTION__);
  //GPS
  leer();
  
  if (millis() - t_start > 2000UL) {
     //muestras los datos
     //TRACE(LO QUE QUIERAS);   
	 // BMP PRESION ALTITUD
	  myFile.println("---------Sensor BMP Presion y altitud----------");
	  s.presion=bmp.readPressure();
	  myFile.print(s.presion);
	  myFile.println(" Pa");
	  TRACE(s.presion);
	  TRACE(" Pa");

	  s.altitud = bmp.readAltitude(101800);//Presion a nivel del mar cambia con el tiempo
	  myFile.print(s.altitud);
	  myFile.println(" m");
	  myFile.flush();
	  TRACE(s.altitud);
	  TRACE(" m");

	  // DHT11 HUM TEMP
	  int err;
	  float temp, humi;
	  if ((err=dht11.read(humi, temp)) == 0) {
		   myFile.println("----------Sensor DHT11 Temperatura y humedad----------");
		   myFile.print("Temperatura: ");
		   myFile.print(temp);
		   myFile.print(" C");
		   myFile.print("  Humedad:");
		   myFile.print(humi);
		   myFile.print(" %");
		   myFile.println();
	  }
	  else {
	       TRACE("Error No :");
	       TRACE(err);}
	  }

      t_start = millis();
  }
}

void leer(){
  char caracter;
  static int indice=0;
  static t_estado estado=INICIO;

  if (!Serial3.available()) {
      return;
  }

  switch(estado){
    case INICIO:
		      while (Serial3.available() > 0) {
			      caracter = Serial3.read();
			      if(caracter=='

){
        estado=LEYENDO;
        NMEA[0]=caracter;
        indice=1;
      }
      }
      break;
    case LEYENDO:
      while (Serial3.available() > 0) {
      caracter = Serial3.read();
      NMEA[indice]=caracter;
      indice++;
      if (caracter=='\n'){
          estado=PROCESANDO;
      }
      break;
    case PROCESANDO:
      String aux = NMEA;
      if (aux.substring(1,6).equals("GPRMC")){
          parserRMC(aux);
      }
      estado=INICIO;
      break;
  }
}