Servo Control Using PWM(MCAL Driver)
Table of Contents
Overview
Welcome to series of Sensor & Module Interfacing using AUTOSAR MCAL drivers. In this blog, we’ll learn how to interface an SG90 Servo Motor and control it with Autosar MCAL PWM Driver using Handson practical by developing the Embedded Software code using Autosar Tech Stack. We will be using ElecronicsV3 Development Board which has S32K144 Automotive Microcontroller.
What is Servo?
The servo is a special motor used to move mechanical parts precisely. Unlike standard motors that continuously rotate after disconnecting it from the power supply, servos can position themselves at specific angles or positions, making them ideal for tasks requiring accuracy. This precision is achieved through a feedback system that constantly watches over the position of the output shaft, adjusting it as needed to match the required position. Widely used in robotics, automation, and hobbyist projects like remote-controlled cars and airplanes.
How to control Servo Motors Via Microcontroller's?
Servo Motors are controlled using Pulse Width Modulation (PWM) signals, where the position of the servo is determined by the width of the High Signal pulse in the PWM signal. This width is termed as Duty Cycle in PWM Signals. More the duty cycle, more rotation servo motor will do. And the frequency of PWM signal, will enable the Servo motor to interpret these commands. Different types of servos operate at different PWM frequencies and PWM duty cycle values for control operation.
Most common servo motor SG90 operates at 50hz PWM Frequency and needs Duty Cycle of 2.5% to 12.5% to rotate the servo motor from 0 degree to 180 degree. Meaning SG90 servo motor need PWM signals of frequency 50hz to start its rotation. And to rotate the servo motor to different position, we need to duty cycle of 2.5 % to 12.5% of this 50hz PWM signals.
PWM Frequency: Most hobby servos operate at a standard frequency of around 50 Hz, which corresponds to a pulse every 20 milliseconds (ms). However, specialized servos for high-speed applications or industrial uses may operate at higher frequencies to achieve faster response times.
- Standard Servos: Typically use 50 Hz.
- High-Speed Servos: Might use higher frequencies, up to 200 Hz or more for quicker positioning and response.
PWM Duty Cycle (High Signal Pulse Width): The High Signal pulse width in a PWM signal determines the position of the servo. For standard servos:
- A High Signal pulse width of 0.5 ms corresponds to a 0-degree position.
- A High Signal pulse width of 1.5 ms corresponds to the 90-degree position (neutral or middle).
- A High Signal pulse width of 2.5 ms corresponds to the 180-degree position.
About SG90 Servo Motor
- The SG90 servo motor operates between 4.8V and 6.5V, with 5V being typical. It provides 2.5 kg/cm torque, meaning it can lift 2.5 kg at a 1 cm distance; closer or farther load placements adjust this capacity accordingly. The SG90 rotates from 0° to 180°, making it ideal for half-circle movements, though continuous rotation options exist for full-circle needs. Its plastic gears are suitable for light projects; for heavier-duty applications, consider a metal-gear servo for added durability.
- – Orange wire: To be connected with the FTM output pin of the microcontroller.
– Red wire: To be connected to VCC/power supply(5V).
– Brown wire: To be connected to the ground reference of the microcontroller. - Voltage: 4.8V to 6.6V
Current: ~550 mA
Frequency(for controlling): 50Hz
Connection Diagram
Now enough of theory and overview, lets come down to DIY part for controlling Servo Motor via Autosar MCAL PWM Driver. For doing, so we will be using ElecronicsV3 Development board which has S32K144 Automotive Microcontroller on it. And as S32K144 is automotive MCU, it has Autosar MCAL layer complaint based RTD stack available for all of its peripherals.
Below are the connection diagram for ElecronicsV3 Development Board with Servo Motor. We have connected PWM Signal pin of servo motor with PTB12 pin of S32K144 MCU on ElecronicsV3 Development Board.
Now for controlling the Servo Motor, we need PWM signals. In Microcontroller PWM signals are generated by their TIMER peripheral. In S32K144 MCU, there is FlexTIMER Peripheral which is a Timer peripheral in it. We will be using it for generating the PWM Signal. And to use the FlexTIMER peripheral we will be needing the RTD files of it based on S32K144 MCU. And this RTD stack that we are going to use is of Autosar MCAL Layer complaint PWM RTD Driver for S32K144 MCU.
Using of this RTD will give us global level understanding on how to generate PWM signals via any Automotive MCU using Autosar Tech Stack be it of NXP, Infineon, STM and etc. To know more about Autosar and Autosar MCAL Layer, refer to this blog.
Before following this DIY blog further, it is highly recommended to enroll and complete
this course "AutoCal Course -V1". This course will teach you and make you learn how to
use basic Autosar MCAL Layer Driver's, in depth explanation of their configurations from
GUI tool, functional concepts and requirments of MCAL Driver's, Data Type's & API explanation of different MCAL
Driver's API's and their use cases. It is Foundational course for learning Autosar Tech stack
and make one skill-able in core technology of Automotive Softwrae.
In this DIY project blog, we will not be dwelling into Autosar MCAL Driver GUI configuration’s, we will directly jump to application code development, debugging and usage of MCAL Driver API’s for building real time projects, parameters that has to be send to use those API’s and chronology of different MCAL APIs for building application code and Complex Device Driver from them.
Getting Started
In terms of Software, we will be needing desktop application S32 Design Studio IDE v3.4 for Embedded Software development for ElecronicsV3 Development Board. Apart from S32 Design Studio IDE, we will also be needing Autosar MCAL RTD software package of S32K1xx MCU installed in S32 DS so as to use the PWM peripheral of S32K144 MCU using Autosar MCAL RTD stack. The Software installation and setup process is explained and stated in this blog, in great detail and step by step process.
This is one time process only, if you have been following our blogs and courses most probably you must have done this setup process.
We are going to move towards the embedded software understanding, development and debugging for SG90 Servo motors via Autosar MCAL PWM Driver with S32K144 MCU.
Step 1: Cloning the Repo from our GettoByte Github
Download the ElecronicsV board Demo codes from the GitHub Repo of Gettobyte Technologies by cloning it into your Host PC/laptop via git version control.
This is our central and main repo; we are developing number of functional demo codes via Autosar MCAL Driver’s, and we are committing them on different branches. One can see list of our branches:
now switch to G2B_SG90_Servo_Motor Branch to get the SG90 servo motor Code with Autosar MCAL PWM Driver.
After that you can open the file explorer to see the Folder Contents of the Repo by start . command.
And now navigate to Sensor_Module Folder and their you will see SG90 Servo motor Demo code
Step 2: Opening the cloned repo in S32 Design Studio
After getting the repo, now we are going to open the GitHub repo Example projects in S32 Design Studio IDE. Make sure that you have downloaded the S32 Design Studio IDE v3.4 and S32K1 RTD package versions 1.0.0 and 1.0.1 which we will be using across all of our demo codes with S32K144 MCU and ElecronicsV3 Development Board.
Follow the below steps mentioned in slider to Open the SG90 Servo Motor Example project in S32 Design Studio after downloading the Example projects from step 1.
After that one can see the Example project in S32 DS. In which under Project Explorer view one can see all the folder’s of our Demo Project.
Step 3: Analyzing the Code
In Project Explorer, you can see all the files and folders of our Autosar MCAL Project. To give an high-level overview and understanding of all folders, refer ro below pic.
Out of all these folders, main folder’s of our concern would be: RTD, generate, S_M_Driver and src folder.
- RTD: has all RTD files (.c/.h) based on Autosar MCAL Compliant standard for configured peripherals.
- generate: has all generated configuration files according to Autosar MCAL Complaint Data Types, which stores information on how the configured peripherals have to be used.
- S_M_Drivers: Contain the external sensor_module library file, which is built on Autosar MCAL Driver API’s.
- Src: has our main application files. E.g example 1.c, example2.c and etc.
Autosar MCAL Driver Configuration for S32K144 Microcontroller’s is done via the .mex file. The .mex file is kind of like Code configuration file for NXP S32K1xx MCU’s, via which we can configure number of software stack’s and MCU components (like clock and pins) in GUI format. This .mex file also fully supports the Autosar MCAL Driver configuration. This gives us enablement to use and learn Autosar MCAL Driver’s menu section and configuration’s without the need of tools like EbTresos, DaVinci and ARXML files.
As our moto of these DIY projects and series is to understand the Autosar MCAL Driver’s, their configuration’s and how to use them so as to build skill set in Autosar Tech Stack. So NXP S32 Design Studio has integrated Autosar MCAL GUI for configuring NXP S32K MCU peripheral drivers. And this integrated GUI is accessed via .mex file of the project created in S32DS.
So, in our demo projects, though we are working with Autosar MCAL Driver but we are not going to use ARXML files, EBTresos and etc tools. As those tools are expensive, increases the overhead for learning core Autosar MCAL Driver concepts. And by using the .mex file based MCAL GUI, one can see changes in configuration code files as we make changes in GUI. Which makes thing relatively easy and hassle from learning point of view.
Now in our DIY Demo project series, we will not dwell into understanding of configuration of MCAL Driver’s, we will be focusing on usage of MCAL API’s, data types and chronology in which MCAL API’s has to be used for building automotive application’s.
For understanding the MCAL Driver concepts and configuration’s. refer to our Autosar MCAL Course: Autocal-V1.
Code and Explanation
Now we will dwell into example1.c file our project and understand how application code of SG90 Servo motor is built and developed for rotating it to different angles via Autosar MCAL PWM Driver API’s.
/* Including necessary configuration files. */
#include "Mcal.h"
#include "Clock_Ip.h"
#include "Port.h"
#include "Pwm.h"
/*Delay function*/
void TestDelay(uint32 delay);
void TestDelay(uint32 delay)
{
static volatile uint32 DelayTimer = 0;
while(DelayTimer<delay)
{
DelayTimer++;
}
DelayTimer=0;
}
uint16_t pwm_duty_cycle(uint8_t duty_cycle_percent)
{
uint16_t duty_cycle = ((32768 * duty_cycle_percent)/100);
return (duty_cycle);
}
int main(void)
{
/********************************Clock Configuration for MCU****************************/
Clock_Ip_StatusType clockStatus;
clockStatus = Clock_Ip_Init(&Mcu_aClockConfigPB_BOARD_InitPeripherals[0]);
while (clockStatus != CLOCK_IP_SUCCESS)
{
clockStatus = Clock_Ip_Init(&Mcu_aClockConfigPB_BOARD_InitPeripherals[0]);
}
/* Busy wait until the System PLL is locked */
while (CLOCK_IP_PLL_LOCKED != Clock_Ip_GetPllStatus());
Clock_Ip_DistributePll();
/***************************************************************************************/
/* Initialize all pins using the Port driver */
Port_Init(NULL_PTR);
/* Initialize all data structure and function of PWM */
Pwm_Init(&Pwm_Config_BOARD_InitPeripherals);
/*Sets the our desired frequency 50Hz for Servo*/
Pwm_SetPeriodAndDuty(0,40000,pwm_duty_cycle(50));
TestDelay(700000);
/* As our Servo, responds only from 0.5ms(2.5% Duty Cycle)
* to 2.5ms(12.5% Duty Cycle), we create a up-down counter
* for simulation
*/
double count = 2.5;
/*
* Direction = 0(UP) means the counter goes from 2.5 to 12.5
* whereas
* Direction = 1(DOWN) means the counter goes from 12.5 to 2.5
*/
uint8 direction = 0;
/*Main Loop*/
for (;;) {
if(direction == 0)
{
if(count <= 12.5){
Pwm_SetDutyCycle(0, pwm_duty_cycle(count));
TestDelay(700000);
count += 0.5;
}
else{
direction = 1;
}
}
else if(direction == 1)
{
if(count >= 2.5){
Pwm_SetDutyCycle(0, pwm_duty_cycle(count));
TestDelay(700000);
count -= 0.5;
}
else{
direction = 0;
}
}
}
}
Breaking down the code
#include "Mcal.h"
#include "Clock_Ip.h"
#include "Port.h"
#include "Pwm.h"
- Declaration of important and used header files where
- “Mcal.h” is the header for MCAL standards
- “Clock_Ip.h” is the header for Clock configuration.
- “Port.h” is the header for Pins and Port configuration.
- “Pwm.h” is the header for PWM configuration.
void TestDelay(uint32 delay);
void TestDelay(uint32 delay)
{
static volatile uint32 DelayTimer = 0;
while(DelayTimer
2. Function prototyping for a delay function that counts the parameter and decrementing it.
uint16_t pwm_duty_cycle(uint8_t duty_cycle_percent)
{
uint16_t duty_cycle = ((32768 * duty_cycle_percent)/100);
return (duty_cycle);
}
3. Function prototyping for an input to percentage duty cycle conversion.
/*************Clock Configuration for MCU**************************/
Clock_Ip_StatusType clockStatus;
clockStatus = Clock_Ip_Init(&Mcu_aClockConfigPB_BOARD_InitPeripherals[0]);
while (clockStatus != CLOCK_IP_SUCCESS)
{
clockStatus = Clock_Ip_Init(&Mcu_aClockConfigPB_BOARD_InitPeripherals[0]);
}
/* Busy wait until the System PLL is locked */
while (CLOCK_IP_PLL_LOCKED != Clock_Ip_GetPllStatus());
Clock_Ip_DistributePll();
/*******************************************************************/
4. Function for clock configuration and initialization to CPU and different peripherals.
/* Initialize all pins using the Port driver */
Port_Init(NULL_PTR);
5. Function for MCU Port initialization, without this function pins of the microcontroller will be settled for usage.
/* Initialize all data structure and function of PWM */
Pwm_Init(&Pwm_Config_BOARD_InitPeripherals);
6. Function for PWM initialization where the passed parameter is the structure of defined requirements in the .mex file.
Pwm_SetPeriodAndDuty(0,40000,pwm_duty_cycle(50));
TestDelay(700000);
7. Function for PWM Frequency and Duty Cycle resetting, according to the user requirement, followed by TestDelay which provides settlement time between multiple functions. This settlement time is not necessary just an addition.
double count = 2.5;
uint8 direction = 0;
8. Variable declaration for usage in the main loop. Our SG90 Servo motor runs at 50Hz with a response to 0.5ms to 2.5ms duty cycle, in percentage, it means 2.5% to 12.5% of the duty cycle. So, we’ll start with a 2.5% duty cycle stored in the ‘count’ variable. The ‘direction’ variable is to acknowledge whether Servo Motor is moving clockwise or anti-clockwise.
for (;;) {
if(direction == 0)
{
if(count <= 12.5){
Pwm_SetDutyCycle(0, pwm_duty_cycle(count));
TestDelay(700000);
count += 0.5;
}
else{
direction = 1;
}
}
else if(direction == 1)
{
if(count >= 2.5){
Pwm_SetDutyCycle(0, pwm_duty_cycle(count));
TestDelay(700000);
count -= 0.5;
}
else{
direction = 0;
}
}
}
9. This is the main loop consisting of the pattern where the motor starts from the 0-degree position and steps clockwise until reaches 12.5% duty cycle. After hitting the 12.5% duty cycle, it starts stepping anti-clockwise step-wise. In our case, the step is taken as 0.5. In short, Servo Motor sweeps from 0 degrees to 180 and back and forth with steps of 0.5% duty cycle.
Building The Project
- For compiling the project, you have to right-click on the project then navigate to the option”Build Project” and click it.
- When your project is completed and ready to compile. You have to build the project to check the compilation errors.
- Compilation errors and warnings related to the project can be seen in the “Console” view, where you can also check other information like the size and format of the code.
Debugging and Flashing
–> This is the last and final step of project development where we program and debug the final application into microcontroller for execution of our DIY Project.
–>In ElecronicsV3 development board, which we are using for doing DIY projects, we have an on-board Jlink debugger that provides hassle free debugging and programing over type-c cable. The Onboard debugger can easily be used just by connecting the Type-C cable port present in elecronicsV3 to the USB Port of the Host PC.
–> As you connect it, in the device manager in your PC you will Jlink Driver detected under the USB drop down, as shown in figure.
Debug Configuration
Now in our S32 Design studio, where we have opened the SG90 servo motor example project and build its application code into executable file, we will do the Debug Configuration of our project so as to program and debug the generated elf file into the MCU S32K144. And for doing so, follow the below step:
Now you are all set. just click that debug button and your code will be flashed into the S32K144 MCU and you’ll enter the debug mode where you can see example1.c source file and in that program is stopped at starting of main() function:
Possible Errors
Demo Project Elf is not properly linked to S32 DS Debug Windows.
Step 1: Right Click on the project name under debug view.
Step 2: Terminate and Relaunch the Debug Session
Step 3: Now project will be opened in Debug Mode successfully.
Step 4: If Problem Persists, erase the Firmware on the chip via Jlink Flash Lite Tool as told in Error 2. And then debug the project again.
Debugging The Code
Now this is one of the best feature of using S32 Design Studio IDE and working on Microcontroller like that of S32K144 MCU, that we can debug our software programs line by line in real time by executing them in hardware and analyzing the flow/behaviors of our software programs. This we can’t do on Arduino IDE kind of frameworks (for those who are working on Arduino/ESP platforms).
Now we are going to put the breakpoints at different locations of the code to understand the code behaviour and working of ADC MCAL PWM API’s.
We are going to put breakpoints at 3 locations:
- Breakpoint at line 33 and then show what is Mod and Counter register value and show freuency generating at logic analyzer of 50 hertz
- Breakpint at line 55 and then show that count value increases, so does CnV register value and PWM Signal at logic analyzer
- Breakpint at line 67 and then show that count value decreases and so does CnV register value and PWM signal at logic analyzer.
Running the Code with Debugging
Marked areas can help you detect whether your code is running continuously without any breakpoints.
Conclusion
In this blog, we learned how a Servo works internally by seeing a side view. Then, we followed the response region of our Servo Motor SG90, which requires a 50Hz frequency, where the shaft moves from 0-degree to 180-degree in the range of 0.5ms to 2.5ms. After this datasheet knowledge, we saw how to build a basic code of PWM to control the servo and move it in steps.
Similarly, you can follow more sensor and module interface blogs for learning through practical implementation.
More DIY Projects using Autosar MCAL Driver's
ADC Control over S32K144(MCAL Driver)
Reading Analog signals/reading using ADC driver of Autosar MCAL layer using ElecronicsV3 Board(S32K144 MCU)
PWM Output Control over S32K144(MCAL Driver)
Generating PWM signals of varying Frequency and Duty Cycle via PWM Driver of Autosar MCAL using ElecronicsV3 Board ( S32K144 MCU)
GPIO Control over S32K144(MCAL Driver)
Interfacing LEDS and Switches via Port Driver of Autosar MCAL Layer using ElecronicsV3 Board(S32K144 MCU)
IOT Enablement for S32K144(using MCAL Driver)
Interfacing of ESP8266 Wi-Fi Module as Web Client using UART Driver of Autosar MCAL Layer via ElecronicsV3 Board (S32K144 MCU)
Servo Control Using PWM(MCAL Driver)
Interfacing MG90 Servo Motor using PWM Driver of Autosar MCAL Layer via ElecronicsV3 Board (S32K144 MCU)
Freemaster Visualisation for ADC Peripheral(MCAL Based)
Integration of FreeMaster Software with ElecronicsV3 Board (S32K144 MCU) via UART Driver of Autosar MCAL Layer
Add Your Heading Text Here
Author: Rohan Singhal
Author