Teensy 4.1 WiFi (Howto)

mstiller

Well-known member
Hi all,

today my new parts arrived including an Adafruit Airlift Feather so i decided to connect the Teensy 4.1 to my WLAN.

(I think this would also work with Teensy 4.0)

Here is a bit of an advanced howto, proceed at your own risk, soldering skills are required!

Hardware needed:

AirLift FeatherWing ESP32

https://www.adafruit.com/product/4264

Teensy Feather Adapter

https://www.adafruit.com/product/3200

Stacking Headers for the Teensy/Airlift, or what i used:

FeatherWing Doubler - Prototyping Add-on For All Feather Boards

https://www.adafruit.com/product/2890

(Also available from other suppliers)

The prepared parts will look like this:

38749017yi.jpg


38749018bt.jpg


38749019zj.jpg


Note: On the AirLift you might need to solder the pads near ESPGPIO0.
I did not get it working without soldering the pads but it might be worthwhile to try without first.

You need this Library:

https://github.com/adafruit/WiFiNINA

I used version 1.3.0 of this library.

If you use Teensyduino i think following the instructions on

https://learn.adafruit.com/adafruit-airlift-featherwing-esp32-wifi-co-processor-featherwing

should be helpful. I used PlatformIO, where you have to add this line to the file platformio.ini in your project dir:

Code:
lib_deps = https://github.com/adafruit/WiFiNINA/#1.3.0

You need to apply this patch to the Adafruit WiFiNINA library to make it work with Teensy4:

Code:
diff --git a/src/utility/spi_drv.cpp b/src/utility/spi_drv.cpp
index ff89d41..3884f30 100644
--- a/src/utility/spi_drv.cpp
+++ b/src/utility/spi_drv.cpp
@@ -81,6 +81,14 @@ void SpiDrv::begin()
       SLAVERESET = (uint8_t)SPIWIFI_RESET;
 #endif

+#ifdef ARDUINO_TEENSY41
+#define SLAVESELECT  5
+#define SLAVERESET   6
+#define SLAVEREADY   9
+#define NINA_GPIO0  10
+#endif
+
+#ifndef ARDUINO_TEENSY41
 #ifdef ARDUINO_SAMD_MKRVIDOR4000
       inverted_reset = false;
 #else
@@ -88,6 +96,7 @@ void SpiDrv::begin()
         inverted_reset = true;
         SLAVERESET = ~SLAVERESET;
       }
+#endif
 #endif

Then you should be able to compile and upload this sketch:

Code:
#define SPIWIFI        SPI  // The SPI port

#include <Arduino.h>
#include <SPI.h>
#include <WiFiNINA.h>

const char *ssid = "YOUR_SSID_HERE";
const char *pass= "YOUR_PASSWORD";
int status = WL_IDLE_STATUS;     // the Wifi radio's status

void printMacAddress(byte mac[]) {
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
    if (i > 0) {
      Serial.print(":");
    }
  }
  Serial.println();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println(ip);

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}


void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  SPI.begin();
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware!");
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 5 seconds for connection:
    delay(5000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network.");
  printCurrentNet();
  printWifiData();
}

void loop() {
  // check the network connection once every 10 seconds:
  delay(10000);
  printCurrentNet();
}

If it works it should look like this in the serial monitor:

Code:
Attempting to connect to WPA SSID: bs_XXXXX
You're connected to the network.SSID: bs_XXXXX
BSSID: D0:03:4B:XX:XX:XX
signal strength (RSSI):-62
Encryption Type:4

IP Address: 192.168.178.40
192.168.178.40
MAC address: A4:CF:12:XX:XX:XX
SSID: bs_XXXXX
BSSID: D0:03:4B:XX:XX:XX
signal strength (RSSI):-62
Encryption Type:4

In the terminal window:

