Skip to main content

Generating a PWM Signal Based on an Analog Input - mikroC

If you like to experiment with microcontrollers you've probably tried out analog-to-digital conversion and generating PWM signals. Using a popular PIC microcontroller like the 16F877A, which has both ADC and CCP (Capture/Compare/PWM) modules, you can test out both of these easily because mikroC provides easy to use library functions for both of them. (Most of you will be familiar with these libraries, so I won't be going in to much detail about them here. Leave a comment if you like to learn more.. :) )

Now, think of a scenario like this: You want to change the duty cycle of your PWM signal based on a analog signal. It can be from a variable resistor that you want to use to increase or decrease the duty cycle, or it can be a feedback from a sensor which is analog.

So, how can we do it?... we simply use the ADC to convert the analog signal and use that value as the duty cycle value. All we need is a microcontroller that has both a CCP and a PWM module. As I said before, the popular 16F877A fits the criteria.

So, now that we have our microcontroller, let's get down to the code.

Here's the sample code
 unsigned int temp_res;  
 unsigned char temp_duty;  
   
 void main() {  
  ADCON1 = 0x80; // Configure analog inputs and Vref  
  TRISA = 0xFF; // Set PORTA as an input  
  TRISC = 0; // Set PORTC as an Output  
  PORTC = 0;  
     
  // Initialize and start the PWM unit  
  PWM_Init(5000);  
  PWM_Start();  
   
  while(1){  
   temp_res = Adc_Read(2); // Get results of AD conversion  
                 from channel 2 (RA2 pin)  
   
   temp_duty = (temp_res/4); // Convert the 10 bit value  
                 to 8 bits  
   
   PWM_Change_Duty(temp_duty); // Set the duty value  
   
   Delay_ms(50); // Slow everything down a little  
  }  
 }  

Let's see what's happening in the code,



  • First, we declare 2 variables - temp_res to store the result of AD conversion and temp_duty to store the 8 bit value for the duty cycle.
  • We use the ADC_Read(2) function to read the analogue input from AN2 pin, convert it to digital and store the 10 bit value in temp_res. 
  • Since the value for the duty cycle should be 8 bits (0 to 255) we simply divide the temp_res by 4 and store it in temp_duty.
  • Finally, we use the PWM_Change_Duty() function and set the duty cycle to the value of temp_duty.
There's nothing new in this code that you don't already know :)

Here's the basic circuit for testing this code
Use the R2 variable resistor to get the varying analog signal. The brightness of the LED will change based on the PWM.

You can use this same method to generate a PWM based on any analog signal. Just think of the possibilities...

References 
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010242

Comments

  1. What is different about the pic16f887 that this code doesnt work with it?

    ReplyDelete
  2. i tried your code, its working but as the analog voltage is changed the pulse width changes but the frequency shown in the DSO remain same, whats the problem?????

    ReplyDelete
  3. please post the link of the header file.

    ReplyDelete

Post a Comment

Popular posts from this blog

Selecting the Correct Gauge Wires for your RC Models

When we are building RC models (aircrafts, multicopters etc.), something we typically overlook is what type of wires to use to distribute power in them. Usually, we try to reduce the weight of the model, so we tend to go with smaller wires. But, we cant expect to put in small circuit-wires and have them handle the amount of power needed. If you look at the wires that comes in the output leads of a Li-Po, or the wires that comes on a standard XT Jack, you'll notice that they're quite huge. Large gauge wires on a Li-Po and XT connectors These need to be huge to handle the amount of amperage that goes through them. So, we should also consider the amperage, and the length of wire needed when selecting the size (gauge) of the wires.

Make Your Own Jupmer Wires for Electronic Breadboard

Note: After starting the 'Tips and Tricks' section I wanted to do my own 'tutorial'. So, here's my first attempt of it. Hope you all find this useful, and sorry about the low quality of the photographs, my camera is just a 2MP. If you, like me, like to experiment with electronics, then you'd probably use an electronic breadboard (also known as protoboard or project-board). These allow you to construct and test circuits without the need to permanently soldering the components. The problem with these is that you have to use wires to connect the components across the bus lines. We normally use single core circuit wires for this purpose, but they tend to bend, break and get stuck in the breadboard when used repeatedly. This may cause short circuiting the bus lines and could be the failure of your circuit. A better option would be to buy a 'Breadboard Jumper Wire' kit, such as this. A Breadboard Jumper Wire Kit These have sets of wire of differ

What do the prop size numbers mean?

Have you been trying to shop for propellers - either online or at a hobby shop - and got confused of the numbering used to denote the size of the propellers? You see things like " 10 x 4.5 CW ", or " 8055 CCW ". What do these numbers mean? A 8 x 4.5 CW and CCW Propeller Set It's actually quite simple once you figure it out. The first number denotes the diameter of the prop (length from tip-to-tip). The second number denotes the pitch of the prop. Here, the pitch is denoted as a length, not a angle. Let's see how that works.