- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
now I have a touch sensor and a LED. The touch sensor enables the LED. Now I want to preset the brightness of the LED. How can I do this?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
It was my mistake, before setting period PWM_Start() or PWM_Init() must have been called.
Note: PWM_Init() is called at the first time PWM_Start() is called
And in the PWM_Init(), period is overwritten to the value set in the GUI.
So I should have written
=================
PWM_Start() ;
PWM_Stop() ; /* before changing the period, PWM must be stopped */
PWM_WritePeriod(PWM_PERIOD) ;
PWM_WriteCompare(led_level) ;
PWM_Start() ;
=================
To test if PWM_WritePeriod() really works,
I made following test program.
schematic
pins
main.c
Note: To handle UART interactions I cheated by using my tty_utility
tty_utils a utility sample for CLI type program
================
#include "project.h"
#include "stdio.h"
#include "tty_utils.h"
#define PWM_PERIOD 1000 /* 65535 (0xFFFF) was too much for this purpose */
#define LED_OFF 0
#define LED_DIM 10 /* could be anywhere from 1 to 1000 */
uint16_t led_period = PWM_PERIOD ;
uint16_t led_level = LED_DIM ; /* set default to ON */
void config_pwm(uint16_t period, uint16_t compare) ;
typedef void (*func_ptr_type)(char *str) ;
void do_help(char *str) ;
void do_period(char *str) ;
void do_compare(char *str) ;
void do_pwm(char *str) ;
void do_status(char *str) ;
typedef struct _cmd_func_st {
char *cmd ;
func_ptr_type func ;
char *description ;
} cmd_func_type ;
cmd_func_type cmd_list[] = {
{ "help", do_help, "Print Help Message" },
{ "period", do_period, "Set PWM Period value, period 1000" },
{ "compare", do_compare, "Set PWM Compare value, compare 10" },
{ "pwm", do_pwm, "Set PWM Config period and compare, pwm 1000 10" },
{ "status", do_status, "Show current setting" },
{ 0, 0, 0 }
} ;
void do_help(char *str)
{
(void) str ;
int i = 0 ;
print("=== command ===\n\r") ;
for (i = 0 ; cmd_list.cmd ; i++ ) {
snprintf(str, STR_BUF_LEN, "%10s : ", cmd_list.cmd) ;
print(str) ;
print(cmd_list.description) ;
print("\n\r") ;
}
}
void do_period(char *str)
{
sscanf(str, "%*s %hd", &led_period) ;
config_pwm(led_period, led_level) ;
}
void do_compare(char *str)
{
sscanf(str, "%*s %hd", &led_level) ;
config_pwm(led_period, led_level) ;
}
void do_pwm(char *str)
{
sscanf(str, "%*s %hd %hd", &led_period, &led_level) ;
config_pwm(led_period, led_level) ;
}
void do_status(char *str)
{
uint16_t period, compare ;
period = PWM_ReadPeriod() ;
compare = PWM_ReadCompare() ;
print("=== PWM Status ===\n\r") ;
snprintf(str, STR_BUF_LEN, "Period: %hd\r\n", period) ;
print(str) ;
snprintf(str, STR_BUF_LEN, "Compare: %hd\r\n", compare) ;
print(str) ;
}
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
CapSense_1_Start() ;
UART_Start() ;
tty_init() ;
splash("CapSense and LED PWM Test") ;
PWM_Start() ;
}
void config_pwm(uint16_t period, uint16_t compare)
{
PWM_Stop() ;
PWM_WritePeriod(period) ;
PWM_WriteCompare(compare) ;
PWM_Start() ;
}
func_ptr_type get_func(char *cmd)
{
int i ;
for (i = 0 ; cmd_list.cmd ; i++ ) {
if (strcmp(cmd, cmd_list.cmd) == 0) {
break ;
}
}
return( cmd_list.func ) ;
}
void do_command(char *str)
{
char command[STR_BUF_LEN+1] ;
func_ptr_type func ;
sscanf(str, "%s", command) ;
func = get_func(command) ;
if (func) {
func(str) ;
} else {
do_help(str) ;
}
}
int main(void)
{
init_hardware() ;
config_pwm(led_period, led_level) ;
prompt() ;
for(;;) {
if (get_line()) {
do_command(str) ;
prompt() ;
}
if (!CapSense_1_IsBusy()) {
CapSense_1_ProcessAllWidgets() ;
if (CapSense_1_IsSensorActive(CapSense_1_BUTTON0_WDGT_ID, CapSense_1_BUTTON0_SNS0_ID)) {
if (led_level == LED_OFF) {
led_level = LED_DIM ;
} else {
led_level = LED_OFF ;
}
PWM_WriteCompare(led_level) ;
CyDelay(500) ; /* cheap debouncing */
}
CapSense_1_ScanAllWidgets() ;
}
}
}
================
Tera Term log
When the program started, as Period = 1000, Compare = 10 and the PWM Clock = 2MHz
About 2KHz pulse(s) are generated
When I entered "pwm 2000 1000" to the prompt (>)
Now frequency is 2KHz and as compre value is 1000 the duty is 50%
When I entered "pwm 3000 1000"
The frequency was about 668Hz and duty is about 30%
When I entered "pwm 1500 1000", frequency was about 1.336 kHz
and duty is about 67%.
So the bad news is that I had a bug in my previous program,
and the good news is PWM_WritePeriod() does its work 😉
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi UlMo_4589691,
If you wish to adjust the brightness of the LED (fixed brightness), you can increase/ decrease the current flowing through the LED. This can be done by varying the resistor connected in series to the LED. Increasing the resistance will dim the LED.
If you wish to dynamically control the brightness of the LED, you can connect it to a PWM block and change the duty cycle of the PWM to increase/ decrease brightness. If ON time is increased , brightness increases.
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Many of the PSoC devicws have a PrISM component which is specialized for dimming LEDs dynamically.
Have a look into the datasheet.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No there is no such PrlSM on my PSoC 4000 Kit
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bragadeesh,
I want to use the second option and have made the code below. There a touch button shall switch on the LED and its brightness I want to set up PWM.
Before I have tested: With no PWM and not connect the LED to the PWM (no "HW connection"), the touch button switches the LED on to full brightness.
Now programming the device the Leds flashes shortly and the touch is not working anymore. Do you know, what is wrong?
#include "project.h"
//leds
#define LED_ON (0u) //Für Oledanschluss OFF=0u --> on=1u
#define LED_OFF (1u)
int main(void)
{
CyGlobalIntEnable; /* Enable global interrupts. Immer notwendig */
CapSense_1_Start();
PWM_Start();
PWM_SetMode(PWM_MODE_PWM_DT);
PWM_SetPWMDeadTime(255);
//How can I controll
for(;;)
{
//CHECK IF CAPSENSE IS NOT BUSY -- Touch funktioniert dann besser
if(!CapSense_1_IsBusy())
{
CapSense_1_ScanAllWidgets();
CapSense_1_ProcessAllWidgets();
ledGreen_Write(CapSense_1_IsWidgetActive(CapSense_1_BUTTON0_WDGT_ID) ? LED_ON : LED_OFF );
}
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I tried with CY8CKIT-044.
My Program starts with LED off,
when you touch the button,
(1) LED lights with 1/4 brightness
(2) LED lights with full brightness
(3) LED turns off
(1) ...
schematic
main.c
====================
#include "project.h"
#define PWM_PERIOD 1000
#define LED_OFF 0
#define LED_1_4 250
#define LED_HALF 500
#define LED_3_4 750
#define LED_FULL 1000
int main(void)
{
int led_level = LED_OFF ;
CyGlobalIntEnable; /* Enable global interrupts. */
CapSense_1_Start() ;
PWM_WritePeriod(PWM_PERIOD) ;
PWM_WriteCompare(led_level) ;
PWM_Start() ;
for(;;)
{
if (!CapSense_1_IsBusy()) {
CapSense_1_ProcessAllWidgets() ;
if (CapSense_1_IsSensorActive(CapSense_1_BUTTON0_WDGT_ID, CapSense_1_BUTTON0_SNS0_ID)) {
switch(led_level) {
case LED_OFF: led_level = LED_1_4 ; break ;
case LED_1_4: led_level = LED_FULL ; break ;
case LED_FULL: led_level = LED_OFF ; break ;
default: led_level = LED_OFF ; break ;
}
// PWM_Stop() ;
PWM_WriteCompare(led_level) ;
// PWM_Enable() ;
CyDelay(500) ; /* cheap debouncing */
}
CapSense_1_ScanAllWidgets() ;
}
}
}
====================
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Although I'm afraid that this may be somewhat supererogatory,
I modified my program to only ON <-> OFF function.
Meantime as I played with my CY8CKIT-044, about 10~100 for compare out of 1000 period cycle seemed to be "dim".
This number may vary in each system(s).
main.c
===============
#include "project.h"
#define PWM_PERIOD 1000 /* 65535 (0xFFFF) was too much for this purpose */
#define LED_OFF 0
#define LED_DIM 10 /* could be anywhere from 1 to 1000 */
int main(void)
{
int led_level = LED_OFF ;
CyGlobalIntEnable; /* Enable global interrupts. */
CapSense_1_Start() ;
PWM_WritePeriod(PWM_PERIOD) ;
PWM_WriteCompare(led_level) ;
PWM_Start() ;
for(;;) {
if (!CapSense_1_IsBusy()) {
CapSense_1_ProcessAllWidgets() ;
if (CapSense_1_IsSensorActive(CapSense_1_BUTTON0_WDGT_ID, CapSense_1_BUTTON0_SNS0_ID)) {
if (led_level == LED_OFF) {
led_level = LED_DIM ;
} else {
led_level = LED_OFF ;
}
PWM_WriteCompare(led_level) ;
CyDelay(500) ; /* cheap debouncing */
}
CapSense_1_ScanAllWidgets() ;
}
}
}
===============
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi
your answer is very helpfull. I think that LED_DIM -input for PWM_WriteCompare) shall be between 0 and 65535 for getting 0 to 100 %.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
There are some more things to consider.
(1) The "period" of the counter defines the frequency. (frequency = 1/period)
(2) As a 16bit counter, the TCPWM can count 0 to 65535 (= 65536 cycles)
(3) If you count up to 65535 with 2MHz clock, it takes 32.768ms => 30.5175 Hz
(4) The "compare" value could be 0 to the period+1, although we can assign up to 65535 anyway.
But 0 to period+1 will be mapped to 0% to 100%
(5) In my sample, I set the period to "1000", so meaningful compare value is 0 to 1001.
(Oops, I notice that I should have set it to 999, so that 0 to 1000 was meaningful, but it's a detail)
(6) On the other hand, to avoid seeing the LED flickering,
usually, we'd like to make the frequency more than 50 or 60Hz,
so that about "10000" or less will be good for the period.
(7) And I chose 1000. (So compare value should be 0 to 1001, which is 0% to 100%)
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
now I have measured the output frequency by the help of an oscilloscope. Changing the PWM_PERIOD or even cancel (//PWM_WritePeriod(PWM_PERIOD) has no impact on the final frequency of 61 Hz.
To work with PWM_PERIOD, do I have change the settings direct in the ''Configure PWM"?
Please find below a screenshot of the ''Configure PWM" and my main.
#include "project.h"
//#define PWM_PERIOD 1 //16 bit clock/period = frequency
#define LED_OFF 0 //16 bit for writeCompare
#define LED_1_4 64*256
#define LED_HALF 128*256
#define LED_3_4 192*256
#define LED_FULL (256*256)-1
int main(void){
int led_level = LED_OFF ;
CyGlobalIntEnable; /* Enable global interrupts. */
CapSense_1_Start() ;
//PWM_WritePeriod(PWM_PERIOD) ; ---------has no impact on frequency
PWM_Start() ;
PWM_WriteCompare(led_level) ;
for(;;) {
if ( ! CapSense_1_IsBusy()) {
CapSense_1_ProcessAllWidgets() ;
if (CapSense_1_IsSensorActive(CapSense_1_BUTTON0_WDGT_ID, CapSense_1_BUTTON0_SNS0_ID)) {
switch(led_level) {
case LED_OFF: led_level = LED_1_4 ; break ;
case LED_1_4: led_level = LED_HALF ; break ;
case LED_HALF: led_level = LED_3_4 ; break ;
case LED_3_4: led_level = LED_FULL ; break ;
case LED_FULL: led_level = LED_OFF ; break ;
default: led_level = LED_OFF ; break ;
}
PWM_WriteCompare(led_level) ;
CyDelay(500) ; /* cheap debouncing */
}
CapSense_1_ScanAllWidgets() ;
}
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
It was my mistake, before setting period PWM_Start() or PWM_Init() must have been called.
Note: PWM_Init() is called at the first time PWM_Start() is called
And in the PWM_Init(), period is overwritten to the value set in the GUI.
So I should have written
=================
PWM_Start() ;
PWM_Stop() ; /* before changing the period, PWM must be stopped */
PWM_WritePeriod(PWM_PERIOD) ;
PWM_WriteCompare(led_level) ;
PWM_Start() ;
=================
To test if PWM_WritePeriod() really works,
I made following test program.
schematic
pins
main.c
Note: To handle UART interactions I cheated by using my tty_utility
tty_utils a utility sample for CLI type program
================
#include "project.h"
#include "stdio.h"
#include "tty_utils.h"
#define PWM_PERIOD 1000 /* 65535 (0xFFFF) was too much for this purpose */
#define LED_OFF 0
#define LED_DIM 10 /* could be anywhere from 1 to 1000 */
uint16_t led_period = PWM_PERIOD ;
uint16_t led_level = LED_DIM ; /* set default to ON */
void config_pwm(uint16_t period, uint16_t compare) ;
typedef void (*func_ptr_type)(char *str) ;
void do_help(char *str) ;
void do_period(char *str) ;
void do_compare(char *str) ;
void do_pwm(char *str) ;
void do_status(char *str) ;
typedef struct _cmd_func_st {
char *cmd ;
func_ptr_type func ;
char *description ;
} cmd_func_type ;
cmd_func_type cmd_list[] = {
{ "help", do_help, "Print Help Message" },
{ "period", do_period, "Set PWM Period value, period 1000" },
{ "compare", do_compare, "Set PWM Compare value, compare 10" },
{ "pwm", do_pwm, "Set PWM Config period and compare, pwm 1000 10" },
{ "status", do_status, "Show current setting" },
{ 0, 0, 0 }
} ;
void do_help(char *str)
{
(void) str ;
int i = 0 ;
print("=== command ===\n\r") ;
for (i = 0 ; cmd_list.cmd ; i++ ) {
snprintf(str, STR_BUF_LEN, "%10s : ", cmd_list.cmd) ;
print(str) ;
print(cmd_list.description) ;
print("\n\r") ;
}
}
void do_period(char *str)
{
sscanf(str, "%*s %hd", &led_period) ;
config_pwm(led_period, led_level) ;
}
void do_compare(char *str)
{
sscanf(str, "%*s %hd", &led_level) ;
config_pwm(led_period, led_level) ;
}
void do_pwm(char *str)
{
sscanf(str, "%*s %hd %hd", &led_period, &led_level) ;
config_pwm(led_period, led_level) ;
}
void do_status(char *str)
{
uint16_t period, compare ;
period = PWM_ReadPeriod() ;
compare = PWM_ReadCompare() ;
print("=== PWM Status ===\n\r") ;
snprintf(str, STR_BUF_LEN, "Period: %hd\r\n", period) ;
print(str) ;
snprintf(str, STR_BUF_LEN, "Compare: %hd\r\n", compare) ;
print(str) ;
}
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
CapSense_1_Start() ;
UART_Start() ;
tty_init() ;
splash("CapSense and LED PWM Test") ;
PWM_Start() ;
}
void config_pwm(uint16_t period, uint16_t compare)
{
PWM_Stop() ;
PWM_WritePeriod(period) ;
PWM_WriteCompare(compare) ;
PWM_Start() ;
}
func_ptr_type get_func(char *cmd)
{
int i ;
for (i = 0 ; cmd_list.cmd ; i++ ) {
if (strcmp(cmd, cmd_list.cmd) == 0) {
break ;
}
}
return( cmd_list.func ) ;
}
void do_command(char *str)
{
char command[STR_BUF_LEN+1] ;
func_ptr_type func ;
sscanf(str, "%s", command) ;
func = get_func(command) ;
if (func) {
func(str) ;
} else {
do_help(str) ;
}
}
int main(void)
{
init_hardware() ;
config_pwm(led_period, led_level) ;
prompt() ;
for(;;) {
if (get_line()) {
do_command(str) ;
prompt() ;
}
if (!CapSense_1_IsBusy()) {
CapSense_1_ProcessAllWidgets() ;
if (CapSense_1_IsSensorActive(CapSense_1_BUTTON0_WDGT_ID, CapSense_1_BUTTON0_SNS0_ID)) {
if (led_level == LED_OFF) {
led_level = LED_DIM ;
} else {
led_level = LED_OFF ;
}
PWM_WriteCompare(led_level) ;
CyDelay(500) ; /* cheap debouncing */
}
CapSense_1_ScanAllWidgets() ;
}
}
}
================
Tera Term log
When the program started, as Period = 1000, Compare = 10 and the PWM Clock = 2MHz
About 2KHz pulse(s) are generated
When I entered "pwm 2000 1000" to the prompt (>)
Now frequency is 2KHz and as compre value is 1000 the duty is 50%
When I entered "pwm 3000 1000"
The frequency was about 668Hz and duty is about 30%
When I entered "pwm 1500 1000", frequency was about 1.336 kHz
and duty is about 67%.
So the bad news is that I had a bug in my previous program,
and the good news is PWM_WritePeriod() does its work 😉
moto