Sending multiple sensor readings between two Arduinos

Hello all-

First, thanks for reading. I'm working on an automotive dash display that will read data from a number of sensors (approx 15) and output data for 23 variables. I'm trying to send all of this data from one Arduino to the other via two HC-05 modules. I've been using this example (Parsing Serial Data Sent To Arduino - esologic),which works with 4 or 5 sensor outputs but adding more and I'm (understandably) getting errors. The total message size is about 160 bytes. Any suggestions on a better approach?

I've thought of maybe converting each sensor reading into a single byte (since almost all are <255), which would reduce the number of bytes to be transferred to about 30, but I'm not sure where to start.

Why not just split the message into several snipets?
Instead of sending it all at once,
send each sensor 1 at a time with a leading data "header" of which sensor the following data sent corresponds to?

Also what speed are you having them connect and "Talk" at?
I would crank down the speed to the slowest settings possible.
It seems in my projects "slow data" can plow through almost anything, and end up correct on the other side.

I was thinking about that- I'm just not sure where to get started coding. I'm still learning about how Serial data is transferred. For example, the coolant temp sensor outputs 100 degrees which is stored as Ct (an int). I could send "" to the second arduino, but I'm not sure how to code it so the second arduino will parse the string it received and recognize that 100 can be assigned to the variable Ct.

Right now I'm transferring at the default 9600 but could easy change to 4800.

I'm no expert but what I have done is added a special character to the end of my data sends,
IE 100* so the serial keeps getting "next" bytes until the byte == your special character "*" then takes what it has, and dumps it into a variable.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

If you have a good receiving system the sending system should be very straightforward.

...R

Thanks all. Robin2- I've seen your serial thread and looked it over multiple times and finally figured out how I can apply it. Thanks for posting that in the first place.

I've tried to adapt your code so that the sending device will send a message like <Ct,100>. The Ct would denote which sensor and the integer the value of the reading. Most of it is working but I'm hung up- I'm trying to have it assign the value of 100 to the Ct variable but the if statement is not activating because it's not seeing messageFromPC as "Ct". Using != works fine and assigns the value to Ct. What am I missing?

void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars,",");      // get the first part - the string
    strcpy(messageFromPC, strtokIndx);// copy it to messageFromPC
    
  	strtokIndx = strtok(NULL, ">"); // this continues where the previous call left off
    integerFromPC = atoi(strtokIndx);     // convert this part to an integer

  Serial.print(messageFromPC);	  
  if (messageFromPC == "Ct") {   
    Ct = integerFromPC; }
}

Nevermind- realized that messageFromPC is an array so I needed to check it value by value.

if (messageFromPC[0] == 'C')

Etc...

You can use the strcmp() function to test for a multi-character match.

However, even better would be to use single character codes. Between the upper- and lower-case characters you have 52 options.

...R

Yeah, I plan on doing that- will clean up the code a little. Thanks again!

Robin- I'm using your code (with modifications of course, but the idea is the same). About 1 in 10 readings or so have errors, however. Here are a couple snippets of printing off the tempChars.

TempChars:M<C,17
25TempChars:fv,4.0
26TempChars:O,17
25TempChars:P,0
24TempChars:R,
26TempChars:H,
25TempChars:S,0
25TempChars:A,383
26TempChars:D,B
25TempChars:U,13
25TempChars:F,5
25TempChars:E,-197
25TempChars:I,,197
26TempChars:B,-197
25TempChars:2
25TempChars:G,,0.008.8

26TempChars:D,
24TempChars:fp,23.8
26TempChars:G,20
25TempChars:ff,0.00
26TempChars:fu,0.00
25TempChars:E,-197
25TempChars:I,-197
26TempChars:B,-197
24TempChars:H,
26TempChars:M,
25TempChars:fx,-58.4
242624252525TempChars:8T,0

The numbers in the 20s are the number of milliseconds it took to run the for loop. You can in the first selection some issues for some variables: I has two commas, and so does G along with additional .8 tagged on the end. Sometimes extra random characters (@, periods, commas, etc) get added into the character array. Any idea what could be causing this? The other arduino is sending data in the following format:

Serial32.print("<C,"); Serial32.print(Ct,0); Serial32.print(">");

Here is the code for the functions I'm using:

void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;

while (Serial3.available() > 0 && newData == false) {
rc = Serial3.read();

if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}

else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//============

