5 years, 3 months ago.

Program executes the "if"even though the condition is not satisfied !

In the program below, without the last "Else", even when the "if" condition is not satisfied, the program executes, not exactly the instructions after the "if", but it keeps incrementing the gaitCounter variable quite regularly, it does this even if I remove totally the sensor. When I added the "Else", it runs the instruction inside it for a while, then it goes again incrementing the gaitCounter even if the reading is still 0. Now, when I start to press on the sensor (here a Force Resistive Sensor), the program runs correctly, that is after the analog input goes higher than 0.5, it runs the instruction (I read the values in real time by Bluetooth).

So to sum up, when the sensor is pressed, the program works correctly, but when it is free, (analog reading is 0), it behaves strangely as explained in the beginning.

Please give me any help. I have never came across such a problem.

#include "mbed.h"
#include <stdio.h>

// Initialize a pins to perform analog input and digital output fucntions
AnalogIn   ain(p15);
Serial device(p28, p27);
//Serial pc(USBTX, USBRX);

DigitalOut LedOut(LED1);
//DigitalOut dout(LED1);
//Serial pc(USBTX, USBRX);


Timer t;
int gaitPeriod[10];
int startTime = 0;
int gaitCounter = 0;
float mean = 0.00;

int main(void)
{
    device.baud(57600);
    t.start();
    
    while (1) {

        if(ain > 0.50f && t.read()>0.80f){
            device.printf("ain : %1.2f%\r\n",ain.read());
            gaitCounter++;
            //device.printf("Gait period: %d%\r%\n",gaitCounter);
        
            if (gaitCounter == 1){
                //startTime = t.read_ms();
                t.reset();
                t.start();
                device.printf("gaitCounter %d\r\n",gaitCounter);
                }
                
            else if (gaitCounter >= 2 && gaitCounter <= 6){
                gaitPeriod[gaitCounter] = t.read_ms();//-startTime;                              
                //startTime = t.read_ms();
                t.reset();//reset timer to zero
                t.start(); //start timer
                //startTime = 0;//reset starTime for the next measurement 
                device.printf("gaitCounter %d\r\n",gaitCounter);
                
                if (gaitCounter == 6){
                    gaitCounter = 0;//reset counter
                    mean =(gaitPeriod[2]+gaitPeriod[3]+gaitPeriod[4]+gaitPeriod[5]+gaitPeriod[6])/5; //Can be done in a function later
                    device.printf("Gait period: %1.2f\r\n", mean);
                    }                                      
                }
        } 
        else {
            device.printf("gaitCounter : %d\r\n",gaitCounter);
            }   
     
    }
}

Yacine,

Sorry for the issues you are having :)

If you could attach your code that would be really helpful.

Regards,

Andrea, team mbed

posted by Andrea Corrado 25 Jan 2017

I adjusted the question. Now, it much more clear.

posted by Yacine Bougrinat 25 Jan 2017

What is the output of your program when it goes wrong? Do you ever get the "ain : ...." line printed out but with a value of less than 0.5?

Also when you calculate mean do /5.0f; rather than /5; Currently you are performing an integer division and then storing the result (which will be rounded down) in a float, you want to perform a floating point division.

posted by Andy A 25 Jan 2017

You can try putting in your if statement also ain.read() instead of just ain.

posted by Erik - 25 Jan 2017

When it goes wrong, I don't get the "ain:...", I get: "gaitCounter : ..." incremeting from the last value, if the last printing was "gaitCounter : 2" it goes to "gaitCounter : 3" and it continues until "gaitCounter : 5" where it goes back to "gaitCounter : 0"

Thanks for the 2nd remark

posted by Yacine Bougrinat 25 Jan 2017

You can try putting in your if statement also ain.read() instead of just ain.

Erik Olieman, I did that, ain.read() but it did not change anything

posted by Erik Olieman

posted by Yacine Bougrinat 25 Jan 2017

Here's another thing: if I remove the last "else", once the program runs and the sensor is free, I get this printed in the phone: ain : 0.0 gaitCounter : 1 ain : 0.0 gaitCounter : 2 .... Why is he getting into the "if" when the condition is not satisfied ??

posted by Yacine Bougrinat 25 Jan 2017

Is there a problem in "if" in the Mbed Compiler ?!

posted by Yacine Bougrinat 25 Jan 2017

Can you change it so that you only read the analog input once e.g.

...
       float inputReading = ain.read();
       if(inputReading > 0.50f && t.read()>0.80f){
            device.printf("ain : %1.2f%\r\n",inputReading);
...

Depending upon the impedance of the source you could be getting different values for the two reads that you currently perform.

posted by Andy A 26 Jan 2017

Andy A. I did that and I got something interesting, the printed readings I got are strange and all bigger than 0.5, that's why it gets into the if. This link shows the photo of what I get in the tablet:

https://drive.google.com/file/d/0B9ZYP1xEreDJWFk2SW51aHBwRzA/view?usp=sharing

The question now is: why do I get those strange values, I am using a Force Resistive Sensor (FSR) with a voltage divider.

posted by Yacine Bougrinat 27 Jan 2017

Problem is even when I completely remove the sensor, I still get the same thing

posted by Yacine Bougrinat 27 Jan 2017

Ok. The problem is solved and I would like to share what was the issue, the program started to run normally, just by adding a delay (wait) after reading the analog value. I have never known that it's so crucial. Is there any way to calculate the delay that is necessary ?

posted by Yacine Bougrinat 27 Jan 2017

1 Answer

5 years, 3 months ago.

Answer based on comments in order to save people digging through the comments...

The solution is to change to only reading the ADC once rather than twice:

// old
 if(ain > 0.50f && t.read()>0.80f){
            device.printf("ain : %1.2f%\r\n",ain.read());
// new
  float inputReading = ain.read();
  if(inputReading > 0.50f && t.read()>0.80f){
    device.printf("ain : %1.2f%\r\n",inputReading);

This prevents the perceived inconsistency/bug of the system executing the if statement but then reporting a value that shouldn't execute that branch.

Modifying the code to ensure that there is a pause between analog reads then seems to clear up the poor readings.

The reason for the poor ADC readings is that an ideal signal source should be very low impedance, in this case it's a resistive sensor followed by a resistive divider. This combined with the relatively poor performance of the ADC in the micro resulted in invalid readings depending upon the ADC read rate.

The correct hardware solution is to add a buffer to the analog input, this is an op-amp with the signal on the + input and the output connected to the - input. This then provides a constant high impedance input for the sensor signal and a low impedance driver into the ADC.

Accepted Answer