Ethernet for Teensy3

Status
Not open for further replies.
The w5100.cpp and w5100.h files referenced above have been used in place of the w5100.* files normally used. I also have WIZ812mj boards that works just fine with the standard library. The references to the WIZ812mj are just my previous comments. The .cpp and .h file above both reference the W5200. According to the WizNet github, all example .ino files should run.
 
Yup. You are correct. However, the files that are posted on the Wiznet Github have two versions.
One for Arduino's 8-bit micro controllers and one for the Due, which is more applicable for the Teensy3 but still would need to be modified remove the very due only specific SPI stuff.

One difference between the wiznet provided files and the one's I am using is this line in W5100.h:

Wiznet:

void read_data(SOCKET s, volatile uint8_t * src, volatile uint8_t * dst, uint16_t len);

headroom:

void read_data(SOCKET s, volatile uint16_t src, volatile uint8_t * dst, uint16_t len);

I'll post a functioning ethernet and perhaps Bonjour library later this weekend that also allows you to take advantage of the higher SPI frequency the WIZ820io is capable of.
 
Downloaded and installed the files mentioned here, and grounded PDWN as mentioned here.

I'm now getting a valid IP address, and can access an external web address, however the WebServer file still does not work properly.

Code:
/*
  Web Server
 
 A simple web server that shows the value of the analog input pins.
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe
 
 */

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0xDE, 0xAD, 0xBA, 0xBE, 0xFA, 0xCE };
IPAddress ip(192,168,1,135);

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(115200);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  delay(1000);
  Serial.println(F("Resetting WIZ nic"));
  pinMode(9, OUTPUT);
  digitalWrite(9, LOW);
  delay(250);
  digitalWrite(9, HIGH);
  
  delay(1000);
  Serial.println(F("Configuring Static IP"));


  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  // 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) {
          Serial.println(F("Sending standard header response"));
          // send a standard http response header
          client.println(F("HTTP/1.1 200 OK"));
          client.println(F("Content-Type: text/html"));
          client.println(F("Connection: close"));  // the connection will be closed after completion of the response
	  client.println(F("Refresh: 5"));  // refresh the page automatically every 5 sec
          client.println(F(""));
          client.println(F("<!DOCTYPE HTML>"));
          client.println(F("<html>"));
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print(F("BoogerHead "));
            client.print(analogChannel);
            client.print(F(" is "));
            client.print(sensorReading);
            client.println(F("<br />"));       
          }
          client.println(F("</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");
  }
}

Output from Serial Monitor
Code:
Resetting WIZ nic
Configuring Static IP
server is at 192.168.1.135
new client
GET / HTTP/1.1
Host: 192.168.1.135
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.65 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

Sending standard header response
client disonnected

The web browser requesting the page just sits waiting for a response.
 
I recently started looking at W5200 optimizations. It turns out the ethernet library has a horribly inefficient design that causes nearly all SPI transfers to be for a single byte, even when accessing 16 bit registers.

So far, I'm not done any work at the low-level to increase the SPI speed. Headroom, maybe we should merge our efforts?
 
Yes, that would be very interesting! I have really not done any optimizing work at that level.
Currently I am happy that I was able to get Ethernet connectivity and got Bonjour to announce the OSC service (Open Sound Control).
Since last week I have been able to communicate bi-directionally with Touch OSC, meaning I can press a button or move a slider in Touch OSC and have the Teensy3 send back OSC messages to display in TouchOSC.

It took some research looking at different versions of the ethernet library to finally get it to work. User manitou has started doing some optimization work in this thread

The modified library he has posted on his github includes some code that would be interesting to explore. For example he has "hacked" in functionality from the SDFat library that includes DMA. At the very least it includes a way to change the SPI bus frequency to increase throughput.

I don't want to derail this thread and apologize if I have already done so. But improved SPI and Ethernet performance even if we loose some compatibility with the Arduino world would be very beneficial as these are such elementary building blocks for many applications. For my own projects for example I'd like to expose all the functionality of my LEDshileds through OSC so a user would be able to control lighting effects e.g. though Puredata or MAXmsp directly without ever having to program the mirocontroller in C/ C++. Getting the best performance out of the SPI and Ethernet libraries would be paramount.
 
Also, while we're at it, It would be very nice if the EthernetBonjour library could be added to Teensyduino. The library was initially written by Georg Kaindl and is located here.
It is a little bit older and since some time DNS and DHCP functionality have been integrated into the Arduino Ethernet library. I've been able to make the minor changes required to get it to work with the Teensy++2 and now with the Teensy3. I believe specifically with projects aimed at the "Internet of Things" the Bonjour functionality is very nice to have and would put Teensy3 even further ahead of the competition.
 
The EthernetUdp library seems to work just fine. I'm trying convert my TeensyPi project from using Serial1 with the RaspberryPi to a networked (wired or wifi, eventually) UDP-based controller.
 
That should not pose a problem, depending on what sort of data you want to transfer. The current OSC library "shipping" with Teensyduino uses either SLIPserial (through USB) or UDP. You can easily connect a little wireless pocket router like the TP-Link TL WR702n (or 703 or 3020) to the the WIZ820io and you're wireless in no time. Ive done that in several projects and it works like a charm.

However, UDP is connectionless, so not only can you loose packets, there is also no mechanism making sure that packets arrive in the correct order!
 
