PWM Issue

16 Mar 2011

Right so I've been looking at controlling some devices using PWM, so to start off I thought an LED connected to the output would keep things simple. My code is intended to upon startup turn led1 on for a second and off for a second. Then if "go" is pressed illuminate it constantly. (this also turns on the surface mount LED on Mbed (boardled) on just to indicate that that point in the code has reached. If "go" is then released after 5 seconds led1 should then return to being on for one second and off for another. However regardless of whether the button is pressed or not led1 stays constantly illuminated. I've checked the code over and over and have consulted relevant areas of the handbook and cookbook but cant find a solution, any ideas??

Cheers

Ollie

/media/uploads/olmasters/pwm_prog_1_lpc1768.bin

16 Mar 2011

The bin file is no use to us, we cannot see your code, only run it. You need to publish your program and give us a reference to it so we can see your code.

01 Aug 2011

Hi all. I have the same problem as Oliver. A little background about my program: My mbed would take in an external trigger which would change the duty cycle of the PWM which has been programmed into it. The problem is depicted in the code which I have written. LED1 shows the PwmOut, LED2 shows if mbed has received the trigger and LED3 show the duty cycle at 50%.

#include "mbed.h"

/* If sections marked * is removed, PWM don't work.
When * is placed before PWM loop, PWM delayed for 2 periods. 
When * is placed after PWM loop, PWM delayed for 1 period. */

PwmOut led(LED1);
DigitalOut iled(LED2);
DigitalOut ind(LED3); // *
AnalogIn trig(p16);

int main() {

    while(1) { 
        ind = 1; // *
        wait(3); // *
        ind = 0; // *
        wait(3); // * 
        
        if (trig <= 1.0) {
           led.period(6);
           led = 0.5;
           iled = 0; // Trig?
        } else {
            led.period(6);
            led = 0.1;
            iled = 1; // Trig'd
        }

    }   
}
01 Aug 2011

Hi Paul,

The problem is caused by the fact calling period() resets the period of the PWM. When you spin around the while loop, it is effectively continuously being reset.

The solution would be to add some logic to know whether your threshold state has changed, and only update the period then.

As an aside (may just be your quick example), AnalogIn returns a value between 0.0 and 1.0, so theoretically, the if() should always be true.

Simon

01 Aug 2011

I have edited the code and it now looks like this:

#include "mbed.h"

PwmOut led(LED1);

DigitalOut iled(LED2);
PwmOut ind(LED3);

AnalogIn trig(p16);

int main() {

    ind.period(6);
    ind = 0.5;
    
    led.period(6);        
    if (trig < 0.6) {           
        led = 0.5;
        iled = 0; // Trig?
    } else {            
        led = 0.1;
        iled = 1; // Trig'd
    }  
}

Should I add an int i that takes note of the trig value? My external trigger is controlled by a push button switch, normally off. It is connected to a 3.3V power source. When the switch is on, there isn't any change in the duty cycle. The iled also do not light up. The voltage reading I got off the scope at p16 is 2.997V. Shouldn't p16 be turned on?

Another problem is that when the mbed is connected to an external power source (in my case a 9V battery), the voltage across p1(GND) and p2(VIN) is around 1.5V. Thus the mbed would never turn on. There aren't any resistors connected between the mbed and power source.

01 Aug 2011

After looking through some other forums, I have implemented Interrupt into my program. So the result is as follows:

#include "mbed.h"

PwmOut led(LED1);

DigitalOut iled(LED2);
PwmOut ind(LED3);

InterruptIn trig(p16);

void change() {
    led = 0.2;
}

int main() {
    trig.rise(&change);
    ind.period(6);
    ind = 0.5;
    
    led.period(6);
    led = 0.5; 
}

Now the problem is how to disable the Interrupt. As suggested in the following thread http://mbed.org/forum/mbed/topic/205/?page=1#comment-864. To disrupt an interrupt, use trig.rise(NULL). I have tried putting in the int main but the initial interrupt would be overwritten. There isn't any effect if these command is placed in the interrupt func.

02 Aug 2011

#include "mbed.h"

PwmOut led(LED1);
DigitalOut iled(LED2);

InterruptIn trig(p16);

int trigVal = 0;    // Interrupt flag

void up() {         // Interrupt
    trigVal = 1;
    iled = 1;       // Trig'd
}

int main() {    
    led.period(1);  // Period
    led = 0.5;      // Duty cycle (dc)
    
    trig.rise(&up); // Trig?
    while(1) {             
        if (trigVal) {
            trigVal = 0;
            iled = 0;            
            led = 0.2; // Changing dc
        }
        wait(1);
        led = 0.5;     // Reverting back to original dc.        
    }   
}

Above is my final code which has worked very well.

The only problem left to solve is the switch bouncing every time it is pressed.

02 Aug 2011

Import libraryPinDetect

InterruptIn style DigitalIn debounced with callbacks for pin state change and pin state hold.

02 Aug 2011

Use Andy's PinDetect library to debounce your interrupt input. I've used it in a couple of projects and it has worked well.

http://mbed.org/users/AjK/libraries/PinDetect/lkyxpw

Good luck,

Mike

03 Aug 2011

#include "mbed.h"

PwmOut led(LED1);
PwmOut opto(p21);
DigitalOut iled(LED2);

InterruptIn trig(p16);

int trigVal = 0;        // Interrupt flag

void up() {             // Interrupt
    trigVal = 1;
    iled = 1;           // Trig'd
}

int main() {    
    led.period(2);      // Period
    led = 1.0;          // Duty cycle (dc)
    opto.period(2);     // Period
    opto = 1.0;         // dc
    
    trig.rise(&up);     // Trig?
    while(1) {                 
        if (trigVal) {
            trigVal = 0;
            iled = 0;            
            led = 0.5;  // Changing dc
            opto = 0.5; // Changing dc
        }
        wait(2);        // If removed, change would not take place
        led = 1.0;      // Reverting back to original dc
        opto = 1.0;     // Reverting back to original dc        
    }       
}

This is my final code without using Andy's library. It is working well. As highlighted in my code, there is a redundant wait() at the 5th line from the bottom. I am wondering if it can be removed and my program still work.