ILI9341_t3n and NativeEthernet on teensy 4.1

Johannes

Active member
I can use NativeEthernet together with the original ILI9341_t3 library, this works well using SPI, not SPI1.
But now I want to migrate my display to SPI1, because I need SPI for the HighPowerStepperDriver lib from Pololu.
I tried using ILI9341_t3n, which works fine on SPI1. But not with NativeEthernet.
In fact also ILI9341_t3n on SPI does not work with NativeEthernet.

Has anyone been able to successfully use NativeEthernet and ILI9341_t3n in the same sketch?
Or is it just me?

Yours,
Johannes
 
Sorry, no idea...

However not sure might help to know what does not work? Does not compile, does not???

That is I am not sure any reason why if ILI9341_t3 works with SPI and NativeEthernet why _t3n would not.

Unless there is some issue like conflicting names or?

Do you have simple setup/sketch which shows the issues?
 
Do you feel like trying QNEthernet instead of NativeEthernet to see if the issue still exists?
 
I am always delighted that there are poeple willing to help in this forum! Thank You!
The code compiles well. And it works well except in the configuration given below:
USE_NATIVE_ETHERNET and USE_ILI9341_T3N, this does not work.

USE_NATIVE_ETHERNET and USE_ILI9341_T3 work well together,
USE_ILI9341_T3N alone without USE_NATIVE_ETHERNET also works.

What I mean when I say "it does not work":
Serial console output stops after printing "initializing ILI9341".
The teensy is somehow stuck (inside tft.begin()) and I cannot upload another sketch until I press the Teensy-button or disconnect the USB cable.



Code:
#define USE_NATIVE_ETHERNET
#define USE_ILI9341_T3N
//#define USE_ILI9341_T3

#ifdef USE_NATIVE_ETHERNET

// In NativeEthernet.cpp,EthernetClass::begin(...) you must remove waiting on the link status:
///  while(!link_status){
///    }
/// Otherwise the program will block until an ethernet cable is connected.
#include <NativeEthernet.h>

const byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
const IPAddress ip(192, 168, 1, 177);
const unsigned int local_port = 8888;
const IPAddress remote_ip(192, 168, 1, 1);
const uint16_t remote_port = 8888;
EthernetLinkStatus link_status = Unknown;
EthernetUDP Udp;
char packetBuffer[64];

#endif

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)

#if defined(USE_ILI9341_T3N)
#include "ILI9341_t3n.h"
ILI9341_t3n
#else
#include "ILI9341_t3.h"
ILI9341_t3
#endif
  tft(255, //uint8_t _CS,
      31, // uint8_t _DC,
      255, //uint8_t _RST = 255,
      11, //uint8_t _MOSI=11,
      13, //uint8_t _SCLK=13,
      255); //uint8_t _MISO=12);

#endif


void setup() {
  while (!Serial);
  Serial.begin(9600);
#ifdef USE_NATIVE_ETHERNET  
  Serial.println("calling Ethernet.begin");
  Ethernet.begin(mac, ip);
  Serial.println("Ethernet.begin finished");
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet HW not found.");
    while (true);
  }
  Serial.println("Ethernet HW found");
  Udp.begin(local_port);
#endif
#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
  Serial.println("initializing ILI9341");
  tft.begin();
  tft.fillScreen(0x0000);
  tft.setTextColor(0xFFFF);
  tft.setTextSize(1);
  tft.setRotation(0);
  Serial.println("ILI9341 initialized");
#endif
}


unsigned int loop_count = 0;

void loop() {
#ifdef USE_NATIVE_ETHERNET
  {
    EthernetLinkStatus s = Ethernet.linkStatus();
    if (s != link_status) {
      link_status = s;
      switch (link_status) {
        case LinkON:
          Serial.println("Ethernet cable connected.");
          break;
        case LinkOFF:
          Serial.println("Ethernet cable disconnected.");
          break;
        default: 
          Serial.println("weird link status.");
      }
    }
  }
  unsigned int x = loop_count;
  for (int i=9;i>=0;i--) {
    packetBuffer[i] = '0' + (x % 10);
    x /= 10;
  }
  Udp.beginPacket(remote_ip, remote_port);
  Udp.write(packetBuffer,10);
  Udp.endPacket();
#endif

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
  tft.fillRect(0,0,tft.width(),8,0x0000);
  tft.setCursor(0,0);
  tft.print(loop_count);
#endif

  Serial.println(loop_count);
  loop_count++;
  delay(100);
}
 