void parseData() {      // split the data into its parts

char * strtokIndx; // this is used by strtok() as an index


Serial.print("TempChars:"); Serial.println(tempChars);
strtokIndx = strtok(tempChars,",");      // get the first part - the string
strcpy(messageFromPC, strtokIndx);// copy it to messageFromPC

if(messageFromPC[0] == 'f') {
strtokIndx = strtok(NULL, ",");
floatFromPC = atof(strtokIndx);
} else {
strtokIndx = strtok(NULL, ">"); // this continues where the previous call left off
integerFromPC = atoi(strtokIndx); // convert this part to an integer
}
if (messageFromPC[0] == 'C') {
Ct = integerFromPC;
//Serial.print("Coolant:"); Serial.print(Ct); Serial.print("F;");
}

if (messageFromPC[0] == 'O') {
Ot = integerFromPC;
//Serial.print("Oil:"); Serial.print(Ot); Serial.print("F;");
}
if (messageFromPC[0] == 'P') {
Op = integerFromPC;
//Serial.print(Op); Serial.println("PSI");
}
if (messageFromPC[0] == 'R') {
rpm = integerFromPC;
//Serial.print("RPM: "); Serial.println(rpm);
}
if (messageFromPC[0] == 'S') {
Sp = integerFromPC;
//Serial.print("Speed:"); Serial.println(Sp);
}
if (messageFromPC[0] == 'U') {
Va = integerFromPC;
//Serial.print("Vac:"); Serial.print(Va); Serial.println("inHg;");
}
if (messageFromPC[0] == 'F') {
Fl = integerFromPC;
//Serial.print("Fuel:"); Serial.print(Fl);Serial.println("%");
}
if (messageFromPC[0] == 'E') {
Et = integerFromPC;
//Serial.print("Outside Temp:"); Serial.print(Et); Serial.println(" F");
}
if (messageFromPC[0] == 'I') {
It = integerFromPC;
//Serial.print("Internal Temp:"); Serial.print(It); Serial.println(" F");
}
if (messageFromPC[0] == 'B') {
Vt = integerFromPC;
//Serial.print("Vent Temp:"); Serial.print(Vt); Serial.println(" F");
}
if (messageFromPC[0] == 'T') {
Tt = integerFromPC;
////Serial.print("Trans Temp:"); //Serial.print(Tt); //Serial.println(" F")
}
if (messageFromPC[0] == 'Z') {
Z = integerFromPC;
//Serial.print("Heading: "); //Serial.println(Z);
}
if (messageFromPC[0] == 'H') {
Hr = integerFromPC;
//Serial.print("Time:"); //Serial.print(Hr); //Serial.print(":"); //Serial.println(Mn);
}
if (messageFromPC[0] == 'M') {
Mn = integerFromPC;
//Serial.print("Time:"); //Serial.print(Hr); //Serial.print(":"); //Serial.println(Mn);
}
if (messageFromPC[0] == 'A') {
Alt = integerFromPC;
//Serial.print("Altitude:"); //Serial.print(Alt); //Serial.println("m");
}
if (messageFromPC[0] == 'D') {
Cr = integerFromPC;
//Serial.print("Course:"); //Serial.print(Cr); //Serial.println("degrees");
}
if (messageFromPC[0] == 'G') {
Ft = integerFromPC;
//Serial.print("Fuel Temp:"); //Serial.print(Ft); //Serial.println("F");
}
if (messageFromPC[0] == 'f' && messageFromPC[1] == 'v') {
Vav = floatFromPC;
//Serial.print("Voltage:"); //Serial.print(Vav); //Serial.print(" volts");
}
if (messageFromPC[0] == 'f' && messageFromPC[1] == 'u') {
Fu = floatFromPC;
//Serial.print("Trip:"); //Serial.println(Fu); //Serial.print("ml");
}
if (messageFromPC[0] == 'f' && messageFromPC[1] == 'f') {
Ff = floatFromPC;
//Serial.print("Rate:"); //Serial.print(Ff); //Serial.println("L/Min; ");
}
if (messageFromPC[0] == 'f' && messageFromPC[1] == 'p') {
Fp = floatFromPC;
//Serial.print("Fuel Pressure:"); //Serial.print(Fp); //Serial.println("PSI;");
}
if (messageFromPC[0] == 'f' && messageFromPC[1] == 'x') {
X = floatFromPC;
//Serial.print("Left/Right: "); //Serial.println(X);
}
if (messageFromPC[0] == 'f' && messageFromPC[1] == 'y') {
Y = floatFromPC;
//Serial.print("Up/Down: "); //Serial.println(Y);

}
}

Please post the complete program.

And before doing so use the AutoFormat tool to make your code easier to read.

It may help to use ELSE IF

And rather than a whole bunch of if (messageFromPC[0] == 'f' && messageFromPC[1] == 'v') { i would do

if (messageFromPC[0] == 'f' ) {
    if ( messageFromPC[1] == 'v') {
    
    }
    else if ( messageFromPC[1] == 'u') {

    }
    // etc
}

You will be much less likely to make a mistake

...R

Thanks. One issue, I believe, is that the other arduino is taking over 1 second to run it's loop. I have a lot of work to do to trim it, but some of the sensor readings just take 300-600 milliseconds.

The receiving arduino code is below. It was too long to post in it's entirety so I removed much of the lcd printing instructions (left the first few lines in as an example). I haven't had a chance to go through and add the 'else's but will do that soon.

#include <LiquidCrystal.h>
const byte numChars = 12;
char receivedChars[numChars];
char tempChars[numChars];
char messageFromPC[numChars] = {};
int integerFromPC = 0;
float floatFromPC = 0.0;
int Ct, Ot, Et, It, Vt, Tt, Ft, rpm, Cr, Alt, Z;
byte  Fl, Va, Op, Sp, Hr, Mn;
float Vav, Fp, Y, X, Ff, Fu;
boolean newData = false;
unsigned long start;
//Pages
int page_counter = 1;
int calc_page = page_counter;
int up = 45;
boolean current_up = LOW;
boolean last_up = LOW;
boolean current_down = LOW;
boolean last_down = LOW;
int down = 10;           //Down button
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  Serial.begin(9600);
  Serial3.begin(9600);
  Serial.println("To test, enter data <SensorName,Value>");
  lcd.begin(20, 4);
}

//---- De-bouncing function for all buttons----//
boolean debounce(boolean last, int pin)
{
  boolean current = digitalRead(pin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(pin);
  }
  return current;
}


void loop() {
  start = millis();
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
    // this temporary copy is necessary to protect the original data
    //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    //showParsedData();
    newData = false;
  }
  //Pages
  current_up = debounce(last_up, up);         //Debounce for Up button
  current_down = debounce(last_down, down);   //Debounce for Down button
  if (last_up == LOW && current_up == HIGH) { //When up button is pressed
    lcd.clear();                     //When page is changed, lcd clear to print new page
    if (page_counter < 4) {           //Page counter never higher than 3(total of pages)
      page_counter = page_counter + 1; //Page up
    }
    else {
      page_counter = 1;
    }
  }
  last_up = current_up;
  //Page Down
  if (last_down == LOW && current_down == HIGH) { //When down button is pressed
    lcd.clear();                     //When page is changed, lcd clear to print new page
    if (page_counter > 1) {           //Page counter never lower than 1 (total of pages)
      page_counter = page_counter - 1; //Page down
    }
    else {
      page_counter = 1;
    }
  }
  last_down = current_down;
  //Screen 1:
  switch (page_counter) {
    case 1: {
        lcd.setCursor(0, 0);
        lcd.print("Clnt:");
        lcd.print(Ct);
        lcd.setCursor(9, 0);
        lcd.print("F;");
        lcd.setCursor(11, 0);
        lcd.print("Volt:");
        lcd.print(Vav, 1);
      //...
      }
      break;
///3 more pages
   
  }
  Serial.print(millis() - start);
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial3.available() > 0 && newData == false) {
    rc = Serial3.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
        //Serial.print("RECEIVED:");Serial.println(rc);
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void parseData() {      // split the data into its parts
  char * strtokIndx; // this is used by strtok() as an index
  strtokIndx = strtok(tempChars, ",");     // get the first part - the string
  strcpy(messageFromPC, strtokIndx);// copy it to messageFromPC
  Serial.print("TempChars:"); Serial.println(strtokIndx);

  if (messageFromPC[0] == 'f') {
    strtokIndx = strtok(NULL, ",");
    floatFromPC = atof(strtokIndx);
  } else {
    strtokIndx = strtok(NULL, ">"); // this continues where the previous call left off
    integerFromPC = atoi(strtokIndx); // convert this part to an integer
  }
  Serial.print("TempChars:"); Serial.println(strtokIndx); Serial.print(floatFromPC); Serial.print(integerFromPC);

  if (messageFromPC[0] == 'C') {
    Ct = integerFromPC;
    //Serial.print("Coolant:"); Serial.print(Ct); Serial.print("F;");
  }

  if (messageFromPC[0] == 'O') {
    Ot = integerFromPC;
    //Serial.print("Oil:"); Serial.print(Ot); Serial.print("F;");
  }
  if (messageFromPC[0] == 'P') {
    Op = integerFromPC;
    //Serial.print(Op); Serial.println("PSI");
  }
  if (messageFromPC[0] == 'R') {
    rpm = integerFromPC;
    //Serial.print("RPM: "); Serial.println(rpm);
  }
  if (messageFromPC[0] == 'S') {
    Sp = integerFromPC;
    //Serial.print("Speed:"); Serial.println(Sp);
  }
  if (messageFromPC[0] == 'U') {
    Va = integerFromPC;
    //Serial.print("Vac:"); Serial.print(Va); Serial.println("inHg;");
  }
  if (messageFromPC[0] == 'F') {
    Fl = integerFromPC;
    //Serial.print("Fuel:"); Serial.print(Fl);Serial.println("%");
  }
  if (messageFromPC[0] == 'E') {
    Et = integerFromPC;
    //Serial.print("Outside Temp:"); Serial.print(Et); Serial.println(" F");
  }
  if (messageFromPC[0] == 'I') {
    It = integerFromPC;
    //Serial.print("Internal Temp:"); Serial.print(It); Serial.println(" F");
  }
  if (messageFromPC[0] == 'B') {
    Vt = integerFromPC;
    //Serial.print("Vent Temp:"); Serial.print(Vt); Serial.println(" F");
  }
  if (messageFromPC[0] == 'T') {
    Tt = integerFromPC;
    ////Serial.print("Trans Temp:"); //Serial.print(Tt); //Serial.println(" F")
  }
  if (messageFromPC[0] == 'Z') {
    Z = integerFromPC;
    //Serial.print("Heading: "); //Serial.println(Z);
  }
  if (messageFromPC[0] == 'H') {
    Hr = integerFromPC;
    //Serial.print("Time:"); //Serial.print(Hr); //Serial.print(":"); //Serial.println(Mn);
  }
  if (messageFromPC[0] == 'M') {
    Mn = integerFromPC;
    //Serial.print("Time:"); //Serial.print(Hr); //Serial.print(":"); //Serial.println(Mn);
  }
  if (messageFromPC[0] == 'A') {
    Alt = integerFromPC;
    //Serial.print("Altitude:"); //Serial.print(Alt); //Serial.println("m");
  }
  if (messageFromPC[0] == 'D') {
    Cr = integerFromPC;
    //Serial.print("Course:"); //Serial.print(Cr); //Serial.println("degrees");
  }
  if (messageFromPC[0] == 'G') {
    Ft = integerFromPC;
    //Serial.print("Fuel Temp:"); //Serial.print(Ft); //Serial.println("F");
  }
  if (messageFromPC[0] == 'f' && messageFromPC[1] == 'v') {
    Vav = floatFromPC;
    //Serial.print("Voltage:"); //Serial.print(Vav); //Serial.print(" volts");
  }
  if (messageFromPC[0] == 'f' && messageFromPC[1] == 'u') {
    Fu = floatFromPC;
    //Serial.print("Trip:"); //Serial.println(Fu); //Serial.print("ml");
  }
  if (messageFromPC[0] == 'f' && messageFromPC[1] == 'f') {
    Ff = floatFromPC;
    //Serial.print("Rate:"); //Serial.print(Ff); //Serial.println("L/Min; ");
  }
  if (messageFromPC[0] == 'f' && messageFromPC[1] == 'p') {
    Fp = floatFromPC;
    //Serial.print("Fuel Pressure:"); //Serial.print(Fp); //Serial.println("PSI;");
  }
  if (messageFromPC[0] == 'f' && messageFromPC[1] == 'x') {
    X = floatFromPC;
    //Serial.print("Left/Right: "); //Serial.println(X);
  }
  if (messageFromPC[0] == 'f' && messageFromPC[1] == 'y') {
    Y = floatFromPC;
    //Serial.print("Up/Down: "); //Serial.println(Y);

  }
}

//============
1 Like

mrbollero:
One issue, I believe, is that the other arduino is taking over 1 second to run it's loop.

Then you need to fix that. Aim for AT MOST 100 millisecs. And 10 millisecs would be better.

If printing to the LCD is causing the problem then only do a little bit of the printing in each iteration of loop. The human eye won't notice.

If (which I doubt) it is completely impossible to reduce the loop() time for the receiver then you will have to slow down the transmitter so it sends less than 64 bytes in the time it takes the receiver to loop().

...R

I was able to reduce from over 2 seconds down to about 600 milliseconds but I don't see it getting much faster. There are just way too many sensors to get it below the 100 mark. Another issue is that I'm having to use Software Serial to send the data due to some wiring issues, but I have a pcb coming that will allow me to resolve that. I would guess many of the errors come from that. Thanks for the suggestions.

mrbollero:
I was able to reduce from over 2 seconds down to about 600 milliseconds but I don't see it getting much faster. There are just way too many sensors to get it below the 100 mark.

Why would it take more than 1 millisec to get data from a sensor? Indeed why would it take more than 10 microsecs?

But without seeing your complete program and the datasheets for the sensors I can't say more than that.

...R

That's a great question, and I've been trying to figure it out myself. I ran some tests today to see if I could reduce the time for readings and my results are below. My unmodified code is full of floats and not very efficient formulas. The 2nd version I edited extensively to remove as many floats as possible and set variables as the smallest variable type I could. The 3rd version is the same as the 2nd but uses print(F("...) for all of the serial printing.

Sensor names are on the far left. In the first column is the average milliseconds that have passed in the loop. The second (boxed) column is the number of milliseconds used by that sensor.

I have a few types of sensors. Coolant and oil temp, oil pressure, and fuel temp are all thermistors. Voltage is measured through a voltage divider. Vacuum uses a digital manifold vacuum pressure sensor. GPS is a Ublox Neo-6m. Fuel pressure is a 30psi digital sensor. Fuel flow is a hall effect based liquid flow sensor. Accelerometer is an MPU-6050.

My most recent code is below. I know it is extremely imperfect (this is my first real Arduino project, and my first real coding project) but I'm learning as I go. Any suggestions would be appreciated.

#include <math.h>
#include <TinyGPS.h>
#include <SoftwareSerial.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#define EXT_BUS 22
#define INT_BUS 23
#define AC_BUS 24
//GPS in Serial 2
#include <Wire.h>
SoftwareSerial Serial32(14, 15); //need to fix with new shield (BT1)
//Coolant, Oil, Trans Temp
const byte t1 = 246, t2 = 46, t4 = 84;
const int t3 = 297;
const byte OTP = 1;
byte Ct, Ot, Tt;
const byte TTP = 2;
const float rtov (5 / 1024);
//Oil Pressure
const byte OPP = 3;
byte Op;
const int op1 = -3004, op2 = 29332;
const long op3 = 95837, op4 = 105439;
//Vacuum
const byte VAP = 7;
byte Va1 = 27, Va2 = 19;
int Va;
//Digital Temp Sensors
OneWire oneWire1(EXT_BUS);
OneWire oneWire2(INT_BUS);
OneWire oneWire3(AC_BUS);
DallasTemperature sensors1(&oneWire1);
DallasTemperature sensors2(&oneWire2);
DallasTemperature sensors3(&oneWire3);
int Et = (sensors1.getTempFByIndex(0));
int It = (sensors2.getTempFByIndex(0));
int Vt = (sensors3.getTempFByIndex(0));
//Battery Voltage
const byte VOI = 15;
byte Vo, Vtot;
const int Vo2 = (7500 / (30000 + 7500)) * 100;
const int numReadings = 5;
int readings[numReadings];
int readIndex = 0;
float Vav;
unsigned long timingstart;
//RPM
//volatile byte rpmcount = 0;
//unsigned long rpmnum = 0;
//int rpmdec = 0;
int rpm = 0;
//unsigned long timeold = 0;
//int interrupt = 4;
int cylinders = 8;
volatile bool newPulse = false;
volatile unsigned long lastPulseTime;
volatile unsigned long lastPulseInterval;
//GPS
long lat, lon;
float flat, flon, Sp, Spc, Alt;
unsigned long age, date, time, chars, Cr;
int year;
byte Hr, Mn;
byte month, day, hour, minute, second, hundredths;
unsigned short sentences, failed;
TinyGPS gps;
//Fuel Level
byte Fl;
const byte FlOhmsMax = 60, FlOhmsMin = 10;
const byte LevelMin = ((5 * (FlOhmsMax / (FlOhmsMax + 100))) * 100), LevelMax = ((5 * (FlOhmsMin / (FlOhmsMin + 100))) * 100);
const int LevelP = (LevelMax - LevelMin);
//define voltage conversion formula variables
//Fuel Pressure
const byte FPP = 6;
const byte Fp1 = 11, Fp2 = 20;
float Fp;
//Fuel Temp
const byte FTP = 4;
const byte ft2 = 47, ft4 = 137;
byte Ft;
const int ft1 = 270, ft3 = 680;
//Fuel Flow
byte sensorPin = 18;
float calibrationFactor = 11;
volatile byte pulseCount;
float Ff;
float flowMilliLitres;
float Fu;
unsigned long oldTime;
//Accelerometer
const int MPU_addr = 0x68; int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
int minVal = 265; int maxVal = 402;
double x; double y; double z;
int calibratepin = 27, calibratestate = 0;
float pitchcalib = 0, rollcalib = 0, compcalib = 0;
bool timeoutOccurred(void);

void setup() {
  //RPM trigger
  attachInterrupt(digitalPinToInterrupt(19), rpmtrigger, FALLING);
  //Digital Temp
  sensors1.begin();
  sensors2.begin();
  sensors3.begin();
  sensors1.setResolution(9);
  sensors2.setResolution(9);
  sensors3.setResolution(9);
  Serial.begin(9600);
  Serial2.begin(4800);
  Serial32.begin(9600);
  //BT2serial.begin(9600);
  //Accelerometer
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);
  pulseCount = 0;
  Ff = 0.0;
  flowMilliLitres = 0;
  Fu = 0;
  oldTime = 0;
  attachInterrupt(digitalPinToInterrupt(18), pulseCounter, FALLING);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }

}
void gpsdump(TinyGPS &gps)
gps.f_altitude();
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
gps.f_speed_mph();
gps.course();
gps.f_get_position(&flat, &flon, &age);
Hr = (static_cast<int>(hour));
Mn = (static_cast<int>(minute));
Sp = (gps.f_speed_mph());
Alt = (gps.f_altitude());
Cr = (gps.course() / 100);
}
void rpmtrigger()
{
  unsigned long now = micros();
  unsigned long pulseInterval = now - lastPulseTime;
  if (pulseInterval > 10)
  {
    lastPulseTime = now;
    lastPulseInterval = pulseInterval;
    newPulse = true;
  }
}
void pulseCounter() {
  pulseCount++;
}

