I have a Core and Relay Shield. Trying to call a function on device but not working. I stripped all the logic out so it should simply turn off a relay that is initialized on. But, The relay comes on and stays on. What am I missing? Where is the return value coming from?
The HTML runs fine and get this result when the button is pressed.
Thanks,
Data Loaded: {“id”:“123456789098765432112334”,“name”:“liftassist”,“last_app”:null,“connected”:true,“return_value”:536891216}
Here are all the components…
HTML CODE: ( with fake core id and token)
(Had to remove left angle bracket to get HTML tags to print)
<!DOCTYPE html>
html>
header>
script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">/script>
script>
var baseURL = "https://api.spark.io/v1/devices/";
var accessToken = "1234567890987654321234456678890998777";
var coreID = "123456789098765432112334";
var method = "pool";
var url = baseURL + coreID + "/" + method;
function start() {
$.post(url,
{
access_token: accessToken,
params: "High" })
.done(function( data ) {
alert( "Data Loaded: " + JSON.stringify(data) );
});
}
/script>
/header>
body>
button type="button" onclick="start()">Pool Light Switch</button>
/body>
/html>
SPARK CORE CODE:
int RELAY1 = D0;
void setup()
{
//Initialize the relay control pins as output
pinMode(RELAY1, OUTPUT);
// Initialize all relays to an ON state
digitalWrite(RELAY1, HIGH);
//register the Spark function
Spark.function("pool", poolControl);
}
void loop()
{
// This loops for ever
}
int poolControl(String command)
{
digitalWrite(RELAY1, LOW);
return 1;
}
I’m guessing your code isn’t loaded on your core. Can you do a spark list with the CLI, or can you hit https://api.spark.io/v1/devices/your_core_id and confirm that your function is present?
The return value comes from the return statement at the end of the Spark function you wrote in your Spark firmware. In this case it should be 1. I like to make it something unique but identifiable easily like 200. It seems like it's talking to your Core, but you have some OTHER code in there that's not returning 1. If that function key "pool" wasn't available it should return something like this:
If I flash the Core with code that does not have the “pool” function I get an " ok false" response. When I flash the pool code the relay is coming on and staying on. Pressing the button gives me the “data loaded” message but does not turn the relay off.
I think you are both correct that Flash is not working properly. Is there a way to reset the core to wipe out old code?
By “reflashing”, do you mean ‘trying to upload the firmware over and over again using the web IDE’? If that’s the case, you could try a factory reset, which might help.
Ok I finally got this working… had a tough time actually getting it programmed from the Web IDE which is most likely most of your problem. If you leave the code as-is, you’ll know it successfully programs if the D7 led will light up blue. Try this code:
<!DOCTYPE html>
<html>
<header>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
var baseURL = "https://api.spark.io/v1/devices/";
var accessToken = "12341234123412341234123412341234";
var coreID = "1234123412341234";
var method = "pool";
var url = baseURL + coreID + "/" + method;
function startMe() {
$.post(url, {
access_token: accessToken,
params: "High" })
.done( function( data ) {
alert( "Data Loaded: " + JSON.stringify(data) );
});
}
</script>
</header>
<body>
<button type="button" onclick="startMe()">Pool Light Switch</button>
</body>
</html>
And the code for the Core… in this case it’s turning on the D7 led and turning it off by function call. Change D7 to D0 for your relay, or just leave it the way it is for a known working test of the LED.
BTW @Dave I think you’ll find this interesting… the original code posted will NOT program for me OTA even with the bug-fix/ota-flash-reliability firmware that’s known to be working flashed to the Core prior to the update.
I’ve narrowed it down to something quite perplexing… if I change the first line of code from
int RELAY1 = D0;
to
#define RELAY1 D0
it flashes just fine.
In either case the code compiles just fine and it hangs at some point near the middle to end of the flashing process usually for the original int definition. This is one of those cases where a debugger on the Core would be handy… if it’s failing at exactly the same spot in the code transfer each time, then there’s something unique about this code that breaks the OTA process.
It also fails if I add this to the top of the file:
#pragma SPARK_NO_PREPROCESSOR
#include "application.h"
int poolControl(String command);
Also if I program it locally with the original int definition it flashes fine and the application works as expected.
BTW, the code specifically that I used in my Core was Satish’s spark-common-lib bug-fix/ota-flash-reliability branch only, master for the other two. I tested this code this morning and it passed 38 out of 38 times with the dual curl command script, so I know the OTA process is known-good at this location, and on this specific Core.
Well I’m actually just clicking the Flash button in the Web IDE. You should be able to replicate it by just trying to flash this code from the web IDE. I haven’t tried to compile the code from the CLI through the Cloud. Every time it failed to re-flash OTA, I made sure to reprogram my Core locally with the OTA fix code… just to be sure I was starting with something that should work.
int RELAY1 = D0;
void setup()
{
//Initialize the relay control pins as output
pinMode(RELAY1, OUTPUT);
// Initialize all relays to an ON state
digitalWrite(RELAY1, HIGH);
//register the Spark function
Spark.function("pool", poolControl);
}
void loop()
{
}
int poolControl(String command)
{
digitalWrite(RELAY1, LOW);
return 1;
}
That is a weird, and awesome bug! (Yay reproducible test cases!). Based on that firmware, I created two binaries, one is only 8 bytes bigger than the other, and one always fails OTA right as the bootloader is switching to copy the external flash back into the stm32. Cool.
If you have CLI and want to follow along, just unzip the source file to a folder named OTA (it’s already this way in the zip file), then while in the directory above the one named OTA run this command:
@Dave if I add one byte of RAM to the OTA FAILS code, the flash size doesn’t change and it still fails, but if I add one command to update the value of that byte in the setup() function the flash size is now 16 bytes larger (which seems like a lot of bytes for this operation) but it will now re-flash OTA.
So it seems like there is some issue with flash size, perhaps it’s hitting a page boundary in just the wrong way that the routine is silently failing. I haven’t tried looking at the debug output yet, but hopefully this gets us going in the right direction.
I have to knock out some other stuff now but I’ll check back tonight !
my work around from when i first noticed the bug… add some useless code or comment out a useless line… worked every time!
@Dave@BDub fits exactly with what i was seeing a while back, if you need some similar code that does the same thing there is a link on the bug bounty post… there are libraries etc so its much bigger but it may help define another fail point to work out what sizes make it stop.