Tinkercad Arduino, please help me with the Error invalid header file

Hello everybody,

im using the tinkercad arduino software and this is a link to my project. For someone willing to help I would be able to send a link where you would be able to edit a copy of the code/circuit board inside the online software.
I have been trying to fix this bug since december and would really appreciate some help.

My findings while trying to fix the bug:

  • The error occurs while calling errorCode(); until that point everything works, i discovered that while commenting everything inside errorCode();
  • If the only thing inside errorCode(); is a call for the Method lcdPrint2 or lcdPrint the error still occurs -> the bug isn't necessary because of the normally used code
  • Another weird occurence in this constellation:

If anything in the code is unclear, please ask, I will explain everything


#include <Servo.h>
#include <Keypad.h>
#include <Adafruit_LiquidCrystal.h>

//Display:
Adafruit_LiquidCrystal lcd_1(0);
//Servo:
Servo vaultservo;
int pos = 0;
//4x4 Keypad: *Quelle
const byte COLS = 4; 
const byte ROWS = 4;
char hexaKeys[ROWS][COLS]={
{'A','3','2','1'},
{'B','6','5','4'},
{'C','9','8','7'},
{'D','#','0','*'}
};
byte rowPins[ROWS] = {13,12,11,10};//Definition der Pins für die 4 Zeilen
byte colPins[COLS] = {6,7,8,9}; //Definition der Pins für die 4 Spalten
char key; //Taste ist die Variable für die jeweils gedrückte Taste.
Keypad keypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); //Das Keypad kann absofort mit "Tastenfeld" angesprochen werden
//password:
char savedpassword[4] = {'0','0','0','0'};
char trypassword[4] = {'x','x','x','x'};
bool boolSavedPassword = false;
int passwordIndex = 0;
bool open = false; 
//LED:
int LEDgreen = 3;
int LEDblue = 4;
int LEDred = 5;

void setup()
{
  vaultservo.attach(0);
  lcd_1.begin(16, 2);
  lcd_1.setBacklight(1);
  pinMode(LEDgreen, OUTPUT);
  pinMode(LEDblue, OUTPUT);
  pinMode(LEDred, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);

}

void loop()
{
  LED();
  servo();

  key = keypad.getKey(); //key entspricht der gedrückten Taste

  if(key){ //sollte ein Knopf gedrückt werden
  	checkKey(key);
  }
}

void checkKey(char key){
	if (!boolSavedPassword && checkForNumber()){
      Serial.println("Bitte drücken sie '*' um ein Passwort zu speichern");
      lcdPrint2("Press '*' to", "save password.");
    } else if (boolSavedPassword && key == '#' && !open){
        
      
		enterCode();
      	//Dieser Teil wirft eimen Error den wir zusammen nicht beheben konnten
            
    } else if (key == 'A' || key == 'B' || key == 'C' || key == 'D'){
      	lcdPrint2("Button has no", "meaning.");
    } else if (key == '*' && !boolSavedPassword){
      	savePassword(); 
    } else if (key == '*' && boolSavedPassword){
      	resetPassword();
    } else {
      	Serial.println("Fehler");
    }
}

void savePassword(){
  lcdPrint2("Enter 4 digits", "to save password");
  while (!boolSavedPassword && passwordIndex <= 3){
    key = keypad.getKey();
    if (key && checkForNumber()){
      savedpassword[passwordIndex] = key;
      passwordIndex++;
    } else if (key){
     lcdPrint2("Error, please", "enter digits.");
     delay(200);
     lcdPrint2("Enter digits", "to save password");
    }
  }
  passwordIndex = 0;
  boolSavedPassword = true;
  lcdPrint2("New password", "now is " + String(savedpassword));
  delay(400);
  lcdPrint2("Press '#' to", "enter code.");
}

void resetPassword(){
  if (open){
    key = keypad.getKey();
    lcdPrint2("Confirm: '*'","Cancel with any.");
    if (key == '*'){
    savePassword();
    } else if (key){
	  lcdPrint2("Cancelled", "reset.");
      delay(400);
      lcdPrint2("Close vault:'#'", "Reset vault:'*'");
   	  }
    } else {
    lcdPrint2("To reset code", "first open safe.");
    delay(300);
    lcdPrint2("Press '#' to", "enter code.");
    } 
}  

void enterCode(){
     /* String counter = "A";
  while (passwordIndex <= 3){
    key = keypad.getKey();
    if (key && checkForNumber()){
      savedpassword[passwordIndex] = key;
      passwordIndex++;
    } else if (key){
     lcdPrint2("Error, please", "enter digits.");
     delay(200);
     lcdPrint2("Enter digits", "to save password");
    }    
    key = keypad.getKey();
    counter = "A";
    for(int i=0; i < passwordIndex; i++){
    counter = counter + "*";
    }  
    if (key && checkForNumber()){
      trypassword[passwordIndex] = key;
      passwordIndex++;
      lcdPrint2(counter, "nothing");
    } else if(key && !checkForNumber()) {
      lcdPrint2(counter, "Enter a digit");
    	}
  }
  if (checkPassword(trypassword, savedpassword)){
    lcdPrint2("Correct code", "safe is now open");
    delay(400);
    lcdPrint2("Close vault:'#'", "Reset vault:'*'");
  } else {
    lcdPrint2("Wrong code", "try again.");
  	} 
  passwordIndex = 0;*/
  }
      

bool checkForNumber(){
  if (key == '1' ||key == '2' ||key == '3' ||key == '4' ||key == '5' ||key == '6' ||key == '7' ||key == '8' ||key == '9'){
    return true;
  } else {
  return false;
  }
}

bool checkPassword(char tryPassw[], char password[]){
  bool samePassword = true;
  int index = 0;
  while(index <= 3 && samePassword == true){
    if (tryPassw[index] != password[index]){
    	samePassword = false;
    } 
    index++;
  }
  return samePassword;
}
             
                    
void LED(){ //schaltet den LED auf grün wenn der Tresor geöffnet ist, ansonsten auf rot wenn der Tresor geschlossen ist.
  if (open){
    analogWrite(LEDgreen, 200);
  } else {
    analogWrite(LEDred, 200);
  }
}

void servo(){
  if (open){
    for (pos = 0; pos <= 180; pos += 1) {
    vaultservo.write(pos);
    //delay(15); 
  	}
  } else {
      for (pos = 90; pos >= 0; pos -= 1) {
    vaultservo.write(pos);
    //delay(15); 
  	}
  }
}

void lcdPrint(int row, String printString){
  if (printString.length() <= 16){
    if (row == 1){
      lcd_1.setCursor(0, 0);
      lcd_1.print(printString);
    } else if (row == 2){
      lcd_1.setCursor(0, 1);
      lcd_1.print(printString);
    } else {
    Serial.println("Nicht die 1 oder 2 Zeile");
    }
  } else {
    Serial.println("String ist zu lang");
  }
}
  void lcdPrint2(String row1String, String row2String){
  lcd_1.clear();
  lcdPrint(1, row1String);
  lcdPrint(2, row2String);
}

Thank you very much to everyone who takes time to read this :slight_smile:

You mention a bug and an error

Please provide details of the problem or problems

While running the Code the console throws this Error:
invalid header file
This is sadly all I have

Is there no indication of which header file is invalid or what is invalid about it ?

My guess would be that TinkerCAD cannot find one or more of the libraries #included by the sketch

Does TinkerCAD have any means of adding libraries ?

As an aside, the sketch compiles OK for me using the Arduino IDE. Is there a reason why you are using TinkerCAD rather than the Arduino IDE ?

Tinkercad will give that error message when something else is wrong.
I tried a simple circuit with the #include <Adafruit_LiquidCrystal.h>, that works.
I tried to compile the sketch in the Arduino IDE, and it compiled without problem.
I tried it in the Wokwi simulation, and it compiles and runs. But the Adafruit library might not be compatible with the Wokwi LCD display.
Since Wokwi can use every library, I suggest to go directly for the best library: "hd44780".

Perhaps Tinkercad has a older version of a library which is not compatible with the rest.
Perhaps you can replace the troubles lines with other functions? And perhaps you should avoid using the String class on a Arduino Uno. You can also use the F() macro to reduce SRAM usage.

Conclusion: Sorry, I did not find the problem and I have no solution. Let's blame Tinkercad for the problem.

No this is all I get, but i have some ideas above where the error might occur.

The libraries used have already worked in the code, but only seem to not work in the method enterCode();

Yes TinkerCAD provides the coder with the used libraries.

Thank you already for finding out the sketch compiles okay.
Could you please try it with the uncommented Method enterCode();
The error occurs because of this

Thank you very much for your ideas.

It is just so frustrating since it seems like it is a problem with TinkerCAD and i would like to finish this project.

You can simulate the code I have posted in the link and it works because i commented the Method enterCode();
But if I uncomment this part of the Code the error occurs

With the code in the enterCode() function the sketch compiles OK for me locally

As I said, Tinkercad will give that error message when something else is wrong.
However, both UKHeliBob and me confirm that the code compiles in the Arduino IDE, and I have tested it in Wokwi and it compiles and runs also there.

You can not keep trying to find out what Tinkercad does not tell.
Step out of this. You need something completely different. Either other code in Tinkercad, or Wokwi simulation or the Arduino IDE for a real project with real hardware.

I added #include <Arduino.h> at the top, to force Tinkercad to give an other message.
It says: variable or field 'lcdPrint2' declared void

Somewhere Tinkercad has a problem with two String objects or pointers to text as parameters.
I suggest to remove the lcdPrint2() function and write those three lines everywhere in the code.

I appreciate your help, I will probably switch to wokwi and try again.
Have a good day

Not sure this is related but don't use pin 0 or 1. They are reserved for Serial

Was bored here at work so I went through your code and commented out all calls to lcdPrint2. Error went away. Then I started uncommenting them one by one and about halfway through, the error came back.
Definitely a TinkerCAD issue.

1 Like

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