Arduino - Ethernet

From Helpful
Jump to navigation Jump to search
This is for beginners and very much by a beginner / hobbyist.

It's intended to get an intuitive overview for hobbyist needs. It may get you started, but to be able to do anything remotely clever, follow a proper course or read a good book.


Some basics and reference: Volts, amps, energy, power · batteries · resistors · transistors · fuses · diodes · capacitors · inductors and transformers · ground

Slightly less basic: amplifier notes · varistors · changing voltage · baluns · frequency generation · Transmission lines · skin effect


And some more applied stuff:

IO: Input and output pins · wired local IO · wired local-ish IO · ·  Various wireless · 802.11 (WiFi) · cell phone

Sensors: General sensor notes, voltage and current sensing · Knobs and dials · Pressure sensing · Temperature sensing · humidity sensing · Light sensing · Movement sensing · Capacitive sensing · Touch screen notes

Actuators: General actuator notes, circuit protection · Motors and servos · Solenoids

Noise stuff: Stray signals and noise · sound-related noise names · electronic non-coupled noise names · electronic coupled noise · ground loop · strategies to avoid coupled noise · Sampling, reproduction, and transmission distortions

Audio notes: See avnotes


Platform specific

Arduino and AVR notes · (Ethernet)
Microcontroller and computer platforms ··· ESP series notes · STM32 series notes


Less sorted: Ground · device voltage and impedance (+ audio-specific) · electricity and humans · power supply considerations · Common terms, useful basics, soldering · landline phones · pulse modulation · signal reflection · Project boxes · resource metering · SDR · PLL · vacuum tubes · Multimeter notes Unsorted stuff

Some stuff I've messed with: Avrusb500v2 · GPS · Hilo GPRS · JY-MCU · DMX · Thermal printer ·

See also Category:Electronics.

Ethernet shield

This article/section is a stub — probably a pile of half-sorted notes and is probably a first version, is not well-checked, so may have incorrect bits. (Feel free to ignore, or tell me)

There are quite a few Ethernet shields out there, but the more official and common shield, and the standard Ethernet library, are based on the Wiznet W5100.


Most network-related processing is done on the shield, but talking to the shield (via SPI) may still take at least a few milliseconds - which can matter to you.

The Ethernet library also supports the newer W5200 and W5500 variants. These two speak faster SPI which means you can handle packets faster, have a little more packet RAM, and they're also a little cheaper.


The W5100 speaks SPI and the shield use pin 10, 11, 12, and 13 (the AVR's hardware SPI), and passes all of the pins through (including the SPI ones - but note the bus bug in the older variant).


There was an older design of that more official shield:

  • has a non-functional SD slot (at least, not officially supported - some people have reported getting it to work.)
  • seems to have a bug where it doesn't release the bus (MISO?), meaning you can't use other SPI devices.
  • Not wired to work with the Mega variants out of the box, but can be made to without too much trouble.(verify)

The newer shield (now the one listed at [1])

  • is marked "ETHShield SD" and "mega compatible" (the latter because it uses SPI over the ICSP header)
  • Has a MAC address on a sticker on the back
  • has a functional microSD slot (its slave select is on digital pin 4(verify)[2]. )
  • seems to not have the bus bug the earlier one has (...since the microSD card also uses the SPI bus)

Both will work with the basic library - and various others will too.



Power

Datasheet mentions it typically dissipates approx ~140mA (183mA max) - at 3.3V. Can't be powered off.(verify)



RAM

The Wiznet chips have packet RAM (8KB of Tx and 8KB of Rx for the W5100, 16KB of Tx and 16KB of Rx for the W5200 and W5500).

On AVRs, receiving full packets into a buffer is going to push your RAM limits, so when you can, you may want to define a protocol that you can deal with in smaller chunks at a time. (you may want to do that with UDP anyway, because packets could arrive out of order)


For some reason the library defines e.g. a UDP_TX_PACKET_MAX_SIZE as 24 bytes, but this does not seem to be a limitation or internal buffer size(verify).



On libraries

IIRC older versions required you to configure a MAC and IP address manually (plus a gateway and subnet if you actually wanted it to route to the internet).

Later (version 1.0?(verify)) it supports DHCP by using Ethernet.begin(mac), plus maintain() and some further logic if you want it to do renews and rebinds.


You are limited to four socket connections (in+out total) because of the W5100 (eight on 5200 and 5500(verify)).


More on the basic ethernet library:

  • Incoming connections on the Server are returned as Client instantiations.
  • It seems that according to server.available(), a client is considered a client not when it connects, but only once it has something to say.
Even if only want your arduino to write out, the client will still have to send data before available() will return it as a Client you can write to (one byte of dummy data is enough).(verify)


Surprisingly, the early versions supported only TCP, not UDP, even though UDP is connectionless. These days you can do both.


There are also other libraries than the standard one, and early days you basically wanted these for their features (such as DHCP, DNS, UDP, OSC, Bonjour) and/or other boards. (see e.g. [3], [4], [5])

(particularly DHCP and DNS are handy as it means you need no hardcoding beyond a unique MAC)







See also:


Other libraries:


Similar devices:


Some code

  1. include <SPI.h>
  2. include <Ethernet.h>
  3. include <EthernetUdp.h>


byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };

EthernetUDP udp_endpoint; EthernetServer tcp_server = EthernetServer(7);

  1. define MY_PACKET_BUFFER_SIZE 100

char packet_buffer[MY_PACKET_BUFFER_SIZE];


void setup() {

 Serial.begin(115200);
 Serial.println("setup()");
 /******** DHCP **********/
 if (Ethernet.begin(mac) == 0) {
   Serial.println("Failed to configure Ethernet");
   // no point in carrying on, so do nothing forevermore:
   while (true) {
     Serial.println("DHCP failure; will reset via watchdog");
     delay(1);
   }
 }
 // print your local IP address:
 Serial.print("My IP address: ");   Serial.println(Ethernet.localIP());
 Serial.print("Subnet mask:   ");   Serial.println(Ethernet.subnetMask());
 Serial.print("Gateway:       ");   Serial.println(Ethernet.gatewayIP());
 Serial.print("DNS server:    ");   Serial.println(Ethernet.dnsServerIP());
 udp_endpoint.begin(7);

}


void loop() {

 switch (Ethernet.maintain()) {
   case 2:
     Serial.println("Renewed success");
     Serial.print("My IP address: ");
     Serial.println(Ethernet.localIP());
     break;
   case 4:
     Serial.println("Rebind success");
     Serial.print("My IP address: ");
     Serial.println(Ethernet.localIP());
     break;
   case 1:
     Serial.println("Error: renewed fail");
     while (true) { delay(1); } // loop to trigger watchdog
     break;
   case 3:
     Serial.println("Error: rebind fail");
     while (true) { delay(1); } // loop to trigger watchdog
     break;
   default:
     break;
 }


 /******** TCP ***********/
 EthernetClient tcp_client = tcp_server.available();
 if (tcp_client) {
   Serial.print("[TCP] Received packet of size ");
   Serial.println( tcp_client.available() );
   Serial.print("[TCP] From ");
   IPAddress remote = tcp_client.remoteIP();
   for (int i = 0; i < 4; i++) { Serial.print(remote[i], DEC); if (i < 3) { Serial.print("."); } }
   Serial.print(", port ");
   Serial.println(tcp_client.remotePort());
   int s=min(tcp_client.available(), MY_PACKET_BUFFER_SIZE);
   tcp_client.read(packet_buffer, s);
   Serial.print("[TCP] Contents:");
   for (int j=0;j<s;j++) {
     Serial.print( (unsigned char)packet_buffer[j], HEX);
     Serial.print(" ");
   }
   Serial.println("");
   Serial.println("");
   tcp_client.write( packet_buffer );
   tcp_client.stop();
 }
 /******** UDP ***********/
 int packetSize = udp_endpoint.parsePacket(); // sets _remainging
 if (packetSize) {
   Serial.print("[UDP] Received packet of size ");
   Serial.println(packetSize);
   Serial.print("[UDP] From ");
   IPAddress remote = udp_endpoint.remoteIP();
   for (int i = 0; i < 4; i++) {
     Serial.print(remote[i], DEC);
     if (i < 3) {
       Serial.print(".");
     }
   }
   Serial.print(", port ");
   Serial.println(udp_endpoint.remotePort());
   // read the packet into packetBuffer
   int s=min(packetSize, MY_PACKET_BUFFER_SIZE);
   udp_endpoint.read(packet_buffer, s);
   Serial.print("[UDP] Contents:");
   for (int j=0;j<s;j++) {
     Serial.print( (unsigned char)packet_buffer[j], HEX);
     Serial.print(" ");
   }
   Serial.println("");
   Serial.println("");
 }

}

Other ethernet

Tuxgraphics_AVR_ethernet_kit_notes#ENC28J60