void loop() {
  timingstart = (millis());
  //Coolant DONE
  if ((analogRead(CTP)) < 270) {
    Ct = (t3 - ((analogRead(CTP) * rtov) * t4));
  }
  else {
    Ct = (t1 - ((analogRead(CTP) * rtov) * t2));
  }
  Serial32.print(F("<C,")); Serial32.print(Ct); Serial32.print(F(">"));
  Serial.print(F("Coolant:")); Serial.print(Ct); Serial.println(F("F;"));
  Serial.print(F("Coolant time:")); Serial.println(millis() - timingstart);
  //same setup for other thermistors (9000 character limit)

  //Voltage DONE
  Vo = (((analogRead(VOI) * rtov) * 100) / (Vo2)) * 10;
  Vtot = Vtot - readings[readIndex];
  readings[readIndex] = Vo;
  Vtot = Vtot + readings[readIndex];
  readIndex = readIndex + 1;
  if (readIndex >= numReadings) {
    readIndex = 0;
  }
  Vav = (Vtot / numReadings) / 10;
  Serial32.print(F("<fv,")); Serial32.print(Vav); Serial32.print(F(">"));
  Serial.print(F("Volt:")); Serial.println(Vo / 10);
  Serial.print(F("VoltAverage:")); Serial.println(Vav, 1);
  Serial.print(F("Voltagetime:")); Serial.println(millis() - timingstart);
  //Vacuum DONE
  Va = (Va1 - (Va2 * (analogRead(VAP) * rtov)));
  //Va = Va/2 yeids approx PSI
  Serial32.print(F("<U,")); Serial32.print(Va); Serial32.print(F(">"));
  Serial.print(F("Vac:")); Serial.print(Va); Serial.println(F("inHg;"));
  Serial.print(F("Vactime:")); Serial.println(millis() - timingstart);
  //RPM
  int rpm;
  if (newPulse)
  {
    rpm = 60000000 / lastPulseInterval;
    newPulse = false;
  }
  else
  {
    rpm = 0;
  }
  if (rpm < 1) rpm = 0;
  Serial32.print(F("<R,")); Serial32.print(rpm); Serial32.print(F(">"));
  Serial.print(F("RPM: ")); Serial.println(rpm);
  Serial.print(F("RPMtime:")); Serial.println(millis() - timingstart);

  //GPS
  bool newdata = false;
  unsigned long start = millis();
  Serial2.flush();
  while (millis() - start < 600)
  { if (Serial2.available() > 0)
    { char c = Serial2.read();
        if (gps.encode(c))
          { newdata = true;
                 break;
              
           }
      }
  }
  if (newdata)
  {
    gpsdump(gps);
  }

  Serial32.print(F("<S,")); Serial32.print(Sp, 0); Serial32.print(F(">"));
  //...prints other variables
  Serial.print(F("Time:")); Serial.print(Hr); Serial.print(F(":")); Serial.println(Mn);
  //...prints other variables


  //Fuel Flow
  if ((millis() - oldTime) > 1000) {
    detachInterrupt(digitalPinToInterrupt(18));
    //Ff = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    Ff = (((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor) * .26; ///gives gallons
    oldTime = millis();
    //flowMilliLitres = (Ff / 60) * 1000; //gives ml
    flowMilliLitres = (Ff / 60) * .26; //gives gallons
    Fu += flowMilliLitres;
  }
  Serial32.print(F("<ff,")); Serial32.print(Ff, 2); Serial32.print(F(">"));
//...
  Serial.print(F("Rate:")); Serial.print(Ff, 2); Serial.println(F("L/Min; "));
//...
  pulseCount = 0;
  attachInterrupt(digitalPinToInterrupt(18), pulseCounter, FALLING);
  Serial.print(F("Fuel flow time:")); Serial.println(millis() - timingstart);

  //Digital Temp
  sensors1.requestTemperatures();
  sensors2.requestTemperatures();
  sensors3.requestTemperatures();

  Serial32.print(F("<E,")); Serial32.print(Et); Serial32.print(F(">"));
  //...
  Serial.print(F("Outside Temp:")); Serial.print(Et); Serial.println(F(" F"));
  //...
  Serial.print(F("Digital temp time:")); Serial.println(millis() - timingstart);
  //ACCEL
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true);
  AcX = Wire.read() << 8 | Wire.read();
  AcY = Wire.read() << 8 | Wire.read();
  AcZ = Wire.read() << 8 | Wire.read();
  int xAng = map(AcX, minVal, maxVal, -90, 90);
  int yAng = map(AcY, minVal, maxVal, -90, 90);
  int zAng = map(AcZ, minVal, maxVal, -90, 90);
  x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI); y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI); z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);
  if (x > 180) x = (x - 360);
  if (y > 180) y = (y - 360);
  Serial32.print(F("<fx,")); Serial32.print(x, 1); Serial32.print(F(">"));
  //...
  Serial.print(F("Left/Right: ")); Serial.println(x, 1);
  //...
  Serial.print(F("Accel time:")); Serial.println(millis() - timingstart);

  Serial.print(F("TOTAL LOOP TIME:")); Serial.println(millis() - timingstart);
}
[/ code]

My assumption is that the Serial printing is what is taking up most of the additional time. I have been running at 9600 baud just for accuracy but can and should increase that dramatically when sending data via usb. I will experiment with baud rate to the bluetooth receiver once I have the wiring straightened out.


Did some testing, baud rate made little to no difference. 19200 seemed to work more quickly than 115200. I only changed the baud rate for the Serial0- will also need to try changing the softwareserial BT speed as well.

I can't make sense of your code the way it is laid out - I have tried tidying it up but it is just too long. Please use the AutoFormat tool to lay it out for easy reading and post the updated version.

Also there seems to be a missing { at the start of the function gpsdump()

...R

That is autoformatted. In my code I have it all divided into sections but had to remove those due to the 9k character limit.

And yes, you're right, it looks like I accidentally deleted the gpsdump { when trimming the code for posting. It exists in my copy of the code.

Below are just the main likely problem sections of my code. Hopefully that makes it a little easier to scan.

Everything before the void setup function can be found in the code above.

I don't think that the majority of the code has anything wrong with like. It is likely all of the printing that is slowing it down. I would guess that the potential problem areas are the interrupts (fuel flow and RPM) or GPS (I have been extensively troubleshooting it, finally have it working reliably but need to experiment with baud rates). The ds19b20 sensors are taking about as much time as they should at the set resolution and the MPU-6050 is consistently taking 34ms which I assume is normal.

void setup() {
  attachInterrupt(digitalPinToInterrupt(19), rpmtrigger, FALLING);
  //Digital Temp
  sensors1.begin();
  sensors2.begin();
  sensors3.begin();
  sensors1.setResolution(9);
  sensors2.setResolution(9);
  sensors3.setResolution(9);
  Serial.begin(9600);
  Serial2.begin(4800);
  Serial32.begin(9600);
  //BT2serial.begin(9600);
  //Accelerometer
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);
  pulseCount = 0;
  Ff = 0.0;
  flowMilliLitres = 0;
  Fu = 0;
  oldTime = 0;
  attachInterrupt(digitalPinToInterrupt(18), pulseCounter, FALLING);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }

}
void gpsdump(TinyGPS &gps)
{
  gps.f_altitude();
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  gps.f_speed_mph();
  gps.course();
  gps.f_get_position(&flat, &flon, &age);
  Hr = (static_cast<int>(hour));
  Mn = (static_cast<int>(minute));
  Sp = (gps.f_speed_mph());
  Alt = (gps.f_altitude());
  Cr = (gps.course() / 100);
}
void rpmtrigger()
{
  unsigned long now = micros();
  unsigned long pulseInterval = now - lastPulseTime;
  if (pulseInterval > 10)
  {
    lastPulseTime = now;
    lastPulseInterval = pulseInterval;
    newPulse = true;
  }
}
void pulseCounter() {
  pulseCount++;
}

void loop() {
  timingstart = (millis());
  //Coolant 
  if ((analogRead(CTP)) < 270) {
    Ct = (t3 - ((analogRead(CTP) * rtov) * t4));
  }
  else {
    Ct = (t1 - ((analogRead(CTP) * rtov) * t2));
  }
  Serial32.print("<C,"); Serial32.print(Ct); Serial32.print(">");
  Serial.print("Coolant:"); Serial.print(Ct); Serial.println("F;");
  Serial.print("Coolant time:"); Serial.println(millis() - timingstart);
  /
  //RPM
  int rpm;
  if (newPulse)
  {
    rpm = 60000000 / lastPulseInterval;
    newPulse = false;
  }
  else
  {
    rpm = 0;
  }
  if (rpm < 1) rpm = 0;
  Serial32.print("<R,"); Serial32.print(rpm); Serial32.print(">");
  Serial.print("RPM: "); Serial.println(rpm);
  Serial.print("RPMtime:"); Serial.println(millis() - timingstart);

  //GPS
  bool newdata = false;
  unsigned long start = millis();
  Serial2.flush();
  while (millis() - start < 600)
  { if (Serial2.available() > 0)
    { char c = Serial2.read();
      if (gps.encode(c))
      { newdata = true;
        break;
      }
    }
  }
  if (newdata)
  {
    gpsdump(gps);
  }

  Serial32.print("<S,"); Serial32.print(Sp, 0); Serial32.print(">");
  Serial32.print("<A,"); Serial32.print(Alt, 0); Serial32.print(">");
  Serial32.print("<D,"); Serial32.print(Cr, 0); Serial32.print(">");
  Serial32.print("<H,"); Serial32.print(Hr); Serial32.print(">");
  Serial32.print("<M,"); Serial32.print(Mn); Serial32.print(">");
  Serial.print("Time:"); Serial.print(Hr); Serial.print(":"); Serial.println(Mn);
  Serial.print("Speed:"); Serial.println(Sp);
  Serial.print("Altitude:"); Serial.print(Alt); Serial.println("m");
  Serial.print("Course:"); Serial.print(Cr); Serial.println("degrees");
  Serial.print("GPStime:"); Serial.println(millis() - timingstart);



  //Fuel Flow
  if ((millis() - oldTime) > 1000) {
    detachInterrupt(digitalPinToInterrupt(18));
    Ff = (((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor) * .26; ///gives gallons
    oldTime = millis();
    flowMilliLitres = (Ff / 60) * .26; //gives gallons
    Fu += flowMilliLitres;
  }
  Serial32.print("<ff,"); Serial32.print(Ff, 2); Serial32.print(">");
  Serial32.print("<fu,"); Serial32.print(Fu, 2); Serial32.print(">");
  Serial.print("Rate:"); Serial.print(Ff, 2); Serial.println("L/Min; ");
  Serial.print("Trip:"); Serial.println(Fu, 0); Serial.print("ml");
  pulseCount = 0;
  attachInterrupt(digitalPinToInterrupt(18), pulseCounter, FALLING);
  Serial.print("Fuel flow time:"); Serial.println(millis() - timingstart);

  /
  //ACCEL
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true);
  AcX = Wire.read() << 8 | Wire.read();
  AcY = Wire.read() << 8 | Wire.read();
  AcZ = Wire.read() << 8 | Wire.read();
  int xAng = map(AcX, minVal, maxVal, -90, 90);
  int yAng = map(AcY, minVal, maxVal, -90, 90);
  int zAng = map(AcZ, minVal, maxVal, -90, 90);
  x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI); y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI); z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);
  if (x > 180) x = (x - 360);
  if (y > 180) y = (y - 360);

  Serial32.print("<fx,"); Serial32.print(x, 1); Serial32.print(">");
  Serial32.print("<fy,"); Serial32.print(y, 1); Serial32.print(">");
  Serial32.print("<Z,"); Serial32.print(z, 0); Serial32.print(">");
  Serial.print("Left/Right: "); Serial.println(x, 1);
  Serial.print("Up/Down: "); Serial.println(y, 1);
  Serial.print("Heading: "); Serial.println(z, 0);
  Serial.print("Accel time:"); Serial.println(millis() - timingstart);

  Serial.print("TOTAL LOOP TIME:"); Serial.println(millis() - timingstart);
}