UDP on a LAN is most always problem-free. As long as the receiving end keeps up with the packet arrival rate. Or uses an agreement of flow control, such as sending a response packet that is in effect, an ACK.
It can be as elaborate as you wish.
Great advantage of UDP is that the two end devices do not have to maintaing/reconnect a TCP connection.
 
It appears that I totally forgot to post these libraries. I'll have to do this later as a lot of this is a bit of a work in Progress.
The original Bonjour library had to be edited :
A. to work with both, the W5100(Arduino Ethernet Shield and WIZ812MJ) and W5200 Ethernet chips (WIZ820io)
B. to work for the Teensy3. It does that now but it does not work for the Teensy++2 anymore.

Currently the Teensy3 can register an OSC (UDP based) service on the network that can easily be picked up by TouchOSC, or an or an HTTP service (TCP based) but I don't know if all the other examples still work. For example the Teensy3 could also discover services. I did not need this functionality for my application so I never tried it.

I need to start a Github account soon ;-)
 
Hi Paul,

I've assembled your board, and am getting ready to test it. Just wanted to make sure of the orientation of the boards. It appears that the micro-b connector of the Teensy 3.0 and the RJ-45 connector of the WIZ820io are oriented in one direction, while the SD Card is positioned at the opposite end, sort of like your Teensy 2 / WIZ812mj setup, correct?

I'm not using the SD card at this time, just testing the WIZ820io.

UPDATE: Works like a charm.:eek:
 
Last edited:
Glad it's working. :)

PJRC will soon be selling this PCB, with the SMT parts soldered and tested. It's been delayed because the first batch of PCBs had a quality problem and had to be returned and a new batch made. With attention diverted to releasing Teensy 3.1, this poor little PCB fell to the low priority list. Hopefully we'll have them for sale in early January.
 
Does anybody have a picture showing the orientation of the Wiz820 and Teensy 3 when attached to the WIZ820io & Micro SD Card Adaptor? I received mine today but I'm not sure how it goes together. Thanks in advance!
 
I would assume both the audio shield and the WIZ820io shields would have the SD card oriented so that pins 9-12 are on the left and pin 13 is on the right and opposite the micro USB adapter, since these pins are the SPI pins, and I believe the SD socket uses SPI.
 
I'd added photos and instructions to the WIZ820_SD_ADAPTOR page.

http://www.pjrc.com/store/wiz820_sd_adaptor.html

Hopefully this helps?

wiz820_assem5.jpg
 
Hi Paul,
Just double checking that the t3 is capable of powering the wiz820io? For some reason in the back of my head I had that it drew more than 100mA (can't seem to find that number in the docs).
Thanks,
David
 
No, it cannot! The Adapter board has a LDO voltage regulator on it that converts the 5V USB power down to the 3.3V needed by the WIZ810io.
 
OK. And if I want to use an external 5V power supply do I connect to the Vin pin on the T3 (still using the adapter board) (i.e. once programmed, there will be no USB connection)? My current set-up (without the adapter board) was:
5V >> 3v3 regulator >> T3 3v3 pin
>> wiz820io Vin pins
(that's suppose to be the voltage reg supplying 3.3v to both the t3 & wiz820io)
so just want to make sure if I supply 5V to the Vin pin on the T3 via the adapter board it can also power the WIZ820io.

Thanks,
David
 
Last edited:
I've just set up a Teensy 3.1 with Wiz820io. I'm using the latest Teensyduino 1.19, downloaded today (18-June). I've un-commented the line in W5100.cpp to set clock to 24MHz and I can see the 24MHz clock with an oscilloscope. Performance is much better than previous Teensy2++ Wiz812 version. However performance seems to be well below what I believe should be achievable. I've read through all the Forum articles I can find, and I think everything is set up as it should be, except possibly I have missed some SPI optimisations.

My test case is sending UDP packets with a Sequence Nr from a Linux Server to Teensy, with a time delay between. I reduce the time delay until Teensy starts dropping packets (missing sequence numbers). With UDP packets of 4 byte payload, I can reach 4170 pkts/sec. With a payload of 100 bytes I can reach 444 pkts/sec. Both equate to a bit rate of around 400 Kbps. Even allowing for substantial overhead on the SPI bus and the size of the packet header, this seems far away from 24Mbps.

Has anyone any suggestions as to where my problem is, or do I have unrealistic expectations? (Am I missing an SPI optimisation?)

btw, Teensy 3.1 fired up immediately with only very minor changes needed to a complex sketch previously running on Teensy 2++.

Thanks,
Craig
 
444 pps seems good to me. Of course, the overhead per packet header is fixed, so the larger the packet the higher the throughput at the IP layer.
The 24Mbps SPI rate is the primary speed constraint and IMO, is very good for an embedded system.

As I recall, most open source Wiznet drivers do not implement an interrupt service and instead use polling (of the interrupt request I/O bit, I recall). Depending on the polling rate, this might slow things a bit. In other systems I used the interrupt from the chip and FreeRTOS ability to wakeup a task on a per-socket basis, for transmit complete or newly received packet. But that's more complex than the usual Arduino application.

Wiznet's TCP/IP/Socket protocol stack on-chip is excellent.
 
Last edited:
Status
Not open for further replies.
Back
Top