interesting DigitalIn behavior

25 May 2012

In the following bit of code, the DigitalIn within the while loop works fine and that data is assigned to the variables chanA and chanB. The IDENTICAL bit of code place before the loop will not function appropriately. I just dont get it. Is there something about placing these digital reads within a loop that makes them work. I must be doing something wrong. Can anyone set me straight here ??

<code> int chanA, chanB, currState, prevState, change;

DigitalIn channelA(p24); DigitalIn channelB(p25);

int main() {

pc.baud(38400);

channelA.mode(PullUp); channelB.mode(PullUp);

chanA = channelA; chanB = channelB;

printf(" %d %d \n",chanA, chanB);

while (1) {

chanA = channelA; chanB = channelB;

printf("%d %d \n",chanA, chanB); } }

</code>

25 May 2012

I would try using

pc.printf(" %d %d \n",chanA, chanB);

rather than

printf(" %d %d \n",chanA, chanB);

What is providing the external signals on the dital inputs. Maybe that is not a stable level?

25 May 2012

Wim

Thanks. Works perfectly now though I have absolutely no idea why. Printf has seemed to work perfectly in sending stuff back to the pc monitor. Strange that in this instance it obviously doesn't. I'm glad you're out there man. Thanks again...

Gar

25 May 2012

Perhaps printf does not flush the buffer to the console while pc.printf does. I believe someone pointed this out to me some time back.

gary belcaster wrote:

Wim

Thanks. Works perfectly now though I have absolutely no idea why. Printf has seemed to work perfectly in sending stuff back to the pc monitor. Strange that in this instance it obviously doesn't. I'm glad you're out there man. Thanks again...

Gar

25 May 2012

Well, spoke too soon once again... I'm incorporating a rotary encoder into the front end of the antenna rotor project design. This is just to input data, eg which country/prefix to point at. I know there are several qei libraries available but in reality I only need input when I call for it; an interrupt capability just isn't necessary. I'm using a greyhill optical encoder and when using the pullup mode it outputs just fine (0 state = 0.1v, 1 state = 2.2v). So here's my code thus far. There is likely a glaring flaw thats just passing me by. Anyone see it???

Gary

#include "mbed.h"

Serial pc(USBTX, USBRX);

int chanA, chanB, currState, prevState, change;

DigitalIn channelA(p24);
DigitalIn channelB(p25);

void qei() {

    chanA = channelA;
    chanB = channelB;
    prevState = (chanA <<1) | (chanB);

    do {
        chanA = channelA;
        chanB = channelB;
        currState = (chanA <<1) | (chanB);
    }    while (prevState == currState);
    
    change = (prevState & 0x1) ^ ((currState & 0x2)>>1);
    if (change == 0) {
        change = -1;
    }
}


int main() {

    pc.baud(38400);

    channelA.mode(PullUp);
    channelB.mode(PullUp);
  
    chanA=channelA;
    chanB=channelB;

    qei();
    pc.printf("%d  \n",change);
}
25 May 2012

What is the resolution of the rotary encoder. I wouldnt be surprised when it made several steps instead of one when you turn it by hand. You may also suffer from bouncing on the flanks of the transitions. A small cap (10 n) may fix that. The pullup may be too weak. This makes the input sensitive to noise. Use an external pullup of 1K or so. Alternatively, try the DebounceIn lib instead of DigitalIn. You can find that in the cookbook.

25 May 2012

Thanks Wim. It's just 24 steps/revolution. Will try the external pullup and see if that sources a fix. Tnx for taking a look..

Gary

25 May 2012

Well Wim, once again, you've put your finger on it. Had 2 x 5k resistors just sitting on the bench so tossed them on as pull-ups and works a treat. My mistake was thinking that the pull-up mode was magic and would handle all situations... Now, I know better. Cheers..

gary