Previously I have learnt how to operate a TCPWM using Device Configurator. In this blog, I will try to control a servo motor using a TCPWM for PSoC6.
BOM: PSoC6 WiFi-BT Pioneer Kit, a servo motor, and some jumper wires.
As previous, I created an Empty_PSoC6_App from the code example and opened up the Device Manager:
Setting clock divider to 10000 to get a 10kHz clock.
Setting up tcpwm1:
I noticed that there is a Enable Compare Swap option available in the Device Manager and I decided to enable it to test out what will happen.
After enabling it, I was able to enter a second compare value Compare 1 for my tcpwm1.
In this case, I set my period to 200 counts to represent 20ms under a 10kHz clock and 4 and 24 to represent 0.4ms and 2.4ms for the Compare 0 and Compare 1 values respectively.
Notice that the 0.4ms and 2.4ms are the minimum and maximum pulse width for my servo to position it at 0 and 180 degree respectively. I got these values by referring the data sheet of my servo and different servo may have different minimum and maximum pulse width required and it is advisable for you to check the datasheet of your servo and change the value if needed.
Next, I enable the Invert PWM_n Output as the PWM initially starts with and low and switches to high when the count reaches the compare value.
And lastly, assign the tcpwm1 to a digital output pin and save the configurations.
The next thing to do is finding out the function that can be use to trigger the swap between the Compare 0 and Compare 1 values.
As previous, I clicked on the Documentation link and get directed to PSoC6 PDL API Reference page.
Since it is something related to TCPWM, I started searching under PDL API Reference > TCPWM (Timer Counter PWM) > Timer/Counter PWM >Functions
I noticed that there is a function that might be related to what I'm searching. The Cy_TCPWM_Counter_EnableCompareSwap function.
So I clicked on that and check out what's inside.
Fortunately, I found that the last line of the Function Usage state that the Compare 0 and Compare 1 values can be swapped using Cy_TCPWM_TriggerCaptureOrSwap function and this is what I was looking for.
But I still have no idea of how the syntax of this function should be, so I copy and paste the function into the search box at the top right corner of the documentation page.
This is what I have got:
I don't really understand what should be the second input argument for the function, but judging from the example in Function Usage, I will try to input it with 0UL and 1UL and see what is going to happen.
After trial and error, I found out that Cy_TCPWM_TriggerCaptureOrSwap(tcpwm1_HW, 1UL); will swap the compare value for the tcpwm1 between Compare 0 and Compare 1.
Below is the final code that I used to turn the servo right and left every 3 seconds.
#include "cy_pdl.h" #include "cycfg.h" int main(void) { /* Initialize the device and board peripherals */ __enable_irq(); init_cycfg_all(); Cy_TCPWM_PWM_Init(tcpwm1_HW, tcpwm1_NUM, &tcpwm1_config); // initialize tcpwm Cy_TCPWM_PWM_Enable(tcpwm1_HW, tcpwm1_NUM); // enable tcpwm1 Cy_TCPWM_TriggerStart(tcpwm1_HW, tcpwm1_MASK); //Start the tcpwm1 (initially 0.4ms high per cycle) (servo positioned at right) for (;;) { Cy_SysLib_Delay(3000); // delay for 3000ms Cy_TCPWM_TriggerCaptureOrSwap(tcpwm1_HW, 1UL); // tcpwm1 swap between 2.4ms(left) and 0.4ms(right) high per cycle } }
GitHub link: https://github.com/wanfp97/ServoControl
After programming and running the code on PSoC6, the servo turned left and right every 3 seconds as it is expected.