element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Embedded and Microcontrollers
  • Technologies
  • More
Embedded and Microcontrollers
Blog PID temperature controller for the EasyL1105 MSPM0 board - Pt. 3: PWM
  • Blog
  • Forum
  • Documents
  • Quiz
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Embedded and Microcontrollers to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 2 Oct 2025 6:27 PM Date Created
  • Views 407 views
  • Likes 5 likes
  • Comments 25 comments
  • MSPM0L1105
  • MSPM0
  • easyL1105
  • texas instruments
Related
Recommended

PID temperature controller for the EasyL1105 MSPM0 board - Pt. 3: PWM

Jan Cumps
Jan Cumps
2 Oct 2025
PID temperature controller for the EasyL1105 MSPM0 board - Pt. 3: PWM

 shabaz designed a development kit for the recent Texas Instruments MSPM0 microcontroller series. 
This 4 part blog series documents the steps to design a PID temperature controller. Part 3: add PWM to generate a PID controlled output.

image
(post that introduces the kit)

Goal of this 3nd post

  • add PWM generation logic, based on  PWM example for the EasyL1105 MSPM0 board 
  • drive duty cycle from PID's output signal

not a goal of this post: have the PID regulation working 100%.

Set up PWM SysConfig

The code uses timer TIMG1, channel 0, to drive PA26. There's no interrupt involved. The duty cycle gets adjusted in the regulation loop.

At this point, I have set the PWM period count to 65535, in an attempt to have the output range identical (but 32768 offset) to the input. 

image

image

Code

note: this design doesn't regulate perfectly yet. At this point in the blog series, all modules are in place and they are tied to the PID. But finetuning PID parameters, input, output, ADC and PWM settings is for post 4.

void perform_pwm() {
    DL_TimerG_setCaptureCompareValue(PWM_0_INST, i32_Output_PID + 32768,
        DL_TIMER_CC_0_INDEX); // update ccr0 value  
}


int main(void) {
    SYSCFG_DL_init();

    // /* timer 5 interrupt ticks per second */ 
    // /* Enable Timer0 NVIC */
    NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);

    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
    gCheckADC = false;

	/* Initialize the parameters of PID */
	Initialize_PID_Parameter();

    /* Start PWM */
    DL_TimerG_startCounter(PWM_0_INST);

    /* Start Timer counting */
    DL_TimerG_startCounter(TIMER_0_INST);    

    while (1) {
        if (perform) {
            perform = false;
            DL_GPIO_setPins(GPIO_GRP_LEDS_PORT,
                GPIO_GRP_LEDS_PIN_LED_GREEN_PIN);

            perform_adc();
            
            perform_pid();

            perform_pwm();

            DL_GPIO_clearPins(GPIO_GRP_LEDS_PORT,
                GPIO_GRP_LEDS_PIN_LED_GREEN_PIN);
        }
    }
}

void perform_pid() {
    /* Execute PID control in every TM0 interrupt. */
    i32_Output_PID = PID(&PID_Var, i32_Target_Command, gAdcResult);
}

If you compare the perform_pid() with the one from the previous post, you 'll see that it now uses ADC as feedback, and output to drive the PWM.

Demo circuit

I used the same (random) low pass filter as in  MSP432 and TI-RTOS: PID Library Part 2 - Real World Example , to turn the PWM into a DC signal.

image

The filter sits between PWM out  (P26) and ADC in (PA25).

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

ccs project for EasyL1105: pid_EasyL1105_20251002_02.zip

Related posts

  • Sign in to reply

Top Comments

  • Jan Cumps
    Jan Cumps 17 days ago in reply to colporteur +1
    It's a Control Technique algorithm. A function that will try to regulate a process' output, in relation to a desired setting. First used in 1911. It requires that you give it feedback on the current…
  • Jan Cumps
    Jan Cumps 12 days ago

    To make it easier to experiment, I'm adding a UART interface, to set p, i, d and target. Via a terminal or pc software. Maybe I add an option to plug in an external PID (LabVIEW?) instead of the firmware one...

    volatile PIDC_T PID_Var = {C_Init_Err, C_Init_I, C_Init_Last_Err, C_Kp, C_Ki, C_Kd, C_Out_Limit};
    volatile int32_t i32_Target_Command, i32_Output_PID;
    
    void cbpidkp(char* string) {
      PID_Var.i32_Kd = GUIComm_ReadInt32(string);
    }
    
    void cbpidki(char* string) {
      PID_Var.i32_Ki = GUIComm_ReadInt32(string);
    }
    
    void cbpidkd(char* string) {
      PID_Var.i32_Kp = GUIComm_ReadInt32(string);
    }
    
    void cbpidtc(char* string) {
      i32_Target_Command = GUIComm_ReadInt32(string);
    }
    
    const tGUI_RxCmd GUI_RXCommands[] = {
      {"pkp", cbpidkp}, // Kp
      {"pki", cbpidki}, // Ki
      {"pkd", cbpidkd}, // Kd
      {"ptc", cbpidtc}, // target
    };
    
    int main(void) {
      /* Initialize peripherals */
      HAL_System_Init();
    
      /* Initialize GUI layer */
      GUI_Init();
    
      /* Initialize the RX command callbacks */
      GUI_InitRxCmd(&GUI_RXCommands[0],
        (sizeof(GUI_RXCommands) / sizeof(GUI_RXCommands[0])));
    
      // ...
    }
    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps 12 days ago in reply to Jan Cumps

    The handler:

    https://dev.ti.com/tirex/explore/node?node=A__ADJ0T9itsmRPt9nb8QQy9A__MSPM0-SDK__a3PaaoK__LATEST&placeholder=true

    It's called by UART rx interrupt for each byte received. It builds a buffer. 

    When a newline is detected, the handler sends the data to the JSON parser. If it's invalid json, or an attribute that we didn't register a callback for, the data is ignored. Else, the correct callback for that data point is called, with the string representation of the received data.

    Then, there are lib functions to retrieve bool, uint, ... that you can use in the callback to turn that into the data type you need.

    Example of registering a callback for a bool variable and a uint16

    // ...
    
    extern volatile bool bEnableSwitch;
    extern volatile _q qIncrement;
    
    // ***** Application Callback Functions to Process data *****
    void callback_boolEnable(char* string)
    {
        // Example to receive a boolean
        bEnableSwitch = GUIComm_ReadBool(string);
    }
    
    void callback_QMathData(char* string)
    {
        qIncrement = GUIComm_ReadUInt16(string);
    }
    
    
    const tGUI_RxCmd GUI_RXCommands[] = {
        {"bEnable", callback_boolEnable},
        {"u16Data", callback_QMathData},
    };
    
    int main() {
    
        // ...
        GUI_InitRxCmd(&GUI_RXCommands[0], (sizeof(GUI_RXCommands) / sizeof(GUI_RXCommands[0])));
        
        // ... 
    }
    

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • kmikemoo
    kmikemoo 12 days ago in reply to Jan Cumps

     Jan Cumps I have only ever heard of PID referencing control systems (40-ish years).  In the 1980's and 90's, we typically only were able to adjust the Proportional - also called Gain.  There may have been another term that I can't think of right now.  Integral and Derivative were set in firmware.  As technology advanced, we were allowed to adjust the I & D.  I can't count the number of systems I fixed by just turning the P down to 30% to 35%.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps 12 days ago in reply to shabaz

    > a lot of JSON parsers are unhelpful if the complete content is not available, and so you either have the choice to wait till all the content arrives (and hard to know that! does one count braces for instance, or send non-standard character sequences),

    The one in the TI SDK acts whenever it gets a newline. 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz 12 days ago in reply to Jan Cumps

    Funnily enough, I used JSON for a similar thing a while back, I've not written a blog on it yet. I used JSON to send a whole variety of attributes values from the microcontroller (Pi Pico in that case) to the PC, and pull out particular attributes and send to particular charts (for instance, you may want occasional board temperature reports to go into a different chart than say a Voltage measurement. One major downside was that since JSON isn't traditionally streamed, a lot of JSON parsers are unhelpful if the complete content is not available, and so you either have the choice to wait till all the content arrives (and hard to know that! does one count braces for instance, or send non-standard character sequences), or start processing earlier with your own custom parser that accepts invalid partial content. I can't recall what I did on the Python end (currently traveling without PC). Although it functioned, my code could be improved a lot, but I have not really used that code much, since it turned out I was unlikely to require such rich functionality that can split to multiple charts. But I'm sure for a real solution, people may well have that need for debugging or performance monitoring more complex systems.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube