Testing boolean return value from function

I have a library that I need to modify, its the WiflyHQ library in the open method.

The wifly gets stuck from time to time and cannot get a prompt. When it tries to open, it fails and logs out that it has crashed and must be rebooted. It never reboots by itself so I decided to first try adding the line:

reboot();

which you see in the bold red letters commented out, but that didnt work apparently. So I’ve decided to test the condition in my sketche’s loop function.

So I added this:

if (wifly.promptFailed==false) {
    Serial.println("wifly didnt open, will reboot it...");
    wifly.reboot();
  }

but I get this error on compiling:

TimeAlarmCO2WiFiPost.ino:69:13: error: within this context
Error compiling.

Ive declared the boolean in the WiflyHQ.h file like this:

boolean promptFailed;

Why cant I do this?

boolean WiFly::open(const char *addr, uint16_t port, boolean block)
{
    char buf[20];
    char ch;

    if (connecting) {
	/* an open is already in progress */
	return false;
    }

    startCommand();

    /* Already connected? Close the connection first */
    if (connected) {
	close();
    }

    simple_utoa(port, 10, buf, sizeof(buf));
    debug.print(F("open ")); debug.print(addr); debug.print(' '); debug.println(buf);
    send_P(PSTR("open "));
    send(addr);
    send(" ");
    send(buf);
    send_P(PSTR("\r"));

    if (!getPrompt()) {
	debug.println(F("Failed to get prompt"));
	debug.println(F("WiFly has crashed and will reboot..."));
	[b]//Add reboot code
	//reboot(); Didn't work for some reason
	promptFailed = false;[color=red][/color][/b]
	while (1); /* wait for the reboot */
	return false;
    }

    if (!block) {
	/* Non-blocking connect, user will poll for result */
	connecting = true;
	return true;
    }

    /* Expect "*OPEN*" or "Connect FAILED" */

    while (readTimeout(&ch,10000)) {
	switch (ch) {
	case '*':
	    if (match_P(PSTR("OPEN*"))) {
		DPRINT(F("Connected\n\r"));
		connected = true;
		/* successful connection exits command mode */
		inCommandMode = false;
		return true;
	    } else {
		finishCommand();
		return false;
	    }
	    break;
	case 'C': {
		buf[0] = ch;
		gets(&buf[1], sizeof(buf)-1);
		debug.print(F("Failed to connect: ")); debug.println(buf);
		finishCommand();
		return false;
	    }

	default:
	    if (debugOn) {
		debug.print(F("Unexpected char: "));
		debug.print(ch,HEX);
		if (isprint(ch)) {
		    debug.print(' ');
		    debug.print(ch);
		}
		debug.println();
	    }
	    break;
	}
    }

    debug.println(F("<timeout>"));
    finishCommand();
    return false;
}

I do not have the wifly library, and you didnt include a link to it or the actual library name, not its class/method - so I am guessing.

If promptFailed is a method then you must use the "()" after it. -

if (wifly.promptFailed()==false) {
    Serial.println ...
}

Quite apart from that if you have a function/method return a boolean the way to us it is

if ( function() ) { things if true }

or if you need the opposite

if ( ! function() ) { things if false }

The "==" operator expects two values, one on either side and will return a boolean

The library is here:

https://github.com/harlequin-tech/WiFlyHQ

promptFailed is a boolean property I added, not a function.

The method is wifly.open() and I did try it as:

If (!wifly.open())...

But it asked me for its 3 arguments.

Marciokoko: But it asked me for its 3 arguments.

Well, those three arguments are kind of important to doing what that function has to do. Why not just give it those arguments?

Dude, you aught to have figured out by now that these code snippets are worthless to us. We can't see how or where you have declared this boolean. And you've only posted the least informative of the error messages you got. There was more to it, post the whole error message.

You can't make getting the relevant info harder than pulling teeth from a crocodile and expect to get any meaningful help.

No, that's the whole message I got.

I posted the link to the library and since I only added a property declaration in the.h file and 1 line in the.cpp like I said, I didn't see the need to post the thousands or so lines of the wiflyhq.cpp file.

I tried posting the whole h and cpp file but I can't because it's too long a file.

Marciokoko: No, that's the whole message I got.

Can't be. There's no error that gives you an "in this context" without telling you what it is talking about. Scroll up. What you've posted is only one tiny piece of an error message.

Marciokoko: I posted the link to the library and since I only added a property declaration in the.h file and 1 line in the.cpp like I said, I didn't see the need to post the thousands or so lines of the wiflyhq.cpp file.

What if you put them in there in the wrong place and we're assuming you did it right?

If it won't post, attach it.

Ok here is what I did. I marked them in red. I tried 2 things:

FIRST

  1. Tried calling reboot from the library itself when that error ocurred by adding the reboot line by itself.

That doesnt seem to work. It keeps crashing and I havent been able to get it to crash while connected to the computer. Actually it was connected to the computer when I tried it but the serial monitor stopped logging after a while and it stopped logging after about 5 samples. The module crashed at about the 12th sample

  1. Adding a boolean flag and checking for it in my sketches loop method.

I just scrolledup to see the whole error:

In file included from TimeAlarmCO2WiFiPost.ino:6:0:
/Users/quique123/Documents/Arduino/libraries/WiFlyHQ/WiFlyHQ.h: In function ‘void loop()’:
/Users/quique123/Documents/Arduino/libraries/WiFlyHQ/WiFlyHQ.h:332:13: error: ‘boolean WiFly::promptFailed’ is private
boolean promptFailed; //Added by me Oct 30 2015
^
TimeAlarmCO2WiFiPost.ino:69:13: error: within this context
Error compiling.

WiflyHQlib.txt (85.6 KB)

Aha, there you go. You've put promptFailed with the private variables in that class. You can't see private variables from outside the class code. Make that variable public.

Ok, I've moved the boolean to the public section. Now here is a related issue which affects this one.

As you noticed, I had tried placing the reboot(); line in the library file itself, wiflyhq.cpp exactly where the code logs the line that it has crashed and must be rebooted. I just got confirmation that the code is run and the reboot function is called but the module doesnt seem to reboot. I got this in the serial monitor:

Failed to get prompt
WiFly has crashed and will reboot...
rebooting...

where the first two lines are from the wifly::open() method and the 3rd and last line is from a comment I added at the beginning of the wifly::reboot() method as shown here:

/** Reboots the WiFly.
 * @note Depending on the shield, this may also reboot the Arduino.
 */
boolean WiFly::reboot()
{
    debug.println(F("rebooting..."));
    if (!startCommand()) {
    return false;
    }
    send_P(PSTR("reboot\r"));
    if (!match_P(PSTR("*Reboot*"))) {
    finishCommand();
    return false;
    }
    delay(5000);
    inCommandMode = false;
    exitCommand = 0;
    init();
    return true;
}

Im thinking this means the boolean code will be called but the shield will not reboot anyway.

This should mean there is something wrong with the module itself, right?

I have another idea, but I need your input. If I have the Arduino reset itself using the wdt, does that "power cycle" the arduino? Because if so, that might be equivalent to hitting the reset button on the wifly module seeing as how the actual wifly.reboot() doesnt work.

So I was thinking of adding the code in the setup():

wdt_enable(WDTO_8S);

and this code in the loop somewhere. Perhaps in the test for the boolean flag I had before like so:

void  loop(){  
  Alarm.delay(10); // wait one second between clock display
  if (wifly.promptFailed==false) {
    Serial.println("wifly didnt open, will reboot it...");
    wdt_reset();  //pat the dog
  }
}

does that "power cycle" the arduino

No.

OK, is there a way to power cycle the Arduino from code?

Marciokoko: OK, is there a way to power cycle the Arduino from code?

Not without using external hardware.

So I guess I have to cross my fingers and hope using wdt or something I found called software_Reset() to see if this will do anything to the WiFi module.

At the moment I'm running other tests to see if instead of rebooting, perhaps closing and reopening my connection will un-hang the WiFi module.

I don't have any experience with the WiFly but from my experience with the W5100 and Ethernet library you could toggle the WiFly Reset pin low for >160us(from the datasheet) with an Arduino pin and then call wifly.begin() or whatever other initialization is needed. If you do a wdt reset of the Arduino first and then a reset of the WiFly that should be just as good as a full power cycle.

Ok that sounds promising. From what I saw, the ic has its reset at pin 40, but it translates to pad position #5?

To set it to low I would have to write LOW to it, but how do I do it for 160us? Just add a delay of about 200uc after the write low call?

How would I simply set it back to what it was?

Marciokoko: How would I simply set it back to what it was?

Write it HIGH again. If it wasn't LOW before there aren't too many options for what it could have been

Ok im looking into this writing LOW to pin. I can see it is pin 5 on the wifly pad. But that module is connected to a shield in my case:

http://www.tinyosshop.com/datasheet/Tinysine%20WIFI%20shield.pdf

but I dont understand how to access pin 5 of the module (red pcb) from the shield connected to my UNO (blue pcb). What am I missing here?

A jumper wire, perhaps ?