Do you feel like trying QNEthernet instead of NativeEthernet to see if the issue still exists?

I did not realize there is another ethernet library for teensy 4.1, thank you! I will give it a try...

This is cool! Thank you! I already like it better than NativeEthernet, because the sketch can start without connected ethernet cable.
In NativeEthernet Ethernet.begin() would block until there is a link. Therefore I had to patch it.

And it works together with ILI9341_t3n!
If you know the reason for this, please share your wisdom!

Below there is the adapted sketch for experimenting with all combinations.

Code:
#define USE_QN_ETHERNET
//#define USE_NATIVE_ETHERNET
#define USE_ILI9341_T3N
//#define USE_ILI9341_T3

#if defined(USE_NATIVE_ETHERNET) || defined(USE_QN_ETHERNET)

#if defined(USE_QN_ETHERNET)
#include <QNEthernet.h>
using namespace qindesign;
using namespace network;
#else
// In NativeEthernet.cpp,EthernetClass::begin(...) you must remove waiting on the link status:
///  while(!link_status){
///    }
/// Otherwise the program will block until an ethernet cable is connected.
#include <NativeEthernet.h>
#endif

const byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
const IPAddress ip(192, 168, 1, 177);
const unsigned int local_port = 8888;
const IPAddress remote_ip(192, 168, 1, 1);
const uint16_t remote_port = 8888;
EthernetLinkStatus link_status = Unknown;
EthernetUDP Udp;
char packetBuffer[64];

#endif

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)

#if defined(USE_ILI9341_T3N)
#include "ILI9341_t3n.h"
ILI9341_t3n
#else
#include "ILI9341_t3.h"
ILI9341_t3
#endif
  tft(255, //uint8_t _CS,
      31, // uint8_t _DC,
      255, //uint8_t _RST = 255,
      11, //uint8_t _MOSI=11,
      13, //uint8_t _SCLK=13,
      255); //uint8_t _MISO=12);

#endif


void setup() {
  while (!Serial);
  Serial.begin(9600);
#if defined(USE_NATIVE_ETHERNET) || defined(USE_QN_ETHERNET)
  Serial.println("calling Ethernet.begin");
  Ethernet.begin(mac, ip);
  Serial.println("Ethernet.begin finished");
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet HW not found.");
    while (true);
  }
  Serial.println("Ethernet HW found");
  Udp.begin(local_port);
#endif
#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
  Serial.println("initializing ILI9341");
  tft.begin();
  tft.fillScreen(0x0000);
  tft.setTextColor(0xFFFF);
  tft.setTextSize(1);
  tft.setRotation(0);
  Serial.println("ILI9341 initialized");
#endif
}


unsigned int loop_count = 0;

void loop() {
#if defined(USE_NATIVE_ETHERNET) || defined(USE_QN_ETHERNET)
  {
    EthernetLinkStatus s = Ethernet.linkStatus();
    if (s != link_status) {
      link_status = s;
      switch (link_status) {
        case LinkON:
          Serial.println("Ethernet cable connected.");
          break;
        case LinkOFF:
          Serial.println("Ethernet cable disconnected.");
          break;
        default: 
          Serial.println("weird link status.");
      }
    }
  }
  unsigned int x = loop_count;
  for (int i=9;i>=0;i--) {
    packetBuffer[i] = '0' + (x % 10);
    x /= 10;
  }
  Udp.beginPacket(remote_ip, remote_port);
  Udp.write(packetBuffer,10);
  Udp.endPacket();
#endif

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
  tft.fillRect(0,0,tft.width(),8,0x0000);
  tft.setCursor(0,0);
  tft.print(loop_count);
#endif

  Serial.println(loop_count);
  loop_count++;
  delay(100);
}

