Square wave generator with ESP32: an economical solution for circuit testing


In the world of electronics, a square wave generator or more generally a signal generator is an essential tool for testing and diagnosing circuits. A device of this kind allows you to inject a known signal into a circuit to observe how it responds, making it easier to identify any problems or anomalous behavior. However, professional signal generators can be expensive, making them unaffordable for many hobbyists, students, and small labs. Fortunately, with the ESP32, you can build a variable frequency square wave generator cheaply and easily, offering a practical and versatile solution for circuit testing.

A square wave generator can be extremely useful for both digital and analog circuits. In the context of digital circuits, square waves are critical because they represent the binary signals (0 and 1) that form the basis of the operation of digital devices. A square wave generator can be used to simulate input to microcontrollers, test the response of sequential and combinatorial logic, verify the functionality of counters and timers, and much more. For example, a square wave generator can simulate the clock of a digital system, allowing you to observe how various components respond to timing.

Within analog circuits, square waves can be used for a variety of purposes. A square wave can be used as a test signal for amplifiers, filters, and other analog devices, allowing you to observe frequency response and distortion. Additionally, because square waves contain a number of harmonics, they can be used to examine a circuit’s response to several frequencies at the same time. For example, in an audio amplifier, a square wave can help identify distortion and stability problems.

Another common use of square waves is in the generation of PWM (Pulse Width Modulation) signals, which can be used to control the speed of motors, the brightness of LEDs, and other actuators. The ESP32, with its LEDC (LED Control) module, is particularly suitable for this type of applications, thanks to its ability to generate high resolution and variable frequency PWM signals.

Building a square wave generator with the ESP32 is not only an economical project, but also a highly educational one. It allows you to deepen your understanding of the principles of PWM, signal generation and the behavior of both digital and analog circuits. Furthermore, it offers the opportunity to explore the advanced capabilities of the ESP32, a powerful and versatile microcontroller that can be used in a wide range of electronic projects.

In this article, we will explore how to make a signal generator using the ESP32, offering an affordable solution for circuit testing. We will see how to configure the microcontroller, write the necessary code and test the operation of the square wave generator. This project will demonstrate how it is possible to build an effective and versatile test instrument on a limited budget, providing a practical alternative to expensive professional signal generators.

As usual we will use the excellent PlatformIO IDE to write the code.

What is PWM?

PWM, an acronym for Pulse Width Modulation, is a technique used to control the power supplied to electronic devices such as motors, LEDs and servomotors. This technique works by varying the pulse width of a digital signal at a constant frequency, allowing you to adjust the amount of energy delivered to the load.

The basic principle of PWM consists of rapid alternation between two states: a high state (ON) and a low state (OFF). During the high state, the signal is active and the load receives energy; during the low state, the signal is inactive and the load receives no power. The duration of the high pulse relative to the total cycle duration defines the duty cycle ratio, generally expressed as a percentage. For example, a 50% duty cycle means the signal is active for half the total cycle time.

The use of PWM allows you to adjust the power supplied to the load by varying the duty cycle ratio. Increasing the duty cycle increases the power supplied to the load, while decreasing the duty cycle reduces the power supplied. This ability to regulate power quickly and efficiently makes PWM ideal for controlling devices that require power modulation, such as DC motors, brushless motors, LED lamps, and servo motors.

In the context of servo motor control, PWM is used to send control signals that determine the desired position of the servo. These signals, called PWM pulses, have a typical frequency of 50 Hz and a pulse duration that varies between 1 ms and 2 ms, with a duration of 1.5 ms usually corresponding to the center position of the servo. By changing the duration of the PWM pulse, you can adjust the position of the servo over a range of approximately 180 degrees, allowing precise control of its rotation.

In conclusion, PWM is a fundamental technique in modern electronics, used to control the power supplied to electronic devices efficiently and precisely. Its versatility makes it widely used in a variety of applications, from regulating the speed of motors to regulating the light intensity of LEDs, up to the position control of servomotors.

Operation of our square wave generator

The operation of the ESP32-based square wave generator is an example of how the power and versatility of this microcontroller can be exploited to obtain a useful and accessible tool. The basis of the project is the use of the ESP32’s LEDC (LED Control) module, which allows the generation of PWM (Pulse Width Modulation) signals with high resolution and variable frequency. This module is particularly suited to creating square waves, which are critical for both digital and analog circuit testing.

The project begins with defining the GPIO pin of the ESP32 on which the square wave will be generated. In this case, we have chosen pin 25. Next, a series of predefined frequencies is established, which the signal generator will cycle, producing square waves at different frequencies for a given time. The selected frequencies range from 100 Hz to 1,000 Hz (but can be extended up to 10kHz), covering a broad spectrum that allows you to test a variety of electronic circuits and components.

The source code loaded onto the ESP32 initially configures the LEDC module with a starting frequency and resolution of 8 bits. The configuration takes place in the program setup, where the LEDC channel is associated with the chosen GPIO pin. In the main program loop, the ESP32 sets the frequency of the LEDC channel to one of the predefined frequencies and generates the square wave by setting the duty cycle to 50%, i.e. a duty cycle in which the signal is half high of the time and low for the other half. This configuration is ideal for obtaining a symmetrical square wave, which represents a standard digital signal.

During execution, the program cycles through the predefined frequencies, generating the corresponding square wave on each of them for a few seconds, before moving on to the next frequency. This process continues indefinitely, allowing the behavior of the circuit to be observed when tested at different frequencies. Each frequency change is recorded and displayed on the serial monitor, offering immediate feedback on the ongoing operation and facilitating verification of the correct operation of the square wave generator.

