Working with multiple tabs

This is my first time using multiple tabs. This is what is says when i am trying to compile it... Anyone know the anwser, the error is in the second tab on all the Println's used. When i compile them seperate they are both working.....

"exit status 1 'Serial' does not name a type"

First tab (Main project tab):

#include <EEPROM.h>

// deze constante veranderen niet
const int  buttonPin = 3;    // waar de button op aangesloten is
//   the button moet aangesloten zijn vanaf pin naar ground, pinmode is een input_pullup

// Deze variabelen veranderen 
bool buttonState;         // momentele status van de button
bool lastButtonState;     // vorige status van de button

unsigned long buttonBecamePressedAt;
unsigned long buttonHasBeenPressedForTotal;
unsigned long buttonHasBeenPressedForThisTime;
unsigned long lastPress; // dit is de laatste state waar de arduino in was
unsigned long hours;
int AdressRoom = 50; // dit is kamer 50 op de EEPROOM


void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  
  EEPROM.get(AdressRoom, hours);
  
  
  Serial.println(".... Hoe lang is de button ingedrukt? ....");
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);
  Serial.println("Last press");
  buttonHasBeenPressedForTotal = (EEPROM.get(AdressRoom, lastPress)); //hier haalt hij de laatste bekende tijd op
  Serial.println(buttonHasBeenPressedForTotal); // hier print hij de laatste bekende staat

  // Initializa de button pin als een input with pullup active low.
  // verzeker dat de button van PIN naar GROUND
  pinMode(buttonPin, INPUT_PULLUP);

  //initialize button states
  buttonState = digitalRead(buttonPin);
  lastButtonState = buttonState;

  Serial.println("Setup done");
  Serial.println(" ");
}

void loop()
{
  // lezen van de pushbutton buttonpin:
  buttonState = digitalRead(buttonPin);

  // vergelijkt de buttonstaat naar de vorige staat
  if (buttonState != lastButtonState) // betekend dat hij veranderd is, welke kant nog onduidelijk
  {
    if (buttonState == LOW)  // veranderd naar ingedrukt
    {
      // als de momentele staat is LOW dan was de button ingedrukt
      Serial.print("Newly pressed at ");
      Serial.print(millis());
      Serial.print(" ms");
      buttonBecamePressedAt = millis();

    }
    else  // changed to released
    {
      // als de huidige staat HIGH dan was de button released
      Serial.print(", newly released at ");
      Serial.print(millis());
      Serial.println(" ms");
      
      lastPress = buttonHasBeenPressedForTotal; //hier neemt hij de "LastPress " over, dit is de laatste bekende tijd
      
      buttonHasBeenPressedForThisTime = millis() - buttonBecamePressedAt; 
      buttonHasBeenPressedForTotal = buttonHasBeenPressedForTotal + buttonHasBeenPressedForThisTime;
     
      
      Serial.print("   This press: ");
      Serial.print(buttonHasBeenPressedForThisTime);
      Serial.print(" ms");

      Serial.print(", Total: ");
      Serial.print(buttonHasBeenPressedForTotal);
      Serial.println(" ms");
      
      hours = buttonHasBeenPressedForTotal / 1000;
      
      Serial.println("Pressed total:");
      Serial.println(hours);


      Serial.println("Hallo");
      EEPROM.put(AdressRoom, lastPress); // hier stopt hij de totale tijd button hoog was in de 
      
    }
    // Delay om "stuiteren" te voorkomen, delay van 50ms is genoeg hiervoor
    delay(50);
  }
  // Verander de huidige staat als de vorige staat, voor de volgende keer door de loop
  lastButtonState = buttonState;

} 

Second tab named NTPSERVER:

#include <SPI.h>         // for communication with Ethernet Shield
#include <TimeLib.h>     // for update/display of time
#include <Ethernet.h>    // for communication with NTP Server via UDP

// variable to hold Ethernet shield MAC address
byte mac[] = { 0xA8, 0x61, 0x0A, 0xA1, 0x97, 0xDF };

// define IPAddress object that will contain the NTP server IP address
   //IPAddress timeSrvr(129,6,15,28);
   IPAddress timeSrvr(132,163,96,3);
   //const char timeSrvr = ("time.nist.gov");
   // IPAddress timeSrvr = ("pool.ntp.org");
   //IPAddress timeSrvr = "pool.ntp.org";

// define Ethernet UDP object and local port 8888
EthernetUDP ethernet_UDP;
unsigned int localPort = 8888;

// variable to store previous displayed time
time_t prevDisplay = 0;

// array to hold incoming/outgoing NTP messages
// NTP time message is 48 bytes long
byte messageBuffer[48];
  Serial.println("Sample Program for the Tutorial: Using An Arduino Ethernet Shield To Get Date and Time");

  // get ethernet shield IP via DHCP
  // [part of Ethernet Library]
  while (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP"); // display error
    delay(1000); // retry after 1 sec
  }

  // DHCP assignment successful, display ethernet shield IP to serial
  // [part of Ethernet Library]
  Serial.print("Ethernet Shield IP (DHCP): ");
  Serial.println(Ethernet.localIP());

  // start UDP
  // [part of Ethernet Library]
  ethernet_UDP.begin(localPort);
  Serial.println("Ethernet UDP Start....");

  // pass function getTime() to Time Library to update current time
  // [part of Time Library]
  setSyncProvider(getTime);
}
void loop()
{
  if (timeStatus() != timeNotSet) {   // check if the time is successfully updated
    if (now() != prevDisplay) {       // update the display only if time has changed
      prevDisplay = now();
      digitalClockDisplay();          // display the current date and time
    }
  }
}
void digitalClockDisplay() {
  
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
  ethernet_UDP.beginPacket(address, 123);
  ethernet_UDP.write(messageBuffer, 48);
  ethernet_UDP.endPacket();
}

If you are going to use C header files in Ardiono projects then add a header guard like this:

#ifndef NTPSERVER_h
#define NTPSERVER_h                   

[...code...]

#endif  // NTPSERVER

So that Arduino objects such as Serial are recognized, you will also need to include Arduino.h:

#include <Arduino.h>

Hello lofobi

Check the bracket {} arrangement inside the NTPSERVER part.

  • six hits for {
  • seven hits for }

Something is missing.

Have a nice day and enjoy coding in C++.

When i add the missing { ontop of the prinln's it still won't work. Why does it works when they are being compiled as seperate codes?

Did you mean NTPSERVER.cpp or NTPSERVER.ino? It makes a difference.

Both of your tabs seem to include a "void loop()" function. Those two declarations will conflict.

So i am only allowed to use 1 loop in the main tab, and than execute the other tab (NTPSERVER) in the loop in de maintab so it keeps repeating?

Yes, indeed, I commented on the assumption that the second tab was adding an NTPSERVER.h file, but the presence of a 'void loop()' in that file does raise the question whether it is, in fact, another .ino file? A .h file would require the header guard and inclusion of <Arduino.h> but not an .ino file.

The brace } just above void loop() seems to have no corresponding function declaration, nor 'if' or 'while' statement. It looks like there should be a function declaration somewhere because code cannot be generally placed outside of functions, except for #include statements, global variables and structure declarations.

Regarding the void loop() function existing in both the second file and the main .ino and the resulting conflict, it looks like perhaps that code inside the second void loop() needs to be instead wrapped in a function which is then called from void loop() in the main file. You don't have to execute the entire code held in the NTPSERVER tab.

It might be helpful to draw a flowchart illustrating what your code needs to do. This may help with organizing your functions and program flow in a logical order so as to achieve your objective. Your time server functions would still reside within in your NTPSERVER library, but can be called as and when required from your main program which controls the program flow.

How am i supposed to call the different tabs? Right now i have these codes (sending code, timer etc in different tabs. In the main tab i am trying to call them in the loop but it keeps giving me "exit status 1, 'Timer was not declared in this scope'.

Main code:

#include <EEPROM.h>
#include <SPI.h>
#include <Ethernet.h>
#include <TimeLib.h>


//-=+=--=+=--=+=--=+=--=+=--=+=--=+=-VOOR DE TIMER-=+=--=+=--=+=--=+=--=+=--=+=--=+=-//
// deze constante veranderen niet
const int  buttonPin = 3;    // waar de button op aangesloten is
const int  Testbutton = 4;    // waar de button op aangesloten is
//   the button moet aangesloten zijn vanaf pin naar ground, pinmode is een input_pullup

// Deze variabelen veranderen 
bool buttonState;         // momentele status van de button
bool lastButtonState;     // vorige status van de button

unsigned long buttonBecamePressedAt;
unsigned long buttonHasBeenPressedForTotal;
unsigned long buttonHasBeenPressedForThisTime;
unsigned long lastPress; // dit is de laatste state waar de arduino in was
unsigned long hours;
int AdressRoom = 50; // dit is kamer 50 op de EEPROOM


//-=+=--=+=--=+=--=+=--=+=--=+=--=+=-Voor de NTP server-=+=--=+=--=+=--=+=--=+=--=+=--=+=-//
// variable to hold Ethernet shield MAC address
byte mac[] = { 0xA8, 0x61, 0x0A, 0xA1, 0x97, 0xDF };

// define IPAddress object that will contain the NTP server IP address
   //IPAddress timeSrvr(129,6,15,28);
   IPAddress timeSrvr(132,163,96,3);
   //const char timeSrvr = ("time.nist.gov");
   // IPAddress timeSrvr = ("pool.ntp.org");
   //IPAddress timeSrvr = "pool.ntp.org";

// define Ethernet UDP object and local port 8888
EthernetUDP ethernet_UDP;
unsigned int localPort = 8888;

// variable to store previous displayed time
time_t prevDisplay = 0;


//-=+=--=+=--=+=--=+=--=+=--=+=--=+=-Voor de URL connectie-=+=--=+=--=+=--=+=--=+=--=+=--=+=-//
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:

char server[] = "ws.ligthartgroup.com";
int port = 8080;
// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 0, 177);
IPAddress myDns(192, 168, 0, 1);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

// Variables to measure the speed
unsigned long beginMicros, endMicros;
unsigned long byteCount = 0;
bool printWebData = true;  // set to false for better speed measurement
//-=+=--=+=--=+=--=+=--=+=--=+=--=+=-Einde-=+=--=+=--=+=--=+=--=+=--=+=--=+=-//



void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  
  EEPROM.get(AdressRoom, hours);
  
  
  Serial.println(".... Hoe lang is de button ingedrukt? ....");
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);
  Serial.println("Last press");
  buttonHasBeenPressedForTotal = (EEPROM.get(AdressRoom, lastPress)); //hier haalt hij de laatste bekende tijd op
  Serial.println(buttonHasBeenPressedForTotal); // hier print hij de laatste bekende staat

  // Initializa de button pin als een input with pullup active low.
  // verzeker dat de button van PIN naar GROUND
  pinMode(buttonPin, INPUT_PULLUP);

  //initialize button states
  buttonState = digitalRead(buttonPin);
  lastButtonState = buttonState;

  Serial.println("Setup done");
  Serial.println(" ");
}

void loop(){
 if (buttonState != lastButtonState);
 {
  Timer();
  NTPSERVER();
 }

Second tab:

// array to hold incoming/outgoing NTP messages
// NTP time message is 48 bytes long
byte messageBuffer[48];
  Serial.println("Sample Program for the Tutorial: Using An Arduino Ethernet Shield To Get Date and Time");

  // get ethernet shield IP via DHCP
  // [part of Ethernet Library]
  while (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP"); // display error
    delay(1000); // retry after 1 sec
  }

  // DHCP assignment successful, display ethernet shield IP to serial
  // [part of Ethernet Library]
  Serial.print("Ethernet Shield IP (DHCP): ");
  Serial.println(Ethernet.localIP());

  // start UDP
  // [part of Ethernet Library]
  ethernet_UDP.begin(localPort);
  Serial.println("Ethernet UDP Start....");

  // pass function getTime() to Time Library to update current time
  // [part of Time Library]
  setSyncProvider(getTime);
}
void loop()
{
  if (timeStatus() != timeNotSet) {   // check if the time is successfully updated
    if (now() != prevDisplay) {       // update the display only if time has changed
      prevDisplay = now();
      digitalClockDisplay();          // display the current date and time
    }
  }
}
void digitalClockDisplay() {
  
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
  ethernet_UDP.beginPacket(address, 123);
  ethernet_UDP.write(messageBuffer, 48);
  ethernet_UDP.endPacket();
}
Third tab:

// lezen van de pushbutton buttonpin:
buttonState = digitalRead(buttonPin);

//Als de testbutton ingedrukt word worden de uren verstuurd

// vergelijkt de buttonstaat naar de vorige staat
if (buttonState != lastButtonState) // betekend dat hij veranderd is, welke kant nog onduidelijk
{
if (buttonState == LOW) // veranderd naar ingedrukt
{
// als de momentele staat is LOW dan was de button ingedrukt
Serial.print("Newly pressed at ");
Serial.print(millis());
Serial.print(" ms");
buttonBecamePressedAt = millis();

}
else  // changed to released
{
  // als de huidige staat HIGH dan was de button released
  Serial.print(", newly released at ");
  Serial.print(millis());
  Serial.println(" ms");
  
  lastPress = buttonHasBeenPressedForTotal; //hier neemt hij de "LastPress " over, dit is de laatste bekende tijd
  
  buttonHasBeenPressedForThisTime = millis() - buttonBecamePressedAt; 
  buttonHasBeenPressedForTotal = buttonHasBeenPressedForTotal + buttonHasBeenPressedForThisTime;
 
  
  Serial.print("   This press: ");
  Serial.print(buttonHasBeenPressedForThisTime);
  Serial.print(" ms");

  Serial.print(", Total: ");
  Serial.print(buttonHasBeenPressedForTotal);
  Serial.println(" ms");
  
  hours = buttonHasBeenPressedForTotal / 1000;
  
  Serial.println("Pressed total:");
  Serial.println(hours);


  Serial.println("Hallo");
  EEPROM.put(AdressRoom, lastPress); // hier stopt hij de totale tijd button hoog was in de AdressRoom  
}
// Delay om "stuiteren" te voorkomen, delay van 50ms is genoeg hiervoor
delay(50);

}
// Verander de huidige staat als de vorige staat, voor de volgende keer door de loop
lastButtonState = buttonState;

}

You can't 'call a tab'. You can call a function defined in a tab, if the tab file is named *.ino. You can call a function defined in a tab if the tab file is named *.cpp and the function name is declared 'extern' (typically in an *.h file included in the main tab). If the tab file is named *.h then the only thing you can do with that tab is "#include" it to make it part of another tab file.

I asked in Reply 5 what the file extensions were.

They are all .ino files!

Second Tab and Third Tab are incomplete. I think both are missing the beginning of the file. I hear there is a problem with Arduino 2 when selecting text to copy and paste. Instead, don't select text and use "Copy for Forum (Markdown)". in the Edit menu.

The parts that got posted don't include a definition of "Timer" so that explains why it is not defined (for me, at least). Sometimes the "not declared in this scope" means that a compile error later in your sketch prevent the compiler from recognizing the definition.

Ok, if I understand correctly, you have two tabs with code called Timer and NTPSERVER and you are trying to call them in void loop() in your main .ino file with:

Timer();
NTPSERVER();

Sorry, but It does not work like that!

A little background: There are two ways of adding external files to your main .ino file. The Arduino programming language is derived from C++ (C PlusPlus). In C++ programs are contained in file pairs with the extension .h and .cpp. The .h file is the 'header' file and usually contains global variable and data structure declarations and well as function declarations. The .cpp file contains all of the working code. Arduino attempted to make things easier for by combining everything into a single .ino file. This required certain "adjustments" to the way the compiler treated the files but the language is still essentially C++.

It is possible to use both file types in an Arduino project, those with a .ino extension as well as CPP style file pairs with .h/.cpp extensions. However, the way they work is different.

When you want to use a .h/.cpp file pair, you have to add #include <Arduino.h> to the .h file so that it the compiler can process the Arduino specific commands and objects within the .h/.cpp file pair. The files are set up as I outlined earlier, for example:

NTPSERVER.h:

#ifndef NTPSERVER_h
#define NTPSERVER_h                   

#include <Arduino.h>

// Global vars
char * receiveBuffer;
String myTime;
etc....

// Functions
function initNTPServer(){}
function getNTPtime(){
function updateClock(){}
function whatever(){}

#endif  // NTPSERVER

NTPSERVER.cpp:

#include NTPSERVER.h

function initNTPServer(){

...code...

}


function getNTPtime(){

... code ...

}

function updateClock(){

...code...

}

function whatever(){

...mode code... 

}

You include the header file and then call each function from you main .ino file, for example:

#include "NTPSERVER.h"

// Some global vars

void setup(){
    initNTPserver();
}


void loop(){
    getNTPtime();
    updateClock();
}

On the other hand, if you are using .ino files, then what happens is that your main project file (the one with the same name as the project folder/directory) gets called first. The other files get appended to the end of this in alphabetical order. A #include statement is not required to use the additional files in your project which essentially gets treated as one long .ino file. In that case, all of the "global" variables (those that need to be seen by all functions) need to be in the main file. Variables that only need to be seen by functions in a specific .ino file can sit within that file. Functions void setup() and void loop() can be placed in any of the .ino files within the project , but can only exist once within the project.

In answer to your question about calling tabs, you don't. You call the functions defined within them just as you would call functions in your main .ino file. (I will not delve into C++ classes here - something maybe for your own research at some point.)

Generally it is recommended to add .h/.cpp file pairs rather .ino files to expand a project, but to keep things simple, you could organize your project so that all global variables, void setup() and void loop() are in your main file and all functions are grouped according to their purpose in the separate .ino files.

Basically, all the code sitting outside of functions in your additional files needs to be contained within functions, or else moved to void setup() or void loop () as appropriate.

Sorry this is a bit long winded, but I hope it clarifies things little.

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