Go Down

Topic: declarations in libraries (Read 1 time) previous topic - next topic

Loren

So here is the code:

Sketch:

Code: [Select]
#include <SPI.h>
#include <Ethernet.h>
#include "eth.h"

Eth eth();
void setup(){

}


void loop(){
 
}


eth.h:
Code: [Select]
#ifndef Eth_h
#define Eth_h

#include <SPI.h>
#include <Ethernet.h>
#include "Arduino.h"

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1, 177);
EthernetServer server(80);


class Eth{


public:
void init();

};
#endif


and eth.cpp:

Code: [Select]
#include "Arduino.h"
#include "eth.h"

void Eth::init(){

 
 
 
}


With the variables declared I get these errors:

Code: [Select]
eth.cpp.o:eth.cpp:14: multiple definition of `ip'
consRemoteTwo.cpp.o:consRemoteTwo.cpp:11: first defined here
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld: Disabling relaxation: it will not work with multiple definitions
eth.cpp.o:eth.cpp:14: multiple definition of `server'
consRemoteTwo.cpp.o:consRemoteTwo.cpp:11: first defined here
eth.cpp.o:(.data.mac+0x0): multiple definition of `mac'
consRemoteTwo.cpp.o:(.data.mac+0x0): first defined here


Any suggestions on what I'm still doing wrong?

Thanks again,

Loren

michinyon

Well,  you need to be careful not to define things twice.

That's why most header files have that  #ifndef  stuff at the beginning,  to prevent them being included twice.

Your "variables"  mac and server  are being defined twice.  This could mean one of two things:
(a)  the same variable is being included twice,  or
(b)  two different variables are being defined, using the same name.

To distinguish these cases,   try re-naming your instances of these variables  to something else.   Like  mac_xxx  and server_xxx.
And then see what happens.


PaulS

Code: [Select]
Eth eth();
That is not how to create an instance of the class. Loose the ().

Loren


Well,  you need to be careful not to define things twice.

That's why most header files have that  #ifndef  stuff at the beginning,  to prevent them being included twice.

Your "variables"  mac and server  are being defined twice.  This could mean one of two things:
(a)  the same variable is being included twice,  or
(b)  two different variables are being defined, using the same name.

To distinguish these cases,   try re-naming your instances of these variables  to something else.   Like  mac_xxx  and server_xxx.
And then see what happens.




I tried to rename the variables.  The same errors are still occurring. 

I did lose the () to create the class.  No changes in the errors there either.

PaulS

Please explain why those are global variables (that is why they are created twice), rather than class fields.

You could define the variables in the sketch, and add extern in front of the declaration statements in the header. That way, the header file would simply affirm that the variables are defined somewhere else, and would allow access to them, wherever they are defined.

Loren

For those trying to avoid the pain of what I just went through here is what I found:


Please explain why those are global variables (that is why they are created twice), rather than class fields.

You could define the variables in the sketch, and add extern in front of the declaration statements in the header. That way, the header file would simply affirm that the variables are defined somewhere else, and would allow access to them, wherever they are defined.


I didn't necessarily want them to be global variables.  After seeing that comment I took another look at the library tutorial and noticed that I should be declaring the variables below with the private declarations for the class:

Code: [Select]
#ifndef eth_h
#define eth_h

#include <SPI.h>
#include <Ethernet.h>
#include "Arduino.h"
 
class Eth{

public:
void init();

private:
byte mac[5];
};
#endif



Loren

I think this will be the last step in helping me figure out how to write libraries.  Here is the code as it stands now:

sketch:
Code: [Select]
#include <SPI.h>
#include <Ethernet.h>
#include "eth.h"

Eth eth;

EthernetServer server(80);

void setup(){
  Serial.begin(9600);
  Serial.println("Setup has begun");
eth.init();
}


void loop(){
  //Serial.println("Loop");
eth.servClient();
}


eth.h:
Code: [Select]
#ifndef eth_h
#define eth_h

#include <SPI.h>
#include <Ethernet.h>
#include "Arduino.h"
 



class Eth{


public:


void init();
void servClient();

private:
byte mac[5];

};
#endif


eth.cpp:
Code: [Select]
#include "Arduino.h"
#include "eth.h"

void Eth::init(){
mac[0] = 0xDE;
mac[1] = 0xAD;
mac[2] = 0xBE;
mac[3] = 0xEF;
mac[4] = 0xFE;
mac[5] = 0xED;
IPAddress ip(192,168,1,177);
extern EthernetServer server;
  Ethernet.begin(mac, ip);
  server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
 
}

void Eth::servClient(){
   Serial.print("Server is at:  ");
Serial.println(Ethernet.localIP());
  //Serial.println("servClient called");
  extern EthernetServer server;
   // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<head><title>Lorens Page</title></head>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
         
          //client.print("Transport is currently:  ");
          //client.print(stat);
          client.println("<br />");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("<br />");       
          }
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }

}


Clients are unable to connect to the server.  I have a feeling this has something to do with the way that I have declared "EthernetServer server(80)" and the way I'm using extern. 

Are the functions "init" and "serveClient" in the Eth class creating their own instance of server?

Again many many thanks!

Loren

PaulS

Why is the server object created in the sketch? It is not used in the sketch.

Loren

That was the only place I could find to create it "Globally" that the source file could see it.  Where should it be declared?

PaulS

Quote
Where should it be declared?

As a private field in the class.

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview