Syntax help need

15 Apr 2012

Greetings, I'm having a tough time with this. In the function tStopFun, the if statement will not increment the second variable in the list. I have tried while loops as an alternative with no luck

#include "mbed.h"



//-----------------Declarations-----------------------------------------------------------------


Serial pc(USBTX, USBRX); // tx, rx

InterruptIn sw1(p17);

Timer t;

PwmOut Spot(p25);
PwmOut Wide(p26);
AnalogIn ADC(p16);





//---------------Variables---------------------------------------------------------------

float dimvalS (0.0);
float dimvalW (0.0);
float tval;
float ADCval;
//---------------Functions-------------------------------------------------------------------


void tStartFun() {    //function attached to interrupt
    t.start();
    wait_us(200);
}

void tStopFun() {
    t.stop();
    tval = (t.read_ms());

    if ((tval > 0.1) && (tval < 800.0 )) {
        dimvalS = dimvalS + 0.33;
        dimvalW = dimvalW + 0.33;

        t.reset();
    }



    else if (tval > 900.0)
        dimvalS = 0.0;
        dimvalW = 0.0;

         t.reset();

   

}


int main() {



// PWM period in micro seconds
    Spot.period_ms(1);// PWM pulsewidth in milliseconds (1khz)
    Wide.period_ms(1);

    sw1.rise(&tStartFun);  // attach the address of the function to the rising edge
    sw1.fall(&tStopFun);

    while (1) {


        Spot = (dimvalS);
        Wide = (dimvalW);


        ADCval = ADC;

        pc.printf ("Spot %f Wide %f ADC %f \r\n ",dimvalS,dimvalW,ADCval);
        //wait_ms(100);

        if (dimvalS > 1.0) {
            dimvalS = (0.33);
        }

        if (dimvalW > 1.0) {
            dimvalW = (0.33);
        }


    }
}

Thanks for any advice

15 Apr 2012

Global variables that are updated inside interrupt driven functions are often optimised out by the compiler. The compiler doesnt get that the variable is used somewhere else and considers it a useless operation. You can fix that by adding the keyword 'volatile' in the declaration:

volatile float dimvalS (0.0);
volatile float dimvalW (0.0);
15 Apr 2012

I think you may have incorrect syntax for the assignment during the declaration.

Try changing this:

float dimvalS (0.0);
float dimvalW (0.0);

to this:

float dimvalS = 0.0;
float dimvalW = 0.0;

Does this help?

Scott

16 Apr 2012

Thanks gents, but still no luck. Changing the variables to volatile did not change the condition. When I remove the parenthesis from the declarations, the compiler complains (expected a ;).

But I noticed when I change

    while (1) {


        Spot = dimvalS;
        Wide = dimvalW;

to

    while (1) {


        Spot = dimvalS;
        Wide = Spot;

The other PWM pin will start to work. I just have limited experience in programming and can't connect the dots

Thanks again for the help.

16 Apr 2012

I think the volatile note made by Wim is a good suggestion but I also saw some missing curly braces for your 'if' clauses so that only the first line in an indented section of code was actually included in the compound statement.

For example:

    else if (tval > 900.0)
        dimvalS = 0.0;
        dimvalW = 0.0;
         t.reset();

isn't equivalent to

    else if (tval > 900.0)
    {
        dimvalS = 0.0;
        dimvalW = 0.0;
        t.reset();
    }

The first example will only include the "dimvalS = 0.0;" statement in the 'else if' clause.

This is my version of your code with some vertical space removed and the compound statements using the curly brace formatting rules that I find easier to line up.

#include <mbed.h>

Serial pc(USBTX, USBRX); // tx, rx

InterruptIn sw1(p17);

Timer t;

PwmOut Spot(p25);
PwmOut Wide(p26);
AnalogIn ADC(p16);

volatile float dimvalS (0.0);
volatile float dimvalW (0.0);
volatile float tval;
volatile float ADCval;

void tStartFun() 
{    
    //function attached to interrupt
    t.start();
    wait_us(200);
}

void tStopFun() 
{
    t.stop();
    tval = (t.read_ms());

    if ((tval > 0.1) && (tval < 800.0 )) 
    {
        dimvalS = dimvalS + 0.33;
        dimvalW = dimvalW + 0.33;
        t.reset();
    }
    else if (tval > 900.0)
    {
        dimvalS = 0.0;
        dimvalW = 0.0;
        t.reset();
    }
}


int main() 
{
    // PWM period in micro seconds
    Spot.period_ms(1);// PWM pulsewidth in milliseconds (1khz)
    Wide.period_ms(1);

    sw1.rise(&tStartFun);  // attach the address of the function to the rising edge
    sw1.fall(&tStopFun);

    while (1) 
    {
        Spot = (dimvalS);
        Wide = (dimvalW);

        ADCval = ADC;

        pc.printf ("Spot %f Wide %f ADC %f \r\n ",dimvalS,dimvalW,ADCval);
        //wait_ms(100);

        if (dimvalS > 1.0) 
        {
            dimvalS = (0.33);
        }

        if (dimvalW > 1.0) 
        {
            dimvalW = (0.33);
        }
    }
}

Things will be made a bit more complicated if the source of the InterruptIn pin is a button since it might be sensitive to bounce. In general I would also recommend against calling wait_us() in an interrupt handler. Your method of initializing the float globals is Ok for C++ but it wouldn't be allowed in C.

18 Apr 2012

Thanks Adam! I fixed the if statements and all is well. The interrupt source is a switch, the wait in the interrupt handler is my first attempt at debouncing the input. It seems to work OK, without the delay I get double counts sometimes. But I do need to implement a proper debounce.

Thanks for the help all!