Description
The Mini Platform for Teensy 4.1 is designed to provide a compact, yet feature rich setup based on the powerful 600MHz Teensy 4.1.
The system comes standard with a low-profile Teensy 4.1 installed (PSA-16-B). It can be optionally ordered with a 16MB PSRAM (PSA-16-2P) memory upgrade or a 8MB PSRAM / 256MB Flash (PSA-16-2G) memory upgrade installed on the bottom side of the Teensy 4.1. These are selectable at the top of the page.
KEY FEATURES OF MINI PLATFORM FOR TEENSY 4.1:
- Teensy 4.1 included with optional QSPI PSRAM and Flash memory upgrades
- ESP32-C3 co-processor for WiFi and Bluetooth connectivity
- 3.5” IPS 480×320 ST7796 LCD with capacitive touchscreen
- SGTL5000 Audio Subsystem
- 16MB NOR Flash memory on baseboard
- 3 User buttons and RGB LED
- CAN bus transceiver on CAN3
- RS485 transceiver on Serial8
- Host USB connector
- Ethernet connector
- High-speed MicroSD card slot on Teensy 4.1 with 32GB MicroSD card and SD to MicroSD Adapter
- 20-pin IDC GPIO connector brings out serial ports, I2C, SPI, CAN, Analog inputs and digital I/O
- CR2032 battery holder
- DC-DC converter front-end for wide input voltage range of 6-16VDC
- 3.3V on-board regulator to off-load and protect the Teensy 3.3V regulator
- Input power setup supports DC power and USB power to Teensy 4.1 and ESP32-S be applied at the same time
- Optional Solderless Breadboard Adapter can plug into IDC GPIO connector for prototyping
Package Includes:
- Mini Baseboard for Teensy 4.1 complete with Teensy 4.1
- Optional memory upgrades
- Optional Accessories
- Optional Solderless Breadboard Adapter
The Mini Platform for Teensy 4.1 Available in Three Versions
These are selectable at the top of the page. Everything is the same except for the memory configuration of the Teensy 4.1 that is installed. More information on memory configurations and their use with Teensy 4.1 can be found here
The Basic Platform comes with a standard Teensy 4.1 with low-profile bottom mounted I/O like our DEV-26-B-LP shown here. No additional memory is installed.
The 16MB PSRAM Upgrade adds two 8MB PSRAM chips to the bottom of the Teensy 4.1 like our DEV-26-2P-LP shown below. PSRAM is volatile memory that sits on a dedicated QSPI bus. It is faster than standard SPI memory since it moves 4-bits at a time, but it is slower than the RAM built-in to the Teensy 4.1 microcontroller.
It is a popular option for audio applications since the PSRAM can be used for adding long audio delays or similar effects or for use with applications that can benefit from having a large scratchpad memory for holding dynamic arrays or similar data structures.
The 8MB PSRAM + 256MB Flash Upgrade adds one 8MB PSRAM chip and one 256MB/2Gbit NAND Flash chip to the bottom of the Teensy 4.1 like our DEV-26-2G-LP shown below. The PSRAM provides volatile scratchpad memory while the Flash memory provides semi-permanent storage that maintains data between power cycles.
Note that this Flash memory cannot be used to directly increase the program memory size of the Teensy 4.1 which is 8MB, but in some cases it can be used to extend the program memory by off-loading static data like BMP or sound files.
Note: Memory configurations above are shown in Megabytes (MB) while some chip manufacturers are now specifying memory size in Megabits (Mb) or Gigabits (Gb). The use of a capital B means Byte while lower case b means bit. Since there are 8 bits in a byte, to convert from MB to Mb (or Gb), multiply by 8. The 256MB Flash for instance is the same as 2Gb.
Optional Accessories
These optional accessories may be useful to add to your order if you don’t already have something on-hand that will work.
AC/DC power adapter. Any 6-16VDC @ 1A or greater adapter with the standard 5.5mm x 2.1mm connector will work OK
In-line DC power switch for easily connecting and disconnecting power without having to pull the AC/DC adapter plug.
USB Micro-B data cable for working with the Teensy 4.1
USB type C data cable for working with the ESP32-C3. Note that most USB type C cables supplied with things like cell phones are power only cables for charging batteries and don’t contain the data wires. If you are not sure what kind you have, you may want to pick one up to be safe.
1.3″ SH1106 OLED display for the ESP32-C3. This works with the example software preloaded on the ESP32-C3 installed on the Mini Platform. Other displays that are compatible with the ESP32-C3 connector setup are listed at the bottom of the page.
Adapter Boards
The system can be further expanded by adding optional adapters.
Solderless Breadboard Adapter
This solderless breadboard adapter plugs into the IDC GPIO connector and mounts a 400 tie-point high quality solderless breadboard for building temporary circuits.
The breadboard adapter has jumpers to select either 3.3V or 5V power for each of the two power rails.
A female header on the end of the breadboard provides access to all of the I/O pins that are brought out to the IDC connector along with 3.3V, 5V and Ground.
Note that the female header is 24-pins on the breadboard adapter while the male IDC connector is 20-pins on the main board. This is to ensure that the connectors cannot accidentally be offset when they are mated since the female header is not keyed.
Technical Details
Mini Platform for Teensy 4.1 Pin Usage
The pin usage map shows all connections to the Teensy 4.1 pins as well as the connections to the GPIO connector.
Pin View of IDC GPIO Connector
Teensy 4.1
Teensy 4.1 is the most powerful Arduino compatible microcontroller available today. Based on the NXP i.MX RT1062 ARM Cortex-M7 running at 600MHz. Perhaps best of all, it is compatible with the popular Arduino IDE programming environment as well as many of the existing Arduino libraries, so it is very easy to get up and running unlike many other advanced microcontrollers that are available.
For more details on the Teensy 4.1 itself, check out this page.
The Teensy 4.1 socket on this system brings all I/O out from the bottom of the Teensy 4.1.
The Teensy 4.1 includes the following changes from the standard Teensy 4.1:
- The VUSB/VIN trace is cut and a 1A SMD Schottky diode is placed across the VUSB / VIN pads so both USB and VIN power can be safely applied at the same time. The baseboard also has a diode in parallel for redundancy.
- Optional PSRAM and/or Flash memory is added depending on configuration ordered.
- VUSB 1-pin header is installed for routing USB power to the baseboard.
- A female 2×3 2mm header is mounted at the Ethernet connector location on the bottom side of the Teensy 4.1 which mates with a male header on the baseboard and connects the Teensy 4.1 to the MagJack on the baseboard for connecting to a physical Ethernet cable.
- Male low-profile 5-pin headers are mounted to the bottom side of the Teensy 4.1 to bring down the USB Host lines to connect to the on-board Host USB connector. VBat connects to a CR2032 battery holder and the Program button is remoted out to the edge of the board for accessibility.
- Low-profile 24-pin male headers are installed
The orange LED on the Teensy 4.1 pin 13 is sometimes used in example programs, so it is buffered and brought out to an orange LED near the edge of the LCD for visibility.
Power Subsystem
DC Input
The board can be powered from 6 – 16VDC via a standard 5.5mm x 2.1mm DC power jack.
Besides the DC power jack, there is also a footprint labeled J1 for an optional 0.1″ 2-pin screw terminal or JST style connector for bringing in power or for powering an external device like a fan off the DC input.
Reverse voltage protection on the input is provided by a MOSFET transistor.
5V and 3.3V Subsystems
The 6-16VDC input power feeds an AP63205 5V DC-DC converter U5 that outputs 5V.
This 5V along with 5V power coming in from the USB connection on the Teensy 4.1 all pass through Schottky diodes to keep the different power subsystems safely isolated while powering the +5V bus on the baseboard. This allows any combination of USB and DC power to be connected.
Note that the ESP32-C3 USB power pins are disabled so the system can’t be powered from the ESP32-C3 USB. After the Schottky voltage drop, this results in approximately 4.7V on the +5V power rail. This is marginal for meeting the full 5V spec, but this works fine since we are regulating this input power down to 3.3V on modules anyway.
This +5V power provides power to the Teensy 5V VIN input. A green power LED lights whenever +5V power is available.
The +5V power also feeds an AMS1117-3.3 linear regulator that powers the ESP32-C3, NOR Flash and GPIO expansion connector to take the load off the Teensy 4.1. The Teensy 4.1 onboard 3.3V regulator output is not used on the baseboard.
3.5″ IPS 480 x 320 ST7796 Capacitive Touch LCD Display
The 3.5″ LCD display uses IPS technology and is a nice performance step-up from the more common ILI9341 2.8 “or 3.2” display that is often used. It has a higher 480×320 resolution, slightly larger screen size, much better off axis viewing and a touchscreen that does not require calibration to get accurate touchpoints.
The LCD uses the ST7796 display controller chip that communicates over SPI and is attached to the main SPI bus on the Teensy 4.1. Teensyduino does not yet support this chip, but KurtE on the Teensy forum has a version of the ST7735_t3 library that does support it. Download that library into your main Arduino Library folder. It can be downloaded from here: https://github.com/KurtE/ST7735_t3/tree/ST7796
One thing to be aware of is that the LCD requires that the colors be inverted to display correctly using the command tft.invertDisplay(true);.
The capacitive touch screen uses the FT6336 touch controller that communicates over the I2C bus. The Adafruit FT6206.h library supports this chip and can be downloaded from the IDE.
The display is connected to the the main SPI bus pins 11, 12, 13 with CS connected to pin 10 and DC connected to pin 9.
The touch screen connects to I2C pins 18 and 19 and the I2C address is hardwired to 0x38. The optional touch /IRQ output is connected to pin 36 on the Teensy 4.1.
ESP32-C3 SuperMini Co-Processor for WiFi / Bluetooth
A 16-pin ESP32-C3 module is included on the baseboard. It is used for its very compact form-factor to provide WiFi and Bluetooth connectivity.
The module communicates with the Teensy 4.1 over a serial port. This module uses a USB-C style connection rather than the USB Micro-B connection found on the Teensy 4.1 for programming or serial communication with a computer. If you are using a USB-C cable from home, ensure it is a data cable. Many cell phones come with a power only cable for charging and don’t include data wires.
A user button on the baseboard near the MicroSD card slot connects to GPIO10 on the ESP32-C3.
Two 4-pin female headers allow for plugging in a standard SSD1306, SH1106 or similar OLED type displays that communicate over the I2C bus with the ESP32-C3. Two headers are provided as these displays are available with two different pinouts which swap the 5V and GND pins. If a display is used, ensure it is plugged into the header that corresponds to your displays pinout. The display is plugged in so that it extends away from the ESP32-C3.
1.3″ SH1106 OLED Display, 128×64 resolution
0.91″ SSD1306 OLED Display, 128×32 resolution
The Teensy 4.1 Serial 7 on pins 28 and 29 connects to the ESP32-C3 Serial on GPIO20 and GPIO21 to provide communications between the two microcontrollers.
The ESP32-C3 can be used as a co-processor to the Teensy 4.1 primarily to offload any WiFi or Bluetooth work since the Teensy 4.1 does not have that capability.
ESP32-C3 Modifications
The ESP32-C3 has 2 modifications made to it for use in this system.
Power – These tiny modules have the unfortunate quirk that you cannot connect power to the 5V pin and USB power at the same time or those two power sources will be shorted together. That could cause damage to one of them. For use with the Mini Platform, we remove a DC blocking diode on the USB and 5V pins to prevent power coming in from any USB cable that may be plugged into the ESP32-C3. This makes the USB port a data only connection. The module is then powered directly from 3.3V on the baseboard. Keep in mind that if the ESP32-C3 is removed from the baseboard, it cannot be powered from a USB cable or the 5V pin and similarly the Mini Platform cannot be powered through the ESP32-C3 USB port.
Power-on Reset – The reset circuit on these modules is inadequate. The result is that the ESP32-C3 module may not reset correctly at power up and so not run any program that is loaded in Flash. They do provide a reset button on the module to push should this happen, but we don’t find that a very acceptable solution. To fix the issue, we remove a tiny 0201 size 0.1uF capacitor on the CHIP EN line and replace it with a 2.2uF cap to increase the power-on reset time.
SGTL5000 Audio Circuit
Due to the Teensy 4.1 powerful processing capability, it is often used for audio projects. For this reason, the audio circuit is included on the baseboard and includes Headphone, Line In and Line Out jacks as well as a microphone input. As shipped with the demo software, if headphones are plugged into the HP jack, pressing Play Audio will play a WAV file off the MicroSD card.
By using the SGTL5000 audio processing chip as used on the original Teensy Audio Adapter, it ensures best compatibility with the powerful Teensy Audio Library Tool.
More info on the audio capability can be found here PJRC Teensy Audio Library Tutorial
16MB Baseboard NOR Flash
A 16MB/128Mb NOR flash (W25Q128JVSIQ) is connected on SPI1. CS is on pin 37. To use this device, you will need to use the SerialFlash library branch at the link below until it is rolled into the Teensyduino software due to a bug in the current SerialFlash library. https://github.com/KurtE/SerialFlash/tree/use_ptr_not_reference
The NOR flash provides semi-permanent data storage that persists after a power cycle and is useful for storing sound files or other data.
Teensy 4.1 MicroSD Card Slot
The Teensy 4.1 has a built-in MicroSD card slot. This card slot uses a built-in SPI bus and is faster than an externally connected card slot would be. We ship the system with a 32GB MicroSD card installed with the PJRC example sound files.
Wired Ethernet
The board has a MagJack for making wired Ethernet connections. Teensy 4.1 has all the circuitry built-in for connecting to Ethernet and the two just need to be physically connected.
The MagJack RJ45 connector provides all the magnetics and built-in capacitors for a reliable Ethernet connection.
The best library to use for Teensy Ethernet is QNEthernet by Shawn Silverman. It can be installed from the Arduino IDE Library Manager. It can also be found on GitHub at: https://github.com/ssilverman/QNEthernet
See our Working with Ethernet for more information on using this feature.
USB Host
The USB Host data lines are brought out to a side mounted USB 2.0 connector.
The USB Host is a 2nd USB port that allows you to connect USB devices to the Teensy 4.1. It is fully independent of the main USB device port, so USB devices can communicate simultaneously with Teensy while Teensy communicates with a computer via the USB device port. The USB Host port operates at up to 480Mbit/sec. Use the USBHost_t36 library for working with this port.
Note that the 5V power to the USB Host port is logically controlled by the Teensy 4.1, so a voltage won’t be present on the connector until it is enabled by the Teensy 4.1 by executing the software command USBHost.begin().
See our Working with USB Host for more information on using this feature.
CAN Bus
CAN Bus is mainly used in automotive applications due to its distributed processing and robust communication protocol. It can also work quite well in other applications where multiple microcontrollers need to communicate over a common bus such as in robotics. Use the FlexCAN_T4 library for working with the CAN bus.
The Teensy 4.1 CAN3 bus on pins 30 and 31 is connected to an SN65HVD230, 231 or 232 CAN bus transceiver. These parts are all equivalent parts in this circuit and selected based on availability.
The output has a 120 ohm termination resistor which has a jumper that can be removed to take the resistor out of circuit if needed for the application.
It connects to a 3-pin screw terminal. Ground is typically not needed since the signal is differential, but is included in case it is desired to ground systems together.
RS485 Bus
RS485 is a long-line serial communication bus that allows multiple devices to connect to the same serial bus over long distances of up to 1200 meters. The underlying protocol is standard TTL level RS232 but with differential transceivers used to extend to long distances and support multiple device drops. Speeds of up to 2.5Mbit/sec are possible. Handy for device control of one or more devices over longer distances or in electrically noisy environments such as industrial control.
Serial8 on pins 34 and 35 are connected to an SP3485E / RS485 transceiver chip. The direction control enable is connected to pin 33.
The output has a 120 ohm termination resistor which has a jumper that can be removed to take it out of circuit if needed for the application. For short benchtop type testing setups, the resistor may need to be removed on both ends.
The output comes out to a 3-pin screw terminal. Ground is typically not needed since the signal is differential, but is included in case it is desired to ground systems together.
User Controls
There are 3 user buttons and an RGB LED connected to the Teensy 4.1 and 1 user button connected to the ESP32-C3.
Teensy 4.1 User Programmable Buttons – The baseboard has 3 user programmable buttons on Teensy 4.1 pins 22, 32 and 40 labeled BTN 1, BTN 2 and BTN 3. Note that pin 40 also comes out to the GPIO I/O Expansion connector. That provides a button input to the breadboard if one is attached.
RGB LED – There is an RGB LED on the baseboard connected to the Teensy 4.1. The RED channel is pin 4, GREEN channel is pin 5 and BLUE channel is pin 6. These are all PWM capable pins.
The demo software loaded on the system simply uses the 3 buttons to turn the red/green/blue channels on or off on the RGB LED.
ESP32-C3 User Programmable Button – The baseboard has 1 user programmable button on ESP32-C3 pin 10.
I/O Expansion
The baseboard incorporates a right angle 20-pin IDC connector to provide access to a selection of GPIO pins. The GPIO connector provides access to the SPI1 bus, I2C1 bus, CAN2 bus, Serial Ports 1/4/6, 10 analog inputs, 16 digital pins as well as 3.3V and 5V power and ground. The pins can be connected to using female breadboard jumpers if not using an adapter board.
These pins are unique except for pin 40 that is shared between the IDC connector and User Button 3. SPI1 which is also shared with the NOR Flash memory chip on the baseboard.
A solderless breadboard adapter is available that will plug into this connector and bring the available pins out to a labeled female header for easily breadboarding circuits.
A 24-pin right-angle female header is used on the adapter boards to avoid the possible issue of having the connectors being accidently offset when mated since the female connector is not keyed.
Pin View of IDC GPIO Connector
Note: Ignore the pin 1 triangle on the male IDC connector. Pin 1 is on the left side of the connector where the ground pins are located.
MISC Stuff
A CR2032 coin cell batter holder connects to the VBat on the Teensy 4.1 for providing battery backup capability.
Using The Mini Platform For Teensy 4.1
The setup described in this section illustrates the basic usage of some of the core parts of the system and provides a starting point for anyone just getting started with the Teensy 4.1 ecosystem. It also helps to jumpstart using the touch LCD since the ST7796 is not as widely used compared to something more common like the ILI9341.
The Mini Platform for Teensy 4.1 will already be loaded with the software below and will run as soon as power is applied.
The programs are not overly clever on the programming to make them easier to follow and pull heavily from various example programs. The communications between the Teensy 4.1 and ESP32-S in particular are handled in a very simplistic fashion by passing simple text strings.
There are two programs below. One is for the Teensy 4.1 and the second is for the ESP32-C3.
Teensy 4.1 Program Overview
- Configures the serial ports and LCD/touch screen
- Checks to see if any of the PSRAM or Flash memory chips have been installed on the Teensy 4.1 and reports that info out the serial port and also prints it on the LCD. This also provides a way to verify that you received the correct version of Teensy 4.1 without having to pry it out of its socket (which is very difficult to do and not recommended).
- Checks for the 16MB NOR Flash installed on the baseboard.
- Reports the microcontroller internal temperature
- Paints three buttons on the LCD screen. One for playing audio, one for scanning for WiFi networks using the ESP32-C3 and one for displaying basic system information.
- Implements a simple serial communication path with the ESP32-S to see if one is attached. First asking if one is out there by sending a ‘?’ and looking for a ‘Y’ yes in return. If found, it enables the WiFi Scan button. If a scan is requested, it sends the command ‘S’ for scan to the ESP32-C3 and then looks for a response back with the found networks. The found networks are then listed on the bottom half of the LCD.
- It also looks for an SD card in the Teensy 4.1 MicroSD card slot with the SDTEST2.WAV file on it (found at https://www.pjrc.com/teensy/td_libs_AudioDataFiles.html.) If found, it enables the Play Audio button to allow the audio to be started and stopped.
- If the System button is selected, it simply rechecks the system configuration same as it does at power up.
- It reports all touch coordinates and button hits and other miscellaneous info out to the USB port for display in a Serial Monitor window if one is open.
ESP32-C3 Program Overview
- Looks for incoming serial commands.
- If it gets a command ‘?’, it responds with ‘Y’ to let the Teensy 4.1 know that yes, it is there.
- If it gets a command ‘S’, it scans for networks and reports the results back to the Teensy 4.1
- It also reports the scan information out the USB port for display in a Serial Monitor window if one is open.
- This program is based largely on the WiFi Scan example program.
- The program also assumes an SH1106 style display is connected to the ESP32-C3 and prints some text to it to demonstrate the basic use of this feature.
You can open two instances of the IDE with one connected to the Teensy 4.1 and one connected to the ESP32-C3 for downloading the programs and Serial Monitor windows can be opened on both to see what is going on. This makes it easy to make program changes to either processor and download new code without messing with cables or changing the board type. To open 2 separate instances of the IDE, they both need to be launched by clicking on the application icon.
Teensy 4.1 Demo Example
/* Mini Platform for Teensy 4.1 Example This program does nothing overly useful, but illustrates some of the basic features and checks for presence of PSRAM/Flash memory installed, SD card installed and the ESP32-C3. Reports the info to the LCD and serial port. If SD card installed, the Audio button plays the wave file "SDTEST2.WAV" from the Teensy audio tutorial https://www.pjrc.com/teensy/td_libs_AudioDataFiles.html The Scan button sends a command to the ESP32S requesting a scan of available WiFi networks. When the ESP32S returns the scan results, the Teensy 4.1 updates those results on the LCD screen and serial port. The System button just rechecks the same system information. The three Teensy 4.1 user buttons simply turn the 3 RGB LED colors ON/OFF The ST7796 LCD uses the ST7796_t3 library branch from: https://github.com/KurtE/ST7735_t3/tree/ST7796 The FT6336 touch overlay uses the Adafruit_FT6206.h library. The onboard 16MB NOR Flash uses this SerialFlash library branch so that it will work properly on SPI1. https://github.com/KurtE/SerialFlash/tree/use_ptr_not_reference This example code is in the public domain. */ #include <ST7796_t3.h> #include <st7735_t3_font_Arial.h> #include <Adafruit_FT6206.h> #include <SPI.h> #include <Audio.h> #include <Wire.h> #include <SD.h> #include <Bounce2.h> #include <SerialFlash.h> #include "LittleFS.h" extern "C" uint8_t external_psram_size; AudioPlaySdWav playSdWav1; AudioOutputI2S i2s1; AudioConnection patchCord1(playSdWav1, 0, i2s1, 0); AudioConnection patchCord2(playSdWav1, 1, i2s1, 1); AudioControlSGTL5000 sgtl5000_1; // Pins used with the Teensy Audio Shield #define SDCARD_CS_PIN BUILTIN_SDCARD #define SDCARD_MOSI_PIN 11 //7 #define SDCARD_SCK_PIN 13 //14 // LCD control pins defined by the baseboard #define TFT_CS 10 #define TFT_DC 9 // Use main SPI bus MOSI=11, MISO=12, SCK=13 with different control pins ST7796_t3 tft = ST7796_t3(TFT_CS, TFT_DC); // Touch screen control pins defined by the baseboard // TIRQ interrupt if used is on pin 2 //#define TIRQ_PIN 2 // The FT6206 uses hardware I2C (SCL/SDA) Adafruit_FT6206 ts = Adafruit_FT6206(); #define BTN1_PIN 22 #define BTN2_PIN 32 #define BTN3_PIN 40 // INSTANTIATE 3 Button OBJECTS Bounce button1 = Bounce(); Bounce button2 = Bounce(); Bounce button3 = Bounce(); #define RGB_R_PIN 4 #define RGB_G_PIN 6 #define RGB_B_PIN 5 // Define Audio button location and size #define AUDIO_X 10 #define AUDIO_Y 10 #define AUDIO_W 105 #define AUDIO_H 32 // Define Scan button location and size #define SCAN_X 10 #define SCAN_Y 70 #define SCAN_W 105 #define SCAN_H 32 #define BUTTON_FONT Arial_14 #define TXT_FONT Arial_12 // Define System checks button location and size #define SYSTEM_X 150 #define SYSTEM_Y 10 #define SYSTEM_W 105 #define SYSTEM_H 32 #define FLASH_CS 37 //128Mb NOR flash chip CS pin #define ESP32SERIAL Serial7 // ESP32 is attached to Serial7 port #define ESP32SERIAL_BUFFER_SIZE 1024 unsigned char esp32SerialBuffer[ESP32SERIAL_BUFFER_SIZE]; // Subroutine prototypes void SetScanButton(boolean); // Handles Scan button when touched void SetAudioButton(boolean); // Handles Audio button when touched void SetSystemButton(); // Handes System button when touched void SystemCheck(); // Misc flags to keep track of things boolean isTouched = false; // Flag if a touch is in process boolean scanRequested = false; // Flag if WiFi scan is in process boolean sDCardInstalled = false; // Flag if SD card installed boolean audioPlaying = false; // Flag if audio is currently playing boolean esp32SAttached = false; // Flag if ESP32S is attached //=============================================================================== // Initialization //=============================================================================== void setup() { Serial.begin(115200); //Initialize USB serial port to computer ESP32SERIAL.begin(115200); //Initialize Seria1 1 connected to ESP32S // Setup extra memory for the ESP32 serial buffer to avoid overruns ESP32SERIAL.addMemoryForRead(esp32SerialBuffer, ESP32SERIAL_BUFFER_SIZE); // Required to get SPI1 to work with NOR Flash chip SPI1.setMOSI(26); SPI1.setSCK(27); SPI1.setMISO(39); SPI1.setCS(37); SPI1.begin(); //Setup buttons as inputs with pullup resistors button1.attach(BTN1_PIN, INPUT_PULLUP); button2.attach(BTN2_PIN, INPUT_PULLUP); button3.attach(BTN3_PIN, INPUT_PULLUP); // Set debounce interval to 15mSec button1.interval(15); button2.interval(15); button3.interval(15); //Setup RGB pins as outputs pinMode(RGB_R_PIN, OUTPUT); pinMode(RGB_G_PIN, OUTPUT); pinMode(RGB_B_PIN, OUTPUT); digitalWrite(RGB_R_PIN, LOW); digitalWrite(RGB_G_PIN, LOW); digitalWrite(RGB_B_PIN, LOW); // Setup LCD screen tft.init(320, 480); tft.invertDisplay(true); // Requires colors to be inverted tft.setRotation(3); // Rotates screen to match the baseboard orientation // Setup touch Screen // Touch Screen default touch threshold of 40 // Can change threshold to change touch sensitivity if (!ts.begin(40)) { Serial.println("Unable to start touchscreen."); } else { Serial.println("Touchscreen started."); } tft.fillScreen(ST7735_BLUE); tft.setCursor(1, 120); // Set initial cursor position tft.setFont(TXT_FONT); // Set initial font style and size // Draw buttons SetAudioButton(false); SetScanButton(false); SetSystemButton(); // Setup audio if (sDCardInstalled) { // Setup the audio AudioMemory(8); sgtl5000_1.enable(); sgtl5000_1.volume(0.5); SPI.setMOSI(SDCARD_MOSI_PIN); SPI.setSCK(SDCARD_SCK_PIN); } else { // If no audio, gray out button tft.setCursor(AUDIO_X + 8, AUDIO_Y + 8); tft.setFont(BUTTON_FONT); tft.setTextColor(ST7735_WHITE); tft.fillRoundRect(AUDIO_X, AUDIO_Y, AUDIO_W, AUDIO_H, 4, ST7735_BLACK); tft.print("No Audio"); } // Setup ESP32 if (!esp32SAttached) { // If no ESP32 gray out button tft.setCursor(SCAN_X + 8, SCAN_Y + 8); tft.setFont(BUTTON_FONT); tft.setTextColor(ST7735_WHITE); tft.fillRoundRect(SCAN_X, SCAN_Y, SCAN_W, SCAN_H, 4, ST7735_BLACK); tft.print("No Scan"); } // Initialize buttons button1.update(); button2.update(); button3.update(); } //=============================================================================== // Main //=============================================================================== void loop() { static boolean red_LED = false; static boolean green_LED = false; static boolean blue_LED = false; // Keep an eye on any audio that may be playing and reset button when it ends if (playSdWav1.isStopped() && audioPlaying) { // Audio finished playing SetAudioButton(false); Serial.println("Audio finished playing"); } // Check to see if the touch screen has been touched if (ts.touched() && isTouched == false) { TS_Point p = ts.getPoint(); Serial.print("x Raw = "); // Show our touch coordinates for each touch Serial.print(p.x); Serial.print(", y Raw = "); Serial.print(p.y); Serial.println(); // Map the touch point to the LCD screen p.x = map(p.x, 0, 320, 0, 320); // X coordinate not remapped p.y = map(p.y, 0, 480, 480, 0); isTouched = true; // Look for a Scan Button Hit if ((p.y > SCAN_X) && (p.y < (SCAN_X + SCAN_W))) { if ((p.x > SCAN_Y) && (p.x <= (SCAN_Y + SCAN_H))) { Serial.println("Scan Button Hit"); if (esp32SAttached) SetScanButton(true); } } // Look for an Audio Button Hit if ((p.y > AUDIO_X) && (p.y < (AUDIO_X + AUDIO_W))) { if ((p.x > AUDIO_Y) && (p.x <= (AUDIO_Y + AUDIO_H))) { Serial.println("Audio Button Hit"); if (sDCardInstalled && !audioPlaying) { SetAudioButton(true); } else if (sDCardInstalled && audioPlaying) { SetAudioButton(false); } } } // Look for a System Button Hit if ((p.y > SYSTEM_X) && (p.y < (SYSTEM_X + SYSTEM_W))) { if ((p.x > SYSTEM_Y) && (p.x <= (SYSTEM_Y + SYSTEM_H))) { Serial.println("System Button Hit"); if (scanRequested == false) SetSystemButton(); } } Serial.print("x = "); // Show our touch coordinates for each touch Serial.print(p.x); Serial.print(", y = "); Serial.print(p.y); Serial.println(); delay(100); // Debounce touchscreen a bit } if (!ts.touched() && isTouched) { isTouched = false; // touchscreen is no longer being touched, reset flag } // If we requested a scan, look for serial data coming back from the ESP32S if (scanRequested && ESP32SERIAL.available()) { Serial.print("Read incoming data"); tft.setCursor(10, 120); tft.setFont(TXT_FONT); while (ESP32SERIAL.available()) { // Print the scan data to the LCD & USB String returnData = ESP32SERIAL.readString(); tft.println(returnData); Serial.println(returnData); } scanRequested = false; // Reset the scan flag and button SetScanButton(false); } // Check on buttons and update RGB LED as required. button1.update(); button2.update(); button3.update(); if (button1.fell()) { red_LED = !red_LED; digitalWrite(RGB_R_PIN, red_LED); } if (button2.fell()) { green_LED = !green_LED; digitalWrite(RGB_G_PIN, green_LED); } if (button3.fell()) { blue_LED = !blue_LED; digitalWrite(RGB_B_PIN, blue_LED); } } //=============================================================================== // Routine to draw Audio button current state and control audio playback //=============================================================================== void SetAudioButton(boolean audio) { tft.setCursor(AUDIO_X + 8, AUDIO_Y + 8); tft.setFont(BUTTON_FONT); tft.setTextColor(ST7735_WHITE); if (!audio) { // button is set inactive, redraw button inactive tft.fillRoundRect(AUDIO_X, AUDIO_Y, AUDIO_W, AUDIO_H, 4, ST7735_RED); tft.print("Play Audio"); audioPlaying = false; if (playSdWav1.isPlaying()) { // Stop any audio that is playing playSdWav1.stop(); Serial.println("Audio being stopped"); } } else { // button is active, redraw button active tft.fillRoundRect(AUDIO_X, AUDIO_Y, AUDIO_W, AUDIO_H, 4, ST7735_GREEN); tft.print("Playing"); audioPlaying = true; if (sDCardInstalled && !playSdWav1.isPlaying()) { // Play audio file Serial.println("Audio being played"); playSdWav1.play("SDTEST2.WAV"); delay(10); // wait for library to parse WAV info } } } //=============================================================================== // Routine to draw scan button current state and initiate scan request //=============================================================================== void SetScanButton(boolean scanning) { tft.setCursor(SCAN_X + 8, SCAN_Y + 8); tft.setFont(BUTTON_FONT); tft.setTextColor(ST7735_WHITE); if (!scanning) { // Button is inactive, redraw button tft.fillRoundRect(SCAN_X, SCAN_Y, SCAN_W, SCAN_H, 4, ST7735_RED); tft.print("Scan WiFi"); } else { // Button is active, redraw button tft.fillRect(1, SCAN_Y + SCAN_H, 360, 240, ST7735_BLUE); // Clear previous scan tft.fillRoundRect(SCAN_X, SCAN_Y, SCAN_W, SCAN_H, 4, ST7735_GREEN); tft.print("Scanning"); ESP32SERIAL.println("S"); // Send command to ESP32 to start scan scanRequested = true; // Set flag that we requested scan Serial.println("Scan being requested"); } } //=============================================================================== // Routine to draw system button current state and initiate system checks //=============================================================================== void SetSystemButton() { tft.setCursor(SYSTEM_X + 8, SYSTEM_Y + 8); tft.setFont(BUTTON_FONT); tft.setTextColor(ST7735_WHITE); tft.fillRect(1, SCAN_Y + SCAN_H, 360, 240, ST7735_BLUE); // Clear previous info tft.fillRoundRect(SYSTEM_X, SYSTEM_Y, SYSTEM_W, SYSTEM_H, 4, ST7735_GREEN); tft.print("System"); Serial.println("System check requested"); // Can't do SystemCheck when audio playing off SD card if (audioPlaying == false) SystemCheck(); tft.setCursor(SYSTEM_X + 8, SYSTEM_Y + 8); tft.setFont(BUTTON_FONT); tft.fillRoundRect(SYSTEM_X, SYSTEM_Y, SYSTEM_W, SYSTEM_H, 4, ST7735_RED); tft.print("System"); } //=============================================================================== // Routine to query installed hardware //=============================================================================== void SystemCheck() { tft.setCursor(1, 120); // Set initial cursor position tft.setFont(TXT_FONT); // Set initial font style and size // Check for PSRAM chip installed uint8_t size = external_psram_size; if (size == 0) { Serial.println("No PSRAM Installed"); tft.println("No PSRAM Installed"); } else { Serial.printf("PSRAM Memory Size = %d Mbyte\n", size); tft.printf("PSRAM Memory Size = %d Mbyte\n", size); } tft.println(); LittleFS_QSPIFlash myfs_NOR; // NOR FLASH LittleFS_QPINAND myfs_NAND; // NAND FLASH 1Gb // Check for NOR Flash chip installed if (myfs_NOR.begin()) { Serial.printf("NOR Flash Memory Size = %d Mbyte / ", myfs_NOR.totalSize() / 1048576); Serial.printf("%d Mbit\n", myfs_NOR.totalSize() / 131072); tft.printf("NOR Flash Memory Size = %d Mbyte / ", myfs_NOR.totalSize() / 1048576); tft.printf("%d Mbit\n", myfs_NOR.totalSize() / 131072); } // Check for NAND Flash chip installed else if (myfs_NAND.begin()) { Serial.printf("NAND Flash Memory Size = %d bytes / ", myfs_NAND.totalSize()); Serial.printf("%d Mbyte / ", myfs_NAND.totalSize() / 1048576); Serial.printf("%d Gbit\n", myfs_NAND.totalSize() * 8 / 1000000000); tft.print("NAND Flash Memory Size = "); // tft.printf("%d bytes / ", myfs_NAND.totalSize()); tft.printf("%d Mbyte / ", myfs_NAND.totalSize() / 1048576); tft.printf("%d Gbit\n", myfs_NAND.totalSize() * 8 / 1000000000); } else { Serial.printf("No Flash Installed\n"); tft.printf("No Flash Installed\n"); } tft.println(); // Check for SD card installed if (!(SD.begin(SDCARD_CS_PIN))) { Serial.println("SD card not found"); tft.println("SD card not found"); sDCardInstalled = false; } else { Serial.println("SD card is Inserted"); tft.println("SD card is Inserted"); sDCardInstalled = true; } tft.println(); // Check for ESP32 installed ESP32SERIAL.print("?"); // Ask ESP32 if it is there delay(100); // Wait a bit for ESP32 to respond if (ESP32SERIAL.available()) { // If there is a response String returnData = ESP32SERIAL.readString(); if (returnData == 'Y') { // ESP32S responded with Y for Yes, I'm here esp32SAttached = true; Serial.println("ESP32-C3 was found"); tft.println("ESP32-C3 was found"); } else { // No response or invalid response Serial.println("ESP32-C3 not found"); tft.println("ESP32-C3 not found"); esp32SAttached = false; } } // Check for NOR Flash on baseboard if (!SerialFlash.begin(SPI1, FLASH_CS)) { Serial.println(F("Unable to access SPI Flash chip")); tft.println("Unable to access SPI Flash Chip"); } else { unsigned char id[5]; SerialFlash.readID(id); Serial.print("ID="); Serial.printf("ID: %02X %02X %02X\n", id[0], id[1], id[2]); unsigned long sizeFlash = SerialFlash.capacity(id); if (sizeFlash > 0) { Serial.print("SPI1 NOR Flash Memory has "); Serial.print(sizeFlash); Serial.println(" bytes"); tft.println(); tft.printf("SPI NOR Flash Memory Size = %d Mbyte\n", sizeFlash / 1000000); } Serial.print(tempmonGetTemp()); Serial.println("°C"); tft.println(); tft.print("CPU Temp: "); tft.print(tempmonGetTemp()); tft.println("°C"); } }
ESP32-C3 Demo Example
/* This sketch interfaces the ESP32-C3 to the Teensy 4.1 via serial port 2. It demonstrates how to receive a request for a scan for WiFi networks and report the results back via serial port and the LCD. If a 1.3" SH1106 OLED 128x64 display is attached to the ESP32-C3 I2C headers it also writes some info out to that display. This display uses the "U8g2lib.h" library that can be downloaded from the Arduino IDE. This is a simple variation of the ESP32 WiFiScan example program */ #include <Wire.h> #include "WiFi.h" #include <U8g2lib.h> #define RX2 20 // Teensy 4.1 is connected to serial port #2 #define TX2 21 //#define SCREEN_WIDTH 128 // OLED display width, in pixels //#define SCREEN_HEIGHT 32 // OLED display height, in pixels #define BTN_PIN 10 U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R2, /* reset=*/ U8X8_PIN_NONE); //=============================================================================== // Initialization //=============================================================================== void setup() { Serial.begin(115200); // USB port Serial1.begin(115200, SERIAL_8N1, RX2, TX2); //Port connected to Teensy 4.1 pinMode(BTN_PIN, INPUT_PULLUP); u8g2.begin(); // Initialize the SH1106 display if one is attached // Set WiFi to station mode and disconnect from an AP if previously connected WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); Serial.println("Setup done"); // Print something to the SH1106 display if it is attached u8g2.firstPage(); // Start the write to the display u8g2.setFont(u8g2_font_ncenB14_tr); // Set the font u8g2.drawStr(3,35,"Hello World!"); // Write 'Hello World!' u8g2.drawRFrame(0,0,127,63,7); // Draw a rectangle around it u8g2.nextPage(); // Completes the write to the display } //=============================================================================== // Main //=============================================================================== void loop() { //static int i = 0; if (Serial1.available()) { char command = Serial1.read(); Serial.println(command); if (command == '?') { // Are you there? Serial.println("Y"); Serial1.print("Y"); // Acknowledge I'm attached u8g2.firstPage(); // if SH1106 attached, update with status u8g2.setFont(u8g2_font_ncenB12_tr); // Set the font u8g2.drawStr(3,35,"I'm Connected!"); // Respond to T4.1 query u8g2.nextPage(); } if (command == 'S'){ Serial.println("scan start"); u8g2.firstPage(); u8g2.setFont(u8g2_font_ncenB10_tr); // Set the font u8g2.drawStr(30,35,"Scanning"); // Update SH1106 display u8g2.nextPage(); // WiFi.scanNetworks will return the number of networks found int n = WiFi.scanNetworks(); Serial.println("scan done"); if (n == 0) { Serial.println("no networks found"); Serial1.println("No networks found"); } else { Serial.print(n); Serial1.print(n); Serial.println(" Networks Found"); Serial1.println(" Networks Found"); for (int i = 0; i < n; ++i) { // Print SSID and RSSI for each network found to both USB and // out Serial2 to attached Teensy 4.1 Serial.print(i + 1); Serial1.print(i + 1); Serial.print(": "); Serial1.print(": "); Serial.print(WiFi.SSID(i)); Serial1.print(WiFi.SSID(i)); Serial.print(" ("); Serial1.print(" ("); Serial.print(WiFi.RSSI(i)); Serial1.print(WiFi.RSSI(i)); Serial.print(")"); Serial1.print(")"); Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*"); Serial1.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*"); } delay(10); } u8g2.setFont(u8g2_font_6x10_mf); // Set the font int lineHt = u8g2.getMaxCharHeight(); u8g2.clear(); // Clear the display u8g2.setCursor(0,lineHt); for (int i = 0; i < n; ++i){ u8g2.print(WiFi.SSID(i)); u8g2.updateDisplay(); u8g2.setCursor(0,lineHt*(i+2)); delay(10); } } } if (digitalRead(BTN_PIN)== LOW) { // button on pin 10 has been pressed - do something } WiFi.scanDelete(); }
Board Construction
The PCB is 5.4″ x 3.0″ with 4-layers and constructed of 1.6mm FR-4 and ENIG plating. The assembly is 5.6″ x 3.0″ with connector overhang.
Green solder mask provides excellent trace visibility in case trace customization is desired.
Their are six 0.138″ diameter holes which can accept up to 3.5mm or #6 screws spaced evenly around the board. The board ships with 6 M3 x 5mm nylon standoffs and M3 screws installed to serve as feet.
Further Reading:
Visit our Tutorial section under the Learn menu for additional information on this system. The tutorial is written for our Prototype System board, but many of the features are in common between the different systems. We will be continuing to update this section as time permits.
Anyone working with the Teensy 4.1 should checkout the PJRC forum as it has exceptional technical support provided by a talented user base including Paul Stoffregen, the creator of the Teensy product line.
PJRC Forum – Excellent source of technical information and project help for the Teensy 4.1
PJRC website – Good source of information about Teeny 4.1 detailed operation with many example applications in blog posts and an alternate source for some items in their on-line store.
PJRC Teensy Audio Library Tutorial – Excellent tutorial and general info on using the Teensy Audio Library and design tools. Note: We will be providing an optional Audio Tutorial Adapter board in the future.
Teensy 4.1 Product Page – This page on our website has more details on the actual Teensy 4.1 development board itself.
Notes:
- None
Technical Specifications
Material | FR-4 | |
Layers | 4 | |
Copper | 1 oz out layers, 1/2 oz inner layers | |
Plating | ENIG (Electroless Nickel Immersion Gold) | |
Solder Resist | Green | |
Silkscreen | Front and Back | White |
Dimensions | Board outline | 137 x 76.2mm (5.4 x 3.0″) |
Board thickness | 1.6mm (0.062″) | |
Mounting holes M3 | 3.5mm (0.138″) | |
Country of Origin | Designed and final assembly in USA | PCB and SMT assembly in China |
Mini Platform for Teensy 4.1 Schematics
Mini Platform for Teensy 4.1 CAD Top
Mini Platform for Teensy 4.1 CAD Bottom