Compiling error when using tabs in IDE

Hi,

For the steering of my railway I have developed a very large logic. So to make it easier to maintain I splitted it up into tabs in IDE 2.0.3.
But when I put the code for the attached keyboard (TM1638QYF) in a seperate tab, I got compiler errors.
I'm wondering why ?

I made an abstract of the complete sketch so it's easier to read here in this topic.
So here is the complete sketch

#include <EEPROM.h>
#include <elapsedMillis.h>
#include <MuxShield.h>

// Needed for RS485
#include "RS485_protocol.h"

// Display TM1638
#include <TM1638.h>
#include <TM1638QYF.h>
//TM1638QYF::TM1638QYF(byte dataPin, byte clockPin, byte strobePin)
TM1638QYF module(24, 25, 26);

byte deviceId = 0;  //Variable to store data read from EEPROM.

int displayStatus = 0;
elapsedMillis displayTimer;
char displayText0[9];  // string om teksten op Display te tonen
char displayText1[9];  // string om teksten op Display te tonen
char displayText2[9];  // string om teksten op Display te tonen
char displayText3[9];  // string om teksten op Display te tonen
char displayText4[9];  // string om teksten op Display te tonen
int debugRS485 = 0;
boolean debugTreinLocation = false;
boolean debugStation = false;
boolean debugSpeed = false;
int modus = 3;
byte treinID[24];
boolean debugTrein[24];
byte treinIDLinks = 0;
byte treinIDRechts = 0;
//===========================================================================
void getKey(TM1638QYF* module, word* button) {
  *button = module->getButtons();
}
void displayNumber(TM1638QYF* module, word* value) {
  module->setDisplayToDecNumber(*value, 0, false);
}
void displayString(TM1638QYF* module, char* msgk, int dot) {
  module->setDisplayToString(msgk, 1 << dot);
}
//===========================================================================
int checkKey(TM1638QYF* module) {
  static int keyStatus;
  static word oldButton;
  static elapsedMillis timerKey;
  int key = 0;
  boolean sameKey;
  word buttons = module->getButtons();
  if (buttons != 0) {
    if (oldButton == 0) {
      timerKey = 0;
    }
    if (buttons == oldButton && timerKey < 1000) {
      sameKey = true;
    } else {
      sameKey = false;
    }
  }
  if (buttons != 0 && !sameKey) {
    for (int i = 0; i < 16; i++) {
      if (buttons >> i == 1) {
        key = i + 1;
        Serial.print(F(" Key :"));
        Serial.println(key);
      }
    }
  }
  oldButton = buttons;
  return key;
}
//===========================================================================
void setup() {
  EEPROM.get(0, deviceId);

  Serial.begin(19200);  // Initialize serial communications with the PC
  Serial.println(F(""));
  Serial.print(F("Begin, Id = "));
  Serial.println(deviceId, HEX);

  sprintf(displayText0, "Begin %02u", deviceId);
  displayKeyboard();

  // Display TM1638
  // virtual void setupDisplay(boolean active, byte intensity);
  module.setupDisplay(true, 7);
}
void loop() {
  // put your main code here, to run repeatedly:
  leesKeyboard(&module);
  displayKeyboard();
  delay(1);
}
//===========================================================================
void leesKeyboard(TM1638QYF* module) {
  static int statusKeyboard;
  static int functie;
  static int key2;
  static int key3;
  static boolean debug;
  static elapsedMillis timerKeyboard;
  if (timerKeyboard > 5000) {
    statusKeyboard = 0;
    functie = 0;
  }

  int key = checkKey(module);
  if (key != 0) {
    timerKeyboard = 0;
  }
  if (key != 0) {
    switch (statusKeyboard) {
      case 0:  // lees key1
        functie = key;
        displayStatus = 1;
        displayTimer = 0;
        sprintf(displayText1, "%02u", functie);
        statusKeyboard = 1;
        break;
      case 1:  // lees key2
        key2 = key;
        displayStatus = 1;
        displayTimer = 0;
        sprintf(displayText1, "%02u-%02u", functie, key2);
        statusKeyboard = 2;
        break;
      case 2:  // lees key3
        key3 = key;
        displayStatus = 1;
        displayTimer = 0;
        sprintf(displayText1, "%02u-%02u-%02u", functie, key2, key3);
        statusKeyboard = 3;
        break;
      default:
        statusKeyboard = 0;
        break;
    }
    if (statusKeyboard == 3) {
      switch (functie) {
        case 1:  // Set treinID
          treinID[key2] = key3;
          statusKeyboard = 0;
          break;
        case 2:  // Set debugTrein
          if (key3 == 1) {
            debugTrein[key2] = true;
          } else {
            debugTrein[key2] = false;
          }
          statusKeyboard = 0;
          break;
        case 3:  // Debug Station
          if (key3 == 1) {
            debugStation = true;
            displayStatus = 3;
          } else {
            debugStation = false;
            displayStatus = 0;
          }
          statusKeyboard = 0;
          break;
        case 4:  // Set treinID
          if (key2 == 1) {
            treinIDLinks = key3;
          }
          if (key2 == 2) {
            treinIDRechts = key3;
          }
          statusKeyboard = 0;
          break;
        case 5:  // Set modus
          if (key2 == 1) {
            if (key3 == 1) {
              modus = 1;
            }
            if (key3 == 2) {
              modus = 2;
            }
          }
          statusKeyboard = 0;
          break;
        default:
          statusKeyboard = 0;
          break;
      }
    }
  }
}
//===========================================================================
void displayKeyboard() {
  if (displayTimer > 4000 && (displayStatus == 1 || displayStatus == 2)) {
    displayStatus = 0;
  }
  switch (displayStatus) {
    case 0:
      displayString(&module, displayText0, 0);
      break;
    case 1:
      displayString(&module, displayText1, 0);
      break;
    case 2:
      displayString(&module, displayText2, 0);
      break;
    case 3:
      displayString(&module, displayText3, 0);
      break;
    case 4:
      displayString(&module, displayText4, 3);
      break;
  }
}

And now splitted
The main part contains only

#include <EEPROM.h>
#include <elapsedMillis.h>
#include <MuxShield.h>

// Needed for RS485
#include "RS485_protocol.h"

// Display TM1638
#include <TM1638.h>
#include <TM1638QYF.h>
//TM1638QYF::TM1638QYF(byte dataPin, byte clockPin, byte strobePin)
TM1638QYF module(24, 25, 26);

First tab is named a_Keyboard

//===========================================================================
void getKey(TM1638QYF* module, word* button) {
  *button = module->getButtons();
}
void displayNumber(TM1638QYF* module, word* value) {
  module->setDisplayToDecNumber(*value, 0, false);
}
void displayString(TM1638QYF* module, char* msgk, int dot) {
  module->setDisplayToString(msgk, 1 << dot);
}
//===========================================================================
int checkKey(TM1638QYF* module) {
  static int keyStatus;
  static word oldButton;
  static elapsedMillis timerKey;
  int key = 0;
  boolean sameKey;
  word buttons = module->getButtons();
  if (buttons != 0) {
    if (oldButton == 0) {
      timerKey = 0;
    }
    if (buttons == oldButton && timerKey < 1000) {
      sameKey = true;
    } else {
      sameKey = false;
    }
  }
  if (buttons != 0 && !sameKey) {
    for (int i = 0; i < 16; i++) {
      if (buttons >> i == 1) {
        key = i + 1;
        Serial.print(F(" Key :"));
        Serial.println(key);
      }
    }
  }
  oldButton = buttons;
  return key;
}

2nd tab is named b_variables

byte deviceId = 0;  //Variable to store data read from EEPROM.

int displayStatus = 0;
elapsedMillis displayTimer;
char displayText0[9];  // string om teksten op Display te tonen
char displayText1[9];  // string om teksten op Display te tonen
char displayText2[9];  // string om teksten op Display te tonen
char displayText3[9];  // string om teksten op Display te tonen
char displayText4[9];  // string om teksten op Display te tonen
int debugRS485 = 0;
boolean debugTreinLocation = false;
boolean debugStation = false;
boolean debugSpeed = false;
int modus = 3;
byte treinID[24];
boolean debugTrein[24];
byte treinIDLinks = 0;
byte treinIDRechts = 0;

3rd tab is named c_Setup

void setup() {
  EEPROM.get(0, deviceId);

  Serial.begin(19200);  // Initialize serial communications with the PC
  Serial.println(F(""));
  Serial.print(F("Begin, Id = "));
  Serial.println(deviceId, HEX);

  sprintf(displayText0, "Begin %02u", deviceId);
  displayKeyboard();

  // Display TM1638
  // virtual void setupDisplay(boolean active, byte intensity);
  module.setupDisplay(true, 7);
}

and the last tab is named d_loop

void loop() {
  // put your main code here, to run repeatedly:
  leesKeyboard(&module);
  displayKeyboard();
  delay(1);
}
//===========================================================================
void leesKeyboard(TM1638QYF* module) {
  static int statusKeyboard;
  static int functie;
  static int key2;
  static int key3;
  static boolean debug;
  static elapsedMillis timerKeyboard;
  if (timerKeyboard > 5000) {
    statusKeyboard = 0;
    functie = 0;
  }

  int key = checkKey(module);
  if (key != 0) {
    timerKeyboard = 0;
  }
  if (key != 0) {
    switch (statusKeyboard) {
      case 0:  // lees key1
        functie = key;
        displayStatus = 1;
        displayTimer = 0;
        sprintf(displayText1, "%02u", functie);
        statusKeyboard = 1;
        break;
      case 1:  // lees key2
        key2 = key;
        displayStatus = 1;
        displayTimer = 0;
        sprintf(displayText1, "%02u-%02u", functie, key2);
        statusKeyboard = 2;
        break;
      case 2:  // lees key3
        key3 = key;
        displayStatus = 1;
        displayTimer = 0;
        sprintf(displayText1, "%02u-%02u-%02u", functie, key2, key3);
        statusKeyboard = 3;
        break;
      default:
        statusKeyboard = 0;
        break;
    }
    if (statusKeyboard == 3) {
      switch (functie) {
        case 1:  // Set treinID
          treinID[key2] = key3;
          statusKeyboard = 0;
          break;
        case 2:  // Set debugTrein
          if (key3 == 1) {
            debugTrein[key2] = true;
          } else {
            debugTrein[key2] = false;
          }
          statusKeyboard = 0;
          break;
        case 3:  // Debug Station
          if (key3 == 1) {
            debugStation = true;
            displayStatus = 3;
          } else {
            debugStation = false;
            displayStatus = 0;
          }
          statusKeyboard = 0;
          break;
        case 4:  // Set treinID
          if (key2 == 1) {
            treinIDLinks = key3;
          }
          if (key2 == 2) {
            treinIDRechts = key3;
          }
          statusKeyboard = 0;
          break;
        case 5:  // Set modus
          if (key2 == 1) {
            if (key3 == 1) {
              modus = 1;
            }
            if (key3 == 2) {
              modus = 2;
            }
          }
          statusKeyboard = 0;
          break;
        default:
          statusKeyboard = 0;
          break;
      }
    }
  }
}
//===========================================================================
void displayKeyboard() {
  if (displayTimer > 4000 && (displayStatus == 1 || displayStatus == 2)) {
    displayStatus = 0;
  }
  switch (displayStatus) {
    case 0:
      displayString(&module, displayText0, 0);
      break;
    case 1:
      displayString(&module, displayText1, 0);
      break;
    case 2:
      displayString(&module, displayText2, 0);
      break;
    case 3:
      displayString(&module, displayText3, 0);
      break;
    case 4:
      displayString(&module, displayText4, 3);
      break;
  }
}

When I put the first tab named 'a_keyboard' in the main part, there is no compiling error.

The error when I compile the splitted version is

D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:2:13: error: variable or field 'getKey' declared void
void getKey(TM1638QYF* module, word* button) {
^~~~~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:2:13: error: 'TM1638QYF' was not declared in this scope
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:2:13: note: suggested alternative: 'TM1638QYF_h'
void getKey(TM1638QYF* module, word* button) {
^~~~~~~~~
TM1638QYF_h
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:2:24: error: 'module' was not declared in this scope
void getKey(TM1638QYF* module, word* button) {
^~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:2:24: note: suggested alternative: 'modff'
void getKey(TM1638QYF* module, word* button) {
^~~~~~
modff
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:2:36: error: expected primary-expression before '' token
void getKey(TM1638QYF
module, word* button) {
^
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:2:38: error: 'button' was not declared in this scope
void getKey(TM1638QYF* module, word* button) {
^~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:2:38: note: suggested alternative: 'ultoa'
void getKey(TM1638QYF* module, word* button) {
^~~~~~
ultoa
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:5:20: error: variable or field 'displayNumber' declared void
void displayNumber(TM1638QYF* module, word* value) {
^~~~~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:5:20: error: 'TM1638QYF' was not declared in this scope
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:5:20: note: suggested alternative: 'TM1638QYF_h'
void displayNumber(TM1638QYF* module, word* value) {
^~~~~~~~~
TM1638QYF_h
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:5:31: error: 'module' was not declared in this scope
void displayNumber(TM1638QYF* module, word* value) {
^~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:5:31: note: suggested alternative: 'modff'
void displayNumber(TM1638QYF* module, word* value) {
^~~~~~
modff
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:5:43: error: expected primary-expression before '' token
void displayNumber(TM1638QYF
module, word* value) {
^
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:5:45: error: 'value' was not declared in this scope
void displayNumber(TM1638QYF* module, word* value) {
^~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:8:20: error: variable or field 'displayString' declared void
void displayString(TM1638QYF* module, char* msgk, int dot) {
^~~~~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:8:20: error: 'TM1638QYF' was not declared in this scope
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:8:20: note: suggested alternative: 'TM1638QYF_h'
void displayString(TM1638QYF* module, char* msgk, int dot) {
^~~~~~~~~
TM1638QYF_h
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:8:31: error: 'module' was not declared in this scope
void displayString(TM1638QYF* module, char* msgk, int dot) {
^~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:8:31: note: suggested alternative: 'modff'
void displayString(TM1638QYF* module, char* msgk, int dot) {
^~~~~~
modff
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:8:39: error: expected primary-expression before 'char'
void displayString(TM1638QYF* module, char* msgk, int dot) {
^~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:8:51: error: expected primary-expression before 'int'
void displayString(TM1638QYF* module, char* msgk, int dot) {
^~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:12:14: error: 'TM1638QYF' was not declared in this scope
int checkKey(TM1638QYF* module) {
^~~~~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:12:14: note: suggested alternative: 'TM1638QYF_h'
int checkKey(TM1638QYF* module) {
^~~~~~~~~
TM1638QYF_h
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:12:25: error: 'module' was not declared in this scope
int checkKey(TM1638QYF* module) {
^~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:12:25: note: suggested alternative: 'modff'
int checkKey(TM1638QYF* module) {
^~~~~~
modff
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino:8:19: error: variable or field 'leesKeyboard' declared void
void leesKeyboard(TM1638QYF* module) {
^~~~~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino:8:19: error: 'TM1638QYF' was not declared in this scope
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino:8:19: note: suggested alternative: 'TM1638QYF_h'
void leesKeyboard(TM1638QYF* module) {
^~~~~~~~~
TM1638QYF_h
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino:8:30: error: 'module' was not declared in this scope
void leesKeyboard(TM1638QYF* module) {
^~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino:8:30: note: suggested alternative: 'modff'
void leesKeyboard(TM1638QYF* module) {
^~~~~~
modff
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino: In function 'int checkKey(TM1638QYF*)':
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:12:31: error: 'int checkKey(TM1638QYF*)' redeclared as different kind of symbol
int checkKey(TM1638QYF* module) {
^
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\a_keyboard.ino:12:5: note: previous declaration 'int checkKey'
int checkKey(TM1638QYF* module) {
^~~~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino: In function 'void loop()':
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino:3:3: error: 'leesKeyboard' was not declared in this scope
leesKeyboard(&module);
^~~~~~~~~~~~
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino:3:3: note: suggested alternative: 'displayKeyboard'
leesKeyboard(&module);
^~~~~~~~~~~~
displayKeyboard
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino: In function 'void leesKeyboard(TM1638QYF*)':
D:\marcb\Documenten\Arduino\Issue TM1638QYF in subtab\d_loop.ino:20:28: error: 'checkKey' cannot be used as a function
int key = checkKey(module);
exit status 1
Compilation error: vaiable or field 'getKey' declared void
^

Main part of the sketch must contains setup() and loop()

What is an extension of this file?

1 Like

No, setup() and loop() must just exist somewhere.

1 Like

The problem is probably the Arduino builder. If you enable verbose output during compilations in file → preferences in the IDE, you get a massive output. Dig through that and find the temp directory. You will find a file .ino.cpp in that directory. That is the file that actually gets compiled.

You will probably find that the function prototypes are declared before

#include <TM1638.h>
#include <TM1638QYF.h>

and hence the compiler does not know about those TM things.

I can't compile your code because I'm too lazy to search for all libraries so you will have to do the hard work yourself.

The workaround is probably to add the prototypes yourself after the includes. Or forget about multiple ino files and use h/cpp files so you have full control.

.. or to add library includes in each .ino file, where the libary is used.

the problem above is that your "Keyboard" file doesn't include the "#include <TM1638QYF.h>" which is where "TM1638QYF" is defined and is the type of variable in the 1st argument of getKey()

large programs are often composed of many files, but functionality, not parts of the program (e.g. #includes, variables) that are separated.

in a model RR C/MRI node i'm working on, i have separate files for the signals, WiFi, EEprom and a serial command interface. each of those files has the includes for the various libraries (e.g. WiFI, EEPROM) and local variables. the main file, Node.ino is named after the directory and contains setup() and loop() which invoke corresponding initialization and operational functions in the other files.

it looks like your code is maintaining a list of trains using a keyboard/display. it may make sense to separate your keyboard and display code and the code managing your "trein" variables into separate files while leaving setup() and loop() in the main .ino file.

"modules" often contain several functions, some are invoked from outside that module and others only invoked within the module. header files are typically created with the extern definitions for the functions used outside the file and are # included in the other files that invoke those functions.

i hope this brief explanation helps your understanding. please ask questions if you need a more complete explanation

All files in the tabs have .ino extension

No, When I put this in the keyboard.ino, I get the same errors.

#include <TM1638.h>
#include <TM1638QYF.h>
//TM1638QYF::TM1638QYF(byte dataPin, byte clockPin, byte strobePin)
TM1638QYF module(24, 25, 26);
//===========================================================================
void getKey(TM1638QYF* module, word* button) {
  *button = module->getButtons();
}
void displayNumber(TM1638QYF* module, word* value) {
  module->setDisplayToDecNumber(*value, 0, false);
}
void displayString(TM1638QYF* module, char* msgk, int dot) {
  module->setDisplayToString(msgk, 1 << dot);
}
//===========================================================================
int checkKey(TM1638QYF* module) {
  static int keyStatus;
  static word oldButton;
  static elapsedMillis timerKey;
  int key = 0;
  boolean sameKey;
  word buttons = module->getButtons();
  if (buttons != 0) {
    if (oldButton == 0) {
      timerKey = 0;
    }
    if (buttons == oldButton && timerKey < 1000) {
      sameKey = true;
    } else {
      sameKey = false;
    }
  }
  if (buttons != 0 && !sameKey) {
    for (int i = 0; i < 16; i++) {
      if (buttons >> i == 1) {
        key = i + 1;
        Serial.print(F(" Key :"));
        Serial.println(key);
      }
    }
  }
  oldButton = buttons;
  return key;
}

please show the errors

The solution is to put all the code from the keyboard file in the main .ino.
like this

#include <EEPROM.h>
#include <elapsedMillis.h>
#include <MuxShield.h>

// Display TM1638


#include <TM1638.h>
#include <TM1638QYF.h>
//TM1638QYF::TM1638QYF(byte dataPin, byte clockPin, byte strobePin)
TM1638QYF module(24, 25, 26);
//===========================================================================
void getKey(TM1638QYF* module, word* button) {
  *button = module->getButtons();
}
void displayNumber(TM1638QYF* module, word* value) {
  module->setDisplayToDecNumber(*value, 0, false);
}
void displayString(TM1638QYF* module, char* msgk, int dot) {
  module->setDisplayToString(msgk, 1 << dot);
}
//===========================================================================
int checkKey(TM1638QYF* module) {
  static int keyStatus;
  static word oldButton;
  static elapsedMillis timerKey;
  int key = 0;
  boolean sameKey;
  word buttons = module->getButtons();
  if (buttons != 0) {
    if (oldButton == 0) {
      timerKey = 0;
    }
    if (buttons == oldButton && timerKey < 1000) {
      sameKey = true;
    } else {
      sameKey = false;
    }
  }
  if (buttons != 0 && !sameKey) {
    for (int i = 0; i < 16; i++) {
      if (buttons >> i == 1) {
        key = i + 1;
        Serial.print(F(" Key :"));
        Serial.println(key);
      }
    }
  }
  oldButton = buttons;
  return key;
}

The complete code is about 1000 lines.
Some part of the variables (tables) are defined in excel. The tuning of each train I have to change these parameters often. So maintain in excel is easy, and I copy them into the code.
So it's easy to have a seperate .ino file for that. You just have to CTRL-C in excel and CTRL-A and CTRL-V in the .ino file. (Easy)

But nevertheless, thanks for all the replies.

that's not the only solution.

...and is not a best solution as I think.... but "the best" is subjective

They are in the very beginning of this post. Why repeating if they are the same.

because the filenames and line #s may be different

Crap... the IDE is getting digital code constipation!

I'm one of the forum's biggest proponent for multi-tabs, but In 12+ years, I think I have never had more that 1 .ino file: main.ino

You need to rethink tabs, going to .h and .cpp to aggregate your thinking and program logic. In the pre-Arduino days, we would use namespaces.

As mentioned earlier, you may need to use prototypes within .h files to prevent the ArduinoIDE build system from screwing up.

Ex:

I allowed JSON to be .ino because I was too lasy to create the prototypes! IDE does it in preprocessing.

/* Faux JSON file format https://groups.google.com/forum/#!topic/node-red/pvY36rlRUdI */

void analog_0(void) {
  float temp = EngineCoolantTemp();
  Serial.print("{\"H2O_Tmp\":"); Serial.print(temp);  Serial.print (",");
}

void analog_1(void) {                                   /* Oil temperature */
  float temp  = float(EngOilTemp() );
  Serial.print ("\"Oil_Tmp\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void analog_2(void) {                                   /* Engine Oil Pressure */
  float temp = float (EngineOilPres());
  Serial.print("\"Oil_Prs\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void analog_10(void) {                                  /* Amps measured */
  float temp = float (BatteryAmps());
  Serial.print("\"Current\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void analog_12(void) {                                   /* Battery voltage measured */
  float temp = float (BatteryVoltage());
  Serial.print("\"Voltage\":"); Serial.print(temp);  Serial.print(",");
  return;
}
void analog_15(void) {                                   /* Gasoline fuel pressure */
  float temp = fuelPressure();                                        /* fuel pressure is a fp math function */
  Serial.print("\"Gas_Prs\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_0(void) {                                  /* Exhaust Gas left */
  int temp  = float (thermocouple_channel( 0));
  Serial.print("\"EGT_1\":"); Serial.print(temp);  Serial.print(",");
  return;
}


void thermo_1(void) {
  int temp  = float (thermocouple_channel( 1));
  Serial.print("\"EGT_2\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_2(void) {
  int temp  = float (thermocouple_channel( 2));
  Serial.print("\"EGT_3\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_3(void) {
  int temp  = float (thermocouple_channel( 3));
  Serial.print("\"EGT_4\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_4(void) {
  int temp  = float (thermocouple_channel( 4));
  Serial.print("\"EGT_5\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_5(void) {
  int temp  = float (thermocouple_channel( 5));
  Serial.print("\"EGT_6\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_6(void) {
  int temp  = float (thermocouple_channel( 6));
  Serial.print("\"EGT_7\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_7(void) {
  int temp  = float (thermocouple_channel( 7));
  Serial.print("\"EGT_8\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_8(void) {
  int temp  = float (thermocouple_channel( 8));
  Serial.print("\"EGT_9\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_9(void) {
  int temp  = float (thermocouple_channel( 9));
  Serial.print("\"EGT_10\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_10(void) {
  int temp  = float (thermocouple_channel(10));
  Serial.print("\"EGT_11\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_11(void) {
  int temp  = float (thermocouple_channel(11));
  Serial.print("\"EGT_12\":"); Serial.print(temp);  Serial.print("}\n");
  return;
}

//    ***** NOTE:  YOU MUST UNCOMMENT IN THE MAIN TAB THE CALLING ROUTINE AND UNCOMMENT+EDIT TO PROVIDE NODERED WITH A NEW LABEL *****
/*void thermo_12(void) {
  float temp  = float (thermocouple_channel(12));
  Serial.print("\"EGT_13\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_13(void) {
  float temp  = float (thermocouple_channel(13));
  Serial.print("\"EGT_14\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_14(void) {
  float temp  = float (thermocouple_channel(14));
  Serial.print("\"EGT_15\":"); Serial.print(temp);  Serial.print(",");
  return;
}

void thermo_15(void) {
  float temp  = float (thermocouple_channel(15));
  Serial.print("\"EGT_16\":"); Serial.print(temp);  Serial.print(",");
  return;
}
*/

So, the main program is now simple:


#include <HardwareSerial.h>         // System library

// Note: Arduino IDE automatically performs a Forward Declaration for functions listed before setup()
#include "./AnalogAverage.h"        // Matrix summations
#include "./BATTERY.h"              // Voltage and Current
#include "./THERMOCOUPLE.h"                  // Exhaust Gas temps left and right
#include "./ENGINE.h"               // Coolent temp, Front cyl temp, Rear cyl temp, oil temp, oil pressure
#include "./FUEL.h"                 // Fuel tank level


This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.