Michael WhiteNathan Turnbow
Published © GPL3+

Coffee Starter Using Blynk

Speed your morning routine up by starting to brew your coffee right when you wake up, so coffee is waiting for you as you leave.

IntermediateFull instructions provided3 hours1,389
Coffee Starter Using Blynk

Things used in this project

Hardware components

Photon
Particle Photon
×2
USB-A to Micro-USB Cable
USB-A to Micro-USB Cable
×2
Relay (generic)
5V Relay
×1
MainStays Coffee Maker
×1
Jumper wires (generic)
Jumper wires (generic)
×9
Temperature Sensor
Temperature Sensor
We used the sealed temperature sensor from the Maker Kit. They are identical in function.
×1
Smartphone
×1

Software apps and online services

Blynk
Blynk
Maker service
IFTTT Maker service

Hand tools and fabrication machines

Wire Strip
Screw Driver

Story

Read more

Schematics

Temperature Sensor Schematic (excluding USB connection)

The picture of our actual circuit may look a little different because we extended the temperature sensor to reach under the coffee maker comfortable but this schematic is the one we used to set up our circuit.

Photon, Relay, Coffee Maker Set-up

Code

Blynk App and Photon Response to "coffeetemp2" Event

C/C++
This code connects the Blynk App to the Particle photon that is connected to the coffee maker through the relay. The code allows a button in the Blynk App to turn the D0 pin to HIGH which controls the relay completing the circuit, which supplies power to the coffee maker allowing it to start brewing. This code also allows the particle to read and respond to the cloud. Once the photon reads from the event it is subscribed to (coffetemp2), the function 'stopcoffeemaker' is run, which starts a delay to allow the coffee maker to finish the brewing process, then turns the D0 pin to LOW which flips the switch in the relay cutting off energy to the coffee maker and effectively turning it off.
// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>

// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>

// This #include statement was automatically added by the Spark IDE.

/**************************************************************
 * Blynk is a platform with iOS and Android apps to control
 * Arduino, Raspberry Pi and the likes over the Internet.
 * You can easily build graphic interfaces for all your
 * projects by simply dragging and dropping widgets.
 *
 *   Downloads, docs, tutorials: http://www.blynk.cc
 *   Blynk community:            http://community.blynk.cc
 *   Social groups:              http://www.fb.com/blynkapp
 *                               http://twitter.com/blynk_app
 *
 * Blynk library is licensed under MIT license
 * This example code is in public domain.
 *
 **************************************************************
 *
 * This example shows how to use Arduino Ethernet shield (W5100)
 * to connect your project to Blynk.
 * Feel free to apply it to any other example. It's simple!
 *
 **************************************************************/

//#include <SPI.h>
//#include <Ethernet.h>
//#include <BlynkSimpleEthernet.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "20f71e6fb1bd426a860b53b2554bcdad";


void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth);
  pinMode(D0, OUTPUT);
  Particle.subscribe("coffeetemp2", stopcoffeemaker);
  

  // You can also specify server.
  // For more options, see Transports/Advanced/CustomEthernet example
  //Blynk.begin(auth, "server.org", 8442);
  //Blynk.begin(auth, IPAddress(192,168,1,100), 8888);
}



void loop()
{
    Blynk.run();

}

void stopcoffeemaker(const char *event, const char *data) {
    
    if(strcmp(data, "brewing") ==1 ){
    delay(600000); //delay 10 min
    digitalWrite(D0, LOW); // turn pin D0 to LOW which turns off the coffee maker
    }
    
    
}

Temperature Reading and Logging

C/C++
This code translates the input from the temperature sensor and when the temperature reading is above 0 degrees Fahrenheit the temperature reading is posted to the cloud through the event named "coffeetemp" and if the temperature reading is above 150 degrees Fahrenheit the string value "brewing" is posted to the cloud through the event named "coldtemp2".
// This #include statement was automatically added by the Particle IDE.
#include <OneWire.h>
OneWire ds = OneWire(D4);
unsigned long lastUpdate = 0;
float lastTemp;
void setup() {
    Serial.begin(9600);
    // Set up 'power' pins, comment out if not used!
    pinMode(D3, OUTPUT);
    pinMode(D5, OUTPUT);
    digitalWrite(D3, LOW);
    digitalWrite(D5, HIGH);
}
// up to here, it is the same as the address acanner
// we need a few more variables for this example
void loop(void) {
    byte i;
    byte present = 0;
    byte type_s;
    byte data[12];
    byte addr[8];
    float celsius, fahrenheit;
    
    if ( !ds.search(addr)) {
        Serial.println("No more addresses.");
        Serial.println();
        ds.reset_search();
        delay(250);
        return;
    }
    
    
    // The order is changed a bit in this example 
    // first the retruned address is printed
    
    Serial.print("ROM =");
    for( i = 0; i<8; i++) {
        Serial.write(' ');
        Serial.print(addr[i], HEX);
    }
    
    if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
  // we have a good address at this point
  // what kind of chip do we have?
  // we will set a type_s value for known types or just return
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS1820/DS18S20");
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    case 0x26:
      Serial.println("  Chip = DS2438");
      type_s = 2;
      break;
    default:
      Serial.println("Unknown device type.");
      return;
  }
  
  ds.reset();               // first clear the 1-wire bus
  ds.select(addr);          // now select the device we just found
  // ds.write(0x44, 1);     // tell it to start a conversion, with parasite power on at the end
  ds.write(0x44, 0);        // or start conversion in powered mode (bus finishes low)
  // just wait a second while the conversion takes place
  // different chips have different conversion times, check the specs, 1 sec is worse case + 250ms
  // you could also communicate with other devices if you like but you would need
  // to already know their address to select them.
  delay(1000);     // maybe 750ms is enough, maybe not, wait 1 sec for conversion
  // we might do a ds.depower() (parasite) here, but the reset will take care of it.
  // first make sure current values are in the scratch pad
  present = ds.reset();
  ds.select(addr);
  ds.write(0xB8,0);         // Recall Memory 0
  ds.write(0x00,0);         // Recall Memory 0
  // now read the scratch pad
  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE,0);         // Read Scratchpad
  if (type_s == 2) {
    ds.write(0x00,0);       // The DS2438 needs a page# to read
  }
  
  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();
  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s == 2) raw = (data[2] << 8) | data[1];
  byte cfg = (data[4] & 0x60);
  switch (type_s) {
    case 1:
      raw = raw << 3; // 9 bit resolution default
      if (data[7] == 0x10) {
        // "count remain" gives full 12 bit resolution
        raw = (raw & 0xFFF0) + 12 - data[6];
      }
      celsius = (float)raw * 0.0625;
      break;
    case 0:
    // at lower res, the low bits are undefined, so let's zero them
      if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
      if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
      if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
      // default is 12 bit resolution, 750 ms conversion time
      celsius = (float)raw * 0.0625;
      break;
    case 2:
      data[1] = (data[1] >> 3) & 0x1f;
      if (data[2] > 127) {
        celsius = (float)data[2] - ((float)data[1] * .03125);
      }else{
        celsius = (float)data[2] + ((float)data[1] * .03125);
      }
  }
  // remove random errors
  if((((celsius <= 0 && celsius > -1) && lastTemp > 5)) || celsius > 125) {
      celsius = lastTemp;
  }
  
  fahrenheit = celsius * 1.8 + 32.0;
  lastTemp = celsius;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
 

  
  if (fahrenheit > 0) {
      // now that we have the readings, we can publish them to the cloud
      String temperature = String(fahrenheit);  // store temp in "temperature" string
      Particle.publish("coffeetemp", temperature);
      if (fahrenheit > 150){
          Particle.publish("coffeetemp2", "brewing"); // publish to cloud
          
      }
      delay (10000);
  }
}

Credits

Michael White

Michael White

1 project • 0 followers
Nathan Turnbow

Nathan Turnbow

1 project • 0 followers
Thanks to Particle.

Comments