Introduction

In the previous post, we saw how The Kitchen Node has been divided into several components to keep the monitoring of them independent. accordingly to this model I have created a circuit design centered on the Arduino Mega 2560 microcontroller that using one of its serial interface updates periodically the ESP8266-01 device. In this design, the alarm conditions enable immediately action feedback, aiming to remove as soon as possible the risky condition. Tanks to this feedback it is not needed to push immediately the alarm but is just kept on the ESP web server, queried regularly by the Control Center.

 

The Circuit

The three relays of the Four Channels Reay board, are used to activate the gas electro valve – normally closed, 12V operated – and power separately the hood light and fan aspirator.

The L298 motor controller can drive up to two DC motors but in this case, it is used only one channel to control the water pump. I have connected the enable signal to a PWM pin of the Arduino 2560 to be able to regulate the water pump speed. In fact, depending on the position of the refill water pipe it is useful to have a fine-tuning setting of the quantity of water per minute. The water pump DC motor speed does not need to be frequently calibrated; it is sufficient a trimmer on the board (connected to the A0 analog input) to set the optimal speed when the system is put in place.

The two HC-SR04 ultrasonic sensors are set one to the bottom of the hood pointing to the area in front of the cooking plate to detect the presence of a person and the other aligned immediately above the cooking plate. This is used to detect if a pan or something is put over the cooking plate, to avoid that there are flames while the plate is empty.

As the MQ-02 gas sensor detects combustible gas only if there is no flame, it will operate in conjunction with the Max6675 thermocouple and the ultrasound pan detector. The interpolation of the status of these three sensors can provide the following information:

 

  • The cooking plate is active and working correctly
  • The gas is open but there is no flame (ALARM)
  • There is a flame on the cooking plate but no pan, no person present (ALARM)

 

The circuit includes four buttons connected to four of the six external interrupts of the Arduino Mega 2560. These buttons control priority activities, not impacting the normal sensors checking and monitoring:

 

  1. Calibrate the weight of bowl the tare (empty bowl)
  2. Calibrate the weight of the full water bowl
  3. Save the current calibration to the Arduino Mega EEPROM
  4. Manual feed water (when the manual operation is needed)

 

If the water bowl levels are calibrated, during the normal operativity the bowl level is controlled by the HX711 load weight sensor and is automatically refilled when the water level in the bowl reaches 10% or less.

There is a fifth button, not active during the normal activity, used to manual unlock an alarm condition. All the buttons are pulled-up by a 10K resistor.

To avoid making a too complex circuit just adding obvious stuff, in the schematics above I have excluded the ESP8266-01 connected to serial 2 of the Arduino Mega and the notification LEDs connected to some of the still available digital pins. All the LEDs just need a digital pin and a 220 Ohm resistor connected to the ground, while the ESP needs a voltage regulator to sync the signal levels and the power supply to the Arduino 5V. Note that in this case, I don't use the 3.3V available on the Arduino GPIO because ESP8266 needs a few more power to work correctly.

To the Serial 3 instead, it is connected the microSD player used to generate audio messages for alarm signaling.

Above: some images showing the first prototyping of the Arduino Mega circuit connected to the sensors and actuators. The final circuit will be assembled on a Mega prototyping shield.

 

The Logic and Software

To implement a state machine logic, I have divided the tasks of the software into separate blocks, regardless of the part of the Kitchen Node is involved:

 

  • Sensors. Get the raw data from all the sensors in the main loop() function.
  • Alarms and notifications. After a reading cycle of the sensors data are compared and integrated to decide if there are alarms to raise or a condition changed the state of the system.
  • Tasks and feedback. The actuators are enabled through specific, independent tasks started by the pattern that emerged from the integration of the previous step.
  • Eventually, alarm blocking feedback.

 

Local Node Status

Notification LEDs and control buttons will be available on the node box, constantly updated by the Alarms and notifications block.

The scheme above shows the panel control of the Kitchen Node:

 

  • Green LEDs – When On, the corresponding component is active and working. When off, the component is not active.
  • Red LEDs – When On, the corresponding component has generated an alarm condition. When off, the component is healthy.
  • Orange LEDs – The orange LEDs are On when the corresponding component is active or the associated sensor has detected activity.
  • Red square button – When an alarm condition occurs, the general Alarm LED is on and the condition should be manually reset by this button.
  • Water Pump block – When the Water Pump LED is active, the pump is refilling the dog water bowl. For any need, including the calibration, the water pump can also be run manually with the corresponding button.

 

Software

All the software developed and updated related to the Super Smart Home project is available under LGPL 3.0 Open Source license on the GitHub repository SuperSmartHome.

The most important part of the software is the status structure that traversal collects the sensors' readings and some of the statuses of the Kitchen Node defined in the header file config.h together with the application constants

 

/**
 * This structure defines all the parameters controlled by the
 * node. At any moment it is possible to know the status of the
 * kitchen environment, alarms and working conditions.
 */
struct KitchenStatus {
    //! General alarm condition. Associated to one
    //! or more alarm status flags.
    boolean isAlarm = false;
    //! Water pump motor speed.
    int pumpSpeed = 0;
    //! Water pump status
    boolean isWaterPumpRunning = false;
    //! Gas valve status
    boolean isGasOpen = false;
    //! Vapor vacuum status
    boolean isVacuum = false;
    //! cooking plate light
    boolean isLight = false;
    //! Water level in grams
    int waterLevel = 0;
    //! Cooking light status
    boolean isCoookingLightOn = false;
    //! Cooking plate temperature (Celsius)
    int tempCookingPlate;
    //! Gas detection flag
    boolean isGas = false;
    //! Gas ppm
    float gasPPM = 0;
    //! Status of the cooking plate (with or without pans)
    boolean isCookingPlateEmpty = true;
    //! Status of humans in front of the cooking plate
    boolean isChefPresent = false;
    //! Flag indicating when a button ISR is running to logically stop
    //! any other IRQ activity
    boolean isISR_Running = false;
};

 

The HX711 load weight sensor has a series of internal mechanisms that should be respected, like the initial self-calibration of the load cell, the initial setup, and some other features. To keep the weight reading as a simple call the whole load cell sensor management is implemented separately in the C++ WaterLevel class using the HX711 Arduino library not needed in the main program. The code below shows the class header with all the definitions and methods documentation.

 

/**
 *  \file waterlevel.h
 *  \brief Class managing the load cell sensor methods and calculations
 *  to determine the water level in the dog bowl.
 *  
 *  Calculate the water level (ml) based on the weight (gr)
 *  
 *  \author Enrico Miglino <balearicdynamics@gmail.com> \n
 *  Balearic Dynamics sl <www.balearicdynamics.com> SPAIN
 *  \date May 2020
 *  \version 1.1
 *  Licensed under GNU LGPL 3.0
 */

#ifndef _WATERLEVEL
#define _WATERLEVEL

#include <HX711.h>
#include "config.h"

//! Number of samples read every weight reading. 
//! Multiple samples reading gives more stability to the measure
#define SCALE_SAMPLES 10

//! Weight structure variables and flags
struct Weight {
    //! Status of the weight sensor. If this value is false,
    //! the weight sensor needs calibration
    boolean calibration;
    //! This is the low level alarm flag. It raise when the 
    //! remaining water weight is less than 10%
    boolean bowlLow;
    //! Remaining percentage of water in the bowl
    float percWater;
    //! Bowl tare. Calculated during calibration and persistent
    //! in the EEPROM
    float bowlTare;
    //! Bowl maximum weight (full of water, no tare). Calculated during calibration
    //! and persistend in the EEPROM.
    float bowlFull;
    //! Last weight get from the sensor, without the tare.
    float currentWeight;
};

/**
 * Class managing the load sensor
 */
class WaterLevel {

  public:
    //! Application status
    Weight currentStatus;  

    //! Sensor library instance
    HX711 scaleSensor;

    /**
     * Initializes the sensor library and the initial default setup
     */
    void begin(void);

    /**
     * Update the tare calibration.
     */
    void calibrateTare(float value);

    /**
     * Update the full bowl calibration.
     */
    void calibrateFullBowl(float value);

    /**
     * Set the calibration status.
     */
     void setCalibration(boolean flag);

    /**
     * Return the calibration status
     */
    boolean getCalibration(void);
    
    /** 
     * Set the default values when the class is instantiated
     */
    void initDefaults(void);

    /**
     * Read the load sensor weight and update the status values.
     * 
     * \note The method also return the weight value to be used
     * during the calibration process.
     */
    float readScale(void);

    /**
     * Optimizes the floating value reducing the precision to one
     * decimal value
     * 
     * \param value The float value to be treated
     * \return The optimized float value
     */
     float valOptimizer(float value);
    
    /**
     * Calculate the remaining weight percentage
     * 
     * The applied formula: (w - tare) * 100 / full bowl weight
     * 
     *  \param w weight in grams
     *  \return the remaining weight in percentage
     */
    void calcRemainingPerc(void);
};

#endif

 

The measuring and calibration parameters are controlled by the class that includes its own internal status structure Weight.

 

Full Content

 

Already Posted (until now)

Super Smart Home #1 The project

Super Smart Home #2 The Door Opener

Super Smart Home #3 Designing the Control Center

Super Smart Home #4 Activating the Door Opener

Super Smart Home #5 Connecting the First Node to the Control Center

Super Smart Home #6 PSoC6 On the Cloud

Super Smart Home #7 From AWS IoT Core to AWS SiteWise

Super Smart Home #8 The Kitchen Node: Parts, Design and Components

Super Smart Home #9 The Kitchen Node: Circuit and Software

Super Smart Home #10 Building IoT nodes with PSoC6-WiFi-Bt and Mbed OS

Super Smart Home #11 Project Summary, Highlights, and More...

Super Smart Home #12 PSoC6 Local Node: Application Skeleton

Super Smart Home #13 PSoC6 Protection Case

 

Sources, Circuits, and Documentation

All the software sources, scripts, circuits schematics, and more are available as Open Source material on the SuperSmartHome GitHub repository.

The video episodes of this challenge are repurposed on the blog posts of the site we-are-borg.com

 

Thanks to

Element14, AWS, and Cypress, main sponsors

Elegoo for 3D printers ad printing material

Digitspace for sensors, actuators, and boards

The friends and community members jancumps and shabaz always available with advice and suggestions.