Now I just have to try with SPI1 instead of SPI...
and sure enough it works. Thanks again!

Being the developer of QNEthernet you might know the reason for the incompatibility beween NativeEthernet and ILI9341_t3n.
Please give some insight!

Yours, Johannes
 
Last edited:
Actually I am surprised it works with passing in 255 for CS...

My Display has no CS pin. Therefore I cannot connect any other device on this SPI bus together with the display.
There is a MIS pin, which I leave disconnected. This way it works well with ILI9341_t3n.

I can also pass 10 for CS, but no difference: NativeEthernet and ILI9341_t3n are incompatible.
 
I ran your sketch:
Code:
#define USE_NATIVE_ETHERNET
#define USE_ILI9341_T3N
//#define USE_ILI9341_T3

#ifdef USE_NATIVE_ETHERNET

// In NativeEthernet.cpp,EthernetClass::begin(...) you must remove waiting on the link status:
///  while(!link_status){
///    }
/// Otherwise the program will block until an ethernet cable is connected.
#include <NativeEthernet.h>

const byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
const IPAddress ip(192, 168, 1, 177);
const unsigned int local_port = 8888;
const IPAddress remote_ip(192, 168, 1, 1);
const uint16_t remote_port = 8888;
EthernetLinkStatus link_status = Unknown;
EthernetUDP Udp;
char packetBuffer[64];

#endif

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)

#if defined(USE_ILI9341_T3N)
#include "ILI9341_t3n.h"
ILI9341_t3n
#else
#include "ILI9341_t3.h"
ILI9341_t3
#endif
tft(10, //uint8_t _CS,
    9, // uint8_t _DC,
    8, //uint8_t _RST = 255,
    11, //uint8_t _MOSI=11,
    13, //uint8_t _SCLK=13,
    12); //uint8_t _MISO=12);

#endif


void setup() {
  while (!Serial);
  Serial.begin(9600);
#ifdef USE_NATIVE_ETHERNET
  Serial.println("calling Ethernet.begin");
  Ethernet.begin(mac, ip);
  Serial.println("Ethernet.begin finished");
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet HW not found.");
    while (true);
  }
  Serial.println("Ethernet HW found");
  Udp.begin(local_port);
#endif
#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
  Serial.println("initializing ILI9341");
  tft.begin();
  tft.fillScreen(0x0000);
  tft.setTextColor(0xFFFF);
  tft.setTextSize(1);
  tft.setRotation(0);
  Serial.println("ILI9341 initialized");
#endif
}


unsigned int loop_count = 0;

void loop() {
#ifdef USE_NATIVE_ETHERNET
  {
    EthernetLinkStatus s = Ethernet.linkStatus();
    if (s != link_status) {
      link_status = s;
      switch (link_status) {
        case LinkON:
          Serial.println("Ethernet cable connected.");
          break;
        case LinkOFF:
          Serial.println("Ethernet cable disconnected.");
          break;
        default:
          Serial.println("weird link status.");
      }
    }
  }
  unsigned int x = loop_count;
  for (int i = 9; i >= 0; i--) {
    packetBuffer[i] = '0' + (x % 10);
    x /= 10;
  }
  Udp.beginPacket(remote_ip, remote_port);
  Udp.write(packetBuffer, 10);
  Udp.endPacket();
#endif

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
  tft.fillRect(0, 0, tft.width(), 8, 0x0000);
  tft.setCursor(0, 0);
  tft.print(loop_count);
#endif

  Serial.println(loop_count);
  loop_count++;
  delay(100);
}
Except I edited to give some default pins...

Code:
calling Ethernet.begin
Ethernet.begin finished
Ethernet HW found
initializing ILI9341
ILI9341 initialized
Ethernet cable connected.
0
1
2
3
...
 
I ran your sketch:
Code:
#define USE_NATIVE_ETHERNET
#define USE_ILI9341_T3N
//#define USE_ILI9341_T3

[...]
tft(10, //uint8_t _CS,
    9, // uint8_t _DC,
    8, //uint8_t _RST = 255,
    11, //uint8_t _MOSI=11,
    13, //uint8_t _SCLK=13,
    12); //uint8_t _MISO=12);
[...]
Except I edited to give some default pins...

Code:
calling Ethernet.begin
Ethernet.begin finished
Ethernet HW found
initializing ILI9341
ILI9341 initialized
Ethernet cable connected.
0
1
2
3
...

I have copy-pasted your entire code into a new sketch, uploaded it, and it makes no difference for me:
the output stops after "initializing ILI9341" and when I upload another sketch I have to press the Teensy button.
I also tried
Code:
  tft(38,//255, //uint8_t _CS,
      28, // uint8_t _DC,
      40,//255, //uint8_t _RST = 255,
      26, //uint8_t _MOSI=11,
      27, //uint8_t _SCLK=13,
      39);//255); //uint8_t _MISO=12);
which did not work, too. Strange.
I even remove all Hardware and the SD-card so that my teensy is just connected to USB and Ethernet. Did not work, either.
 
Code:
#define USE_NATIVE_ETHERNET
#define USE_ILI9341_T3N
//#define USE_ILI9341_T3

#ifdef USE_NATIVE_ETHERNET

// In NativeEthernet.cpp,EthernetClass::begin(...) you must remove waiting on the link status:
///  while(!link_status){
///    }
/// Otherwise the program will block until an ethernet cable is connected.
#include <NativeEthernet.h>

const byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
const IPAddress ip(192, 168, 1, 177);
const unsigned int local_port = 8888;
const IPAddress remote_ip(192, 168, 1, 1);
const uint16_t remote_port = 8888;
EthernetLinkStatus link_status = Unknown;
EthernetUDP Udp;
char packetBuffer[64];

#endif

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)

#if defined(USE_ILI9341_T3N)
#include "ILI9341_t3n.h"
ILI9341_t3n
#else
#include "ILI9341_t3.h"
ILI9341_t3
#endif
 tft(38,//255, //uint8_t _CS,
      28, // uint8_t _DC,
      40,//255, //uint8_t _RST = 255,
      26, //uint8_t _MOSI=11,
      27, //uint8_t _SCLK=13,
      39);//255); //uint8_t _MISO=12);tft(10, //uint8_t _CS,

#endif


void setup() {
  while (!Serial);
  Serial.begin(9600);
#ifdef USE_NATIVE_ETHERNET
  Serial.println("calling Ethernet.begin");
  Ethernet.begin(mac, ip);
  Serial.println("Ethernet.begin finished");
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet HW not found.");
    while (true);
  }
  Serial.println("Ethernet HW found");
  Udp.begin(local_port);
#endif
#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
  Serial.println("initializing ILI9341");
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
  tft.setCursor(10, tft.height()/4);
  tft.setTextSize(2);
  tft.setRotation(0);
  tft.print("Initialized");
  Serial.println("ILI9341 initialized");
#endif
}


unsigned int loop_count = 0;

void loop() {
#ifdef USE_NATIVE_ETHERNET
  {
    EthernetLinkStatus s = Ethernet.linkStatus();
    if (s != link_status) {
      link_status = s;
      switch (link_status) {
        case LinkON:
          Serial.println("Ethernet cable connected.");
          break;
        case LinkOFF:
          Serial.println("Ethernet cable disconnected.");
          break;
        default:
          Serial.println("weird link status.");
      }
    }
  }
  unsigned int x = loop_count;
  for (int i = 9; i >= 0; i--) {
    packetBuffer[i] = '0' + (x % 10);
    x /= 10;
  }
  Udp.beginPacket(remote_ip, remote_port);
  Udp.write(packetBuffer, 10);
  Udp.endPacket();
#endif

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
//  tft.fillRect(0, 0, tft.width(), 8, ILI9341_BLACK);
  tft.setCursor(10, (tft.height()*3)/4);
  tft.print(loop_count);
#endif

  Serial.println(loop_count);
  loop_count++;
  delay(100);
}
Updated to your new pins. Moved the pins to the display and it works for me...

Note: I am using Arduino 1.8.19, The current beta release of Teensyduino.

And using master branch of ILI9341_t3n. You might make sure that yours is up to date. I was also also using a different branch that I did a couple months ago for an issue with DMA, but this is not DMA...

I also updated your sketch slightly to use opaque text output so did not have to erase..
 
Note: I am using Arduino 1.8.19, The current beta release of Teensyduino.

And using master branch of ILI9341_t3n. You might make sure that yours is up to date. I was also also using a different branch that I did a couple months ago for an issue with DMA, but this is not DMA...

I also updated your sketch slightly to use opaque text output so did not have to erase..

I now have upgraded to ILI9341_t3n, but I still have Arduino 1.8.13 and Teensyduino 1.53. This must be the reason why it does not work for me.
Thanks for the opaque text output, this is much better!

Until I update and probably also after updating I will use QNEthernet instead of NativeEthernet. Together with ILI9341_t3n.
 
Here's a version that is designed for QNEthernet. I took out the #ifdefs for readability and added a few notes. (Hopefully I didn't make any mistakes.) There's a few other ways to do things here, this is just one way.

Code:
#define USE_ILI9341_T3N
//#define USE_ILI9341_T3

#include <QNEthernet.h>
using namespace qindesign::network;

const IPAddress ip(192, 168, 1, 177);
const IPAddress subnet_mask(255, 255, 255, 0);
const IPAddress gateway(192, 168, 1, 1);

const uint16_t local_port = 8888;  // Note: Changed to uint16_t
const IPAddress remote_ip(192, 168, 1, 1);
const uint16_t remote_port = 8888;

bool link_state = false;
EthernetUDP udp;
uint8_t packet_buf[64];  // Note: Changed to uint8_t for use with EthernetUDP::send()

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)

#if defined(USE_ILI9341_T3N)
#include "ILI9341_t3n.h"
ILI9341_t3n
#else
#include "ILI9341_t3.h"
ILI9341_t3
#endif
  tft(255, //uint8_t _CS,
      31, // uint8_t _DC,
      255, //uint8_t _RST = 255,
      11, //uint8_t _MOSI=11,
      13, //uint8_t _SCLK=13,
      255); //uint8_t _MISO=12);

#endif


void setup() {
  Serial.begin(115200);  // Note: 115200 is better than 9600
  while (!Serial && millis() < 4000) {
    // Wait for Serial or a timeout
    // Note: You had this before Serial.begin(); it needs to come after
  }

  Serial.print("Initializing Ethernet...");
  if (Ethernet.begin(ip, subnet_mask, gateway)) {
    Serial.println("done."); 
    udp.begin(local_port);
  } else {
    Serial.println("ERROR!");
  }

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
  Serial.println("initializing ILI9341");
  tft.begin();
  tft.fillScreen(0x0000);
  tft.setTextColor(0xFFFF);
  tft.setTextSize(1);
  tft.setRotation(0);
  Serial.println("ILI9341 initialized");
#endif
}

unsigned int loop_count = 0;

void loop() {
  // Note: Could also monitor with Ethernet.onLinkState() as a callback; see the examples
  // Note: Ethernet.linkState() is new to QNEthernet
  bool s = Ethernet.linkState();
  if (s != link_state) {
    link_state = s;
    if (s) {
      Serial.println("Ethernet link ON");
    } else {
      Serial.println("Ethernet link OFF");
    }
  }

  if (link_state) {
    unsigned int x = loop_count;
    for (int i=9;i>=0;i--) {
      packet_buf[i] = '0' + (x % 10);
      x /= 10;
    }
    // Note: The following is instead of beginPacket()/write()/endPacket()
    udp.send(remote_ip, remote_port, packet_buf, 10);
  }

#if defined(USE_ILI9341_T3) || defined(USE_ILI9341_T3N)
  tft.fillRect(0,0,tft.width(),8,0x0000);
  tft.setCursor(0,0);
  tft.print(loop_count);
#endif

  Serial.println(loop_count);
  loop_count++;
  delay(100);
}
 
Back
Top