Pages: 1 [2]   Go Down
Author Topic: declarations in libraries  (Read 1471 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 155
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So here is the code:

Sketch:

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

Eth eth();
void setup(){

}


void loop(){
 
}

eth.h:
Code:
#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:
#include "Arduino.h"
#include "eth.h"

void Eth::init(){

 
 
 
}

With the variables declared I get these errors:

Code:
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
Logged

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3011
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 612
Posts: 49200
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Full Member
***
Karma: 0
Posts: 155
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 612
Posts: 49200
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 155
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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

Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 155
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
#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:
#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
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 612
Posts: 49200
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Full Member
***
Karma: 0
Posts: 155
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 612
Posts: 49200
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Where should it be declared?
As a private field in the class.
Logged

Pages: 1 [2]   Go Up
Jump to: