Code Monkey home page Code Monkey logo

ethercard's Introduction

EtherCard

Travis Status

EtherCard is a driver for the Microchip ENC28J60 chip, compatible with Arduino IDE. It is adapted and extended from code written by Guido Socher and Pascal Stang.

High-level routines are provided to allow a variety of purposes including simple data transfer through to HTTP handling.

License: GPL2

Requirements

  • Hardware: This library only supports the ENC28J60 chip.
  • Hardware: Only AVR-based microcontrollers are supported, such as:
    • Arduino Uno
    • Arduino Mega
    • Arduino Leonardo
    • Arduino Nano/Pro/Fio/Pro-mini/LiliPad/Duemilanove
    • Any other Arduino clone using an AVR microcontroller should work
  • Hardware: Non-AVR boards are NOT currently supported (101/Zero/Due) #211
  • Hardware: Depending on the size of the buffer for packets, this library uses about 1k of Arduino RAM. Large strings and other global variables can easily push the limits of smaller microcontrollers.
  • Hardware: This library uses the SPI interface of the microcontroller, and will require at least one dedicated pin for CS, plus the SO, SI, and SCK pins of the SPI interface. An interrupt pin is not required.
  • Software: Any Arduino IDE >= 1.0.0 should be fine

Library Installation

EtherCard is available for installation in the Arduino Library Manager. Alternatively it can be downloaded directly from GitHub:

  1. Download the ZIP file from https://github.com/njh/EtherCard/archive/master.zip
  2. Rename the downloaded file to ethercard.zip
  3. From the Arduino IDE: Sketch -> Include Library... -> Add .ZIP Library...
  4. Restart the Arduino IDE to see the new "EtherCard" library with examples

See the comments in the example sketches for details about how to try them out.

Physical Installation

PIN Connections (Using Arduino UNO or Arduino NANO):

ENC28J60 Arduino Uno Notes
VCC 3.3V
GND GND
SCK Pin 13
MISO Pin 12
MOSI Pin 11
CS Pin 10 Selectable with the ether.begin() function

PIN Connections using an Arduino Mega

ENC28J60 Arduino Mega Notes
VCC 3.3V
GND GND
SCK Pin 52
MISO Pin 50
MOSI Pin 51
CS Pin 53 Selectable with the ether.begin() function

Using the library

Full API documentation for this library is at: http://www.aelius.com/njh/ethercard/

Several example sketches are provided with the library which demonstrate various features. Below are descriptions on how to use the library.

Note: ether is a globally defined instance of the EtherCard class and may be used to access the library.

Initialising the library

Initiate To initiate the library call ether.begin().

uint8_t Ethernet::buffer[700]; // configure buffer size to 700 octets
static uint8_t mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; // define (unique on LAN) hardware (MAC) address

uint8_type vers = ether.begin(sizeof Ethernet::buffer, mymac);
if(vers == 0)
{
    // handle failure to initiate network interface
}

Configure using DHCP

To configure IP address via DHCP use ether.dhcpSetup().

if(!ether.dhcpSetup())
{
    // handle failure to obtain IP address via DHCP
}
ether.printIp("IP:   ", ether.myip); // output IP address to Serial
ether.printIp("GW:   ", ether.gwip); // output gateway address to Serial
ether.printIp("Mask: ", ether.netmask); // output netmask to Serial
ether.printIp("DHCP server: ", ether.dhcpip); // output IP address of the DHCP server

Static IP Address

To configure a static IP address use ether.staticSetup().

const static uint8_t ip[] = {192,168,0,100};
const static uint8_t gw[] = {192,168,0,254};
const static uint8_t dns[] = {192,168,0,1};

if(!ether.staticSetup(ip, gw, dns);
{
    // handle failure to configure static IP address (current implementation always returns true!)
}

Send UDP packet

To send a UDP packet use ether.sendUdp().

char payload[] = "My UDP message";
uint8_t nSourcePort = 1234;
uint8_t nDestinationPort = 5678;
uint8_t ipDestinationAddress[IP_LEN];
ether.parseIp(ipDestinationAddress, "192.168.0.200");

ether.sendUdp(payload, sizeof(payload), nSourcePort, ipDestinationAddress, nDestinationPort);

DNS Lookup

To perform a DNS lookup use ether.dnsLookup().

if(!ether.dnsLookup("google.com"))
{
    // handle failure of DNS lookup
}
ether.printIp("Server: ", ether.hisip); // Result of DNS lookup is placed in the hisip member of EtherCard.

Gotchas

Currently the library does not have a local network ARP cache implemented. This means if sending UDP:

  • The only ARP lookup it does is for the gateway address.
  • You cannot send UDP frames except via a gateway.

If you are wondering why your local UDP packets are not being received, this is why! (See #59, #181, #269, #309, #351, #368).

The general workaround is to use a gateway and send UDP packets only to non-local network addresses.

Related Work

There are other Arduino libraries for the ENC28J60 that are worth mentioning:

  • UIPEthernet (Drop in replacement for stock Arduino Ethernet library)
  • EtherSia (IPv6 Arduino library for ENC28J60)
  • EtherShield (no longer maintained, predecessor to Ethercard)
  • ETHER_28J60 (no longer maintained, very low footprint and simple)

Read more about the differences at this blog post.

ethercard's People

Contributors

arnaudd-fr avatar brianlah87 avatar chatelao avatar chrissalisbury avatar denisvm avatar folkertvanheusden avatar fredycpu avatar globalcitizen avatar greblys avatar ivankravets avatar jcw avatar jorropo avatar konfiot avatar koocotte avatar lordmrcs avatar lucadentella avatar lupinchen avatar mrbig avatar njh avatar nonflammable avatar nubok avatar nuno-silva avatar per1234 avatar pmaag avatar riban-bw avatar solarkennedy avatar swarren avatar tankslappa avatar tuxmartin avatar vicatcu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ethercard's Issues

not reply arp response

when i ping the server ip, tcpdump capture arp request and reply arp requsest, but enc28j60 not response that reply. is this a issue?

Strange DHCP behaviour

Hi there,

DHCP is reliable when I connect it directly to the router (DHCP server), however when i connect to via various switches it fails.

At work, with enterprise switches that are daisy chained, it also fails at obtaining an IP via DHCP. Any ideas why this would be happening?

My PC's all work fine. It works 100% when using the NanodeUIP library.

Do I need to enableBroadcast?

Thanks
John

Glitch in DHCP support

The DHCP code for EtherCard assumes that in responses from DHCP servers, the first option in the options list indicates that the response is a DHCP message (option code 53). RFC 2131 does say that DHCP messages need to be identified as such by one of the options in the option list, but it doesn't say it has to be the first one in the list. Some routers, for example a D-Link DIR-655 I have,don't put the DHCP message option first. This causes code using the EtherCard not to be able to get a DHCP address. The options portion of the DHCP response from this router looks like:

63 82 53 63         // Magic cookie: 99 130 83 99
06 04 C0 A8 00 01   // Domain Name Server Option: ip 192.168.0.1
03 04 C0 A8 00 01   // Router Option: ip 192.168.0.1
01 04 FF FF FF 00   // Subnet Mask: 255.255.255.0
36 04 C0 A8 00 01   // DHCP Server Itentifier: ip 192.168.0.1
33 04 FF FF FF FF   // IP Address Lease Time: Forever (I assigned it in the router)
35 01 2             // DHCP Message Type: DHCPOFFER
FF                  // End Option

As you can see, the DHCP message option is the last one (other than the end marker) in the list.

JeeUdp, missing library

I get Andy's EtherShield to work with my generic ENC28J60 Arduino Ethernet Shield, but I can't get any to work with EtherCard. Is EtherCard specific to the JeeLabs device?

OK, I found JeeLib on Github and included it. Easy enough.

I want UDP.. I'm trying to use Adumote app for iPad with an ENC28J60 ethernet shield.

problem on twitter example

The provided twitter example can tweet only once in a day...is it a problem with the supertweet api or do we need to change any other setting....i dont have a static ip....

browseUrl and client headers?

Hi,
I've modified this API to take an optional parameter, additionalheaderline. I need it to specify the "Accept:" header for an image resource. (It would also be useful for specifying "Authorization:" headers.)

If this makes sense, I can send a patch?

Steve

Pachube example stops working after an hour

Hi Jcw,
Im just moving from Ethershield to your library and I was really amazed about the improvements. The Pachube example was really easy to adapt, and in five minuts it just worked.

The problem is that after 30 min or an hour, it stop working correctly, and the data sent is not the appropiate (in this example is 3Bgw7aqyA0x).

As you can see here, I barey modified the example http://www.rafaeltorrales.info/arduino/pachube_temperature.ino
So, could you tell me if this is a know error, and some patching/good practices I could apply?

891
REQUEST: 174
PUT http://api.pachube.com/v2/feeds/37273.csv HTTP/1.0
Host: api.pachube.com
X-PachubeApiKey: nvjdYAgV1OcKjsbKpotePfC5mb0RRyxbCd-2z98z3Is
Content-Length: 11

3Bgw7aqyA0x
REPLY:
HTTP/1.1 400 Bad Request
Date: Tue, 21 Feb 2012 06:49:15 GMT
Content-Type: text/plain; charset=utf-8
Connection: close
X-Pachube-Logging-Key: logging.nlYdAxqi03Bgw7aqyA0x
X-PachubeRequestId: 59bf3c1ab0d6c401ea635015be7770c0da290d3b
Cache-Control: no-cache
Content-Length: 61
Age: 0

CSV Parser Error: CSV is invalid. Incorrect number of fields.

Resolve MAC with ARP

When I send an UDP package to my computer there is no mac address set. So my UDP listener doesn't accept the packages. I set the mac address on the hard way but I need a solution to resolve this.

ethercard / tcpip.cpp

static const char *client_postval; to static char *client_postvalbetter,Generally client_postval is a variable,such as sensor data。

static void httpPost (prog_char *urlbuf, prog_char *hoststr,
                        prog_char *header, const char *postval,
                        void (*cb)(uint8_t,uint16_t,uint16_t));

change to

static void httpPost (prog_char *urlbuf, prog_char *hoststr,
                        prog_char *header, char *postval,
                        void (*cb)(uint8_t,uint16_t,uint16_t));

Other code refer to the variable to be changed accordingly

can you add httpPut Function to send data to coms.com?

Long DNSLookup times just after dhcpSetup

Hi,

I am getting very long DNS Lookup times just after calling dhcpSetup, quite often around 15 seconds.

I traced the issue to be that EtherCard::dnsLookup was waiting for clientWaitingGw

As a test I added some code in the main setup(), to wait for clientWaitingGw to be valid before I called dnsLookup, and this reduced the clientWaitingGw time to less than 2 seconds.

So, I tried splitting up the while loop that waits for both isLinkUp and clientWaitingGw and wait separately, and this seems to fix the long delays I was getting

// use during setup, as this discards all incoming requests until it returns
bool EtherCard::dnsLookup (prog_char* name, bool fromRam) {
word start = millis();

if 0

while (!isLinkUp() || clientWaitingGw())
{
packetLoop(packetReceive());
if ((word) (millis() - start) >= 30000)
return false;
}

else

while (!isLinkUp())
{
    packetLoop(packetReceive());
    if ((word) (millis() - start) >= 30000)
        return false;
}

start = millis();
while (clientWaitingGw())
{
    packetLoop(packetReceive());
    if ((word) (millis() - start) >= 30000)
        return false;
}

endif

memset(hisip, 0, 4);
dnsRequest(name, fromRam);

start = millis();
while (hisip[0] == 0) {
if ((word) (millis() - start) >= 30000)
return false;
word len = packetReceive();
if (len > 0 && packetLoop(len) == 0)
checkForDnsAnswer(len);
}

return true;
}

I'm not entirely sure how why this fixes the issue, but isLinkUp() seems to do some comms with the hardware (readbyte and writebyte), so I suspect this delaying the acquisition of the gateway mac by placing a lot of processing load on the ENC28J60

Has anyone else noticed this problem?

How to handle two frames in HTTP response

@jcw, @thiseldo I'm trying to get some code running to integrate with Cosm, but I'm running into a strange problem. It seems I only ever see the beginning of the response in the content delivered to my callback function from Cosm in response to a GET request (ala ether.browseUrl). Looking at the transaction in wireshark and using the "Follow Stream" operation, it shows that in fact the response is comprised of two TCP segments / Frames of sizes 512 bytes and 141 bytes respectively, for a total of a 653 byte response from the web server. Is there any way for me to gain access to the latter half of the server response (you know, past all the headers that I don't care about to the actual data in the body)? I've got the Ethernet::buffer allocated at 630 bytes.

Compiler Errors

I have just cloned the git repo to try with Arduino 1.0 IDE. I copied the ethercard directory to /usr/share/arduino/libraries/Ether Card.

So far every example I have tried comes up with compiler errors, either in the library code, or the example itself. For example with WebClient:

webClient.cpp:16:16: error: variable 'website' must be const in order to be put into read-only section by means of 'attribute((progmem))'
webClient.cpp: In function 'void loop()':
webClient.cpp:52:63: error: invalid conversion from 'const char_' to 'prog_char_ {aka char_}' [-fpermissive]
/usr/share/arduino/libraries/EtherCard/EtherCard.h:144:15: error: initializing argument 1 of 'static void EtherCard::browseUrl(prog_char_, const char_, prog_char_, void (*)(uint8_t, uint16_t, uint16_t))' [-fpermissive]

Is the library currently compatabile with Arduino 1.0?

CNAME not supported in DNS lookup?

Tt looks like DNS with a CNAME record (which are very common in load balancing/cloud based servers) result in a timeout and the result is 0.0.0.0 in remote addr.

Example DNS record:

$ dig www.gmail.com

; <<>> DiG 9.9.0 <<>> www.gmail.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36588
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;www.gmail.com.                 IN      A

;; ANSWER SECTION:
www.gmail.com.          69473   IN      CNAME   mail.google.com.
mail.google.com.        534226  IN      CNAME   googlemail.l.google.com.
googlemail.l.google.com. 150    IN      A       74.125.79.17
googlemail.l.google.com. 150    IN      A       74.125.79.18
googlemail.l.google.com. 150    IN      A       74.125.79.19
googlemail.l.google.com. 150    IN      A       74.125.79.83

;; Query time: 54 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Sun Apr 22 21:13:56 2012
;; MSG SIZE  rcvd: 159

And I changed getDHCPandDNS to connect to www.gmail.com to show the problem:

 char website[] PROGMEM = "www.gmail.com";

which results in:

[getDHCPandDNS]
My IP: 192.168.1.124
GW IP: 192.168.1.1
DNS IP: 192.168.1.1
DNS failed
Server: 0.0.0.0

>>> REQ

>>> REQ

I'm not really an expert on the DNS protocol and it's implementation in ethercard, but can this be solved/added?

Cheers,
Davy

Library looks broken

Today I downloaded the Arduino IDE and put this library in the right folder. I opened an example to test if everything works and BOOM, my whole display full of errors. I think there is something changed what gives the errors...

I used the webclient example code (without changes) and I got this errors:

In file included from webClient.cpp:4:0:
/usr/share/arduino/libraries/ethercard/EtherCard.h:148:26: error: ‘prog_char’ has not been declared
/usr/share/arduino/libraries/ethercard/EtherCard.h:149:26: error: ‘prog_char’ has not been declared
/usr/share/arduino/libraries/ethercard/EtherCard.h:151:25: error: ‘prog_char’ has not been declared
/usr/share/arduino/libraries/ethercard/EtherCard.h:151:44: error: ‘prog_char’ has not been declared
/usr/share/arduino/libraries/ethercard/EtherCard.h:152:25: error: ‘prog_char’ has not been declared
/usr/share/arduino/libraries/ethercard/EtherCard.h:175:26: error: ‘prog_char’ has not been declared
webClient.cpp:16:16: error: variable ‘website’ must be const in order to be put into read-only section by means of ‘attribute((progmem))’
webClient.cpp: In function ‘void setup()’:
webClient.cpp:39:31: error: no matching function for call to ‘EtherCard::dnsLookup(char [15])’
webClient.cpp:39:31: note: candidate is:
In file included from webClient.cpp:4:0:
/usr/share/arduino/libraries/ethercard/EtherCard.h:175:15: note: static bool EtherCard::dnsLookup(int_, bool)
/usr/share/arduino/libraries/ethercard/EtherCard.h:175:15: note: no known conversion for argument 1 from ‘char [15]’ to ‘int_’
webClient.cpp: In function ‘void loop()’:
webClient.cpp:52:63: error: no matching function for call to ‘EtherCard::browseUrl(const char_, const char [4], char [15], void (&)(byte, word, word))’
webClient.cpp:52:63: note: candidate is:
In file included from webClient.cpp:4:0:
/usr/share/arduino/libraries/ethercard/EtherCard.h:148:15: note: static void EtherCard::browseUrl(int_, const char_, int_, void ()(uint8_t, uint16_t, uint16_t))
/usr/share/arduino/libraries/ethercard/EtherCard.h:148:15: note: no known conversion for argument 1 from ‘const char
’ to ‘int*’

No link lights after Init on arduino ethernet shield enc28j60

Using this lib

http://jeelabs.org/pub/snapshots/EtherCard.zip

when i load any example sketch when i run it they hand during the init line of setup nothing after it executes and it does not time out.

Thoughts.

This lib looks like it could be the first real library for the arduino ethernet shield enc28j60

i should say i have a fully functioning sketch using the lib from here

https://github.com/thiseldo/EtherShield

So i know it can work just need to understand what might be failing and preventing me from using this lib..

Let me know what additional information might be needed to review the issue

Thank you Paul~

prog_char deprecated and tcpip.cpp error

Hi,
I've found an error in file EtherCard.h, dns.cpp and tcpip.cpp. prog_char is deprecated and I had to change it with "char PROGMEM" in these three files.
After the changes I have these errors in my Arduino IDE (v1.0.1) when I try to compile any example file:

/home/rey/sketchbook/libraries/ethercard/tcpip.cpp: In function ‘word www_client_internal_datafill_cb(byte)’:
/home/rey/sketchbook/libraries/ethercard/tcpip.cpp:467:21: error: section attribute cannot be specified for local variables
/home/rey/sketchbook/libraries/ethercard/tcpip.cpp: At global scope:
/home/rey/sketchbook/libraries/ethercard/tcpip.cpp:496:42: error: section attribute not allowed for ‘urlbuf’
/home/rey/sketchbook/libraries/ethercard/tcpip.cpp:496:92: error: section attribute not allowed for ‘hoststr’
/home/rey/sketchbook/libraries/ethercard/tcpip.cpp:505:41: error: section attribute not allowed for ‘urlbuf’
/home/rey/sketchbook/libraries/ethercard/tcpip.cpp:505:63: error: section attribute not allowed for ‘hoststr’
/home/rey/sketchbook/libraries/ethercard/tcpip.cpp:505:86: error: section attribute not allowed for ‘additionalheaderline’

How I can resolve?

Thank you and sorry for my bad english

Arduino 1 compiling problems

When I compile all the examples I get this problem. Maybe I can help by sharing this problem.

In file included from getStaticIP.cpp:4:
/Users/toonnelissen/Documents/Arduino/libraries/EtherCard/EtherCard.h:77: error: conflicting return type specified for 'virtual size_t Stash::write(uint8_t)'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:39: error: overriding 'virtual void Print::write(uint8_t)'
/Users/toonnelissen/Documents/Arduino/libraries/EtherCard/EtherCard.h:117: error: conflicting return type specified for 'virtual size_t BufferFiller::write(uint8_t)'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:39: error: overriding 'virtual void Print::write(uint8_t)'

fail DHCP

ether.dhcpSetup() didnt give any IP/GWIP/DNSIP

Websocket/pusher.com support

Hi everyone,

it would be great if you could provide a websocket client in order to connect to services like pusher.com

Thanks.

Possible use of uninitialized variable in EtherCard::packetLoop

The following code snippet from tcpip.cpp throws a warning when compiling the code:

word EtherCard::packetLoop (word plen) {
  word len;

  if(using_dhcp){
    ether.DhcpStateMachine(len);  // <= 'len' has not been initialized
  }
  ...
  ...

So if DHCP is beeing used the variable 'len' is used but it has not been initialized.

I have not checked the consequence/validity of this error. I just noticed that the compiler throws a warning when it is compiling the code above.

SPI & buffer problem when combining this library with SD library

I got the library up and running.
I made a example that served 3 webpages. (combination of your ethernode/rbbb_server example)

I'm using a arduino UNO and a ethernet shield ( http://iteadstudio.com/store/index.php?main_page=product_info&cPath=18&products_id=349 )

But since I want to serve a bigger webpage, I like to put some html pages on a SD card.

Both libraries work as expected, but when combined they compile but won't go into the void setup. Initiating serial connection an say something over serial, won't work.
I think it has probably something to do with the SPI and more exact the Select Pin or SS.
Or maybe the problem is in the libraries, both are initializing the SPI pins. But if that would be the problem there should be a compile error.
There should be a controller that handles both SPI SS pin. In my case it is pin 8 for the ethernet SS and pin 9 for the SD SS. And pin 10 is unconnected.

My next question is about the buffer. Right now the buffer is max 1500, because of the ethernet packet.
Am I right when I say that this library is only capable of sending 1 packet per request?

I can go the easy rout by serving the html on our own server and just leave the easy stuff for the arduino, but that wouldn't be fun.
Right know I'm using Jquery mobile to interface with the arduino. With the js libraries running online and the html pages on the arduino. But I'm not half-way with my page.

Can you help me or show me the way to make this work?

HTTP/1.1 400 Bad Request using the webclient example

Hello, im using the webclient example included on the libary changing only the website[] to infoabout.me/arduino/text.php where is only a php script that answer "hello world", the aswer on the serial monitor is:

<<< REQ >>>
HTTP/1.1 400 Bad Request
Date: Tue, 20 Nov 2012 14:28:16 GMT
Server: Apache
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1

<title>400 Bad Request</title>

Bad Request

Y...

Im very new to the libary and I assume this error is pretty dumb but I dont know what Im doing wrong. Thanks for any help!

Ethercard web server

Good day guys! I'm currently working on a web server switch for my project and here is the code. So far it is working fine, its just having some timeouts after it has been open for more than 30 mins.

include <EtherCard.h>

// Ethernet Part declaration
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

define BUFFER_SIZE 800

BufferFiller bfill;
byte Ethernet::buffer[BUFFER_SIZE];
static byte myip[] = {192,168,1,15};
// Ethernet Part ends here

const int ledPin = 6;

void setup () {

Serial.begin(9600);

//Ethernet Debugging

ether.begin(BUFFER_SIZE, mymac, 10);

ether.staticSetup(myip);

//Ethernet Debugging Ends Here

pinMode(10, OUTPUT);
digitalWrite(10, HIGH);

pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
}

void homepage(){
bfill.emit_p(PSTR(
"<title>Ethernet Controller</title>"
"



IP Based Automated
Load Carrier with RFID Security
"
"



"
""
""
""
"
Room Destination
"
"


Mobot is

"
));
}
void http_Unauthorized(){
bfill.emit_p(PSTR("HTTP/1.0 401 Unauthorized\r\n"
"Content-Type: text/html\r\n\r\n"
"

401 Unauthorized

"
));
}

void loop() {
//checking for requesting client
word len = ether.packetReceive();
word pos = ether.packetLoop(len);

if(pos) {
bfill = ether.tcpOffset();

//storing buffer on data variable
char *data = (char *) Ethernet::buffer + pos;

if (strncmp("GET /", data, 5) != 0) {
        // Unsupported HTTP request
        // 304 or 501 response would be more appropriate
         http_Unauthorized();
    }
else {
    data += 5;

        if (data[0] == ' ') {
            // Return home page
            homepage();
        }
        else if (strncmp("?cmd=GV208 ", data, 10) == 0) {
            homepage();
            Serial.println("Recieve ON");
           digitalWrite(ledPin, HIGH);


        }
        else if (strncmp("?cmd=GV209 ", data, 10) == 0) {
          homepage(); 
            Serial.println("Recieve OFF");
            digitalWrite(ledPin, LOW);
        }
        else if (strncmp("?cmd=GV210 ", data, 10) == 0) {
            homepage(); 
            Serial.println("Recieve HALF");
            analogWrite(ledPin,150);
        }
        else if (strncmp("?cmd=GV211 ", data, 10) == 0) {
            homepage(); 
            Serial.println("Recieve HALF");
            analogWrite(ledPin,10);
        }
        else {
            // Page not found
            http_Unauthorized();
        }
    }
ether.httpServerReply(bfill.position());

}
}

My problem is that when I want to create a better looking webpage, everything stops loading. I guess this is the limited RAM issues? (I'm thing of buying ATMEGA1280 to have more RAM, currently using ATMGE328)
While I still dont have a new mcu, is it possible to send the html on multiple packets instead of one so I can host a bigger html file? or is buying a new MCU the only solution for now?

Also about the timeouts, is there a problem in my code which is causing the timeouts? Can i do anything to avoid these timeouts and high latency issues?

Another thing how is it possible to use an SD card with this library? I tried using the ETHER_28J60.h library and it is working fine with its ether.print command.
Im having problem using the data I read on my SD on bfill.emit_p command.
What I do is
while (sd.available()){
c= sd.read();
bfillemit_p(c);
}
kinda like this.
this code works fine on other libraries( changing bfill.emit_p with the print command of the other library) but it is not working on ethercard.h library. How do I use my SD right on this library?

THX GUYS and more power to the community!

SPI_SS Pins in Arduino MEGA

I use Arduino MEGA1280, who has SPI pins in: 50, 51, 52 (and 53 as CS).
I changed manually the code in enc28j60.cpp at lines 247 to use these pins, but if I change the CS pin (SPI_SS) to another, like 49, because I have the SD card module, they don't work.

I see recently the ether.begin support a third parameter, but it is limited at pins 8, 9, and 10, so this not help-me.
Is possible expand the CS pin to all digital pins, for who use Arduino MEGA can use this library too?

Best Regards

Posting Questin here (have not been able to log onto fourms)

Question Moved here

http://forum.jeelabs.net/node/677

(CLOSED)

ether.browseUrl(PSTR("/rc/status/submit.asp?"), "rcid=paulvi1&TP1=22&TP2=1&TP3=1&TP4=2&RELAYDATA=119&ATO=0&INTFAN=1&TANKFAN=0&MLIGHT=1&LLIGHT=0", website, my_result_cb);

im using the client to request a web page with a url like this

i would like to be able to send variable data for each of the url comnds tp1=xx.xx and so on but i can not seem to figure out how to do it im a few hours into it and just not finding that smoking gun to get my light to turn on...

Any help or pointing me into the right direction would be great

Thank you

TP1-4 = Float
RELAYDATA and the rest are Byte

Problem about UDP send with ethercard ENC28J60

I have a problem about UDP send with ethercard.

My problem is about:
I use Arduino uno3+ ENC28J60 + DHT11 + two 7segment LED to display temperature and humidity and send data to host PC by UDP , all the hardware and sub-module test normal, the ENC28J60 CS connect to D10, the measured power supply voltage for ENC28J60 is 3.3V, The IDE with the 1.03 version, EtherCard with the latest version. all functions in normal when I running wireshake to capture data on host PC,I got correctly display of temperature and humidity and the received UDP data is OK, but when I stop capture data with wireshake,the host computer can not receive any data, what possible with the problem?

I've try several different program on host PC and got the same result.
When I do the capturing with winshake, the program I use to receive UDP data can got correct result, when I stop capturing with winshake, the program I use to receive UDP data can't received any data.

I do a test by replace ENC28J60 with W5100 ,I got a correct result without runing winshask.
Compare with the w5100 code I think the code for UDP in ethercard maybe short of something for bind sorport to disport,but I don't know how to modify the ethercard library. I also I don't know how to use ether.udpTransmit() for Transmit udp data,can someone give me a example?

Thanks!

the code as below:

//CS→D10;SI→D11;SO→D12;SCK→D13

include <EtherCard.h>

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = {192,168,2,23};
static byte gwip[] = {192,168,23,254};
byte Ethernet::buffer[100];
static byte destip[]= {192,168,2,10};
static int myport=1000,destport=1001;

// bits representing segments A through G (and decimal point) for numerals 0-9
const int numeral[10] = {
//ABCDEFG /dp
B11111100, // 0
B01100000, // 1
B11011010, // 2
B11110010, // 3
B01100110, // 4
B10110110, // 5
B10111110, // 6
B11100000, // 7
B11111110, // 8
B11110110, // 9
};
// pins for decimal point and each segment
// dp,G,F,E,D,C,B,A
const int segmentPins[] = { 9,8,7,6,5,4,3,2};
const int nbrDigits= 2; // the number of digits in the LED display
//dig 1 2
const int digitPins[nbrDigits] = { A4,A5};
int dppin=A3; //set the decimal point link to PIN A3

include <dht11.h>

dht11 DHT11;

define DHT11PIN A0 //DHT11 PIN 3 →UNO A0

char string1[2];//humidity
char string2[2];//temperature

void setup()
{
Serial.begin(19200);

if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)
Serial.println( "Failed to access Ethernet controller");
if (!ether.staticSetup(myip))
Serial.println("Failed to set IP address");

// ether.setGwIp(gwip);

for(int i=0; i < 8; i++)
pinMode(segmentPins, OUTPUT); // set segment and DP pins to output
for(int i=0; i < nbrDigits; i++)
pinMode(digitPins, OUTPUT);

}

void loop()
{

int chk = DHT11.read(DHT11PIN);

Serial.print("Read sensor: ");
switch (chk)
{
case DHTLIB_OK:
Serial.println("OK");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println("Checksum error");
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.println("Time out error");
break;
default:
Serial.println("Unknown error");
break;
}

int humd=int(DHT11.humidity);
int temp=int(DHT11.temperature-2);

itoa(humd,string1,10);
itoa(temp,string2,10);

//ether.udpPrepare(myport,destip,destport);
//ether.udpTransmit(4);
ether.sendUdp ((char*) string1, 64, myport, destip, destport);
Serial.println("DATA send by UDP!");
Serial.println(humd);
Serial.println(temp);
// delay(2000);

//Display on 7segment
int counter1=200;
while(counter1)
{
counter1--;
// showNumber(DHT11.humidity);
showNumber(humd);
}
counter1=200;
while(counter1)
{
counter1--;
analogWrite(dppin,0);
// showNumber(DHT11.temperature-2);
showNumber(temp);
analogWrite(dppin,200);
}
}

void showNumber( int number)
{
if(number == 0)
showDigit( 0, nbrDigits-1) ; // display 0 in the rightmost digit
else
{
// display the value corresponding to each digit
// leftmost digit is 0, rightmost is one less than the number of places
for( int digit = nbrDigits-1; digit >= 0; digit--)
{
if(number > 0)
{
showDigit( number % 10, digit) ;
number = number / 10;
}
}
}
}
// Displays given number on a 7-segment display at the given digit position
void showDigit( int segnumber, int digit)
{
digitalWrite( digitPins[digit], HIGH );
for(int segment = 1; segment <8; segment++)
{
boolean isBitSet = bitRead(numeral[segnumber], segment);
// isBitSet will be true if given bit is 1

//isBitSet = ! isBitSet; // remove this line if common cathode display

digitalWrite( segmentPins[segment], isBitSet);
}
delay(5);
digitalWrite( digitPins[digit], LOW );
}

card not responding

I am trying ethercard because it supports dhcp, but I can't get it working. I needed to remove some "PSTR" and "PROGMEM", and got it compiled with arduino 1.0.3. But When I try the demos, it prints "Failed to access Ethernet controller". Any ideas please?

I am using this module: http://img.alibaba.com/img/pb/128/356/547/547356128_673.jpg

UPDATE: I found the program is hanging in this instruction:

while (!readOp(ENC28J60_READ_CTRL_REG, ESTAT) & ESTAT_CLKRDY);

In the working library I found this:
// The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
And they replaced the wihile by sleep(50). I tried this but it stills not working. It does not hang but byte rev = readRegByte(EREVID); answers 0.

Multi packets http pages with the arduino

i have modified your library for sending webpages with bigger length as a frame

EDIT :WORKING CODE ON 15 july 2013!!!!!
I figured out compatibility problem between SD library in arduino ide and ethercard lib
switched to tinyFAT library and works very well
transfered 240 Megabytes from SD card wihout any packet loss !
Transfer speed :130 kilobytes /second

what i have changed :(this is the final code with bug corrections)

// added in ethercard.h :

static void httpServerReply_with_flags (uint16_t dlen , byte flags);
static void httpServerReplyAck ();

// added in tcpiip.cpp (declarations)

static unsigned long SEQ;

// added in tcpiip.cpp (functions)

static void get_seq() { //get the sequence number of packets after an ack from GET
SEQ =(((unsigned long)gPB[TCP_SEQ_H_P]_256+gPB[TCP_SEQ_H_P+1])_256+gPB[TCP_SEQ_H_P+2])*256+gPB[TCP_SEQ_H_P+3];
} //thanks to mstuetz for the missing (unsigned long)

static void set_seq(word dlen) { //set the correct sequence number and calculate the next with the lenght of current packet
gPB[TCP_SEQ_H_P]= (SEQ & 0xff000000 ) >> 24;
gPB[TCP_SEQ_H_P+1]= (SEQ & 0xff0000 ) >> 16;
gPB[TCP_SEQ_H_P+2]= (SEQ & 0xff00 ) >> 8;
gPB[TCP_SEQ_H_P+3]= (SEQ & 0xff );
SEQ=SEQ+dlen;//next sequence number
}

void EtherCard::httpServerReplyAck () {
make_tcp_ack_from_any(info_data_len,0); // send ack for http get
get_seq(); //get the sequence number of packets after an ack from GET
}

void EtherCard::httpServerReply_with_flags (word dlen , byte flags) {
set_seq(dlen);
gPB[TCP_FLAGS_P] = flags; // final packet
make_tcp_ack_with_data_noflags(dlen); // send data
}

Here you will find the actual version of this libray with my updates and
two working exemples (sending http pages in more packets from programm, and sending http content from sd card)

the multipacketSD exemple uses about 15 kb of flash but dont forget to fill sd card with exemple content /library/exemples/multipackesSD/copy to sd !!! headers files are needed (.hea)

http://microinfo.fr/multipackets.rar

Sorry for my english , i'm french
Frédéric HERMS

Keep connection open?

Is there a way to keep the connection open so that the server can keep pushing data to the device?

Card not work

Hello everyone!
Yesterday I bought this ethernet shield for arduino one and after all pieces was ok i tried to run an example in particular the program back soon but the serial monitor return me

[backSoon]
Failed to access Ethernet controller
DHCP failed
IP: 0.0.0.0
GW: 0.0.0.0
DNS: 0.0.0.0

I think the problem is the card ...
But i can be wrong something I use Arduino 1.0 for the compiler and i program my arduino with etherneth controller on ,makeover with the lan cable connect.

AVR-GCC PROBLEM

Hi guys, i just bought an arduino ethernet shield v1.1 so i'm trying to use it with this library.
the problem is that every sketch i try to compile gives this error:

/usr/share/arduino/libraries/EtherCard/tcpip.cpp: In function 'word www_client_internal_datafill_cb(byte)':
/usr/share/arduino/libraries/EtherCard/tcpip.cpp:459:20: error: variable 'c' must be const in order to be put into read-only section by means of 'attribute((progmem))'
/usr/share/arduino/libraries/EtherCard/tcpip.cpp:468:20: error: variable 'c' must be const in order to be put into read-only section by means of 'attribute((progmem))'

Thanks in advance

DHCP Issues with ENC28J60, receiving everything except IP

Hi there,

When using the latest code and running the testDHCP example, I get the following serial debug.

[testDHCP]
MAC: 74:69:69:2D:30:31
Setting up DHCP
DHCP failed
My IP: 0.0.0.0
Netmask: 255.255.255.128
GW IP: 192.168.195.1
DNS IP: 10.100.8.15

It seems to pick up the correct values for everything as expected, except IP. Any ideas?

Johan

Missing udp receive

I cannot found a udp receive function in the library.
Did you think to implement it or I didn't found the correct function.

Using the thread ability the function can be blocking.
Thanks

Wrong MAC when sending broadcast

Hello,

When sending a broadcast packet (255.255.255.255) the recipient MAC remains to 00:00:00:00:00:00. If not wrong, it should be also set to the broadcast MAC (as for the WOL packets for instance).

I made the following fix in tcpip.cpp, function EtherCard::udpPrepare:

replaced
if ((dip[0] & 0xF0) == 0xE0) // multicast address

by
if ((dip[0] & 0xF0) == 0xE0 || *((long *) dip) == 0xFFFFFFFF) // multicast or broadcast address

Seems to work.

Rgds,

L.

UDP Send & Recive data

Dear jcw ,
Frist i wanna thank you for ur effort on this library , second i wanna ask if u can help me on to send and recive udp package with this library becouse i wanna send data from my phone to wifi network using udp and when ethercard recived data do action . this example for what i wanna .

i wanna send >>> " Hi arduino " from my phone using udp application then
when i recive this send back to me at my phone >>> " hi phone " . and so on......

i hope you get my point , thanks for ur time and ur help

Sending broadcast UDP packets

Hi,

I use ethercard for an implemetation of the xPL protocol on arduino.

I have a problem sending broadcast UDP packets.
On a network 192.168.1.0 sending packet to 255.255.255.255 don't work, I need to specify the real broadcast address of the network ( 192.168.1.255 ) and to modify the tcpip.cpp file, line 317

From : if ((dip[0] & 0xF0) == 0xE0) // multicast address
To : if ((dip[0] & 0xF0) == 0xE0 || dip[3] == 0xff) // multicast/broadcast address

This is ugly since a broadcast address don't necessary finish by 255 ... but I don't know how to simply detect if the destination Ip address is the broadcast address of the network ? or Am I missing something ?

Thanks for reading me, sorry for my english.

DNS reply parsing insists on server supporting recursion

As discovered in the forums - http://forum.jeelabs.net/node/1074

Performing a domain lookup of amazon.co.uk against Amazon's own server 207.171.178.13 fails.

Investigation revealed that the response flags from the Amazon did not contain the "Recursion available" and the reply validation of checkForDnsAnswer() was insisting this flag was present.

Changing the conditional from (p[3] & 0x8F) != 0x80) to (p[3] & 0x0F) != 0x00) solves the problem allowing the domain to resolve.

Is there any reason the library insists on recursion being available?

How to get all response packets from browseUrl?

I've been working on a solution so that browseUrl can return all packets to its callback, not just the first packet.
i.e the current code sets TCP_FLAGS_FIN_V when the first packet in response to browseUrl is received. This appears to terminate the connection, hence the other response packets (if there are any), are lost.

I did a hacky change to the code to check if the buffer length was 512 and if so, it presumes there is more data, and rather than sending ACK + FIN_V it just sends ACK (and doesn't change the client state)
If there was less than 512 bytes, it presumes that its the last packet and sends ACK+FIN_V and sets the client_tcp_state to 6 as in the original code.

This seems to work, but I'm pretty sure that just checking for len==512 is probably not the best way to check for last packet.

ie the callback keeps getting called as each packet arrives, as long as the main event loop ether.packetLoop(ether.packetReceive()); is being called in loop()

The code I changed was in the Ethercard:packetloop for when tcp_client_state ==3 (see below)

I don't know if this code would break something else.

Is there a clean way to do this?

BTW. I want to do this because I need to grab data from a webpage to get current temperature and the page is not designed to be a feed and hence is about 10k of text.

--------- my hacky code changes in Ethercard:packetloop -----------

if (tcp_client_state==3 && len>0)
{

 if (client_tcp_result_cb) 
  {
    word tcpstart = TCP_DATA_START; // TCP_DATA_START is a formula
    if (tcpstart>plen-8)
    {
      tcpstart = plen-8; // dummy but save
    }
    word save_len = len;
    if (tcpstart+len>plen)
    {
      save_len = plen-tcpstart;
    }
    (*client_tcp_result_cb)((gPB[TCP_DST_PORT_L_P]>>5)&0x7,0,tcpstart,save_len);

    // Roger Clark. Added code to handle multipacket responses
    // NOTE. This code is experimental and seems to work for browseURL but may break other features

    //  Only go to state 6 and send  FIN_V if the saved buffer length !=512
    // NOTE 512 is a hack, this really needs to be changed ot the packet length
    if (save_len!=512)
    {
      make_tcp_ack_from_any(len,TCP_FLAGS_PUSH_V|TCP_FLAGS_FIN_V);
      tcp_client_state = 6;
    }
    else
    {
      // send ACK and stay in current state ready to receive more data
      make_tcp_ack_from_any(len,TCP_FLAGS_PUSH_V);//|TCP_FLAGS_FIN_V);
    }
    // Roger Clark. End of changes.
    return 0;
  }
}

Something strange happing with my ethernet controller?

Hi Guys,

Awesome library!

But I've had some problems were suddenly the communication would stop working.. After many try-repoducing sessions it seems even the demo projects fail? Do you know what I could still check?

If I run the getDHCPandDNS example the following is printed to my console:


[getDHCPandDNS]
My IP: 192.168.1.124
GW IP: 192.168.1.1
DNS IP: 192.168.1.1
Server: 173.194.65.113

>>> REQ
<<< reply 46 ms
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/foo/bar
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
Date: Thu, 16 Feb 2012 19:22:26 GMT
Expires: Sat, 17 Mar 2012 19:22:26 GMT
Cache-Control: public, max-age=2592000
Server: sffe
Content-Length: 226
X-XSS-Protection: 1; mode=block
Connection: close

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<

>>> REQ

>>> REQ

>>> REQ

>>> REQ

>>> REQ

>>> REQ

So somehow after the first time it doesn't work anymore? strangely both the orange and the green light keep working.

(I'm using one of these bad boys: http://www.lcsoft.net/Hardware/Detail.aspx?id=4a52cee8-a024-4390-90ab-095dd21ebbdb on a Arduino).

Cheers,
Davy

draw web page with multiple ethernet packet.

Due to my application I have limited ethernet buffer (500 bytes only), but I need to draw large web page.
Is it possible to draw web page with multiple ethernet packet?

Thanks & regards
jags

SMTP protocol problems

Hi,

I've been looking at the possibility of sending SMTP (email) using Ethercard, however the way the current packetloop works doesn't seem to be very compatible with SMTP.

I can get as far as the connection message being returned e.g. "220 SMTP server ready",
by having a custom fill callback function, that doesn't fill with anything.
and by setting persist_tcp_connection=true to stop the connection being immediately closed

However looking at the ACT sent in response to the connection message, the current packetloop sends [PSH,ACK] where normally SMTP just sends ACK

Even if I ignore this, the next step in the protocol is to send the "HELO" message using [PSH,ACK]
however by this point the packetloop code seems very confused and setting tcp_client_state=2 and waiting for the next call to the buffer fill callback, doesn't happen because the packetloop returns before it gets to the state==2 code :-(

Can someone tell me whether the current packetloop is likely to be able to support a new protocol at all, or with minor modifications, or whether I would need to write my own packetloop (based heavily on the existing code) ?

PS. I'm an experienced programming, but have had no dealings with TCPIP before.

FYI.
Looking at a working SMTP transfer the overall packet structure looks like this

SYN
SYN,ACK
ACK

TCP duplicate ACK (not sure why this happens)

PSH,ACK server sends connection message
ACK client ack to server connection message
PSH,ACK client sends HELO message
ACK server sends ACK for client ACK

etc etc

Wierd result for get data

I don't know if i'm doing something wrong, but im getting really wierd results

void report_temp (float temp, int unit) {

  char buf[16];
  char buf_full[32];                                        // 32 == Wierdness, 128 is working

  // Construct GET payload
  String s = "t=";
  s = s + String(dtostrf(temp,7,3,buf));
  s = s + "&u=";
  s = s + String(unit);

  s = s.replace(" ","");

  // Convert s to char *
  s.toCharArray(buf_full, sizeof(buf_full));

  Serial.println(buf_full);        // <--- Always looks fine wether i use 32 or 128

  ether.browseUrl(PSTR(SITE_REPORT_URL), buf_full, website, callback);

  }

When i am using 32 as size for buf_full, i get a request that looks like this on server side;

  [13/Dec/2011:00:11:37 +0100] "GET /temp/report.php?ºÙ\x08 HTTP/1.1" 200 19 "-" "-"

When using 128 as buffer size, i get something that makes sense

  [13/Dec/2011:00:47:20 +0100] "GET /temp/report.php?t=23.250&u=0 HTTP/1.1" 200 12 "-" "-"

How is this possible? The resulting string is not more than 16 chars? And when i do Serial.println() it seems fine

Anyways, thanks for a great peice of software :)

// Robin

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.