project

Dependencies:   mbed HTTPClient LM75B mbed-rtos EthernetInterface MMA7660

main.cpp

Committer:
rr387
Date:
2021-12-30
Revision:
3:e68b56ffa127
Parent:
2:f7645c6a85f3
Child:
4:88613477855a

File content as of revision 3:e68b56ffa127:

/* mbed Microcontroller Library
 * Copyright (c) 2019 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */
#include "mbed.h"
#include "FP.h"//header file for function pointer
#include "HTTPClient.h"
#include "EthernetInterface.h"


#define TRIGGER_HAND PTB18//setting trigger pin of ultrasonic sensor near hand
#define ECHO_HAND PTB19//setting echo pin of ultrasonic sensor near hand

#define TRIGGER_BOTTLE PTC1//setting trigger pin of ultrasonic sensor inside bottle
#define ECHO_BOTTLE PTC8//setting echo pin of ultrasonic sensor inside bottle

#define PUMP_SIGNAL PTC9//stting the signal pin  of the relay pin connected to pump

#define BOTTLE_FULL 9//
#define ON 1
#define OFF 0
Serial pc(USBTX, USBRX); //Create Serial interface
DigitalOut RED(LED1, 1);//alert light when sanitizer is empty
DigitalOut GREEN(LED2, 1);//user present station on
DigitalOut BLUE(LED3, 1);//station free
int hand_distance = 0;//variable to update feild 1 in thingsspeak
int santizer_lev = 0;//variable to update feild 1 in thingsspeak
long userCount = 0;//variable to update feild 1 in thingsspeak

//Ethernet Interface
EthernetInterface eth;
//HTTP Client for interfacing to web services
HTTPClient http;
#define IP "184.106.153.149" // thingspeak.com IP Address

char resp[1024];// response from http post
int ret = 0;// error feed back from

HTTPText inText(resp, 1024);

void post_field1(){
    HTTPMap map;
    char buf[10];
    char buf1[10];
    sprintf(buf,"%d",userCount);//Convert UserCount to char*
    sprintf(buf1,"%d",santizer_lev);//Convert SanitizerLevel to char*
    map.put("api_key","JPZYYS7J18NX4XV5");  //Fill your thingspeak API KEY
    map.put("field1", buf); // Add UserCount to HTTPMap
    map.put("field2", buf1);// Add SanitizerLevel to HTTPMap
    pc.printf("\r\nPosting Data...");
    ret = http.post("https://api.thingspeak.com/update", map, &inText);     //Publish Field1 and Field2 to Thingspeak
    if (!ret){
        pc.printf("\r\nPOST successfully - read %d characters", strlen(resp));
        pc.printf("\r\nResult: %s\n", resp);
    }else{
        pc.printf("\r\nError Connecting to ethernet port - ret = %d - HTTP return code = %d", ret, http.getHTTPResponseCode());
    }
}

void set_red()//funtion to set red led
{
    RED=0; GREEN = 1; BLUE = 1;
}
void set_green()//funtion to set green led
{
    RED = 1; GREEN = 0; BLUE = 1;
}
void set_blue()//funtion to set blue led
{
    RED = 1; GREEN = 1; BLUE = 0;
}

class ultrasonic{
    private:
        DigitalOut trigger;//trigger pin for UltarSonic sensor
        InterruptIn echo; //Echo pin for water_level measurement. Uses as Interrupt to avoid code execution blocking.
        Ticker measure; //Ticker to trigger water_level measurement periodically.
        Timeout trigger_low; //Timeout interrupt to set trigger pin low after 10us of HIGH.
        Timer echoTimer; //Timer to get the time elapsed between echo sent and echo received back
        int echo_time_us;
        int meas_gap; //1sec
        volatile bool measuring;
        FP<void,int> fp;
         
        void set_trigger_high(){ //Function to set Trigger Pin HIGH for 10us and set measuring = true
            measuring = true;
            trigger = ON;
            trigger_low.attach_us(this, &ultrasonic::set_trigger_low, 10); //set trigger pin OFF after 10us   
        }
        
        void set_trigger_low(void){ //Function to set trigger pin LOW to fiish trigger after 10us. This will be called by low timer object.
            trigger = OFF;
        }
        
        void start_echo(void){//Function to start listening for echo back. This will start timer echoTimer. Will be based on Echo Pin RISE(or HIGH)
            if(!measuring) return; //avoid fluctuations on echo pin if any. Continue echo calculation only if measuring is TRUE.
            echoTimer.reset();
            echoTimer.start(); //Timer start since Echo pin is HIGH
        }
        void stop_echo(void){//Function to stop echoTimer after echo received back. Will be based on Echo Pin FALL(or LOW).
            if (!measuring)return; //avoid fluctuations on echo pin if any
            echoTimer.stop(); //stop timer since echo pin back to LOW
            echo_time_us = echoTimer.read_us(); //Calculate time for ultrasonic wave RTT.
            if(echo_time_us > 2000 || echo_time_us < 125)return; //ignore reading in case abnormally high or low RTT time
            measuring = false; //Marke measurement completed
            fp(echo_time_us / (29 * 2));
        }
public: 
        ultrasonic(PinName _trigger, PinName _echo, int _meas_gap):trigger(_trigger), echo(_echo){ //Constructor: initialize trigger(default value OFF) & echo pin
            
            echo.rise(this, &ultrasonic::start_echo); //Attach function to Interrupt on Echo pin Rise
            echo.fall(this, &ultrasonic::stop_echo); //Attach function to Interrupt on Echo pin Fall
            meas_gap = _meas_gap;
            measuring = false;
        }

        void start_measure(){ //function to Set Trigger Pin high repeatedly every 'time' seconds
            measure.attach(this, &ultrasonic::set_trigger_high,meas_gap);//ticker to trigger measurement with callback function
        }
        void stop_measure(void){ //Dettach from Ticker and stop measurements
            //signal = OFF;
            measuring = false;
            measure.detach();
        }
        void req_callBack(FP<void, int> _fp){
            fp = _fp;
        }
}; 


class _pump{
    private:
        DigitalOut signal; //pin for controlling relay
        const int pump_timeout = 400000;//the amount of sanitizer pumping into the hand
        Timeout time_out;//interrupt based timer
        
    public:
        _pump(PinName _signal):signal(_signal,OFF){
        }
        
        void switch_on(){//switch on the punp
            signal = ON;
            time_out.attach_us(this, &_pump::switch_off, pump_timeout); //set trigger pin OFF after 10us  
                   }
        void switch_off(){//switch off the pump
            signal = OFF;
        }
        
        int get_state(){//return the signal state of pump
            return signal.read();
        }
};

class _station{
    private:
        ultrasonic hand_sensor;
        ultrasonic bottle_sensor;
        _pump pump;
        FP<void,int> detect_hand_fp;//to find the user hand using function pointer detect hand fp
        FP<void,int> santizer_level_fp;//to find the level of sanitizer using this function 
        const int threshold = 14;//the max value hand to be detected
        const int bottle_empty = 13;// the max value bottle level to get empty
        bool user_served;//variable to check the user served
        bool station_on;//varible to keep the sanitizing station on
    public:
        _station(PinName _trigger,PinName _echo, PinName __trigger,PinName __echo, PinName _signal):hand_sensor(_trigger, _echo, 1),bottle_sensor(__trigger, __echo, 10),pump(_signal){
            
            bool user_served= false;//initialize user serve
            bool station_on = true;//initialize the station to start
        }
        
        void start_station(){//This section the station will check the hand and bottle distance detection
            start_measure_bottle();//start to measure the bottle sanitizer level
        }
        
        void start_detect_hand(){//start detecting the hand 
            detect_hand_fp.attach(this, &_station::detect_hand);//attach the function pointer detect hand
            hand_sensor.req_callBack(detect_hand_fp);//pass function pointer to ultrasonic function
            hand_sensor.start_measure();//start hand sensor
        }
        void stop_detect_hand(){//stop detecting the hand
            hand_sensor.stop_measure();//stop ultrasonic sensor 
            detect_hand_fp.detach();//detach the function pointer
        }
        
        void start_measure_bottle(){//start measuring the level of sanitizer
            santizer_level_fp.attach(this, &_station::santizer_level);//attach the function pointer sanitizer level
            bottle_sensor.req_callBack(santizer_level_fp);//pass function pointer to ultrasonic function
            bottle_sensor.start_measure();//start calculating level of sanitizer
        }
        void stop_measure_bottle(){//stop measuring the level
            stop_detect_hand();//stop detecting hand
            bottle_sensor.stop_measure();//stop the ultrasonic sensor
            santizer_level_fp.detach();//detach the function pointer
        }
        
        void santizer_level(int d){
            //int x = d - BOTTLE_FULL;
            //santizer_lev = BOTTLE_FULL - x;
            santizer_lev = d;
            char field[50];
            if (d <= bottle_empty){ //Bottle Empty
                 set_red();//sanitizer empty red light alert
                 station_on = false;//make the station off
                 stop_detect_hand();//stop sensing the hand
            } 
            if (d > bottle_empty){ //Bottle still have sanitizer
                set_blue();//sanitizer present and users are welcome
                if(!station_on){// if no user is using the station
                    start_detect_hand();// start hand detection
                    station_on = true;// on the station for pumping
                }
            }
        }
        void detect_hand(int d){//hand detection
            hand_distance = d;
            if (d <= threshold && user_served){ //hand Detected when user is served and the threshold is greater than the distance
                set_green();//green led glows when hand is detected
                pump.switch_on();//switch the pump on
                userCount++;//count the user number
                user_served= false;//stop the pumping after one pump of sanitizer
                 
            } 
            if (d > threshold){ //hand not Detected
                set_blue();//station is free ready to serve user
                user_served= true;//start checking for the user
            } 
        }
};



int main()
{
    int ret = 0;
    char field[50];
   _station station(TRIGGER_HAND, ECHO_HAND, TRIGGER_BOTTLE, ECHO_BOTTLE, PUMP_SIGNAL);
    station.start_station();
    
    eth.init(); //Use DHCP
    ret= eth.connect();

    if (!ret){
            pc.printf("\r\nConnected, IP: %s, MASK: %s, GW: %s",
            eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
    } else {
        pc.printf("\r\nError eth.connect() - ret = %d", ret);
    }
    
    
    while (true) {
        pc.printf("Hand Distance = %d\n\r", hand_distance);//print the hand distance calculated
        pc.printf("Sanitizer = %d\n\r", santizer_lev);//print the sanitizer level detected
        wait(5);
        post_field1();//callin the post feild1 to post the information to thingspaek
        
    }
}




/*
#include "mbed.h"
#include "HTTPClient.h"
#include "LM75B.h"
#include "MMA7660.h"
#include "EthernetInterface.h"


LM75B sensor(D14,D15);
MMA7660 accel(PTE25 , PTE24);
char buffer[256];
char resp[1024];
char val[4][16];   
int ret = 0;

Serial pc(USBTX,USBRX);
//Ethernet Interface
EthernetInterface eth;
//HTTP Client for interfacing to web services
HTTPClient http;
#define IP "184.106.153.149" // thingspeak.com IP Address

//http client init
HTTPMap map;
HTTPText inText(resp, 1024);
//String thingtweetAPIKey = "TTEVLP931ODJ5GMT";


int main () {   
//ethernet init
    eth.init(); //Use DHCP
    ret= eth.connect();

    if (!ret){
            pc.printf("\r\nConnected, IP: %s, MASK: %s, GW: %s",
            eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
    } else {
        pc.printf("\r\nError eth.connect() - ret = %d", ret);
    }
    
    while(1){
        pc.printf("\r\nWriting to thingspeak");
        map.put("api_key","xxx");  /* Fill your thingspeak API KEY*/
/*
        sprintf(val[0],"%4.1f",sensor.read());
        map.put("field1", val[0]);
        map.put("field1", val[0]);
        map.put("field1", val[0]);
        
        
        
        pc.printf("\r\nPosting Data...");
        ret = http.post("https://api.thingspeak.com/update", map, &inText);     //writing data to Thingspeak
        if (!ret){
            pc.printf("\r\nPOST successfully - read %d characters", strlen(resp));
            pc.printf("\r\nResult: %s\n", resp);
        }else{
            pc.printf("\r\nError Connecting to ethernet port - ret = %d - HTTP return code = %d", ret, http.getHTTPResponseCode());
        }
    }
}
*/