STM32F1 Blue-pill: WiFi shield (WiFiNINA)

Spread the love

First of all, read the article “STM32: WiFiNINA with ESP32 WiFi Co-Processor“, where there are all the basics to understand this shield usage better.

STM32F1 blue pill wifi shield (WiFiNINA)
STM32F1 blue pill wifi shield (WiFiNINA)

For me, It’s very important the network connection and network limitation on STM32 It’s very tedious. Adafruit offers a solution, but I think that a shield It’s more usable.

So I designed a shield to add WiFi to my STM32F1 blue-pill.

PCB

You can get the PCB for a few dollars.


STM32F1 blue pill wifi shield PCB PCBWay
PCB from PCBWay

The PCB is quite simple, and I also add an interface to update the firmware over esp32. Strangely, esp32-s seems to update better than esp32-wroom-32. Probably the thin wire adds noise to the serial transfer.

ESP32 S pinout low resolution
ESP32 S pinout low resolution

Here my selection of esp32 ESP32 Dev Kit v1 - Selectable - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 CP2104 CH340 - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S

It’s crucial to select an stm32f1 of good quality. Some clone devices have trouble.

Pinout STM32 STM32F1 STM32F103 STM32F103C8 low resolution
Pinout STM32 STM32F1 STM32F103 STM32F103C8 low resolution

Here my selection of stm32 STM32F103C8T6 STM32F401 STM32F411 ST-Link v2 ST-Link v2 official

Here is the PCB drawing.

STM32F1 blue pill wifi shield (WiFiNINA)
STM32F1 blue pill wifi shield (WiFiNINA)

The result is this PCB. Here is the top view:

STM32F1 blue pill wifi shield: up
STM32F1 blue pill wifi shield: up

and here is the bottom.

STM32F1 blue pill wifi shield: bottom
STM32F1 blue pill wifi shield: bottom

At the top, you can see the pad to solder to select the CS pin of the WiFi module (refer the article about Wifi coprocessor).

ESP32DescriptionSTM32
GPIO05CSPB1, PB0, PA4
GPIO18SCKPA5
GPIO23MISOPA6
GPIO14MOSIPA7
GPIO33BUSY/READY (IRQ)PA3
EN (reset on LOW)RST/ENPA2
GPIO0 (Flash)FlashPA1 (not needed)
GNDGNDGND
VIN3.3vFrom 5v to a voltage regulator

At the bottom, I add a terminal SH1.0 horizontal to interface with FTDI and two buttons to program and reset the esp32.

Here a set of terminal Terminal sh1.0 jst1.25 zh1.5 ph2.0 xh2.54 - 2.54mm PCB Screw Terminal Blocks

You can refer to the article “ESP32-wroom-32, esp32-S: flash, pinout, specs and IDE configuration” which explains how to program esp32 without a prototyping board.

esp32-wroom-32 programming flash connection breadboard
esp32-wroom-32 programming flash connection breadboard

Assembling the PCB

The board is very simple to assemble. You need:

  • an esp32-s or an esp32-wroom-32

The WiFi co-processor ESP32 Dev Kit v1 - Selectable - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 CP2104 CH340 - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S

  • SMD voltage regulator AMS1117-3.3V

Voltage regulator AliExpress SMD (AMS1117) - AliExpress 3.3v (LM1117) - AliExpress 5v (7805) - AliExpress 9v (7809)AliExpress 12v (7812) - AliExpress 3.3v TO-92 (78L33)

  • SMD buttons

SMD buttons SMD buttons 3X6X2.5

  • SH1.0 terminal

Terminal Terminal sh1.0 jst1.25 zh1.5 ph2.0 xh2.54 - 2.54mm PCB Screw Terminal Blocks

  • 805 SMD resistor (10uF)
  • Female header

Before assembling upload the firmware to the esp32, the little SMD connector can generate some noise, and some esp32-wroom-32 doesn’t allow uploading the firmware.

Before assembling upload the WiFi firmware to the esp32

You also need to solder the relative pad to the CS pin you select.

Use the connector to upload the firmware to the esp32

You can refer to this article “ESP32-wroom-32, esp32-S: flash, pinout, specs and IDE configuration” to have full information about the process.

As I already said, I added a connector to upload the firmware to the esp32. To use It, you need an FTDI.

FTDI AliExpress USB to TTL CH340G - AliExpress USB to TTL FT232RL


You also need to crimp a cable, and you can see the pin position on the PCB (G, V, Tx, and Rx).

STM32 WiFi shield with FTDI to update firmware nina-fw
STM32 WiFi shield with FTDI to update firmware nina-fw

The upload process is simple:

  • Connect the FTDI;
  • Hold down Prog button;
  • Click and release EN button;
  • Release Prog button (now esp32 is in download mode);
  • Launch the upload process on the port of your FTDI.

You can find the complete process and firmware in the relative article “STM32: WiFiNINA with ESP32 WiFi Co-Processor“.

First communication test

Now put your STM32F1 on your shield.

STM32F1 blue pill wifi shield
STM32F1 blue pill wifi shield

And we are going to test a basic communication between your ESP32 and your STM32.

Check firmware sketch

The sketch asks for the version of the firmware installed on the ESP32.

/*
 * This example check if the firmware loaded on the NINA module
 * is updated.
 *
 * modified by Renzo Mischianti <www.mischianti.org>
 *
 * www.mischianti.org
 *
 */
#include <SPI.h>
#include <WiFiNINA.h>

#define SPIWIFI       SPI  // The SPI port
#define SPIWIFI_SS    PA4   // Chip select pin
#define ESP32_RESETN  PA2   // Reset pin
#define SPIWIFI_ACK   PA3   // a.k.a BUSY or READY pin
#define ESP32_GPIO0   -1

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

  // Print a welcome message
  Serial.println("WiFiNINA firmware check.");
  Serial.println();

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

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  // Print firmware version on the module
  String fv = WiFi.firmwareVersion();
  String latestFv;
  Serial.print("Firmware version installed: ");
  Serial.println(fv);

  latestFv = WIFI_FIRMWARE_LATEST_VERSION;

  // Print required firmware version
  Serial.print("Latest firmware version available : ");
  Serial.println(latestFv);

  // Check if the latest version is installed
  Serial.println();
  if (fv >= latestFv) {
    Serial.println("Check result: PASSED");
  } else {
    Serial.println("Check result: NOT PASSED");
    Serial.println(" - The firmware version on the module do not match the");
    Serial.println("   version required by the library, you may experience");
    Serial.println("   issues or failures.");
  }
}

void loop() {
  // do nothing
}

Remember to select the correct CS pin (according to your pad soldering)

#define SPIWIFI_SS    PB0   // Chip select pin

If all is ok, the output of the sketch is:

Firmware version installed: 1.7.4
Latest firmware version available : 1.2.1

Check result: PASSED

This is good, but the test is not sufficient to be sure that all works correctly. Now, we upload a sketch to scan all wifi networks.

WiFi network scanner sketch

/*

 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
 modified 17 May 2022
 by Renzo Mischianti

 */


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

#define SPIWIFI       SPI  // The SPI port
#define SPIWIFI_SS    PA4   // Chip select pin
#define ESP32_RESETN  PA2   // Reset pin
#define SPIWIFI_ACK   PA3   // a.k.a BUSY or READY pin
#define ESP32_GPIO0   -1

void printMacAddress(byte mac[]);
void printEncryptionType(int thisType);
void listNetworks();

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  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(10000);
  }
  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();
}

If you obtain an output like this, the board is ok.

Scanning available networks...
** Scan Networks **
number of available networks:6
0) reef-casa-sopra	Signal: -49 dBm	Encryption: WPA2
1) reef-casa-orto	Signal: -69 dBm	Encryption: WPA2
2) reef-casa-centro	Signal: -78 dBm	Encryption: WPA2
3) reef-casa-centro	Signal: -83 dBm	Encryption: WPA2
4) reef-casa-sotto	Signal: -87 dBm	Encryption: WPA2
5) TIM-18355607	Signal: -91 dBm	Encryption: WPA2

Thanks

  1. STM32F1 Blue-Pill: pinout, specs, and Arduino IDE configuration (STM32duino and STMicroelectronics)
  2. STM32: program (STM32F1) via USB with STM32duino bootloader
  3. STM32: programming (STM32F1 STM32F4) via USB with HID boot-loader
  4. STM32F4 Black-Pill: pinout, specs, and Arduino IDE configuration
  5. STM32: ethernet w5500 with plain HTTP and SSL (HTTPS)
  6. STM32: ethernet enc28j60 with plain HTTP and SSL (HTTPS)
  7. STM32: WiFiNINA with ESP32 WiFi Co-Processor
    1. STM32F1 Blue-pill: WiFi shield (WiFiNINA)
    2. STM32F4 Black-pill: WiFi shield (WiFiNINA)
  8. How to use SD card with stm32 and SdFat library
  9. \STM32: SPI flash memory FAT FS
  10. STM32: internal RTC, clock, and battery backup (VBAT)
  11. STM32 LoRa
    1. Unleashing IoT Potential: Integrating STM32F1 Blue-Pill with EByte LoRa E32, E22, and E220 Shields
    2. Unleashing IoT Potential: Integrating STM32F4 Black-Pill with EByte LoRa E32, E22, and E220 Shields
  1. STM32 Power saving
    1. STM32F1 Blue-Pill clock and frequency management
    2. STM32F4 Black-Pill clock and frequency management
    3. Intro and Arduino vs STM framework
    4. Library LowPower, wiring, and Idle (STM Sleep) mode
    5. Sleep, deep sleep, shutdown, and power consumption
    6. Wake up from RTC alarm and Serial
    7. Wake up from the external source
    8. Backup domain intro and variable preservation across reset
    9. RTC backup register and SRAM preservation

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *