Android App - MIT Inventor 2 - Spark - Web enabled button

Good Evening!

I am a very beginner programmer and thought I would share a project that I finished in a day. I wanted to create an Android Application that I could open and close my garage doors from my phone. This is a very simple setup and anyone should be able to find there way!

  1. Connected spark to a two way relay:

I used a 5v 2A power brick and wired the ground and the VCC directly to the adapter. I wired the In1 to the D6 pin of the spark, and In2 to the D4 pin. You can choose any of the digital outputs from the spark, just keep your code consistent.

  1. Upload the firmware from the Spark Build to your device. I modified the basic code from the Internet connected LED.
// -----------------------------------
// Controlling Garage Door
// -----------------------------------

int door1 = D4;   // which ever pin you wire the relay too, put it here
int door2 = D6;


// Last time, we only needed to declare pins in the setup function.
// This time, we are also going to register our Spark function

void setup()
{

   // Here's the pin configuration, same as last time
   pinMode(door1, OUTPUT);
   pinMode(door2, OUTPUT);

   // We are also going to declare a Spark.function so that we can open a garage door from the cloud.
   Spark.function("door1",doorOne);       //remember this door1 and door2, we are going to call it from the android app
   Spark.function("door2",doorTwo);
 
   // This is saying that when we ask the cloud for the function "door1", it will employ the function doorOne() from this app.

   // For good measure, let's also make sure both Relays are off when we start:
   digitalWrite(door1, LOW);
   digitalWrite(door2, LOW);

}


// Since we're waiting for input through the cloud this time,
// we don't actually need to put anything in the loop

void loop()
{
   // Nothing to do here
}

// We're going to have a super cool function now that gets called when a matching API request is sent


int doorOne(String command) {
    /* Spark.functions always take a string as an argument and return an integer.
    Since we can pass a string, it means that we can give the program commands on how the function should be used.
    In this case, telling the function "on" will turn the Relay on them off right away to simulate a button press.
    Then, the function returns a value to us to let us know what happened.
    In this case, it will return 1 for the RELAY turning on, 0 for the RELAY turning off,
    and -1 if we received a totally bogus command that didn't do anything to the RELAYS.
    */

    if (command=="on") {
        digitalWrite(door1, HIGH);
        delay(250);  //this delay seems to work for the garage door
        digitalWrite(door1, LOW);
        return 1;
    }
    else if (command=="off") {
        digitalWrite(door1, LOW);
        return 0;
    }
    else {
        return -1;
    }
}

int doorTwo(String command) {
    // Spark.functions always take a string as an argument and return an integer.
    

    if (command=="on") {
        digitalWrite(door2, HIGH);
        delay(250);
        digitalWrite(door2, LOW);
        return 1;
    }
    else if (command=="off") {
        digitalWrite(door2, LOW);
        return 0;
    }
    else {
        return -1;
    }
}

Once this was working I was able to test it out with a simple html file. But I wanted an android app. So onto MIT inventor 2.

http://appinventor.mit.edu

Sign up and create an account. The real hard part is actually placing the buttons and text that you need. But for this to work I created 2 buttons, a result text, and added the web component under connectivity. You will have to play around with layouts to get something that looks nice. This is the minimum you will need for the application to work.

Onto designer:

You are going to build a set of blocks by selecting the items from the left, and dragging and dropping the items you want.
This is going to be the hardest part. I will show you what I did, and try to explain it as much as possible.

  1. First you are going to create to global variables, one is going to be your access_token and other is your device ID. You can technically hard code these in your program, but this makes it easier. (variables are under the variables tab)
    Once you drag two global variables, you will have to rename them, and attach a text block. This text block will contain you actual numbers (token and device id)

  2. Second is too create your actions. Under the button block you will see the block called [When(button).Click]
    basically you will be adding commands to run when the button is clicked. My first block I got from under the status text. It is originally has the text “Status” but when I click I wanted to change it too “Working…”
    After it changes to “Working…” I want to call the actual procedure to open the door.

  3. Create your procedure: Procedures are purple blocks. [@ to door1] when I call that procedure I want to run the following commands that are attached. First command is too set my URL (web component), by using join I am combining my URL with my variables. The purple is just text, and orange is to grab a variable. Eg. https://api.spark.io/v1/devices/ + get{global Device_ID} builds the single line https://apt.spark.io/v1/devices/1e003000

I then use the procedure to post text(post HTTP request) to my spark. “args=on” sends the command “on” to the spark with corresponds to the spark firmware:

    if (command=="on") {
        digitalWrite(door2, HIGH);
        delay(250);
        digitalWrite(door2, LOW);
        return 1;
    }

The door1, and door2 in the URL correspond to the two procedures in the spark firmware:

   Spark.function("door1",doorOne);
   Spark.function("door2",doorTwo);
  1. Response text

The last part is not needed to function, but provides some feedback to your spark. When I click on a button, I wanted it to say working, then if I got a valid response 200, then it worked. If I got any other response then say failed.

I build the response section using the block from web called [when (Web1),gotText]
I am using the if then from the control blocks (select if then, then click on star then drag the else to attach)
The logic is:

If (math) variable responseCode = 200 then print success, else print failure.
yellow is control, blue is from math, dark green result under the resultText block, orange is from variables, purple is text.

If you have any questions please let me know. I typed this out in 10 minutes so might not be as clear as possible.


(ScruffR: I’ve just reformatted your code blocks)

4 Likes

Hey looks good! trying to do something similar. Why does the response code have to be equal to 200? Why is 200 significant?

This is the common HTTP response code for successful (OK) requests.

1 Like

okay thanks for the help!

In your spark firmware you have the spark return a “1” if the command received is equal to "on"
What does this “return 1” do?

Although it’s not my code, these return x statements are the way how the device signals back to the caller of the remote function what it did.
Whether this return code is used or not is up to the calling app.

Is it possible to have app inventor receive that returned “1”?
Thanks again!

I’d say yes, but since I’m not using it, you might need to ping the OP.

Would you mind clarifying OP for me please?

“OP” = “Original Poster”

Thank You!

I have not tried out yet, but instead of posting to the Spark you can issue a call or get command. This would allow you to read a value and display it on the app. Here is a link to someone that wrote a smart thermostat for his phone. It allows him to read a temperature probe and display the current value in his app.

Thanks!