Beginner Tutorial: IFTTT Publish an Event + Spark Internet Button

Heyo! We’re going to be using Spark’s new Internet Button and the IFTTT channel to build a fun way to stay connected with loved ones while they travel. To build along with me you’ll need a Spark Core or Photon and an Internet Button. I’ll be setting this up using gmail, but if you don’t have a gmail account you can setup a similar project using SMS.

All right, let’s get going….

I live in Minneapolis but I often work out at Particle HQ in San Francisco. When I’m at the HQ the days tend to be packed full of meetings, brainstorming and projects (or Kickstarter launches!). I sometimes don’t get a chance to connect with my husband all day so I thought I’d build a fun project to make sure I let him know I’m thinking of him amidst the whirlwind life at a startup. Yeah it’s a little corny, but trust me, when your Sig-O supports you through the late nights and general life-takeover of a startup you’ll want to make fun projects for them, too.

So! I’m going to build a button for the Sparkhaus (HQ) that sends a message to my husband to let him know I’m thinking of him when it’s pressed. All of your buttons will send messages to my husband too. In all seriousness though, this tutorial is about learning how to easily build projects using the directional buttons on your Internet Button and IFTTT.

Time to build.

Step 1: Hardware setup

I don’t think this will actually end up being much of a step, since your Photon and Button will ship pre-connected, but just in case, you’ll want to make sure your Photon is correctly plugged into your Internet Button as in the picture below:

Step 2: Connect your device to the Internet and claim it to your account. (If you’ve already claimed your device skip to step 3)

If this is the first time you’ve opened your board let’s start our by getting your Core/Photon claimed, instructions can be found here.

###Step 3: Log into your account at Particle.io/build

  • Click on the “Cores” button to make sure that your Core/Photon is connected. You should see a small cyan dot to the right of the name of the Photon in use. Make sure that the star to the left of your board in use is the one that is filled in.

###Step 4: Create a new app in the Web IDE

In anticipation of the launch of the Internet Button, @richard put together some awesome Button/IFTTT specific firmware. This will continue to evolve and will become an official Library prior to Button delivery. It makes creating these projects super easy.

In this case, I’m going to share my firmware with you - you’ll want to copy and paste it directly into the text editor of the IDE (labeled as “code”). If you want some help with navigating around the IDE a great place to start is the Web IDE section of our docs site.
Don’t forget to add the library and make sure there are no duplicate #includes introduced during the process.

#include "InternetButton/InternetButton.h"

InternetButton b = InternetButton();
uint8_t button1 = 0;
uint8_t button2 = 0;
uint8_t button3 = 0;
uint8_t button4 = 0;
uint8_t buttonAll = 0;
int gaugeCount = 0;


// The code in setup() runs once when the device is powered on or reset. Used for setting up states, modes, etc
void setup() {
    // Tell b to get everything ready to go
    b.begin();
}

/* loop(), in contrast to setup(), runs all the time. Over and over again. 
Remember this particularly if there are things you DON'T want to run a lot. Like Particle.publish() */
void loop() {
    if(b.allButtonsOn()){
        if(!buttonAll){
            buttonAll = 1;
            Particle.publish("allbuttons",NULL, 60, PRIVATE);
            b.rainbow(10);
            delay(100);
            b.allLedsOff();
        }
    }
    else {buttonAll = 0;}
    
    if(b.buttonOn(1)){
        if(!button1){
            button1 = 1;
            Particle.publish("button1",NULL, 60, PRIVATE);
            b.ledOn(12,50,0,0);
            delay(100);
            b.ledOff(12);
        }
    }
    else {button1 = 0;}
    
    if(b.buttonOn(2)){ 
        if(!button2){
            button2 = 1;
            Particle.publish("button2",NULL, 60, PRIVATE);
            b.ledOn(3,0,50,0);
            delay(100);
            b.ledOff(3);
        }
    }
    else {button2 = 0;}
    
    if(b.buttonOn(3)){
        if(!button3){
            button3 = 1;
            Particle.publish("button3",NULL, 60, PRIVATE);
            b.ledOn(6,0,0,50);
            delay(100);
            b.ledOff(6);
        }
    }
    else {button3 = 0;}
    
    if(b.buttonOn(4)){
        if(!button4){
            button4 = 1;
            Particle.publish("button4",NULL, 60, PRIVATE);
            b.ledOn(9,30,30,30);
            delay(100);
            b.ledOff(9);
        }
    }
    else {button4 = 0;}
}

Flash to your Core/Photon. Your board will blink magenta during this process and then automatically reconnect when it has the new firmware on board.

Now we’re ready for IFTTT.

###Step 5: Log onto IFTTT and hit “New Applet”

Then click “+this” to choose your action.

Step 6: Select Particle as your Trigger Channel (IFTTT step 1)

If you have not already activated the Particle channel you’ll need to do so now. Use the same email address you use for your Particle login account (but note that it needs to be all lowercase here for some reason).

###Step 7: Choose a Trigger (IFTTT step 2)

I want to use the part of my firmware that includes Particle.publish so I’m going to select “New Event Published”.

###Step 8 Complete Trigger Fields (step 3 in IFTTT)

In our firmware we can see that there are several events connected to Particle.publish() and we could fill in any of them (allbuttons, button1, etc).

I’m going to choose button2 for this example. That means this part of my code does the work on the firmware side: Particle.publish(“button2”,NULL, 60, PRIVATE);

I’ll want to fill out my trigger fields as below:

If (Event Name)
• Here I’ll add the Event Name (Topic) from my firmware -> button2

Is (Event Contents)
• Event Input is actually an optional field so I’ll go ahead and leave it blank.

Device Name or ID
• I’ll select the Core I want to use -good ol’ Narwhal Dentist

Once I’ve filled everything out I hit “Create Trigger” and move on.

###Step 9: Choose Action Channel (step 4 IFTTT)

I’d like to send an email when I press the button so I’m choosing the Gmail channel. You can also experiment with this recipe using other notification channels.

###Step 10: Choose an Action (step 5 IFTTT)

In this case there’s only one Gmail action to choose - send an email

Step 11: Complete Action Fields (step 6 IFTTT)

Now is where we can fill in who our email is going to and what we want it to say. I have no yet experimented with including a gif in this email but I am definitely planning to do so.

###Step 12: Create and Activate (step 7 IFTTT)

This is where you can write a nice description of your recipe (or else just leave what is automatically populated)

###Step 13: You’re all done!

Now it’s just time for testing. And for keeping your co-workers away from your button so that your sig-o does not get sent an email every 5 minutes. Here’s what Bill gets from me :slight_smile:

Next Steps: Now that you’ve learned how to use the push-buttons on your Internet Button with IFTTT you can go back and start creating different recipes for each individual push. While button2 may send an email to Bill, maybe I’ll set button1 to post to Spark’s slack channel that I’m hungry and want to go get food, or I’ll set button4 to post a tweet on @spark_io whenever it gets pressed. Lots of possibilities. Go crazy and please share your own projects!

6 Likes

Integrate with your Pebble!

@steph and @christine

This is an old thread but here is what I have for both publish and subscribe. I subscribe to a google doc and can see the replies real time. (about a 4 second lag).

The sort of image is here except I do no use the A5 pin I just connect it to 3V3.

My .ino is here


//PUT YOUR GLOBAL VARIABLES HERE
int myLoops = 0;

    
 // Any general setup stuff goes here   
void setup(){
    
    Particle.subscribe("my-lamp-on", myHandler, MY_DEVICES);   // for using the DO IFTTT button or the IF this then that

}


void loop(){
     
// here I am testing IFTTT publish

    delay(1);  // slow down the loop
    myLoops ++;
   
    if (myLoops >= 3000){   // wait 3 second betrween measurements actually about 5 seconds
       myLoops = 0;
        pinMode(D7, OUTPUT);
        digitalWrite(D7, 1);   // D7 On
        delay(20);
        
        pinMode(D7, OUTPUT);
        digitalWrite(D7, 0);   // D7 Off
        delay(20);
        
       if (analogRead(A0) >= 1000){
          Spark.publish("bright-light", "1000", 60, PRIVATE);
       } 

       if (analogRead(A0) <= 30){
          Spark.publish("no-light", "30", 60, PRIVATE);
       } 
    }
      
}


  void myHandler(const char *event, const char *data)    // for the DO or IF   IFTTT button
  {
        pinMode(D0, OUTPUT);
        digitalWrite(D0, 1);   // flash D0 for 2 seconds could change this to D7
        delay(2000);
        
        pinMode(D0, OUTPUT);
        digitalWrite(D0, 0);   // D7 Off

  }

Using this file your IFTTT code can detect a bright light and then turn on the LED. you can also detect dark while ignoring normal light levels.

Here is my image using the photon and SNAP CIRCUITS 750 with extra SNAP to Breadboard pins.

Today I am going to get my students to test if we remove the MY_DEVICES can we activate the lights on other students photons. We will need to make “my-lamp-on” become more unique such as “my-lamp-on-3534345” different for each student.

@Moors7 @christine

Hey Moors7, you are good at solving code issues. I wanted my code above to only take a reading once every ~3-5 seconds, but it either does not take a reading (if I flash a light for about a second) or it sends 2 or 3 readings to IFTTT. Any suggestions. Not sure if it is an issue with my code or Particles implementation of IFTTT.

Hey @rocksetta,

Looks like a neat project.
The way you do your timing is a bit unconventional, since it now depends on loop completion time, which can vary, as you may have noticed.

There are several ways you can use to remedy this, to make it more stable.

The simple-yet-not-so-great option: (this is blocking)

void loop() {
  // do stuff
  delay(3* 1000); //3s delay
}

The-more-common-solution: https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing (they explain it better than I’ll ever be able to)

The-really-fancy-stuff: (recently released software timers :smile:)
https://docs.particle.io/reference/firmware/photon/#software-timers

2 Likes

@christine @Steph

What a great lesson for my grade 11/12 students. They setup the above circuit and loaded the above .ino.

Then setup IFTTT using either the website or the App.

Activated Particle as a trigger channel in IFTTT.

Chose “New Event Published” .

All I really had to give them was these two images.

For the trigger:

and for the action:

More than half the class managed to do the extra step of: controlling the LED on a second groups Photon, when a bright light was brought near the first groups light sensor. Amazingly easy lesson. Super powerful results.

Thanks Particle.

4 Likes

@Moors7 @christine

Thanks for the tip about the Timer function. Here is the new version of the .ino which works much better, no random firing of the IFTTT. It now gets one reading every 7 seconds.

    //PUT YOUR GLOBAL VARIABLES HERE
    
    Timer myTimer1(7000, my7sFunction);   // activate function every 7 seconds
                                         // Must hold the light on while D7 flashes
    
        
     // Any general setup stuff goes here   
    void setup(){
        
        pinMode(D0, OUTPUT);
        pinMode(D7, OUTPUT);
        myTimer1.start();
        Particle.subscribe("my-lamp-on", myLampFunction, MY_DEVICES);  
        // for using the "DO" IFTTT button or the IF this then that                                                                      
        // must remove ", MY_DEVICES" for Public anyone to access

    }
    
    
    void loop(){
         
      // your looping stuff here
    
    }
    
    
    void my7sFunction(){
        
        static int myCount = 0;
        myCount++;    // not really used but good to keep count
        
        digitalWrite(D7, 1);   // D7 On, flash D7 every 7 seconds
        delay(20);
        digitalWrite(D7, 0);   // D7 Off
        
        if (analogRead(A0) >= 1000){  
            Spark.publish("bright-light", "1000", 60, PRIVATE);
        } 
    
        if (analogRead(A0) <= 30){
            Spark.publish("no-light", "30", 60, PRIVATE);
        } 
          
    }
    
    
    void myLampFunction(const char *event, const char *data){   
 // for the "DO" or "IF" IFTTT buttons
    
            digitalWrite(D0, 1);   // flash D0 for 2 seconds
            delay(2000);
            
            digitalWrite(D0, 0);   // D7 Off
    
      }
1 Like

Glad to see its working. If I might add one more thing: software timers are to be treated as interrupts, and should thus ideally be kept as simple/short as possible. Use it to set a flag which you can check for in your loop. The code you’ve currently got probably work, but if you can make that change, that’d be better :smile:

Thanks @Moors7. Had no idea how to do your suggestion until I found this bit of code.

The isrFlag makes a ton of sense.

2 Likes

So I took @Moors7 suggestion and rewrote my code. Here is the working product. Interesting when using IFTTT, I switched back and forth between a few of my students particle logins and I had to set my Particle.subscribe to public (by removing , MY_DEVICES) even though I was correctly logged into IFTTT and particle as one of my students trying to access the students photon. Almost as if IFTTT had remembered my first particle login so when I cleared that and logged in as a student to particle from within IFTTT, IFTTT thought I did not have access to the new photon. My suggestion is that, if you have problems with subscribe is to start with public and then work towards making things private.

Most people can start with private since they will not be switching back and forth between logins like I was doing.

//PUT YOUR GLOBAL VARIABLES HERE
volatile bool myFlag1 = false;
          int myCount = 0;

Timer myTimer1(7000, my7sFunction);   // activate function every 7 seconds

  

void my7sFunction(){
    
    myFlag1 = true;

}  
  
    
 // Any general setup stuff goes here   
void setup(){
    
    pinMode(D0, OUTPUT);
    pinMode(D7, OUTPUT);
    
    myTimer1.start();
    Particle.subscribe("my-lamp-on", myLampFunction);   //, MY_DEVICES
    // for using the "DO" IFTTT button or the "IF" this then that
    // must remove ", MY_DEVICES" for Public anyone to access
    
}




void myLampFunction(const char *event, const char *data){    

    digitalWrite(D0, 1);   // flash D0 for 2 seconds
    delay(2000);
        
    digitalWrite(D0, 0);   // D0 Off

}



void loop(){
     
  // your looping stuff goes here
  
    if (myFlag1){
        
        myCount++;    // not really used, but good to keep count
        digitalWrite(D7, 1);   // turn D7 on
        delay(20);
        
        if (analogRead(A0) >= 1000){
           Particle.publish("bright-light", "1000", 60, PRIVATE);
        } 

        if (analogRead(A0) <= 30){
           Particle.publish("no-light", "30", 60, PRIVATE);
        } 
        
        digitalWrite(D7, 0);  // turn D7 off
        myFlag1 = false;      // reset timer variable
    }
  
}

This is a DRAFT:

It looks like a webpage can publish an event on IFTTT, using the Maker channel on IFTTT. Here is some working code. First a webpage code, with a form to POST data to IFTTT, an image of that page, then the IFTTT page, then an optional php page that saves the sent variables to a file as proof that the event was fired.

<html>
<head>


<title>HTML form to IFTTT </title>



</head>

<body onload="{
   myStorage1 = localStorage.getItem('myStoredText1')
   if(myStorage1  != null){     
      document.getElementById('myToken').value = myStorage1 
    }   
    myStorage2 = localStorage.getItem('myStoredText2')
    if(myStorage2  != null){
       document.getElementById('myDeviceId').value = myStorage2      
    }
          
}">



<h2 align=center>HTML form to IFTTT using the Maker Channel<br> </h2>



Device ID:<input id="myDeviceId" name="myCoreID" type=text size=50 placeholder="button_pressed4"> <br>



Access Token:<input id="myToken" name="access_token" type=password size=50 placeholder="5622ce6bba702ef6bd3456d5ed26aaa4a28d7c9"> <br>





<form name="myForm" method="POST" id="myCoolForm" ><br>

<input id="myParameter1" name="value1" type=text     size=50 value="d7-send-high"> 
<input id="myParameter2" name="value2" type=text     size=50 value="d7-send-low"> 
<input id="myParameter3" name="value3" type=text     size=50 value='{"fred":"tom","Mary":"45"}'> 

<input type=submit onclick="{
    document.myForm.action = 'https://maker.ifttt.com/trigger/' + document.all.myDeviceId.value + '/with/key/'+ document.all.myToken.value
}">

</form>



<input type="button" value="Store the Photon's Token and ID locally!" onClick="{
   localStorage.setItem('myStoredText1', document.all.myToken.value)   
   localStorage.setItem('myStoredText2', document.all.myDeviceId.value)
   alert( document.all.myToken.value + ' ' +document.all.myDeviceId.value + ' \nHas been stored')
}">






<br><br>




</body>
</html>

Here is an image of the page. Oops I forgot to change some of the statements from the page I took it from.

Here is the working IFTTT receipe. NOTE: YOU CAN ONLY SEND THREE VARIABLES THAT MUST BE CALLED value1, value2, value3.

The more advanced php page.

<?php

$myFile = "testFile.txt";

// opens the file for appending (file must already exist)
$fh = fopen($myFile, 'a');


$myPost = "value1 =". $_POST['value1'] . "value2 =" . $_POST['value2'] . "value3 =" . $_POST['value3'];

// Write to the file
fwrite($fh, $myPost);

fclose($fh);
?>

Here is what gets sent to the file called testFile.txt (which must be pre-saved on the php server)

value1 =d7-send-high, value2=d7-send-low, value3= {“fred”:“tom”,“Mary”:“45”}value2 =value3 =

strange the value2 =value3 = at the end of the line but that is what I got.

I will try to combine this stuff with my code for the photon in the post above. This could allow a mySQL database (or some other php code) to do some of the heavy computing for a photon and then returninformation back to the photon.

1 Like

So the above code is a bit confusing and my webpage has some remnents from old code that make it confusing so I started a new topic at

The firmware flash fails for me, with a fatal error caused by ‘sparkbutton’ - https://i.imgur.com/Og0mpDV.png

Is this due to a new naming of the button or something else?

Try including the Internet button library, then comment out the previous include (the one mentioned in the error).

Hi, Steph!

Thanks for posting this tutorial. I’m finally getting started with the Photon button. I see a comment below that says it’s an old one, which might be causing my issue…

When I load up the code in the Particle web-based ide, I get this error:

iftttbuttonpush.cpp:1:37: fatal error: SparkButton/SparkButton.h: No such file or directory
 #include "SparkButton/SparkButton.h"
compilation terminated.
make[1]: *** [../build/target/user/platform-6iftttbuttonpush.o] Error 1
make: *** [user] Error 2
Error: Could not compile. Please review your code.

It seems to be saying I’m not including the SparkButton.h file correctly. Is there a different way to include that file?

See screengrab below.

Thanks!
Toby

Considering it’s the exact same issue as asked directly above, have you given that solution a try? https://docs.particle.io/guide/getting-started/build/photon/#using-libraries

@Moors7, Thanks for the quick reply.

Yes, I included the library at your suggestion (see updated screengrab below), but the result is the same.

Any thoughts on where to look next?

Toby

You’re still trying to include a library that doesn’t exist, then using that same non-existing library.

It should look something like this:

@Moors7: Ah thanks! Yup, that fixed that file reference error.

With the updated code, I'm getting all sorts of other errors (see below). I am well-versed in php, but this is my first go with a different code base. What's the best way to troubleshoot errors like these? Should I just work from the top-down?

iftttbuttonpush.cpp:3:1: error: 'SparkButton' does not name a type
 void setup();
 ^

iftttbuttonpush.cpp: In function 'void setup()':
iftttbuttonpush.cpp:15:5: error: 'b' was not declared in this scope
 
     ^

iftttbuttonpush.cpp: In function 'void loop()':
iftttbuttonpush.cpp:21:8: error: 'b' was not declared in this scope
 }
        ^

iftttbuttonpush.cpp:24:13: warning: 'Spark' is deprecated (declared at ../wiring/inc/spark_wiring_cloud.h:357): Spark is now Particle. [-Wdeprecated-declarations]
 Remember this particularly if there are things you DON'T want to run a lot. Like Spark.publish() */
             ^
iftttbuttonpush.cpp:32:8: error: 'b' was not declared in this scope
             b.allLedsOff();
        ^

iftttbuttonpush.cpp:35:13: warning: 'Spark' is deprecated (declared at ../wiring/inc/spark_wiring_cloud.h:357): Spark is now Particle. [-Wdeprecated-declarations]
     else {buttonAll = 0;}
             ^
iftttbuttonpush.cpp:43:8: error: 'b' was not declared in this scope
             b.ledOff(12);
        ^

iftttbuttonpush.cpp:46:13: warning: 'Spark' is deprecated (declared at ../wiring/inc/spark_wiring_cloud.h:357): Spark is now Particle. [-Wdeprecated-declarations]
     else {button1 = 0;}
             ^
iftttbuttonpush.cpp:54:8: error: 'b' was not declared in this scope
             b.ledOff(3);
        ^

iftttbuttonpush.cpp:57:13: warning: 'Spark' is deprecated (declared at ../wiring/inc/spark_wiring_cloud.h:357): Spark is now Particle. [-Wdeprecated-declarations]
     else {button2 = 0;}
             ^
iftttbuttonpush.cpp:65:8: error: 'b' was not declared in this scope
             b.ledOff(6);
        ^

iftttbuttonpush.cpp:68:13: warning: 'Spark' is deprecated (declared at ../wiring/inc/spark_wiring_cloud.h:357): Spark is now Particle. [-Wdeprecated-declarations]
     else {button3 = 0;}
             ^
make[1]: *** [../build/target/user/platform-6iftttbuttonpush.o] Error 1
make: *** [user] Error 2
Error: Could not compile. Please review your code.