Jameson Barlaan
Published

MEGA Milk Monitor

Without having to leave your chair, you can now configure your fridge to give the temperature of the milk and as well as how much is left.

BeginnerFull instructions provided1.5 hours112
MEGA Milk Monitor

Things used in this project

Hardware components

Temperature Sensor
Temperature Sensor
×1
SparkFun Load Cell Amplifier - HX711
SparkFun Load Cell Amplifier - HX711
×1
Buzzer
Buzzer
×1
Capacitor 100 nF
Capacitor 100 nF
×1
Argon
Particle Argon
×2

Software apps and online services

Particle Build Web IDE
Particle Build Web IDE
ThingSpeak API
ThingSpeak API

Story

Read more

Schematics

Argon Bidirectional Communication Flowchart

Demonstrates the steps that the argons will take and how they will communicate between each other.

Argon 1 Wiring Diagram

Argon 1 Wiring Diagram

Argon 1 Circuit Diagram

Argon 1 Circuit Diagram

Argon 2 Wiring Diagram

Argon 2 Wiring Diagram

Code

Scale Calibration, Temperature Sensor, THINGSPEAK

C/C++
Programs the HX711 load cell; collects the reading from the temp sensor and converts to Fahrenheit/Celsius, and sends temp values to THINGSPEAK.
// This #include statement was automatically added by the Particle IDE.
#include <HX711ADC.h>
#include <ThingSpeak.h>

// Defining the Pins for Temperature and Load Sensor
const int tempPin = A0;
const int led2 = D7;
const int DOUT_PIN = D2;
const int SCK_PIN = D3;
 
HX711ADC scale;
TCPClient client;

// Create a variable that will store the temperature value
double temperature = 0.0;
double temperatureF = 0.0;
double weight = 0;
double Nweight = 0;


unsigned long myChannelNumber = 2104988;    // change this to your channel number
const char * myWriteAPIKey = "F5750CTTI5PBAKRD"; // change this to your channels write API key


void setup()
{
    ThingSpeak.begin(client);
    
     Particle.subscribe("hook-response/SENDHERE", myHandler, MY_DEVICES);
  // Setting the pins as input/output
  //////////////////////////////////
  pinMode(led2, OUTPUT);
  pinMode(tempPin, INPUT);
  
  
  
  //Declaring Particle variable
  ///////////////////////////////////
  Particle.variable("temperature", &temperature, DOUBLE);
  Particle.variable("temperatureF", &temperatureF, DOUBLE);
  Particle.variable("weight", weight);
  Particle.variable("New_Weight", Nweight);
  
  
  // Setting Serial Speed
  ////////////////////////////////////
  Serial.begin(38400);


  // Calibrating the Scale
  ////////////////////////////////////
  scale.begin(DOUT_PIN, SCK_PIN);

  Particle.publish("Before Setup: \t\t" + String(scale.get_units(5), 1));
            
  scale.set_scale(-142671.3333);
  scale.tare();               // reset the scale to 0
  Particle.publish("After Setup: \t\t" + String(scale.get_units(5), 1));
  
  
  Particle.publish("Set Milk");
  digitalWrite(led2, HIGH);
  delay(5000);
  Particle.publish(String(scale.get_units(5)));
  weight = scale.get_units(5);
  digitalWrite(led2, LOW);
}

void myHandler(const char *event, const char *data) {
  // Handle the integration response
}
void loop()
{
    int sensorValue = analogRead(A0);

 delay(2000);
  
  // The returned value from the device is going to be in the range from 0 to 4095
  // Calculate the voltage from the sensor reading
    int reading = analogRead(tempPin);
  double voltage = (reading * 3.3) / 4095.0;

  // Calculate the temperature and update our static variable
  temperature = (voltage - 0.5) * 100;

  // Now convert to Farenheight
  temperatureF = ((temperature * 9.0) / 5.0) + 32.0;
  Particle.publish(String(temperatureF));

  
  Serial.print("one reading:\t");
  Serial.print(scale.get_units(), 1);
  Serial.print("\t| average:\t");
  Serial.println(scale.get_units(10), 1);
  Nweight = scale.get_units(10);
  Particle.publish(String(Nweight));
  
  
    if (0.1 < Nweight && Nweight < weight/2) {
        Particle.publish("alarm");
    }
    
    if (Nweight > weight/2) {
        Particle.publish("Good");
    }
          
  ThingSpeak.writeField(myChannelNumber, 1, String(temperatureF), myWriteAPIKey);
}

Receiving Argon

C/C++
The receiving argon, will receive the publish and subscribe readings from the cloud. Code for buzzer as well as LCD.
// This #include statement was automatically added by the Particle IDE.
#include <LiquidCrystal.h>


// Pin and variable setup
LiquidCrystal lcd(D3, D4, D5, D6, D7, D8);
int buzzerPin = D4; // define the pin that the buzzer is connected to


void setup() {
  pinMode(buzzerPin, OUTPUT); // set the buzzer pin as an output
  
  // setting up the LCD display
  lcd.begin(16, 2); // set the number of columns and rows
  lcd.clear(); // clear the display
  
  /// Listening for "alarm"  
  Particle.subscribe("alarm", buzz, ALL_DEVICES);
  Particle.subscribe("tare", taring, ALL_DEVICES);
  Particle.subscribe("off_scale", off_scale, ALL_DEVICES);
  Particle.subscribe("on_scale", on_scale, ALL_DEVICES);
  
}

void taring(const char *event, const char *data){
    
  lcd.setCursor(6, 0);
  lcd.print("Taring in: 5");
  delay(1000);
  lcd.print("Taring in: 4");
  delay(1000);
  lcd.print("Taring in: 3");
  delay(1000);
  lcd.print("Taring in: 2");
  delay(1000);
  lcd.print("Taring in: 1");
  delay(1000);
  lcd.print("Done Taring");
  delay(5000);
  lcd.clear();
}

void buzz(const char *event, const char *data){
  lcd.print("No Milk!!!"); // print a message to the LCD
  Particle.publish("No Milk!!!");
  lcd.print(""); // flashes message
  digitalWrite(buzzer, HIGH);
  digitalWrite(buzzer, LOW);
  delay(1000); // wait for 1 second
  tone(buzzer, 2093, 650);
  delay(500);
}

void off_scale(const char *event, const char *data){
    int remaining_time = (5 * 60);  // 5 minutes converted to seconds 
    
    // display remaining time as countdown
    for (int i = remaining_time; i > 0; i--) {
        lcd.printf("Time remaining: %d seconds\r", i);  // use \r to overwrite previous output
        delay(1000);  // wait for 1 second
    }
}

void on_scale(const char *event, const char *data){
    lcd.clear();
    
}

Credits

Jameson Barlaan

Jameson Barlaan

0 projects • 0 followers

Comments