Telemetria

Hola a todos:

Os presento mi proyecto de telemetria y os pido una mano. Se trata de medir velocidad en las ruedas, posicion de las suspensiones e inclinacion. Como soy novato primero hago el programa de cada sensor por separado y luego lo voy añadiendo, me a ido bien asi y asi sigo, hasta ahora. Cuando hago el sketch de los opticos funciona muy bien y me lo muestra en serial pero cuando lo uno al programa "principal" solo me muestra en serial 0 y en sensor 2 ni se enciende. creo que es problema de las interrupciones pero no hay manera. Pongo los dos a ver si alguien encuentra el fallo. Por cierto, la idea es ir poniendo mas sensores pero poco a poco

int half_revolutions = 0;
int rpm = 0;
unsigned long lastmillis = 0;

int half_revolutions2 = 0;
int rpm2 = 0;
unsigned long lastmillis2 = 0;




void setup()
{
Serial.begin(9600);
  attachInterrupt(1, rpm_wheel, FALLING); // Sensor optico en D3
  attachInterrupt(0, rpm_wheel2, FALLING); // Sensor optico 2 en D2
  

}





void loop()

{
 if (millis() - lastmillis == 1000)    //Actualiza cada segundo

 { 

 detachInterrupt(1);//Desconecta el interruptor 1 mientras calcula

 rpm = half_revolutions * 15; // pasa la frecuencia a RPM con una interrupcion. RUEDA DELANTERA
 rpm=rpm*30;// a Rph
 rpm=rpm*0.00186;// a Km/h   MODIFICAR SEGUN CIRCUNFERENCIA DE RUEDA


  half_revolutions = 0; // pone rpm a 0
  lastmillis = millis();
 attachInterrupt(1, rpm_wheel, FALLING); //enciende interruptor
  Serial.println("Km/h =\t");
 Serial.println(rpm);
 }

 if (millis() - lastmillis2 == 1000)    //Actualiza cada segundo
 {
 detachInterrupt(0);//Desconecta el interruptor 2 mientras calcula

 rpm2= half_revolutions2 * 15; // pasa la frecuencia a RPM con una interrupcion. SENSOR 2
 rpm2=rpm2*30;// a Rph
 rpm2=rpm2*0.00186;// a Km/h  MODIFICAR SEGUN CIRCUNFERENCIA DE RUEDA

  
 half_revolutions2 = 0; // pone rpm2 a 0
 lastmillis2 = millis();


 attachInterrupt(0, rpm_wheel2, FALLING); //enciende interruptor 2


 Serial.println("Km/h2 =\t");
 Serial.println(rpm2);


  }
}
  void rpm_wheel(){
  half_revolutions++;
 }
  void rpm_wheel2(){
  half_revolutions2++;
 }

Y aqui el otro

#include <SD.h>
#include <UTouch.h>
#include <UTFT.h>
#include<Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t GyZ;
UTFT lcd(ILI9486,38,39,40,41);
UTouch tactil( 6, 5, 4, 3, 2);
extern uint8_t BigFont[];
extern uint8_t BigFont[];
extern uint8_t NineSegNumFont[];
int pantalla;
int pinPot=A0;
int valorPot=0;
int pinPot1=A1;
int valorPot1=0;
int half_revolutions = 0;
int rpm = 0;
int half_revolutions2 = 0;
int rpm2 = 0;
unsigned long lastmillis = 0;
unsigned long lastmillis2 = 0;
const int chipSelect = 53;

void setup()
{
  Wire.begin();
   Wire.beginTransmission(MPU_addr);
   Wire.write(0x6B);  // PWR_MGMT_1 register
   Wire.write(0);     // set to zero (wakes up the MPU-6050)
   Wire.endTransmission(true);
  pinMode(pinPot, INPUT);
  pinMode(pinPot1,INPUT);
  Serial.begin(9600);
  attachInterrupt(1, rpm_wheel, FALLING); // Sensor optico en D3
  attachInterrupt(0, rpm_wheel2, FALLING); // Sensor optico 2 en D2 
 lcd.InitLCD();
 lcd.clrScr();
 tactil.InitTouch();
 tactil.setPrecision(PREC_HI);
 pantalla = 1;
  Serial.print("Iniciando SD...");
  pinMode(10, OUTPUT);
  
  if (!SD.begin(chipSelect)) {
    Serial.println("Fallo tarjeta.");
    return;
    Serial.println("tarjeta iniciada.");
}
}
void loop()
{
  Wire.beginTransmission(MPU_addr);  // GYRO 
  Wire.write(0x3B);                   // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);     
  GyZ=Wire.read()<<8|Wire.read();       
  GyZ=GyZ/181,1; //pasar a grados

 if (millis() - lastmillis == 1000)    //Actualiza cada segundo
  { 
 detachInterrupt(1);//Desconecta el interruptor 1 mientras calcula
  rpm = half_revolutions * 15; // pasa la frecuencia a RPM con una interrupcion. RUEDA DELANTERA
 rpm=rpm*30;// a Rph
 rpm=rpm*0.00186;// a Km/h   MODIFICAR SEGUN CIRCUNFERENCIA DE RUEDA
 
  half_revolutions = 0; // pone rpm a 0
  lastmillis = millis();
 attachInterrupt(1, rpm_wheel, FALLING); //enciende interruptor
   Serial.println(rpm); 
 }

 if (millis() - lastmillis2 == 1000)    //Actualiza cada segundo
 {
 detachInterrupt(0);//Desconecta el interruptor 2 mientras calcula
  rpm2= half_revolutions2 * 15; // pasa la frecuencia a RPM con una interrupcion. SENSOR 2
 rpm2=rpm2*30;// a Rph
 rpm2=rpm2*0.00186;// a Km/h  MODIFICAR SEGUN CIRCUNFERENCIA DE RUEDA  
 half_revolutions2 = 0; // pone rpm2 a 0
 lastmillis2 = millis();  
 attachInterrupt(0, rpm_wheel2, FALLING); //enciende interruptor 2  
 Serial.println(rpm2); 
 
 } 
  {
  char buffer[30]; 
  char buffer1[30];
  char buffer2[30];  
  valorPot= analogRead(pinPot);
  valorPot1=analogRead(pinPot1);
  lcd.setFont(BigFont);
  lcd.setColor(VGA_WHITE);
  sprintf(buffer,"%d", valorPot); // CAMBIAR POR TEMP RUEDA DELANTERA
  sprintf(buffer1,"%d", valorPot1);// CAMBIAR POR TEMP RUEDA TRASERA
  sprintf(buffer2,"%d", rpm);  
  
  lcd.print(buffer , 390, 90);
  lcd.print("Tª DEL " ,RIGHT,50);
  lcd.print(buffer1 , 390, 240);
  lcd.print("Tª TRAS " ,RIGHT,190);
  lcd.print(buffer2,CENTER, 150);// VELOCIDAD ( SOLO DELANTERA )
  lcd.print("Km/h", CENTER,190);  
  delay(500);
   }
    {
      // primer potenciometro
    String dataString = "";
  // lee el sensor.si cambiamos < 1 por x lee hasta el sensor x
  for (int analogPin = 0;analogPin < 1; analogPin++){
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 1) {
      dataString += ","; 
    }
  }
  File dataFile = SD.open("Susp_Del.txt", FILE_WRITE);
  if (dataFile) 
  {
    dataFile.println(dataString);
    dataFile.close();
    // imprime tambien en serial
    Serial.println(dataString);
    delay(100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir Susp_Del.txt");
  }   
  // 2º potenciometro
  String dataString2= "";
  for (int analogPin = 1;analogPin < 2; analogPin++)    // lee el sensor 2 (del 1 al 2)
  {
    int sensor = analogRead(analogPin);
    dataString2 += String(sensor);    
  }
  File dataFile2 = SD.open("SuspTras.txt", FILE_WRITE);
  if (dataFile2)
  {
    dataFile2.println(dataString2);
    dataFile2.close();
    // imprime tambien en serial
    Serial.println(dataString2);
    delay (100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir SuspTras.txt");
  }  
  // Velocidad del
    File dataFile3 = SD.open("Vel_del.txt", FILE_WRITE);
  if (dataFile3)
  {
    dataFile3.println(rpm);
    dataFile3.close();
    // imprime tambien en serial
    Serial.println(rpm);
    delay (100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir Vel_del.txt");
  }   
  // Velocidad tras
  
  File dataFile4 = SD.open("Vel_tras.txt", FILE_WRITE);
  if (dataFile4)
  {
    dataFile4.println(rpm2);
    dataFile4.close();
    // imprime tambien en serial
    Serial.println(rpm2);
    delay (100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir Vel_tras.txt");
  }   
  // GYRO  
  File dataFile5 = SD.open("Gyro.txt", FILE_WRITE);
  if (dataFile5)
  {
    dataFile5.println(GyZ);
    dataFile5.close();
    // imprime tambien en serial
    Serial.println(GyZ);
    delay (100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir Gyro.txt");
  } 
}

}
 void rpm_wheel(){
  half_revolutions++;
 }
  void rpm_wheel2(){
  half_revolutions2++;
 }

Es mejor que en las comparaciones de tiempo uses >= (mayor o igual) ya que como lo tienes ,la condicion solo se va a cumplir cuando la diferencia de tiempo sea exactamente de 1000 ms y eso solo funcionaria si justo en el momento de la comparacion la diferencia es esa,lo cual es dificil segun lo que tarde en procesarse una vuelta del loop .

Gracias jose. Parte del problema solucionado pero el sensor 2 no se enciende. Esta conectado en D2, no se si puedo conectar en otro. Esta semana me llegan el resto de sensores, temperatura, gps, voltaje de bateria.... Ire poniendo la evolucion

supongo que ya has probado a intercambiar los sensores para comprobar que no sea el sensor lo que falla.las varibles usadas en interrupciones deberian ser declaradas con el modificador volatile:

volatile int half_revolutions;

tampoco tiene mucho sentido tener lastmilis y lastmilis2 ,cuando pase un segundo calculas las 2 .

Bueno ya he probado el equipo en la moto y como no surgen problemillas. los opticos leen bien pero llegando a una velocidad creo que saturan y dan 0. El gyro me da unos grados muy grandes y creo que es porque al frenar se inclina hacia delante y los grdos laterales aumentan. Ya me ha llegado el sensor de temperatura y el gps, cuando lo tenga montado lo pongo.

haces muchas operaciones matemáticas mientras bloqueas interrupcciones. Eso lleva tiempo y no es aconsejable. Simplifica lo que puedas

rpm = half_revolutions * 15; // pasa la frecuencia a RPM con una interrupcion. RUEDA DELANTERA
 rpm=rpm*30;// a Rph
 rpm=rpm*0.00186;// a Km/h   MODIFICAR SEGUN CIRCUNFERENCIA DE RUEDA
 
  half_revolutions = 0; // pone rpm a 0
  lastmillis = millis();
  attachInterrupt(1, rpm_wheel, FALLING); //enciende interruptor
  rpm = half_revolutions * 0.837; // a Km/h  MODIFICAR SEGUN CIRCUNFERENCIA DE RUEDA
  half_revolutions = 0; // pone  a 0
  attachInterrupt(1, rpm_wheel, FALLING); //enciende interruptor
  lastmillis = millis();

Paraste interrupcciiones de modo que millis() se frenó también. Es minimo pero es un error. Yo lo haría asi.

Dime si mejora/cambia o no notas nada.

Haciendolo como dice surbyte mejora, pero no suficiente. Tiene que leer 34 pasos por segundo. He probado a poner delay de 2 sec. y va muy bien.
El problema es que afecta a el resto de sensores y no me conviene. Necesito que algunos lean cuantas mas veces mejor.
Ahi va el codigo

#include <SD.h>

#include<Wire.h>
#include <Adafruit_MLX90614.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t GyZ;


int pinVoltios =A2;
float valorVoltios = 0;
int pinPot=A0;
int valorPot=0;
int pinPot1=A1;
int valorPot1=0;
int half_revolutions = 0;
int rpm = 0;
int half_revolutions2 = 0;
int rpm2 = 0;
unsigned long lastmillis = 0;

const int chipSelect = 53;


void setup()
{
  Wire.begin();
   Wire.beginTransmission(MPU_addr);
   Wire.write(0x6B);  // PWR_MGMT_1 register
   Wire.write(0);     // set to zero (wakes up the MPU-6050)
   Wire.endTransmission(true);
   
  pinMode(pinVoltios, INPUT);  
  pinMode(pinPot, INPUT);
  pinMode(pinPot1,INPUT);
  Serial.begin(9600);
  mlx.begin(); 
  attachInterrupt(1, rpm_wheel, FALLING); // Sensor optico en D3
  attachInterrupt(0, rpm_wheel2, FALLING); // Sensor optico 2 en D2
  
 
 
 Serial.print("Iniciando SD...");
  pinMode(10, OUTPUT);
  
  if (!SD.begin(chipSelect)) {
    Serial.println("Fallo tarjeta.");
    return;
  
  Serial.println("tarjeta iniciada.");
}
}

void loop()

{
  Wire.beginTransmission(MPU_addr);  // GYRO 
  Wire.write(0x3B);                   // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  
      
  GyZ=Wire.read()<<8|Wire.read();  
     
  GyZ=GyZ/181,1; //pasar a grados
   
  
  Serial.println();
  valorVoltios = analogRead(pinVoltios);
  valorVoltios= valorVoltios/41;   // para hacer division
  Serial.print(valorVoltios);
  
  
  delay(1000);


 if (millis() - lastmillis >= 10)    //Actualiza cada segundo
 
 { 

 detachInterrupt(1);//Desconecta el interruptor 1 mientras calcula
 detachInterrupt(0);//Desconecta el interruptor 2 mientras calcula
 
 rpm = half_revolutions * 0.81; // pasa la frecuencia a velocidad (450*0.00circunferencia)con una interrupcion. RUEDA DELANTERA
 rpm2= half_revolutions2 * 0.837; // pasa la frecuencia a velocidad (450*0.00circunferencia) con una interrupcion. RUEDA TRASERA
 half_revolutions = 0; // pone rpm a 0
 half_revolutions2 = 0; // pone rpm2 a 0
 attachInterrupt(1, rpm_wheel, FALLING); //enciende interruptor
 attachInterrupt(0, rpm_wheel2, FALLING); //enciende interruptor 2
 lastmillis = millis();
  
 
 
 delay (2000);
 }


     // primer potenciometro
  
  String dataString = "";

  // lee el sensor.si cambiamos < 1 por x lee hasta el sensor x
  for (int analogPin = 0;analogPin < 1; analogPin++){
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 1) {
      dataString += ","; 
    }
  }

  File dataFile = SD.open("Susp_Del.txt", FILE_WRITE);


  if (dataFile) 
  {
    dataFile.println(dataString);
    dataFile.close();
    // imprime tambien en serial
    Serial.println(dataString);
    delay(100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir Susp_Del.txt");
  } 
  
  
  
  // 2º potenciometro
  String dataString2= "";

  
  for (int analogPin = 1;analogPin < 2; analogPin++)    // lee el sensor 2 (del 1 al 2)
  {
    int sensor = analogRead(analogPin);
    dataString2 += String(sensor);
    if (analogPin < 2) {
      dataString2 += ","; 
    } 
    
  }

  File dataFile2 = SD.open("SuspTras.txt", FILE_WRITE);


  if (dataFile2)
  {
    dataFile2.println(dataString2);
    dataFile2.close();
    // imprime tambien en serial
    Serial.println(dataString2);
    delay (100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir SuspTras.txt");
  } 
  
  
  //Voltaje Bateria
  
   String dataString3 = "";

  // lee el sensor.si cambiamos < 1 por x lee hasta el sensor x
  for (int analogPin = 2;analogPin < 3; analogPin++){
    int sensor = analogRead(analogPin);
    dataString3 += String(sensor);
    if (analogPin < 3) {
      dataString3 += ","; 
    }
  }

  File dataFile3 = SD.open("Volt_Bat.txt", FILE_WRITE);


  if (dataFile3) 
  {
    dataFile3.println(dataString3);
    dataFile3.close();
    // imprime tambien en serial
    Serial.println(dataString3);
    delay(100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir Volt_Bat.txt");
  } 
  
  
  // Velocidad del
  
  File dataFile4 = SD.open("Vel_del.txt", FILE_WRITE);


  if (dataFile4)
  {
    dataFile4.println(rpm);
    dataFile4.close();
    // imprime tambien en serial
   Serial.println(rpm);
    delay (100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir Vel_del.txt");
  } 
  
  // Velocidad tras
  
  File dataFile5= SD.open("Vel_tras.txt", FILE_WRITE);


  if (dataFile5)
  {
    dataFile5.println(rpm2);
    dataFile5.close();
    // imprime tambien en serial
    Serial.println(rpm2);
    delay (100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir Vel_tras.txt");
  } 
  
  
  // GYRO
  
  File dataFile6 = SD.open("Gyro.txt", FILE_WRITE);


  if (dataFile6)
  {
    dataFile6.println(GyZ);
    dataFile6.close();
    // imprime tambien en serial
    Serial.println(GyZ);
    delay (100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir Gyro.txt");
  } 
  
  // TEMPERATURA NEUMATICO
  
   File dataFile7 = SD.open("TempNeum.txt", FILE_WRITE);


  if (dataFile7)
  {
    dataFile7.println(mlx.readObjectTempC());
    dataFile7.close();
    // imprime tambien en serial
    Serial.println(mlx.readObjectTempC());
    delay (100);
  }  
  // si el archivo no abre da error
  else {
    Serial.println("error abrir TempNeum.txt");
  } 
}


 void rpm_wheel(){
  half_revolutions++;
 }
  void rpm_wheel2(){
  half_revolutions2++;
 }

Ya he solucionado el problema de que no me funcionara el optico en D2 con la TFT, sin ella si funciona. Simple, cambiar la entrada 2 por la 19 que en mega tambien admite interrupciones.

 attachInterrupt(1, rpm_wheel, FALLING); // Sensor optico en D3
  attachInterrupt(4, rpm_wheel2, FALLING); // Sensor optico 2 en D19

hirukiracing: He probado a poner delay de 2 sec. y va muy bien.

Que es esto?

delay(1000);


  if (millis() - lastmillis >= 10) {   //Actualiza cada segundo 
      detachInterrupt(1);//Desconecta el interruptor 1 mientras calcula
      detachInterrupt(0);//Desconecta el interruptor 2 mientras calcula
       
      rpm = half_revolutions * 0.81; // pasa la frecuencia a velocidad (450*0.00circunferencia)con una interrupcion. RUEDA DELANTERA
      rpm2= half_revolutions2 * 0.837; // pasa la frecuencia a velocidad (450*0.00circunferencia) con una interrupcion. RUEDA TRASERA
      half_revolutions = 0; // pone rpm a 0
      half_revolutions2 = 0; // pone rpm2 a 0
      attachInterrupt(1, rpm_wheel, FALLING); //enciende interruptor
      attachInterrupt(0, rpm_wheel2, FALLING); //enciende interruptor 2
      lastmillis = millis();
      delay (2000);
  }

perdoname la expresión pero es una barbarídad tras otra. Asi que empiezas con un delay de 1seg que detiene todo. Luego entras en una condición con millis() cada 10 mseg que se cumple siempre y DENTRO otro delay de 2 segundos!! Todo esto implica una locura.

Dejame estudiarlo y te sugiero algo mejor.

EDITO 1. No entiendo para que abres un archivo para cada variable a loggear. Porque no abres un solo archivo y loggeas todo y lo estampas con la hora supongo, porque veo rpm, giro, voltage, pero solos??? sin correspondencia con los demas. Se leen todos los sensores y se estampan juntos con una marca de tiempo, si quieres usa millis() o algun evento.

Sigo analizando...

bueno esta es mi versión. todavia tiene cosas para mejorar pero a ver que tal sale.
Crea otro sketch para no comprometer el tuyo.

#include <SD.h>

#include <Wire.h>
#include <SPI.h>     // Necesario para la SD card
// #include "RTClib.h"

#include <Adafruit_MLX90614.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

const int MPU_addr = 0x68;  // I2C address of the MPU-6050
int16_t GyZ;

const byte pinPot1    = A0;
const byte pinPot2    = A1;
const byte pinVoltios = A2;

float valorVoltios    = 0;
// int valorPot          = 0;
// int valorPot1         = 0;
int half_revolutions1 = 0;
int rpm1              = 0;
int half_revolutions2 = 0;
int rpm2              = 0;
unsigned long lastmillis = 0, start_log;

const int chipSelect = 53;
int count = 0 ;       // Controla cada cuanto tiemepo se vuelcan los datos a la SD
File logfile;       // Fichero a escribir en la SD


void setup() {
  
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  
  pinMode(pinVoltios, INPUT);  
  pinMode(pinPot, INPUT);
  pinMode(pinPot1,INPUT);
  Serial.begin(9600);
  mlx.begin(); 
  attachInterrupt(1, rpm_wheel1, FALLING); // Sensor optico en D3
  attachInterrupt(0, rpm_wheel2, FALLING); // Sensor optico 2 en D2
  
 
 
  Serial.print("Iniciando SD...");
  pinMode(10, OUTPUT);
  
  if (!SD.begin(chipSelect)) 
      Serial.println("Fallo tarjeta.");
  
  else 
      Serial.println("tarjeta iniciada.");
  
  // Creamos el fichero de registro
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++)   {  
       filename[6] = i/10 + '0';
       filename[7] = i%10 + '0';
       if (! SD.exists(filename)) {       // Si no existe el fichero, lo creamos
            logfile = SD.open(filename, FILE_WRITE); 
            break;  // leave the loop!
       }
  }

  if (! logfile) 
      error("No s epudo crear el fichero de registro");
    
  Serial.print("Registrando en: ");   Serial.println(filename);
  // connect to RTC
  // deberías agregarlo
  // Wire.begin();  
  // if (!RTC.begin()) 
  //     logfile.println("No hay RTC.");   
  // else
  //     Serial.println("RTC correcto. Iniciando captura de datos");   
  
  // Pongo los encabezados
  logfile.print("Fecha/Hora, ") ; 
  //logfile.print(" ID ") ; 
  //logfile.print(", ");  
  logfile.print("Susp Del, Susp Tras, Volt Bat, Vel del, Vel Tras, Gyro, ");
  logfile.println("Temp Neum") ; 
  start_log = millis();
}

void loop() {

  //DateTime now;
  
  Wire.beginTransmission(MPU_addr);     // GYRO 
  Wire.write(0x3B);                     // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  
      
  GyZ = Wire.read()<<8|Wire.read();  
  GyZ = GyZ/181.1;                        //pasar a grados
  
  valorVoltios = analogRead(pinVoltios);
  valorVoltios = valorVoltios/41;         // para hacer division
  Serial.println();
  Serial.print(valorVoltios);

  // solo se ejecuta 1 vez cada 1000 mseg
  if (millis() - lastmillis >= 1000) {   //Actualiza cada segundo 
      detachInterrupt(1);//Desconecta el interruptor 1 mientras calcula
      detachInterrupt(0);//Desconecta el interruptor 2 mientras calcula
       
      rpm1= half_revolutions1* 0.81; // pasa la frecuencia a velocidad (450*0.00circunferencia)con una interrupcion. RUEDA DELANTERA
      rpm2= half_revolutions2 * 0.837; // pasa la frecuencia a velocidad (450*0.00circunferencia) con una interrupcion. RUEDA TRASERA
      half_revolutions1= 0; // pone rpm1a 0
      half_revolutions2 = 0; // pone rpm2 a 0
      attachInterrupt(1, rpm_wheel1, FALLING); //enciende interruptor
      attachInterrupt(0, rpm_wheel2, FALLING); //enciende interruptor 2
      guardarDatos = true;
      lastmillis = millis();
  }
  
  // En realidad todo esto podria estar dentro del if anterior. No hay cambio.
  if (guardarDatos) {
    String dataString = "";
    dataString = String(millis()/1000);
    dataString += ","; 

    // primer potenciometro Suspencion Delantera
    int sensorSD = analogRead(pinPot1);
    dataString += String(sensorSD);  // suspencion delantera
    dataString += ","; 

    // 2º potenciometro suspencipon  Trasera
    int sensorST = analogRead(pinPot2);  // Supensión trasera
    dataString += String(sensorST);
    dataString += ","; 
          
    //Voltaje Bateria
    int sensorBat = analogRead(pinVoltios);
    dataString += String(sensorBat);
    dataString += ","; 
    // logfile.print("Fecha/Hora, ") ; 
    // logfile.print("Susp Del, Susp Tras, Volt Bat, Vel del, Vel Tras, Gyro, ");
    // logfile.println("Temp Neum") ; 
    dataString += String(rpm1)+","+String(rpm2)+","+Sring(GyZ)+","+String(mlx.readObjectTempC());
    logfile.println(dataString);  // envio orde de grabar pero...

    if (count++ > 64 )  {   
        logfile.flush(); // Para forzar la escritura en la SD
        count = 0 ;       // Cada 64 lecturas
    }
    guardarDatos = false;
  }
}
  
void rpm_wheel1(){
  half_revolutions++;
}

void rpm_wheel2(){
  half_revolutions2++;
}

Mira a ver si funciona. Como no tengo la librería Adafruit no puedo comprobar su compilación.
Hay muchos cambios y simplificaciones.
Tambien agregué el estampado de segundos con millis()/1000.
Yo le pondria un RTC para que pudieras llevar la hora.

Gracias surbyte.
Lo he probado y me daba errores varios. He corregido algunos pero otros no se como.

Estos son:
sketch_jun04a.ino: In function ‘void setup()’:
sketch_jun04a.ino:70:17: error: expected ‘)’ before ‘error’
sketch_jun04a.ino: In function ‘void loop()’:
sketch_jun04a.ino:119:7: error: ‘guardarDatos’ was not declared in this scope
sketch_jun04a.ino:124:7: error: ‘guardarDatos’ was not declared in this scope
sketch_jun04a.ino:126:5: error: ‘dataString’ was not declared in this scope
sketch_jun04a.ino:146:97: error: call of overloaded ‘String(double)’ is ambiguous
sketch_jun04a.ino:146:97: note: candidates are:
In file included from /usr/share/arduino/hardware/arduino/cores/arduino/Arduino.h:192:0,
from /usr/share/arduino/libraries/SD/SD.h:18,
from sketch_jun04a.ino:1:
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:70:11: note: String::String(long unsigned int, unsigned char)
explicit String(unsigned long, unsigned char base=10);
^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:69:11: note: String::String(long int, unsigned char)
explicit String(long, unsigned char base=10);
^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:68:11: note: String::String(unsigned int, unsigned char)
explicit String(unsigned int, unsigned char base=10);
^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:67:11: note: String::String(int, unsigned char)
explicit String(int, unsigned char base=10);
^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:66:11: note: String::String(unsigned char, unsigned char)
explicit String(unsigned char, unsigned char base=10);
^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:65:11: note: String::String(char)
explicit String(char c);
^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:60:2: note: String::String(const String&)
String(const String &str);
^
sketch_jun04a.ino: In function ‘void rpm_wheel1()’:
sketch_jun04a.ino:158:3: error: ‘half_revolutions’ was not declared in this scope

El porque de hacer archivos separados es para luego poder tratar cada sensor por separado, hacer graficas…

Este es el codigo correspondiente al error

#include <SD.h>

#include <Wire.h>
#include <SPI.h>     // Necesario para la SD card
// #include "RTClib.h"

#include <Adafruit_MLX90614.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

const int MPU_addr = 0x68;  // I2C address of the MPU-6050
int16_t GyZ;

const byte pinPot1    = A0;
const byte pinPot2    = A1;
const byte pinVoltios = A2;

float valorVoltios    = 0;
// int valorPot          = 0;
// int valorPot1         = 0;
int half_revolutions1 = 0;
int rpm1              = 0;
int half_revolutions2 = 0;
int rpm2              = 0;
unsigned long lastmillis = 0, start_log;

const int chipSelect = 53;
int count = 0 ;       // Controla cada cuanto tiemepo se vuelcan los datos a la SD
File logfile;       // Fichero a escribir en la SD


void setup() {
 
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
 
  pinMode(pinVoltios, INPUT); 
  pinMode(pinPot1, INPUT);
  pinMode(pinPot2,INPUT);
  Serial.begin(9600);
  mlx.begin();
  attachInterrupt(1, rpm_wheel1, FALLING); // Sensor optico en D3
  attachInterrupt(0, rpm_wheel2, FALLING); // Sensor optico 2 en D2
 
 
 
  Serial.print("Iniciando SD...");
  pinMode(10, OUTPUT);
 
  if (!SD.begin(chipSelect))
      Serial.println("Fallo tarjeta.");
 
  else
      Serial.println("tarjeta iniciada.");
 
  // Creamos el fichero de registro
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++)   { 
       filename[6] = i/10 + '0';
       filename[7] = i%10 + '0';
       if (! SD.exists(filename)) {       // Si no existe el fichero, lo creamos
            logfile = SD.open(filename, FILE_WRITE);
            break;  // leave the loop!
       }
  }

  if (! logfile )
  
    error   ("No s epudo crear el fichero de registro");
   
  Serial.print("Registrando en: ");   Serial.println(filename);
  // connect to RTC
  // deberías agregarlo
  // Wire.begin(); 
  // if (!RTC.begin())
  //     logfile.println("No hay RTC.");   
  // else
  //     Serial.println("RTC correcto. Iniciando captura de datos");   
 
  // Pongo los encabezados
  logfile.print("Fecha/Hora, ") ;
  //logfile.print(" ID ") ;
  //logfile.print(", "); 
  logfile.print("Susp Del, Susp Tras, Volt Bat, Vel del, Vel Tras, Gyro, ");
  logfile.println("Temp Neum") ;
  start_log = millis();
}

void loop() {

  //DateTime now;
 
  Wire.beginTransmission(MPU_addr);     // GYRO
  Wire.write(0x3B);                     // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true); 
     
  GyZ = Wire.read()<<8|Wire.read(); 
  GyZ = GyZ/181.1;                        //pasar a grados
 
  valorVoltios = analogRead(pinVoltios);
  valorVoltios = valorVoltios/41;         // para hacer division
  Serial.println();
  Serial.print(valorVoltios);

  // solo se ejecuta 1 vez cada 1000 mseg
  if (millis() - lastmillis >= 1000) {   //Actualiza cada segundo
      detachInterrupt(1);//Desconecta el interruptor 1 mientras calcula
      detachInterrupt(0);//Desconecta el interruptor 2 mientras calcula
       
      rpm1= half_revolutions1* 0.81; // pasa la frecuencia a velocidad (450*0.00circunferencia)con una interrupcion. RUEDA DELANTERA
      rpm2= half_revolutions2 * 0.837; // pasa la frecuencia a velocidad (450*0.00circunferencia) con una interrupcion. RUEDA TRASERA
      half_revolutions1= 0; // pone rpm1a 0
      half_revolutions2 = 0; // pone rpm2 a 0
      attachInterrupt(1, rpm_wheel1, FALLING); //enciende interruptor
      attachInterrupt(0, rpm_wheel2, FALLING); //enciende interruptor 2
      guardarDatos = true;
      lastmillis = millis();
  }
 
  // En realidad todo esto podria estar dentro del if anterior. No hay cambio.
  if (guardarDatos) {
    String dataString1 = "";
    dataString = String(millis()/1000);
    dataString += ",";

    // primer potenciometro Suspencion Delantera
    int sensorSD = analogRead(pinPot1);
    dataString += String(sensorSD);  // suspencion delantera
    dataString += ",";

    // 2º potenciometro suspencipon  Trasera
    int sensorST = analogRead(pinPot2);  // Supensión trasera
    dataString += String(sensorST);
    dataString += ",";
         
    //Voltaje Bateria
    int sensorBat = analogRead(pinVoltios);
    dataString += String(sensorBat);
    dataString += ",";
    // logfile.print("Fecha/Hora, ") ;
    // logfile.print("Susp Del, Susp Tras, Volt Bat, Vel del, Vel Tras, Gyro, ");
    // logfile.println("Temp Neum") ;
    dataString += String(rpm1)+","+String(rpm2)+","+String(GyZ)+","+String(mlx.readObjectTempC());
    logfile.println(dataString);  // envio orde de grabar pero...

    if (count++ > 64 )  {   
        logfile.flush(); // Para forzar la escritura en la SD
        count = 0 ;       // Cada 64 lecturas
    }
    guardarDatos = false;
  }
}
 
void rpm_wheel1(){
  half_revolutions++;
}

void rpm_wheel2(){
  half_revolutions2++;
}

Estos son los errores biem puestos. Gracias surbyte por tu paciencia

   sketch_jun04a.ino: In function 'void setup()':
sketch_jun04a.ino:70:17: error: expected ')' before 'error'
sketch_jun04a.ino: In function 'void loop()':
sketch_jun04a.ino:119:7: error: 'guardarDatos' was not declared in this scope
sketch_jun04a.ino:124:7: error: 'guardarDatos' was not declared in this scope
sketch_jun04a.ino:126:5: error: 'dataString' was not declared in this scope
sketch_jun04a.ino:146:97: error: call of overloaded 'String(double)' is ambiguous
sketch_jun04a.ino:146:97: note: candidates are:
In file included from /usr/share/arduino/hardware/arduino/cores/arduino/Arduino.h:192:0,
                 from /usr/share/arduino/libraries/SD/SD.h:18,
                 from sketch_jun04a.ino:1:
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:70:11: note: String::String(long unsigned int, unsigned char)
  explicit String(unsigned long, unsigned char base=10);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:69:11: note: String::String(long int, unsigned char)
  explicit String(long, unsigned char base=10);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:68:11: note: String::String(unsigned int, unsigned char)
  explicit String(unsigned int, unsigned char base=10);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:67:11: note: String::String(int, unsigned char)
  explicit String(int, unsigned char base=10);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:66:11: note: String::String(unsigned char, unsigned char)
  explicit String(unsigned char, unsigned char base=10);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:65:11: note: String::String(char)
  explicit String(char c);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:60:2: note: String::String(const String&)
  String(const String &str);
  ^
sketch_jun04a.ino: In function 'void rpm_wheel1()':
sketch_jun04a.ino:158:3: error: 'half_revolutions' was not declared in this scope

Bueno ya nos iremos entendiendo. Siempre hablo de editar el post escrito no de crear uno nuevo con el cambio pero ya lo iras captando.

Como veo todo te saltas muchos pasos y tus problemas tienen que ver con tu desconocimiento. Has copiado y pegado códigos y con buen tino llegaste hasta aca pero estos errores son básicos de programación. Ejemplo:

119:7: error: 'guardarDatos' was not declared in this scope

guardarDatos no ha sido declarado Entonces simplemente te falta definirlo como variable.

No es tan dificil!! Si interpretas que te dice el compilador, vas resolviendo que es cada cosa.

Tienes razon surbyte soy muy novato todavia. Paso a paso ire aprendiendo. Los errores me los da el codigo que tu me pasaste. Voy a intentar solucionarlo y te digo algo

Al código que yo te pase le agregué solo 1 par de variables. GuardaDatos es una. Si no esta definida, pues defínela. Simple solución!! Ya lo expliqué en el post#13. Si hay mas sin definir, defínelas también! Es básico.

Los códigos que sugiero no los puedo compilar porque me faltan elementos. No tengo tus librerías y tampoco las voy a descargar porque no tengo tu hardware. Por eso te sugerí ayudarte vía Remota y declinaste la oferta. No se le ofrezco a muchos pero si cuando me interesa el proyecto como en tu caso, si lo hago.