Control of an SG90 servomotor with ESP32 and touchscreen display

Introduction

The project “Control of an SG90 servomotor with ESP32 and touchscreen display” combines the potential of the ESP32, a versatile and powerful microcontroller, with the versatility of an interactive touchscreen display, to create a sophisticated and efficient control system.

The SG90 servo, with its wide range of motion and precision, is an ideal choice for a variety of applications, from robotics to home automation. Integrating this servo with the ESP32, known for its connectivity and processing capabilities, opens the door to a wide range of innovative and custom designs.

The touchscreen display adds an unprecedented level of interactivity, allowing users to interact directly with the system and control servo position with a simple touch of the display. This intuitive approach makes the user interface accessible even to those who are not familiar with programming or advanced electronics.

Through this project, we will explore the details of how to configure and program the ESP32 to control the SG90 servo, how to create an interactive user interface using the touchscreen display, and how to integrate the two components to create a complete and functional control system. From theory to practice, we’ll review each step of the development process, offering step-by-step instructions and helpful tips to help you build your project successfully.

We will delve into the operation and capabilities of the 2.8″ TFT LCD display, with particular attention to its technical specifications. We will also analyze the key role of the ESP32 in managing the display and use the TFT_eSPI and TFT_eWidget libraries to create an intuitive and customized user interface

Combining the power of modern electronics with the simplicity of the intuitive user interface, the project “Controlling an SG90 servo motor with ESP32 and touchscreen display” promises to bring new possibilities in the world of DIY automation and robotics whether whether you are a curious beginner or an expert in the sector.

As usual, for the development of the project, we will use the excellent IDE PlatformIO.

The SG90 servomotor

The SG90 servo motor is an electromechanical component widely used in a wide range of applications, ranging from robotics to radio-controlled models, from home automation to electronic hobbies. Its popularity is due to its compactness, its reliability and its ease of use, making it one of the most popular and accessible servomotors on the market.

The operation of the SG90 servo motor is based on a precise position control mechanism. Inside the servo motor, there is an electric motor, a set of gears and a control circuit. The control signal sent to the servo motor determines the position of the motor shaft, allowing accurate control of its rotation over a range of approximately 180 degrees.

A key point of the SG90 servo motor is its ability to operate in position feedback mode, which means the motor constantly monitors the position of the shaft and works to keep it in the desired position. This makes it ideal for applications requiring precise and reliable position control, such as steering controls in radio-controlled vehicles, movements of robotic arms or automatic door openings.

To use an SG90 servo motor, you need to power it with an appropriate voltage and provide a control signal via an input pin. The control signal is a pulse width modulated (PWM) pulse with a typical frequency of 50 Hz and a variable duty cycle, which determines the desired position of the servo motor. You can drive the servo motor using a microcontroller such as the ESP32, which generates control signals according to program instructions.

In summary, the SG90 servo motor is a critical component for a variety of electronic projects requiring precise and reliable position control. With its ease of use and reliable performance, it has become a favorite actuator for hobbyists and engineers looking to bring their ideas to life.

The SG90 servo motor that we will use here has 3 connection wires: two for the 5V power supply and the third for its control. Being small and not very powerful, it is suitable for acting on small loads.

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.

What is ILI9341 2.8″ SPI LCD TFT Display?

The ILI9341 2.8″ SPI TFT LCD Display is a type of high-resolution color liquid crystal display (LCD) designed to provide a visual interface in electronic projects. It communicates with the microcontroller via a dedicated SPI interface. In addition to color display, it features of a resistive touchscreen that allows direct interaction with the user (via dedicated SPI interface), and of an SD (Secure Digital) card slot that allows you to easily store and access data (via dedicated SPI interface).

Technical features:

Screen size: 2.8 inches (diagonal)
Risoluzione: 320 x 240 pixel
Controller: ILI9341, a popular TFT display controller that supports communication via SPI (Serial Peripheral Interface)
Interface: SPI (Serial Peripheral Interface) for communication with microcontrollers and other devices
Touchscreen: resistive, which allows direct interaction with the user through pressure
SD card slot: for accessing SD memory cards via the SPI interface, allowing data storage and access
Colors: Supports display of 65,536 colors (16-bit)
Viewing angle: good, with clear vision from different angles
Backlight: LED backlight for uniform and adjustable brightness
Compatibility: compatible with a wide range of microcontrollers and development boards

Functionality and use: the ILI9341 2.8″ SPI TFT LCD display with resistive touchscreen and SD card slot can be used in a variety of applications, including:

  • Creating interactive user interfaces for embedded devices and IoT projects
  • Display of text, graphics and images with the possibility of interaction via touchscreen
  • Implementation of data logging systems that use the SD card slot to store and access data
  • Making portable media devices, such as video players and image viewers, with the ability to store media files on the SD card

Advantages:

  • User interaction: the resistive touchscreen allows direct and intuitive interaction with the user interface.
  • External storage: the SD card slot offers the possibility of storing a large amount of data externally to the main device (for example images to be used as wallpaper or icons).
  • Versatility: Thanks to its SPI interface and its advanced technical features, it is suitable for a wide range of applications in electronics and embedded computing.

Limitations:

  • Programming complexity: It may require some familiarity with embedded programming and graphics libraries to take full advantage of its features.
  • Limited screen size: Display size may be limited for some applications that require a larger view.

In summary, the ILI9341 2.8″ SPI TFT LCD Display with resistive touchscreen and SD card slot is a versatile choice for embedded projects that require high-quality color display, user interaction and external storage capacity. With its advanced features and Compatibility with a wide range of microcontrollers, it is ideal for a variety of applications in embedded electronics and computing.

The graphics libraries used: TFT_eSPI and TFT_eWidget

TFT_eSPI library: The TFT_eSPI library is a highly optimized graphics library designed to provide a simple and powerful interface for managing color TFT displays with microcontrollers based on ESP8266 and ESP32 architecture. Here are some of the main features of the TFT_eSPI library:

  • Compatibility: supports a wide range of TFT displays with SPI-compatible controllers, including the popular ILI9341 controller used in 2.8″ TFT displays.
  • High speed: takes advantage of the hardware capabilities of the ESP8266 and ESP32 microcontrollers to achieve high performance and fast screen refresh times.
  • Memory saving: it is designed to take up as little memory space as possible, allowing other microcontroller resources to be used for additional functionality.
  • Touchscreen support: integrates resistive touchscreen management functionality, allowing user interaction through touches and pressures on the display.
  • Advanced color management: offers a wide range of color management features, including viewing color images, creating graphs, and much more.
  • Graphics library: provides a variety of functions and methods for drawing geometric shapes, text and other graphics on the TFT display.

TFT_eWidget library: The TFT_eWidget library is an additional library designed to further simplify the development of interactive user interfaces on TFT displays using the TFT_eSPI library. Here are some of the main features of the TFT_eWidget library:

  • Default UI components: provides a wide range of user interface (UI) components, such as buttons, scrollbars, text boxes, and more, that can be easily integrated into your designs.
  • Advanced customization: allows full customization of UI components, including changing color, size, and style to fit specific project needs.
  • Easy integration: thanks to its intuitive interface and simple programming methods, it allows for quick and hassle-free integration of UI components into existing projects.
  • Touchscreen support: automatically manages user interaction via the resistive touchscreen, allowing intuitive use of UI components through taps and presses on the display.

In summary, the TFT_eSPI and TFT_eWidget libraries offer a complete and powerful development experience for creating interactive user interfaces on TFT displays with ESP8266 and ESP32 microcontrollers. With their advanced features and ease of use, they are ideal for a wide range of applications in embedded electronics and IoT.

SPI interface

The display, touchscreen and SD card reader each use dedicated SPI interfaces. It is a 4-wire serial communication protocol commonly used in embedded projects. These four wires are:

  1. MISO (Master In Slave Out): this is the pin through which the module receives data from the master device, which is usually the Arduino or another microcontroller.
  2. MOSI (Master Out Slave In): this is the pin through which the module sends data to the master device.
  3. SCK (Serial Clock): this is the clock pin that synchronizes data transmission between the module and the master device.
  4. CS (Chip Select): this pin is used to select the module and initialize data sending/receiving operations.

What components do we need?

The list of components is not particularly long:

  • a breadboard to connect the NodeMCU ESP32 to other components
  • some DuPont wires (male – male, male – female, female – female)
  • an SG90 servomotor
  • a ILI9341 Display LCD TFT SPI 2.8″
  • and, of course, a NodeMCU ESP32 !

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

While the servomotor looks like this:

The SG90 servomotor used in this project
The SG90 servo motor used in this project

Note the unusual colors used for the connecting wires. In particular we have:

  • the brown wire will go to ground
  • the red wire will go to the 5V pin of the ESP32
  • the orange wire is the control wire and we will connect it to GPIO 16 of the ESP32

TFT LCD display pinout: On the left side there are connections (top) for the touchscreen and (bottom) for the display. On the right side the connections for the SD card module
TFT LCD display pinout: On the left side there are connections (top) for the touchscreen and (bottom) for the display. On the right side the connections for the SD card module

The connections between the display and the ESP32 module will follow the indications in this table:

TOUCHSCREENESP32
T_IRQGPIO27
T_DOGPIO19
T_DINGPIO23
T_CSGPIO14
T_SCKGPIO18
DISPLAYESP32
MISOGPIO19
LED3.3V
SCKGPIO18
MOSIGPIO23
D/CGPIO04
RESETGPIO22
CSGPIO05
GNDGND
VCC5V
Connection table between the display and the ESP32

In this project we will not use the SD card module built into the display. As you can see the touchscreen shares MISO, MOSI and SCK connections with the display.

In the following image you can see the electrical diagram created with Fritzing:

Electrical diagram created with Fritzing
Electrical diagram created with Fritzing

For those who prefer it, below we see the electrical diagram created by EasyEda:

Electrical diagram created with EasyEda
Electrical diagram created with EasyEda

The U2 connector is used to connect the servomotor. In particular, pin 1 corresponds to the control signal while 2 and 3 respectively correspond to 5V and ground.

The sketch

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:

[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
monitor_speed = 115200
upload_speed = 921600
framework = arduino

The libraries (ESP32Servo, TFT_eSPI and TFT_eWidget) can be installed directly by modifying the platformio.ini file as follows:

[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = arduino
monitor_speed = 115200
upload_speed = 921600
lib_deps = 
	bodmer/TFT_eSPI@^2.5.43
	bodmer/TFT_eWidget@^0.0.6
	madhephaestus/ESP32Servo@^1.2.0

We also need to replace a file in the TFT_eSPI library after it has been installed. This is the User_Setup.h file that you can download from the link below:

and, once unzipped, put this downloaded file in the project folder PROJECT_NAME/.pio/libdeps/az-delivery-devkit-v4/TFT_eSPI/ (after perhaps renaming the old file as User_Setup.h_OLD just to preserve it).

PLEASE NOTE:the path PROJECT_NAME/.pio/libdeps/az-delivery-devkit-v4/TFT_eSPI/ is the same for both Linux and Windows.

Finally, you need to download the Free_Fonts.h file from the link below and copy it into the project’s include folder:

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 and the file containing the fonts are included:

#include <Arduino.h>
#include "Free_Fonts.h" // Include the header file attached to this sketch
#include <ESP32Servo.h>
#include <TFT_eSPI.h> 
#include <TFT_eWidget.h>           
#include <SPI.h>

Then the myservo object which manages the servomotor, the GPIO 16 to which it is connected and the servoPosition variable which will store its position value are defined:

Servo myservo;  // create servo object to control a servo
static const int servoPin = 16;
int servoPosition = 0;    // variable to store the servo position

The color scheme of the graphic indicator and the frequency of its updating are then defined:

// Meter colour schemes
#define RED2RED 0
#define GREEN2GREEN 1
#define BLUE2BLUE 2
#define BLUE2RED 3
#define GREEN2RED 4
#define RED2GREEN 5

#define TFT_GREY 0x2104 // Dark grey 16-bit colour

#define LOOP_PERIOD 100 // Display updates every 100 ms

Then we define the tft object that manages the display, the knob object that manages the slider cursor, the definition of REPEAT_CAL which we will set to true every time we want to calibrate the touchscreen and the s1 object that manages the slider:

TFT_eSPI tft = TFT_eSPI(); 

TFT_eSprite knob = TFT_eSprite(&tft); // Sprite for the slide knob

#define REPEAT_CAL true      // put true to perform a touchscreen calibration

SliderWidget s1 = SliderWidget(&tft, &knob);    // Slider 1 widget

When REPEAT_CAL is set to true, the sketch will begin by having us calibrate the touchscreen. It will then print the calibration values ​​on the Serial Monitor to be manually placed in a suitable array called calData present in the setup function. Once the calibration has been done and the array has been filled, we can set REPEAT_CAL to false so as to no longer have to repeat the calibration operation since we have manually inserted the calibration values ​​into the array in the setup function. Obviously, if the calibration does not satisfy us, we are always free to repeat it by setting REPEAT_CAL to true again.

Following is the rainbow function which establishes the colors of the various quadrants of the circular indicator shown on the display and indicating the degrees of rotation:

unsigned int rainbow(byte value)
{
  // Value is expected to be in range 0-127
  // The value is converted to a spectrum colour from 0 = blue through to 127 = red

  byte red = 0; // Red is the top 5 bits of a 16-bit colour value
  byte green = 0;// Green is the middle 6 bits
  byte blue = 0; // Blue is the bottom 5 bits

  byte quadrant = value / 32;

  if (quadrant == 0) {
    blue = 31;
    green = 2 * (value % 32);
    red = 0;
  }
  if (quadrant == 1) {
    blue = 31 - (value % 32);
    green = 63;
    red = 0;
  }
  if (quadrant == 2) {
    blue = 0;
    green = 63;
    red = value % 32;
  }
  if (quadrant == 3) {
    blue = 0;
    green = 63 - 2 * (value % 32);
    red = 31;
  }
  return (red << 11) + (green << 5) + blue;
}

We then find the touch_calibrate function which is invoked when REPEAT_CAL is set to true and which provides the calibration values ​​to be inserted into the calData array present in the setup function:

// Code to run a screen calibration, not needed when calibration values set in setup()
void touch_calibrate()
{
  uint16_t calData[5];
  uint8_t calDataOK = 0;

  // Calibrate
  tft.fillScreen(TFT_BLACK);
      
  tft.setCursor(20, 0);
  tft.setTextFont(2);
  tft.setTextSize(1);
  
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.println("Touch corners as indicated");
  tft.setTextColor(TFT_RED, TFT_BLACK);
  tft.println("Set REPEAT_CAL to false to stop this running again!");

  tft.setTextFont(1);
  tft.println();

  tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);

  Serial.println(); Serial.println();
  Serial.println("// Use this calibration code in setup():");
  Serial.print("  uint16_t calData[5] = ");
  Serial.print("{ ");

  for (uint8_t i = 0; i < 5; i++)
  {
    Serial.print(calData[i]);
    if (i < 4) Serial.print(", ");
  }

  Serial.println(" };");
  Serial.print("  tft.setTouch(calData);");
  Serial.println(); Serial.println();

  tft.fillScreen(TFT_BLACK);
  
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.println("Calibration complete!");
  tft.println("Calibration code sent to Serial port.");

  delay(4000);
}

The ringMeter function actually draws the ring meter on the screen:

// #########################################################################
//  Draw the meter on the screen, returns x coord of righthand side
// #########################################################################
int ringMeter(int value, int vmin, int vmax, int x, int y, int r, const char *units, byte scheme)
{
  // Minimum value of r is about 52 before value text intrudes on ring
  // drawing the text first is an option
  
  x += r; y += r;   // Calculate coords of centre of ring

  int w = r / 3;    // Width of outer ring is 1/4 of radius
  
  int angle = 180;  // Half the sweep angle of meter (300 degrees)

  int v = map(value, vmin, vmax, -angle, angle); // Map the value to an angle v

  byte seg = 3; // Segments are 3 degrees wide = 100 segments for 300 degrees
  byte inc = 6; // Draw segments every 3 degrees, increase to 6 for segmented ring

  // Variable to save "value" text colour from scheme and set default
  int colour = TFT_BLUE;
 
  // Draw colour blocks every inc degrees
  for (int i = -angle+inc/2; i < angle-inc/2; i += inc) {
    // Calculate pair of coordinates for segment start
    float sx = cos((i - 90) * 0.0174532925);
    float sy = sin((i - 90) * 0.0174532925);
    uint16_t x0 = sx * (r - w) + x;
    uint16_t y0 = sy * (r - w) + y;
    uint16_t x1 = sx * r + x;
    uint16_t y1 = sy * r + y;

    // Calculate pair of coordinates for segment end
    float sx2 = cos((i + seg - 90) * 0.0174532925);
    float sy2 = sin((i + seg - 90) * 0.0174532925);
    int x2 = sx2 * (r - w) + x;
    int y2 = sy2 * (r - w) + y;
    int x3 = sx2 * r + x;
    int y3 = sy2 * r + y;

    if (i < v) { // Fill in coloured segments with 2 triangles
      switch (scheme) {
        case 0: colour = TFT_RED; break; // Fixed colour
        case 1: colour = TFT_GREEN; break; // Fixed colour
        case 2: colour = TFT_BLUE; break; // Fixed colour
        case 3: colour = rainbow(map(i, -angle, angle, 0, 127)); break; // Full spectrum blue to red
        case 4: colour = rainbow(map(i, -angle, angle, 70, 127)); break; // Green to red (high temperature etc.)
        case 5: colour = rainbow(map(i, -angle, angle, 127, 63)); break; // Red to green (low battery etc.)
        default: colour = TFT_BLUE; break; // Fixed colour
      }
      tft.fillTriangle(x0, y0, x1, y1, x2, y2, colour);
      tft.fillTriangle(x1, y1, x2, y2, x3, y3, colour);
      //text_colour = colour; // Save the last colour drawn
    }
    else // Fill in blank segments
    {
      tft.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_GREY);
      tft.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_GREY);
    }
  }
  // Convert value to a string
  char buf[10];
  byte len = 3; if (value > 999) len = 5;
  dtostrf(value, len, 0, buf);
  buf[len] = ' '; buf[len+1] = 0; // Add blanking space and terminator, helps to centre text too!
  // Set the text colour to default
  tft.setTextSize(0);


  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  // Uncomment next line to set the text colour to the last segment value!
  tft.setTextColor(colour, TFT_BLACK);
  tft.setTextDatum(MC_DATUM);
  // Print value, if the meter is large then use big font 8, othewise use 4
  if (r > 84) {
    tft.setTextPadding(55*2); // Allow for 3 digits each 55 pixels wide
    tft.drawString(buf, x, y, 4); // Value in middle
  }
  else {
    tft.setTextPadding(3 * 14); // Allow for 3 digits each 14 pixels wide
    tft.drawString(buf, x, y, 4); // Value in middle
  }
  tft.setTextSize(0);
  tft.setTextPadding(0);
  // Print units, if the meter is large then use big font 4, othewise use 2
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  // if (r > 84) tft.drawString(units, x, y + 60, 4); // Units display
  // else tft.drawString(units, x, y + 15, 2); // Units display
  tft.drawString(units, x, y + 25, 4);

  // Calculate and return right hand side x coordinate
  return x + r;
}

We then meet the setup function which appears quite complex:

Initially activate the serial port, activate the display by setting its orientation, background and font:

Serial.begin(115200);
delay(1000);
tft.begin();

tft.setRotation(1);

tft.fillScreen(TFT_BLACK);
tft.setFreeFont(FF18);

Then calibrate the touchscreen if REPEAT_CAL is set to true. In this case it will print the calibration values ​​on the Serial Monitor that we will have to insert into the calData array present in the else. If REPEAT_CAL was set to false, it would not perform the calibration but would perform the else directly using the calibration values ​​previously inserted into the calData array.

// Calibrate the touch screen and retrieve the scaling factors when REPEAT_CAL is true
if (REPEAT_CAL) {
    touch_calibrate();
    tft.fillScreen(TFT_BLACK);
} else {
// Fill this array with values calculated by touch_calibrate() function when REPEAT_CAL is true and printed on Serial Monitor
    uint16_t calData[5] = { 400, 3459, 257, 3471, 7 };
    tft.setTouch(calData);
}

To be more clear in the use of our device:

  • initially we set REPEAT_CAL to true;
  • we compile and upload the sketch;
  • we run the sketch that will make us perform the calibration operation, finally printing the calibration values ​​on the Serial Monitor;
  • we take these values ​​and copy them into the calData array present in the else block (instead of 400, 3459, 257, 3471, 7);
  • let’s now set REPEAT_CAL to false, compile and load the sketch.

When the ESP32 restarts it will no longer make us perform the calibration because it will use the values ​​entered in point 4 of the previous list.

The values ​​indicated in the sketch are those obtained by me and will not necessarily coincide with those obtained by you.

Then follows the definition of the slider parameters and its position on the screen:

// Create a parameter set for the slider
slider_t param;

// Slider slot parameters
param.slotWidth = 4;           // Note: ends of slot will be rounded and anti-aliased
param.slotLength = 200;        // Length includes rounded ends
param.slotColor = TFT_BLUE;    // Slot colour
param.slotBgColor = TFT_BLACK; // Slot background colour for anti-aliasing
param.orientation = H_SLIDER;  // sets it "true" for horizontal

param.knobColor = TFT_WHITE;   // Anti-aliased with slot backgound colour
param.knobLineColor = TFT_RED; // Colour of marker line (set to same as knobColor for no line)

param.startPosition = 0;      // Start position for control knob

param.orientation = V_SLIDER; // sets it "false" for vertical

param.knobWidth = 19;
param.knobHeight = 19;
param.knobRadius = 19/2; // Half w and h so creates a circle

param.sliderLT = 180;     // Top for vertical slider
param.sliderRB = 0;       // Bottom for vertical slider
param.sliderDelay = 200; // 200ms per pixel movement delay (movement is blocking until complete)

// Create slider using parameters and plot at 10,15
s1.drawSlider(10, 15, param);

// Show bounding box (1 pixel outside slider working area)
int16_t x, y;    // x and y can be negative
uint16_t w, h;   // Width and height
s1.getBoundingRect(&x, &y, &w, &h);     // Update x,y,w,h with bounding box
tft.drawRect(x, y, w, h, TFT_DARKGREY); // Draw rectangle outline

delay(1000);
s1.setSliderPosition(100);
delay(1000);
s1.setSliderPosition(0);

The function ends with the setting of the parameters to control the servomotor:

ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
myservo.setPeriodHertz(50);    // standard 50 hz servo
myservo.attach(servoPin, 790, 4000);   // choose these values ​​by trial and error in order to calibrate the two extremes of the servomotor between 0 and 180 degrees

In particular, the values ​​790 and 4000 in the function myservo.attach(servoPin, 790, 4000); they must be determined by trial and error in order to calibrate the extreme values ​​(from 0 to 180 degrees) of the angle assumed by the servomotor rotor.

The sketch closes with the loop function which every LOOP_PERIOD ms detects the position of the slider (and therefore the value to be set in degrees on the servomotor) and sets the position of the servomotor with the function myservo.write(s1.getSliderPosition());. Furthermore, at each cycle, it calls the ringMeter function which, as mentioned above, physically draws the angular meter on the screen:

void loop() {
  static uint32_t updateTime = 0;
  uint16_t t_x = 9999, t_y = 9999; // To store the touch coordinates
  if (millis() - updateTime >= LOOP_PERIOD) 
  {
    updateTime = millis();

    if( tft.getTouch(&t_x, &t_y, 250) ) {
      if (s1.checkTouch(t_x, t_y)) {
        Serial.print("Slider = "); Serial.println(s1.getSliderPosition());
        myservo.write(s1.getSliderPosition()); 
      }
    }

    // Set the the position, gap between meters, and inner radius of the meters
    int xpos = 0, ypos = 5, gap = 4, radius = 52;


    // Draw a large meter
    xpos = 480/2 - 160, ypos = 0, gap = 15, radius = 100;

    // Comment out above meters, then uncomment the next line to show large meter
    ringMeter(s1.getSliderPosition(),0,180, xpos,ypos,radius," degrees",GREEN2RED); // Draw analogue meter
  }
}

Video of the operation

The video initially shows the calibration phase and then the actual use of the device.

Newsletter

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
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
Scroll to Top