Using MIT App Inventor to pass integer values to Photon

Hello,
This may be more of an MIT App Inventor question, but maybe someone is familiar with app inventor and can help. I could also use help with handing the variables on the photon code side. I haven’t seen much information about that.I’m trying to pass two integer values, thermostat setpoints, from MIT App inventor to my Photon. Originally, I was just attempting to send the values, but it was suggested that I needed to make a list. I have attempted to do this using an example I found, but having issues. Right now I’m getting the following error on my Android phone when I click the button:

Error 1112: Unable to build request data: element 1 is not a list.

I’m not sure what element 1 is or how to fix the problem. Beyond that I don’t know what other errors I might be making in the
execution of this task. I haven’t been able to find much information about sending numerical values or list.
Can someone please help?

Thanks,

James

Have you already had a look through the threads mentioning appinventor?
https://community.particle.io/search?q=appinventor

If you got some “code” from any of these, posting a link would help.

It would help to know what you’re trying to accomplish. It looks like from your code that you want to send two values to your device. Is that correct? I’m not sure you would need a list to do that. I think something like this, where you combine the two values, should work.

This could be simplified quite a bit to the following that doesn’t use any global variables

These would send the two values separated by a comma, which you could then separate in your device code. You would need to change tempValues in the /tempValues?access_token= string to whatever the name of your Particle.function is.

Hello Ric,

Thanks for your reply. I’m trying to build a phone app that will take a low and high temperature setting and send it to the particle board to be compared with a temperature reading from a temp probe connected to the Photon. It mimics a thermostat, which could be achieved with one temperature setting, but it was already set up that way from another team member.

I have attempted to duplicate the blocks you suggested with the correct information for my application. I don’t understand how this whole operation works with the function on the particle end. Am I supposed to put place holders in the function heading for them or am I supposed to declare a variable either globally or in the function and the procedure call automatically modifies the value within the function. Also, I have another variable for water temperature from the temp probe that is being passed in from the main function where the function is being called. Is this going to work?

Below are screen shots of the blocks and the particle function. Originally, I had the variable names identified in the app inventor blocks and used the same name in the function. I’m not sure what I should do at this point.

Thanks for your reply. I took a look at the link. Sorry if I didn’t look around enough to find the appropriate page, I did a search, but didn’t seem to find anything related to my question.

You need a Particle.function whose name is Heater_Control. What the code blocks are doing is calling that function. So you should create that in setup like so,

Particle.function("Heater_Contol", functionHandler);

You then need to have the handler, functionHandler, defined as it should be for a particle function,

int functionHandler(String cmd) {
    // cmd is a String that should contain the pair of values that you sent
    // do what you need to do to parse the string 
    return 1;
}

**Note:**I just noticed that your name, Heater_Control, is too long. It needs to be 12 characters or less.

Oh my

Ric,

I’m obviously not an experienced programmer. The only command I can find in the particle related sites for parsing string is stream.parseInt(), but when I try to put that in my code the compiler says stream is undeclared in the scope. What class is stream.parseInt() from or what include directive should I use to make it work supposing this is the command I should use? I tried IO stream.

You said the code blocks in app inventor are calling Heater_Control, but Heater_Control is set to htrCntrl so shouldn’t the particle function be htrCntrl?

I have changed the code to mostly empty functions and just trying to get the string into my code first. Does this look like I’m on the right track?

void htrCntrl(){

   Particle.function("htrCntrl", tempCntrl);
   //int loTemp = stream.parseInt();
   //int hiTemp = stream.parseInt();
   
}

int tempCntrl(String command){
    
     Serial.println("tempCntrl has been called."); 
     Serial.println(command);
    
    return 1;
}

This is what you were sending with your code block:
https://api.particle.io/v1/devices/"deviceID"/Heater_Control?accessToken="access token here"

This url calls a Particle.function called Heater_Control (the parameter you passed just before the ?)
Make sure you change your block code to have htr_Cntrl instead of Heater_Control

Particle.function("htr_Cntrl", tempCntrl);

tempCntrl is the actual function that will be executed by the call from your phone app.

As for parsing the string that's passed in to functionHandler, you can do that using the C function strtok(). That's not a Particle thing, just C. First, you have to convert the String object, cmd, to a char* which is what strtok() takes, then convert those char* to int with atoi

int tempCntrl(String cmd) {
   char stringArgs[10];
   cmd.toCharArray(stringArgs, 10);
   char* lowTempString = strtok(stringArgs, ",");
   int temp = atoi (lowTempString);

   char* highTiempString = strtok(NULL, ",");
   int highTemp = atoi(highTempString);
        
   return 1;
}

So, now you have the two ints, lowTemp and highTemp, that you can do with what you want.

1 Like

Ok, I think I know what you’re saying now – you changed Heater_Control to htrCntrl because the previous name was too long, and you’re using tempCntrl as the function name. I’ve updated my last post to show that.
The point you seem to be missing is that the Particle.function line is basically just informing the cloud that you have that function; that line should go in setup(); you don’t have any code after that, that does anything. It should not be inside void htrCntrl() as you have in your last post.

void setup() {
    Particle.function("htrCntrl", tempCntrl);
    //other stuff that you need to setup
}
1 Like

I’m getting the string into the function now. I had some typos in the app inventor blocks that were preventing it from working. So now I’m working on getting it parsed. I think my problem was I wasn’t capitalizing stream, but it still won’t compile. I changed the code to this:

void htrCntrl() {
    Particle.function("htrCntrl", tempCntrl);
}
    
int tempCntrl(String command) {
     Serial.println("tempCntrl has been called."); 
     Serial.println(command);
     int loTemp = String.parseInt();
     int hiTemp = String.parseInt();
        
    return 1;
}

Should something like this work. Will it take the first part up to the comma with the third line in tempCntrl and skip the comma in the forth line and take the rest?

oh, I have tried stream and string. which should I use?

In such case you need to show the exact error messages.

And you can't use a class method like parseInt() if you haven't got an object of that type.
A String object is not a Stream object, hence you can't use the Stream methodes on it.

Using @Ric's strtok() suggestion would be the way to go

see above

Or you could go the "less pro" way with String methodes toInt(), substring() and indexOf()

What is the purpose of the htrCntrl function? Are you calling it from setup (if so, why not just put the Particle.function call in setup like I said)? The Particle.function should only be called once.

1 Like

I’m calling htrCntrl from main which is doing other things as well, I think would be the reasoning there, but I’m sure I don’t see things as clearly as you. I’m doing this for a school project with two other individuals. So, there is more code and actually the compile errors I was just talking about seemed to be coming from other parts of the code. When I comment out the part I’m asking about though the errors go away.

If I wasn’t using the right command to parse it, I suppose I should back up and try what you have told me, if I can figure it out. Oh I just noticed you sent some code. Let me incorporate that and see what I get.

This gives raise to another question: "How are you building the firmware?"

The usual framework used on these devices does not feature a main() function.
The actual main() function is burried in the Particle firmware framework and not meant to be tampered with if ther is no good reason for it.

But the point is Particle.function() is to be called only once per function initialisation and hence should be placed in setup() normally.

Okay, I’m using Particle Build to build the firmware. I have Particle function is setup and I have what you see in the code, so I guess it’s being called twice.

Thanks for your help and the code. I’m getting an integer value now. The rest of my code is not totally working, but I can probably figure that out on my own. If not I guess I’ll be back.

I didn’t mean for you to totally have to do it for me, but I wanted to be able to figure it out and it would have took a lot of back and forth for me to get all of that.

It’s way past my bed time here on the east coast.

Looks like I may have replied to the wrong post, but thanks for the help from both of you. I will try to rectify the situation with calling the Particle function from the wrong place or calling it twice.