PWM video code analysis and explanation

Publisher:心灵律动Latest update time:2023-01-30 Source: zhihuKeywords:PWM Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. LED lights flash at different frequencies

Next, we take the following LED light flashing code as an example to change the delay length to see the effect of the LED light.

void setup()

{

  pinMode(2, OUTPUT);

}


void loop()

{

  digitalWrite(2, HIGH);

  delay(50); // Wait for xx millisecond(s)

  digitalWrite(2, LOW);

  delay(50); // Wait for xx millisecond(s)

}

animated cover

500ms delay flash (1Hz frequency)


animated cover

200ms delay flash (2.5Hz frequency)

animated cover

50 ms delay flash (10Hz frequency)

Through three comparative experiments, we found that as the frequency increases, our LED lights slowly begin to feel less flicker. Due to the visual dwell effect of our human eyes, generally a refresh rate greater than 50Hz can meet our requirements.


2. High frequency LED flashing deformation process

We still use this code to fix the frequency at 50Hz, and then keep the period unchanged, that is, the combined time of the high and low levels is equal to 40ms, and then change the duty cycle of the high and low levels (the percentage of the high and low levels in the total cycle), we pass Adjust the length of the high and low level delays to adjust the brightness ratio

Code part:

void setup()

{

  pinMode(2, OUTPUT);

}


void loop()

{

  digitalWrite(2, HIGH);

  delay(10); // Wait for 1000 millisecond(s)

  digitalWrite(2, LOW);

  delay(10); // Wait for 1000 millisecond(s)

}

animated cover

50Hz frequency maximum brightness (that is, the delay is 0 when the light is off, and the delay is 20ms when it is on)

animated cover

50Hz frequency 50% brightness (that is, the delay is 10ms when the light is off, and the delay is 10ms when the light is on)

animated cover

50Hz frequency 25% brightness (that is, the delay is 15ms when the light is off, and the delay is 5ms when the light is on)

animated cover

50Hz frequency 10% brightness (that is, the delay is 18ms when the light is off, and the delay is 2ms when the light is on)

We connect the above actions together, that is to say, we make the brightness delay a continuous change. In order to achieve better results in practice, we change the delay to a delay of 200 us, so that the continuous change effect is better.

Code part:

void setup()

{

  pinMode(2, OUTPUT);

}


int count = 0;

int PWM_Time = 50;

  

void loop()

{

  digitalWrite(2, HIGH); //LED light off

  delayMicroseconds(200-PWM_Time); // Wait for xx millisecond(s)

  digitalWrite(2, LOW); // LED light on

  delayMicroseconds(PWM_Time); // Wait for xx millisecond(s)

  

  count++;

  if(count==50)

  {

      count = 0;

      PWM_Time++;

      if(PWM_Time>=200) PWM_Time = 0;

  }

}

animated cover

LED light gradually brightening effect

Let's modify it further and make it a breathing effect.

Code part:

void setup()

{

  pinMode(2, OUTPUT);

}


int count = 0; // Because the delay is relatively short, it will change if used directly.

      // It's too fast to see the effect. Let's add a counting variable.

int PWM_Time = 0; // LED duty cycle variable

int LED_Togle_Flag = 0; // LED gradually turns on and off flip flag

  

void loop()

{

  if(LED_Togle_Flag)

  {

    digitalWrite(2, HIGH); //LED light off

    delayMicroseconds(200-PWM_Time); // Wait for xx millisecond(s)

    digitalWrite(2, LOW); // LED light on

    delayMicroseconds(PWM_Time); // Wait for xx millisecond(s)

  }

  else

  {

    digitalWrite(2, HIGH); //LED light off

    delayMicroseconds(PWM_Time); // Wait for xx millisecond(s)

    digitalWrite(2, LOW); // LED light on

    delayMicroseconds(200-PWM_Time); // Wait for xx millisecond(s)

  }

  

  

  count++;

  if(count==50)

  {

  count = 0;

    PWM_Time++;

    //Switch light and dark change logic

    if(PWM_Time>=200) 

    {

    PWM_Time = 0;

        LED_Togle_Flag = ~LED_Togle_Flag;

    }

  }

}

animated cover

LED light breathing light


LED "Meteor Shower"

First, let’s analyze the logic of the meteor shower:

First we need to achieve such an effect, the first one is the brightest, and then the next one is 45% of the brightness of the previous one.

Code part:

// ----------------------------------------------------------------------------

// LED_Rains.ino

//

// Raindrop flow effect implemented by digital pins

// The difference between the raindrop flow effect and the running water light (marquee) is that the raindrop flow effect has a trailing effect, that is, the light that has been lit is slowly extinguished.

//

//Use all pins of UNO to use analog PWM to achieve the effect of raindrop flow, including analog input ports that can also be used as digital outputs

// Each pin is connected to the positive pole of the LED, and the negative pole of the LED is connected to GND.

// ----------------------------------------------------------------------------


const unsigned char leds[] = { A4, A5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // All pins are arranged in the order of LED wiring

const unsigned int maxPwm = 100; // To simulate PWM manually, you can define the maximum PWM value yourself, so it is easier to calculate by defining a number of one hundred or one thousand.


unsigned int ledPwm[12] = { 1, 3, 4, 6, 9, 13, 18, 25, 35, 50, 70, 100}; // Store the brightness PWM value of each LED during operation



void setup()

{

    for (char i = 0; i < 12; ++i)

    {

        pinMode(leds[i], OUTPUT);

    }

}


void loop()

{

    unsigned int i, j;


    for (i = 0; i < 12; ++i) // Turn on the light first, then turn off the light when the duty cycle reaches the switching point

    {

        digitalWrite(leds[i], LOW);

    }

   

    for( i=0; i    {

    for (j = 0; j < 12; ++j)

        {

            if (i == ledPwm[j])

                digitalWrite(leds[j], HIGH);

        }

        delayMicroseconds(1);

    }

}

animated cover

Static meteor shower effect

Code explanation:

We first store proportional values ​​in the brightness array ledPwm[12]. Here I calculate it based on a ratio of 70%.

For example, the darkest value is 100, then the next darkest value is 100*70% = 70, and so on. Then we light the lights according to the assigned brightness.

This part of the code is to light up all the LED lights first

    for (i = 0; i < 12; ++i) // Turn on the light first, then turn off the light when the duty cycle reaches the switching point

    {

        if (ledPwm[i] == 0)

            continue;

        digitalWrite(leds[i], LOW);

    }

This part of the code controls the off time according to the brightness of the LED light. We first divide the brightness into 100 parts according to the maximum brightness value "maxPWM". The delay for each part is 1us, and then check the current value in the internal loop. Whether the brightness value reaches the allocated number of copies. If it reaches, it will turn off. If it does not reach, it will continue to stay on.


 for( i=0; i    {

    for (j = 0; j < 12; ++j)

        {

            if (i == ledPwm[j])

                digitalWrite(leds[j], HIGH);

        }

        delayMicroseconds(1);

    }



Let the LED "meteor shower" move

Obviously, such a static meteor shower still cannot meet our requirements. Next, we will make the meteor shower move first.

We need it to move like this

LED meteor shower dynamic decomposition diagram

Let's try to move it by one bit first. I just need to rearrange the values ​​​​in the ledPwm[12] array. This is actually an array operation.

unsigned int ledPwm[12] = {3, 4, 6, 9, 13, 18, 25, 35, 50, 70, 100, 1}; // Store the brightness PWM value of each LED during operation

The effect of LED meteor shower moving one position



LED "Meteor Shower" continuous motion

From the above we know that if we have a way to perform continuous operations on the array, we can achieve the effect of a "meteor shower" flow.


The code below is the time counter that comes with Arduino. You can directly read the value inside and use it to assist counting. In fact, you don’t need this. You can count directly in it yourself.


extern volatile unsigned long timer0_millis;


Complete version of the code: Put all the numerical variables that need to be changed at the front. This is a common practice in writing reusable programs. It can be flexibly adapted to multiple lights, and at the same time, the speed and brightness ratio can be adjusted.

// ----------------------------------------------------------------------------

// LED_Rains.ino

//

// Raindrop flow effect implemented by digital pins

// The difference between the raindrop flow effect and the running water light (marquee) is that the raindrop flow effect has a trailing effect, that is, the light that has been lit is slowly extinguished.

//

//Use all pins of UNO to use analog PWM to achieve the effect of raindrop flow, including analog input ports that can also be used as digital outputs

// Each pin is connected to the positive pole of the LED, and the negative pole of the LED is connected to GND.

// ----------------------------------------------------------------------------


const unsigned char leds[] = { A4, A5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // All pins are arranged in the order of LED wiring

const unsigned int maxPwm = 100; // To simulate PWM manually, you can define the maximum PWM value yourself, so it is easier to calculate by defining a number of one hundred or one thousand.

const unsigned int initPwm = 100; // The pwm value of the brightest light, that is, the brightness of the first light when moving

const unsigned int deltaPwm = 1; // The pwm value of the light slowly extinguishing, how much darker the next light is than the previous light. This is equivalent to an arithmetic queue. Equally different brightnesses don’t feel good, so the next factor of equal proportions is introduced.

const unsigned int deltaPercent = 45; // The latter light is darker than the previous light, and its brightness is a few percent of the previous light. Compared with the previous decrease, this is equivalent to a geometric series

const unsigned long delayMs = 100; //Movement delay, unit ms

const unsigned char ledNum = sizeof(leds) / sizeof(leds[0]); // Number of pins, that is, the number of LEDs


unsigned int ledPwm[ledNum]; //Storage the brightness PWM value of each LED during runtime


void setup()

{

    for (char i = 0; i < ledNum; ++i)

    {

        pinMode(leds[i], OUTPUT);

        ledPwm[i] = 0;

    }

}


extern volatile unsigned long timer0_millis; // Declare the external variable timer0_millis for use in the program. It is actually the return value of millis() - the number of milliseconds the program has been running.

[1] [2]
Keywords:PWM Reference address:PWM video code analysis and explanation

Previous article:Debugging methods for using new IC chips in microcontroller projects
Next article:(3) Another way to learn the basic components of button control LED lights

Recommended ReadingLatest update time:2024-11-22 14:11

Three-phase voltage type PWM rectifier circuit
 The main circuit of the three-phase voltage-type PWM rectifier has a very fast response and a better input current waveform. When working in a steady state, the output DC voltage remains unchanged, and the switch tube is pulse-width modulated according to the sinusoidal law. The output voltage of the rectifier AC is
[Power Management]
Three-phase voltage type PWM rectifier circuit
Design of switching power supply based on SG3525
With the development of power conversion technology, power MOSFET is widely used in switching converters. For this reason, Silieon General Semiconductor Company (Silieon General) of the United States launched SG3525 to drive n-channel power MOSFET. SG3525 is a current-controlled PWN controller. It can directly compare
[Microcontroller]
Design of switching power supply based on SG3525
Freescale 16-bit MCU (VIII) - PWM module test
1. PWM module introduction        PWM is widely used in the industrial field and is an effective means to achieve D/A conversion and accurate pulse sequence output. Many microcontrollers are equipped with PWM output function. The PWM module of XEP100 microcontroller has the following features: (1) The XEP100 microco
[Microcontroller]
Brief Analysis of PWM Driver and Test Program of Mini2440 Development Board
First look at the circuit schematic #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include
[Microcontroller]
Brief Analysis of PWM Driver and Test Program of Mini2440 Development Board
STM32f4---PWM output experimental code
The pwm.c source file code is as follows:   //TIM14 PWM initialization   //PWM output initialization //arr: automatic reload value psc: clock pre-division number void TIM14_PWM_Init(u32 arr,u32 psc) {                     GPIO_InitTypeDef GPIO_InitStructure;   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;   TIM_OCInit
[Microcontroller]
SiRuiPu releases the first automotive-grade current sensing amplifier TPA132Q! With PWM suppression capability, it helps new energy vehicle motor drive
3PEAK (stock code: 688536), a semiconductor supplier focusing on high-performance analog chips and embedded processors, has launched the TPA132Q, an automotive-grade bidirectional current sensing amplifier with enhanced PWM rejection capability. TPA132Q provides excellent current detection accuracy and fa
[Automotive Electronics]
SiRuiPu releases the first automotive-grade current sensing amplifier TPA132Q! With PWM suppression capability, it helps new energy vehicle motor drive
Cuk PWM DC/DC Converter
The Boost and Buck circuits can be cascaded to form a Cuk circuit. The combination process is shown in the figure. It can be seen from the circuit conversion process in the figure that after the Boost and Buck circuits are properly converted, the switch tube V, diode D, and capacitor C in the two circuits can overla
[Power Management]
Cuk PWM DC/DC Converter
Analysis and Design of Phase-Shifted Full-Bridge ZVS-PWM Converter
1 Circuit principle and working mode analysis 1.1 Circuit Principle Figure 1 shows the circuit topology of the phase-shifted full-bridge ZVS-PWM resonant converter. Vin is the input DC voltage. Si (i=1.2.3, 4) is the power MOS switch tube with the same parameters of the i-th. Di and Gi (i=1, 2, 3, 4) are t
[Power Management]
Analysis and Design of Phase-Shifted Full-Bridge ZVS-PWM Converter
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号