Code:
ms@braeburn:WiFiNINA #5009 22:28 :) ping 192.168.178.40
PING 192.168.178.40 (192.168.178.40): 56 data bytes
64 bytes from 192.168.178.40: icmp_seq=0 ttl=255 time=188.952 ms
64 bytes from 192.168.178.40: icmp_seq=1 ttl=255 time=121.472 ms
64 bytes from 192.168.178.40: icmp_seq=2 ttl=255 time=38.590 ms
64 bytes from 192.168.178.40: icmp_seq=3 ttl=255 time=250.641 ms
64 bytes from 192.168.178.40: icmp_seq=4 ttl=255 time=167.443 ms

Caveat: Sometime it does not find the ESP32, i think it could benefit from some SPI pullup resistors, but i am not sure
which values to use and where exactly. Did not look at Paul's SPI recommendation page today.
 
Last edited:
PS:

I think that issue with the SPI pullups might actually be true. I remembered that the FeatherWing Logger has pull-ups, so i stacked another module. It looks gross now but worked at the first try.
 
More investigation reveals, that you can in fact use the Adafruit library https://github.com/adafruit/WiFiNINA
but you should use master and add this on top of the sketch:

Code:
#if defined(TEENSYDUINO)
  #define SPIWIFI       SPI  // The SPI port
  #define SPIWIFI_SS     5   // Chip select pin
  #define ESP32_RESETN   6   // Reset pin
  #define SPIWIFI_ACK    9   // a.k.a BUSY or READY pin
  #define ESP32_GPIO0   -1
#endif

And this in setup():

Code:
WiFi.setPins(SPIWIFI_SS, SPIWIFI_ACK, ESP32_RESETN, ESP32_GPIO0, &SPIWIFI);

Besides i still have the issue that it works only with the added AdaLogger feather even after adding two 10k pull-ups on CS and MOSI.

Any clues?
 
Hiya, I wondered if anyone has had any more progress I this? I've run through all the steps and not having any joy (am currently waiting on delivery of an Adalogger) Can anyone give guidance on an alternative to using the logger?
 
Laptop USB power sufficient for this setup?

Hiya, I wondered if anyone has had any more progress I this? I've run through all the steps and not having any joy (am currently waiting on delivery of an Adalogger) Can anyone give guidance on an alternative to using the logger?

Also I was wondering if the USB port on my laptop would provide sufficient power to run this setup? (given that the instructions here rely on response via the serial monitor)

Or would it be prudent to add an aditional power supply?

I'm a bit of a NOOB with this stuff. I've been tinkering with Arduino for 10 or 15 years with reasonabel success but this is a bit of stretch for me :) so I'm grateful for any assistance

Cheers
 
This seems like it would be an attractive solution, however, I'm still pretty confused as to the rationale behind the stacking configuration. If you line up the teensy 4.1 or 3.6 with the featherwing the pins as referenced for the airlift don't seem to match. In the original post, the pins that cut vertically across the teensy are at the edge while the feather adapter has them more centrally located?


If this is the case, is the OP suggesting we use some other MISO/MOSI pin set? Or is this poor coupling due to the pull-ups?


https://cdn-shop.adafruit.com/1200x900/3200-04.jpg
 
@mstiller - Been playing with WiFiNINA and the Adafruit ESP32 Huzzah Feather. I am not totally sure WiFiNINA works with it. I Flashed the ESP32 with the latest Adafruit WiFiNINA firmware which was successful and compared pinouts for the Huzzah and ESP32 Airlift Featherwing. They seemed to be the same. Wired up a T4.1 and the Huzzah and tried your sketch and the ScanNetwork.ino sketch. Guess what:
Code:
Communication with WiFi module failed!

Expected I guess. These are the sketches I used:
Code:
#define SPIWIFI        SPI  // The SPI port

#include <Arduino.h>
#include <SPI.h>
#include <WiFiNINA.h>

const char *ssid = "SSID";
const char *pass= "PASSWORD";

int status = WL_IDLE_STATUS;     // the Wifi radio's status
  #define SPIWIFI       SPI  // The SPI port
  #define SPIWIFI_SS     5   // Chip select pin
  #define ESP32_RESETN   6   // Reset pin
  #define SPIWIFI_ACK    9   // a.k.a BUSY or READY pin
  #define ESP32_GPIO0   -1

void printMacAddress(byte mac[]) {
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
    if (i > 0) {
      Serial.print(":");
    }
  }
  Serial.println();
}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println(ip);

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}


void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // Set up the pins!
  WiFi.setPins(SPIWIFI_SS, SPIWIFI_ACK, ESP32_RESETN, ESP32_GPIO0, &SPIWIFI);
  SPI.begin();
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware!");
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 5 seconds for connection:
    delay(5000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network.");
  printCurrentNet();
  printWifiData();
}

void loop() {
  // check the network connection once every 10 seconds:
  delay(10000);
  printCurrentNet();
}

And:
Code:
/*

 This example  prints the board's MAC address, and
 scans for available Wifi networks using the NINA module.
 Every ten seconds, it scans again. It doesn't actually
 connect to any network, so no encryption scheme is specified.

 Circuit:
 * Board with NINA firmware on it (In this case its an Adafruit AirLift)

 created 13 July 2010
 by dlf (Metodo2 srl)
 modified 21 Junn 2012
 by Tom Igoe and Jaymes Dec
 */


#include <SPI.h>
#include <WiFiNINA.h>

// Configure the pins used for the ESP32 connection
#if defined(TEENSYDUINO)
  #define SPIWIFI       SPI  // The SPI port
  #define SPIWIFI_SS     5   // Chip select pin
  #define ESP32_RESETN   6   // Reset pin
  #define SPIWIFI_ACK    9   // a.k.a BUSY or READY pin
  #define ESP32_GPIO0   -1
#endif

#if defined(ADAFRUIT_FEATHER_M4_EXPRESS) || \
  defined(ADAFRUIT_FEATHER_M0) || \
  defined(ADAFRUIT_FEATHER_M0_EXPRESS) || \
  defined(ARDUINO_AVR_FEATHER32U4) || \
  defined(ARDUINO_NRF52840_FEATHER) || \
  defined(ADAFRUIT_ITSYBITSY_M0) || \
  defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS) || \
  defined(ARDUINO_AVR_ITSYBITSY32U4_3V) || \
  defined(ARDUINO_NRF52_ITSYBITSY)
  // Configure the pins used for the ESP32 connection
  #define SPIWIFI       SPI  // The SPI port
  #define SPIWIFI_SS    13   // Chip select pin
  #define ESP32_RESETN  12   // Reset pin
  #define SPIWIFI_ACK   11   // a.k.a BUSY or READY pin
  #define ESP32_GPIO0   -1
#elif defined(ARDUINO_AVR_FEATHER328P)
  #define SPIWIFI       SPI  // The SPI port
  #define SPIWIFI_SS     4   // Chip select pin
  #define ESP32_RESETN   3   // Reset pin
  #define SPIWIFI_ACK    2   // a.k.a BUSY or READY pin
  #define ESP32_GPIO0   -1
#elif defined(TEENSYDUINO)
  #define SPIWIFI       SPI  // The SPI port
  #define SPIWIFI_SS     5   // Chip select pin
  #define ESP32_RESETN   6   // Reset pin
  #define SPIWIFI_ACK    9   // a.k.a BUSY or READY pin
  #define ESP32_GPIO0   -1
#elif defined(ARDUINO_NRF52832_FEATHER )
  #define SPIWIFI       SPI  // The SPI port
  #define SPIWIFI_SS    16   // Chip select pin
  #define ESP32_RESETN  15   // Reset pin
  #define SPIWIFI_ACK    7   // a.k.a BUSY or READY pin
  #define ESP32_GPIO0   -1
#elif !defined(SPIWIFI_SS)   // if the wifi definition isnt in the board variant
  // Don't change the names of these #define's! they match the variant ones
  #define SPIWIFI       SPI
  #define SPIWIFI_SS    10   // Chip select pin
  #define SPIWIFI_ACK    7   // a.k.a BUSY or READY pin
  #define ESP32_RESETN   5   // Reset pin
  #define ESP32_GPIO0   -1   // Not connected
#endif


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

  Serial.println("WiFi Scanning test");

  // Set up the pins!
  WiFi.setPins(SPIWIFI_SS, SPIWIFI_ACK, ESP32_RESETN, ESP32_GPIO0, &SPIWIFI);

  // check for the WiFi module:
  while (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    delay(1000);
  }
  String fv = WiFi.firmwareVersion();
  Serial.println(fv);
  if (fv < "1.0.0") {
    Serial.println("Please upgrade the firmware");
    while (1) delay(10);
  }
  Serial.println("Firmware OK");

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC: ");
  printMacAddress(mac);
}

void loop() {
  // scan for existing networks:
  Serial.println("Scanning available networks...");
  listNetworks();
  delay(10000);
}

void listNetworks() {
  // scan for nearby networks:
  Serial.println("** Scan Networks **");
  int numSsid = WiFi.scanNetworks();
  if (numSsid == -1) {
    Serial.println("Couldn't get a wifi connection");
    while (true);
  }

  // print the list of networks seen:
  Serial.print("number of available networks:");
  Serial.println(numSsid);

  // print the network number and name for each network found:
  for (int thisNet = 0; thisNet < numSsid; thisNet++) {
    Serial.print(thisNet);
    Serial.print(") ");
    Serial.print(WiFi.SSID(thisNet));
    Serial.print("\tSignal: ");
    Serial.print(WiFi.RSSI(thisNet));
    Serial.print(" dBm");
    Serial.print("\tEncryption: ");
    printEncryptionType(WiFi.encryptionType(thisNet));
  }
}

void printEncryptionType(int thisType) {
  // read the encryption type and print out the name:
  switch (thisType) {
    case ENC_TYPE_WEP:
      Serial.println("WEP");
      break;
    case ENC_TYPE_TKIP:
      Serial.println("WPA");
      break;
    case ENC_TYPE_CCMP:
      Serial.println("WPA2");
      break;
    case ENC_TYPE_NONE:
      Serial.println("None");
      break;
    case ENC_TYPE_AUTO:
      Serial.println("Auto");
      break;
    case ENC_TYPE_UNKNOWN:
    default:
      Serial.println("Unknown");
      break;
  }
}


void printMacAddress(byte mac[]) {
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
    if (i > 0) {
      Serial.print(":");
    }
  }
  Serial.println();
}

I was under the impression the an external Adafruit ESP32 device could be used. Bottom Line I am not sure of what I am doing:)
Appreciate any input you can give...

Thanks...
 
wwatson, If I'm not mistaken, it looks like the serial RX and TX are reversed between the Airlift Featherwing and the Hazzah. That would certainly do it. Ensure that the RX of one goes to the TX of the other and vise versa.
 
Thanks, Will try it.

Edit: Went over my wiring this morning and found a couple of mistakes. I fixed those and now the red led on the Huzzah turns on flashes in sync with the led on the T4.1(SCK). I think there is communication over the SPI buss but right now I can't get Serial.print() to work and print out a simple 'Hello World'.

More to investigate I guess:)
 
Last edited:
Hello,

Any new updates to this? I currently have followed all the steps listed but instead of using the breakout board im just using a breadboard. I am using the latest code provided but i still am getting that it cannot communicate with the module. I have also noticed that no leds turn on when the ESP32 is powered (Not sure if its supposed to). And the reset button doesnt set off the LEDS either (Maybe i just have a faulty board?).

Any help on the matter would be much appreciated. I can post pictures of my setup for a more indepth analysis.

Best,
W
 
Back
Top