To test and verify the operation of the generator, you can use tools such as an oscilloscope or a frequency meter. By connecting the GPIO pin of the ESP32 to the measurement device, you can view the generated square wave and verify its frequency and stability. An oscilloscope allows you to directly observe the shape of the square wave, confirming that the duty cycle is indeed 50% and that the frequency corresponds to the set frequency. This visual check is crucial to ensure that the generator is working properly and to identify any problems with distortion or instability in the signal.

In conclusion, the ESP32-based square wave generator is a simple yet powerful design, offering a practical and economical solution for electronic circuit testing. The ability to generate square waves at variable frequencies makes this instrument extremely versatile, suitable for both digital and analogue applications. Thanks to the power and flexibility of the ESP32, you can build an efficient signal generator without having to invest in expensive professional tools, making this project ideal for hobbyists, students and small laboratories.

What components do we need?

The list of components is not particularly long:

  • a breadboard to connect the ESP32 NodeMCU to other components
  • some DuPont wires (male – male, male – female, female – female)
  • (optional) a digital frequency meter to precisely measure the frequency of the signal generated by the ESP32. This tool can help you verify that your square wave generator is working properly.
  • (optional) an oscilloscope, essential for viewing the generated square wave. It allows you to observe the waveform, check the frequency and duty cycle, and identify any distortions or anomalies in the signal.
  • and, of course, an ESP32 NodeMCU !

The ESP32 model chosen for this project is that of the AZ-Delivery company.

Project implementation

The electrical diagram

Before creating the actual circuit let’s take a look at the pinout of the board:

Pinout of the ESP32
Pinout of the ESP32

As you can see from the following image, the electrical diagram (made with Fritzing) is truly elementary:

Square wave generator wiring diagram
Square wave generator wiring diagram

To use it you will have to connect the ground of the frequency meter and/or oscilloscope and/or the device under test to the blue branch of the breadboard which is connected to the ground of the ESP32 and the input of the frequency meter and/or oscilloscope and/or the device under test to yellow wire, which is signal output. Always remember that, being a digital signal generated by an ESP32 device, the voltage value corresponding to logical 0 is equal to 0V while the voltage value corresponding to logical 1 is equal to 3.3V. Make sure that the device that will receive this signal is capable of processing these values. For example, a device that has 0V – 5V logic (such as an Arduino) is not guaranteed to be able to recognize the value of 3.3V as a logical 1.

Let’s create the PlatformIO project

We have already seen the procedure for creating a PlatformIO project in the article How to create a project for NodeMCU ESP8266 with PlatformIO.

Although it refers to the ESP8266 board, the procedure is similar.
Simply, when choosing the platform, you will have to choose the AZ-Delivery ESP-32 Dev Kit C V4.

Do not install any of the libraries mentioned in the article.

Now edit the platformio.ini file to add these two lines:

monitor_speed = 115200
upload_speed = 921600

so that the file looks like this:

platform = espressif32
board = az-delivery-devkit-v4
framework = arduino
monitor_speed = 115200
upload_speed = 921600

You can download the project from the following link:

unzip it, take the main.cpp file and replace it with the one you have in the previously created project.

Now let’s see how the sketch works.

Initially the necessary libraries are included:

#include <Arduino.h>

then the output GPIO is defined:

const int gpioPin = 25; // Output pin

The frequencies that must be generated, the number of frequencies to be generated, the channel and the resolution are then defined:

// Frequencies in Hz
const int frequencies[] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
const int numFrequencies = sizeof(frequencies) / sizeof(frequencies[0]);

// LEDC channel and resolution
const int ledcChannel = 0;
const int ledcResolution = 8; // 8 bit resolution

In the setup function, the serial port is first initialized, the LEDC channel is configured with a frequency of 1 kHz and the GPIO chosen as output is assigned to the LEDC channel:

ledcSetup(ledcChannel, 1000, ledcResolution); // Configure the LEDC channel with a starting frequency of 1000 Hz
ledcAttachPin(gpioPin, ledcChannel); // Assign the pin to the LEDC channel

In the loop function we find a for block that iterates the frequency array frequencies, sets the frequency on the LEDC channel and the duty cycle and writes on the Serial Monitor which frequency it is generating:

for (int i = 0; i < numFrequencies; i++) {
    int frequency = frequencies[i];
    ledcWriteTone(ledcChannel, frequency); // Sets the frequency of the LEDC channel
    ledcWrite(ledcChannel, 128); // Set duty cycle to 50% (128 of 256 for 8-bit resolution)

    Serial.print("Rectangular wave generation at ");
    Serial.println(" Hz");

   delay(5000); // Wait before switching to the next frequency

Video of the operation

As you can see, as the frequency increases, the pulses become thicker. You can also try making it generate different frequency values.

If you want to try this generator with the frequency meter made with ESP32 and TFT display, I invite you to take a look at the article Digital frequency meter with ESP32 and TFT display: an economical and essential solution for the electronics laboratory published in this same blog.


If you want to be informed about the release of new articles, subscribe to the newsletter. Before subscribing to the newsletter read the page Privacy Policy (UE)

If you want to unsubscribe from the newsletter, click on the link that you will find in the newsletter email.

Enter your name
Enter your email
0 0 votes
Article Rating
Inline Feedbacks
View all comments
Would love your thoughts, please comment.x
Scroll to Top