Blog

Coffee, Internet Buttons and Slack

Coffee, Internet Buttons and Slack

In a recent blog I detailed how I designed a case for a button that people can press to notify the office via Slack that a fresh pot of coffee has been brewed. Now for the fun part, the programming.

This project uses the Particle Photon and the Internet Button. Particle's hardware and development environment makes easy IoT projects like this a breeze. There are three components to the code that we'll need to put together:

  1. The Slack webook that receives the Particle event and publishes a message to the Slack channel.
  2. The Particle webhook that receives the event from the photon and forwards it to Slack.
  3. The Particle firmware that sends the button press event and provides some feedback to the button pusher.

1. Slack Webhook

Slack has an extensive guide for setting up incoming webhooks and a guide for formatting the data you send. You'll just need to take note of the Webhook URL.

2. Particle Webhook

Creating a Particle webhook is much easier since the release of the Particle Dashboard Console. Particle has a great walkthrough for setting up the webhook.. A screenshot of the values I used are below. Replace "your info here" with your Slack Webhook URL from step 1.

Particle Webhook Creating Screenshot

The :coffee: emoji is a custom emoji that I added to Slack. Slack has a guide for adding custom emoji here.

3. Photon Firmware

Finally, the code. The first thing I did was create a wrapper class that added functionality to Particle's library. Particle's class is the InternetButton so mine is the CoffeeButton. The CoffeeButton class inherits from InternetButton and adds some cleaner ways of detecting a button press and named variables for each of the buttons.

Important Note: If you are using the Particle Build web IDE adding the include statement #include "InternetButton/InternetButton.h" will not be enough to link to the InternetButton library. You will need to click the libraries button, select the InternetButton library and add it to your project.

CoffeeButton.cpp

#include "application.h"
#include "CoffeeButton.h"

// Count the number of buttons that are currently pressed
uint8_t CoffeeButton::countButtonsOn(void)
{
    // Initialize the counter
    uint8_t buttons_on = 0;
    // Increment for every button pressed
    buttons_on += buttonOn(top);
    buttons_on += buttonOn(left);
    buttons_on += buttonOn(right);
    buttons_on += buttonOn(bottom);
    // Return the counter
    return buttons_on;
}

/* Return 1 if any button is pressed
 * Return 0 otherwise
 */
uint8_t CoffeeButton::anyButtonOn(void)
{
    if(countButtonsOn())
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

// Return 1 if the selected button i is pressed
uint8_t CoffeeButton::buttonOn(uint8_t i){
    // Only buttons 4 through 7 are valid
    if((i>=4) && (i<=7))
        // Use the built in Particle function to read the button state
        return !digitalRead(i);
    else
        return 0;
}

CoffeeButton.h

// This #include statement was automatically added by the Particle IDE.
#include "InternetButton/InternetButton.h"


class CoffeeButton : public InternetButton
{
    public:
        // Declare constant members for naming the buttons
        const uint8_t top = 4;
        const uint8_t left = 5;
        const uint8_t bottom = 6;
        const uint8_t right = 7;
        
        // Expose our class methods
        uint8_t countButtonsOn(void);
        uint8_t anyButtonOn(void);
        uint8_t buttonOn(uint8_t i);
};

The bulk of the code is the coffee.ino file. This code initializes the coffee button and triggers the actions on a button press. The Internet Button has built in Neopixel LEDs and a buzzer so when the button is pressed I had the coffee button play a short jingle and light up a series of lights. It then publishes an event to the Particle server.

coffee.ino


// This #include statement was automatically added by the Particle IDE.
#include "CoffeeButton.h"

#include <string.h>
 
#define DEBOUNCE_TIME 3000 //3000 ms = 3 s
 
// b is our button
CoffeeButton b;
 
unsigned long last_push; // Keep track of the last button push time
uint8_t led_number; 
 
String notes[6]  = {"E5", "G5", "E6", "C6", "D6", "G6"}; // A short melody
uint8_t i; // For incrementing
 
void setup() {
    // Initialize the button
    b.begin();
    //Initialize the debounce time
    last_push = millis();
}
 
void loop() {
    //If any button is pressed
    if(b.anyButtonOn()) 
    {
        //Only allow a button press every 3 seconds
        if(millis() > last_push + DEBOUNCE_TIME)
        {
            // Play a string of notes and light up random colors around the circle.
            for(i=0; i<6; i++)
            {
                b.ledOn(i+1, random(255), random(255), random(255));
                b.playNote(notes[i],8);
                b.ledOff(i+1);
            }
            //Publish to the Particle server
            Particle.publish("coffee", "Fresh coffee in the kitchen", 60, PRIVATE);
            //Update debounce time
            last_push = millis();
        }
    }
}

 

A more robust application would include additional features like response checking and error handling, but this will get us started for finding the freshest brew. Thanks for reading!

Learn more about DMC's embedded design and IoT solutions

Comments

There are currently no comments, be the first to post one.

Post a comment

Name (required)

Email (required)

CAPTCHA image
Enter the code shown above:

Related Blog Posts