Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with .available() #34

Open
RileyStarlight opened this issue Feb 13, 2017 · 3 comments
Open

Issues with .available() #34

RileyStarlight opened this issue Feb 13, 2017 · 3 comments

Comments

@RileyStarlight
Copy link

I have been having problems with .available(), returning zero when there really was data in the input buffer. It seems that you need to leave a small amount of time between queries to return a correct value. Even though is not always like that.

@PaulStoffregen
Copy link
Owner

Perhaps the stop bit time matters?

If there really is a problem, I'm afraid I can't do anything (and must close this issue) unless you provide a (hopefully small) complete program that demonstrates the problem, and all other details needed to reproduce the problem. Realistically, the test program needs to be used with other hardware, which must be something like another Arduino or Teensy board also running a complete program, or some other hardware that's readily available for testing.

@RileyStarlight
Copy link
Author

Thank you for answering so quickly
The system that I am implementing uses an AT modem with which I communicate to send or receive data. This problem I have detected (and bypassed) in two points of my code.
The first is in the initialization of the modem, where I send AT and I expect to receive an AT echo followed with OK in a window of time.

bool modemBegin() {
    bool ret = false;
    char atbuff[16] = "";
    unsigned long tout = 0;

    sigfox.begin(9600);
    if (checkDebug(DEBUG_SERIAL | VERBOSE_DEBUG)) Serial.println(F(";Warming up modem..."));
    delay(SIGFOX_WARM_TIME);
    if (checkDebug(DEBUG_SERIAL | DEBUG_SERIAL_ATECHO)) Serial.println("\r\n;>> AT");
    Serial.flush();
    sigfox.println("AT");
    tout = millis();
    while (((tout - millis()) < AT_TIMEOUT) && (!sigfox.available()));
    delay(10); // FIXME should not be necessary but it doesn't work without it
    if (sigfox.available()) ret = modemExtractString(atbuff);
    else ret = false;
    return ret;
}

If I ask twice in a row, it leaves the loop correctly, since data has been received but it becomes false.
Just as instead of asking true or false make a numerical comparison, the result is the same and its solution too.

In the second case, within the finite state machine where the incoming data is processed, the available data questions in each case cause it to return false, causing the function to re-enter when it exits, since there are data available. Similarly in the previous case, it does not matter whether the comparison is boolean or numeric.

bool modemExtractString(char str[]) {
    bool ret = false;
    char c = 0;
    unsigned char subs = 0;
    unsigned int index = 0;
    unsigned long tout = 0;
    receiveFSM_t s = FSM_NONE;

    tout = millis();
    do {
        switch (s) {
          case FSM_NONE:
            s = FSM_ECHO_DETECT_1;
            break;
          case FSM_ECHO_DETECT_1:
            if (sigfox.available()) {
                c = sigfox.read();
                //Serial.print("D1 ");
                //Serial.println(c);
                if (c == 'A') s = FSM_ECHO_DETECT_2;
            }
            break;
          case FSM_ECHO_DETECT_2:
            if (sigfox.available()) {
                c = sigfox.read();
                //Serial.print("D2 ");
                //Serial.println(c);
                if (c == 'T') s = FSM_ECHO_SKIP_1;
                else s = FSM_NONE;
            }
            break;
          case FSM_ECHO_SKIP_1:
            if (sigfox.available()) {
                c = sigfox.read();
                //Serial.print("E1 ");
                //Serial.println(c);
                if (c == '\r') s = FSM_ECHO_SKIP_2;
            }
            break;
            // [...]
          case FSM_SAVE_UNTIL_EOP:
            if (sigfox.available()) {
                c = sigfox.read();
                //Serial.print("S  ");
                //Serial.println(c);
                str[index++] = c;
                //[...]
            }
            break;
        }
    } while ((s != FSM_OK) && ((millis() - tout) < AT_TIMEOUT));
    if (s == FSM_OK) {
        s = FSM_NONE;
        ret = true;
    }
    return ret;
}

In this case I can not enter a delay, since it causes overflow of the input buffer (up to 320 characters can be processed). The solution has been to not enter the function until there are the minimum of characters to process, 8 in my case.

if (sigfox.available() > 8) modemExtractString(rxstr); 

I hope this helps to locate the problem, anything else you need, you tell me.

@PaulStoffregen
Copy link
Owner

I'm currently working on another project. Actually, a very long list of other projects.

With only code fragments, I can't dedicate the time to fill in the rest to make this into a complete program, and then try to find a modem which will reproduce the problem.

If you want me to actually investigate, to actually put engineering time into this, you must post a complete program I can copy and paste into Arduino and upload to a board. If any part is missing, if it doesn't compile, I will stop there and do nothing more, so please take a moment to actually copy the program you post back into Arduino and verify it truly does reproduce the problem.

Then I'm going to need to know where to buy this modem. Ideally, you could write a 2nd program to run on another Arduino which does the simplest possible modem responses to reproduce the problem. I have plenty of Arduino boards. But if this modem is readily available, I could buy one. I do have a modest budget for such thing.

But the thing I do not have is time for guesswork. An incomplete program or lack of specific details means I will not look into this problem. I simply have far too many other urgent projects to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants