Request sent but recieving Bad Request error from browser

I’ve just started trying to use Particle.function to send data from a website to a Particle. While the data is being sent and the action is working as expected my JavaScript (jQuery) $.ajax() request is coming back with a Bad Request error.

The only thing I can think of is that this is because my site is on localhost but thought I would run it by the community to see if anyone else has had a similar problem.

JavaScript AJAX request

    // Fire off the request to /form.php
    request = $.ajax({
        url: "https://api.particle.io/v1/devices/" + $("#deviceid").val() + "/settimer",
        type: "POST",
        data: {args: $("#minutes").val() , access_token: $("#accesstoken").val() }
    });

PHP Form:

<form id="timer">
    <label for="minutes">Set Tmer for</label>
    <input id="minutes" name="m" type="text" value="" placeholder="30" max="99" min="1" inputmode="numeric" maxlength="2" />
    <label for="minutes">minutes</label>
    <input id="deviceid" type="hidden" name="deviceid" value="<?php echo( $_COOKIE["deviceid"] ); ?>">
    <input id="accesstoken" type="hidden" name="accesstoken" value="<?php echo( $_COOKIE["accesstoken"] ); ?>">
    <input class="button" type="submit" value="Set" />
</form>

Happy to provide more code if needed. :slight_smile:

I’m still having this problem but it seems to be a timeout and not a bad request. Do I need to be doing something to tell the API that my request was successful and send that back to the JavaScript in the browser?

Firmware code:

void setup() {
    Particle.function("settimer", getMinutes); //listen for the number of minutes
    //additional setup stuff

}

//this gets the input from our POST request and sets the number of minutes and runs the countdown
int getMinutes( String command ) {
    int minutes = command.toInt();  //minutes from our function
    float milliseconds = minutes * 60000; //number of milliseconds
    float wait = milliseconds / 85; // total millisconds divided by 85 (we have 85 "steps" between 170 and 255 in the wheel function)
    startCountdown(wait); //run the countdown function
}

Your function has to return an integer and has to return it within a few seconds - no waiting inside a Particle.function()!

To elaborate on that, you’d need a return X at the end, and preferably keep the function as short as possible. Set a ‘flag’ which you pick up on in your loop. Then handle all the waiting/actions there. That way your function can respond immediately, and won’t block the rest.

1 Like

Thanks @Moors7 and @ScruffR!

I was able to get the Particle.function() to return correctly by using the following code

bool checkFlag = FALSE; // global to check if getMinutes have been set 
int timerMilliseconds; 

void setup() {
     Particle.function("settimer", getMinutes); //listen for the number of minutes
}

void loop() {
    if( checkFlag ) {
        startCountdown( timerMilliseconds );//run the countdown function
        checkFlag = FALSE;
    }
}

 //this gets the input from our POST request and sets the number of minutes and runs the countdown
int getMinutes( String command ) {
    int minutes = command.toInt();  //minutes from our function
    float milliseconds = minutes * 60000; //number of milliseconds
    float wait = milliseconds / 85; // total millisconds 
    timerMilliseconds = wait;
    checkFlag = TRUE;
    return timerMilliseconds;
}  

It seems a bit silly to create timerMilliseconds but I was having trouble converting from float to int I also use wait in another function so couldn’t use the name globally. Any suggestions on how to handle this or is this an okay method of going about this?

How about that?

volatile int timerMilliseconds;

void loop() {   
   if( timerMilliseconds > 0 ) {
        startCountdown( timerMilliseconds ); //run the countdown function
        timerMilliseconds = 0; 
    }
}

int getMinutes( String command ) {
    return (timerMilliseconds = command.toInt() * 60000 / 85);
}

Since toInt() returns zero on fail your code won’t brake and you can consider 0 as no success on your remote end.

2 Likes

Wow way to simplify things a ton! :smile: Thanks so much!

1 Like