First Final Version, Will probably need revision with regards to LCD and maybe the clock

Dependencies:   mbed HTTPClient MMA8452Q mbed-rtos 4DGL-uLCD-SE NTPClient SDFileSystem1 EthernetInterface

main.cpp

Committer:
stephenb
Date:
2020-12-19
Revision:
5:c802be973546
Parent:
3:65349fe42061

File content as of revision 5:c802be973546:

#include "mbed.h"
#include "NTPClient.h"
#include "EthernetInterface.h"
#include "HTTPClient.h"
#include "SDFileSystem.h"
#include "MMA8452Q.h"
#include "alarm.h"

//Set up 
SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
MMA8452Q accel(p28, p27, 0x1D); //Accelerometer
InterruptIn ain1(p16); //Temperature Sensor Interrupt
AnalogIn ain(p15); //Temperature Sensor input
HTTPClient httpClient;
Thread thread; //Temperature check thread
Thread accelerometer; //Accelerometer check thread
Timer Clock; //Timer for timestamps


void parse(char buffer[], int *j, char *string); //FUNCTION TO PARSE HTTP GET DATA
void sdlog(int type, float time, float input0, char input1[], char input2[], char input3[]); //Function to write to the SD card
char httpGetData[200]; //BUFFER TO HOLD DATA FROM HTTP GET REQUEST
int location(); //Function to get the location data
void temperature(); //Outputs the temeprature to LCD and SD card
void tempchange_thread(); //Temperature function to check value exceeds limits
void accel_thread(); //Function to measure the accelerometer

int main() {
    Clock.start(); //Start timer
    accel.init(); //initalize accelerometer
    thread.start(tempchange_thread); //Start temperature check thread
    accelerometer.start(accel_thread); //Start accelerometer thread
    ain1.rise(tempchange_thread);
    ain1.fall(tempchange_thread);



    //Display Settings
    uLCD.baudrate(115200); //Baudrate of display
    uLCD.cls();    //Clear uLCD screen
    uLCD.background_color(BLACK); //Background colour
    uLCD.color(WHITE);  //Text colour
    
    
    while(true){ //Loop to control timing of temperature and location updates
        location();
        for (int k = 0; k < 20; k++){ //Temperature fcn runs every 30 seconds, location fcn runs every 10 minutes
            temperature();  
            wait(30); //waits 30 seconds before running the fcn again
            } 
        }
}


void parse(char buffer[], int *j, char *string) {
//extracts next location string data item from buffer
    int i=0;
    for (i=0; i<=strlen(buffer); i++) {  //TOTAL SIZE OF RETURNED DATA
        if ((buffer[*j+i] == ',')||(buffer[*j+i] == '\0' )) { //IF comma or end of string
            //comma is the string field delimiter
            string[i]=0; //SETS END OF STRING TO 0
            *j=*j+i+1; //UPDATES to 1 after comma seperated value
            break;
        } else string[i]=buffer[*j+i]; //Keep adding to the string
    }
}

void sdlog(int type, float time, float input0, char input1[], char input2[], char input3[]){
     FILE *file;
    switch (type){
    case 0:
            file = fopen("/sd/location.txt", "w");
        fprintf(file, "TIME: %f, Latitude: %s Longitude: %s, City: %s\n\r", time, input1, input2, input3);
        fclose(file);
        break;
    case 1:
            file = fopen("/sd/temperature.txt", "w");
        fprintf(file, "TIME: %f, %f degC\n\r", time, input0);
        fclose(file);
        break;
    case 2:
            file = fopen("/sd/acceleration.txt", "w");
        fprintf(file, "TIME: %f, WARNING: LOAD EXCEDDED MAXIMUM ALLOWED ANGLE\n\r", time);
        fclose(file);
        break;
    default:
    break;
    }
}

int location(){
    eth.init(); //USE DHCP to get local IP address
    eth.connect(); //Connect to the network
        
    char success[10]={0};  //success first
    char countryFull[20]={0}; //Full Country Name
    char countryAbrv[5]={0}; //Abbreviated Country Name or country Code
    char stateAbrv[5]={0}; //Abbreviated State or region code
    char stateFull[15]={0}; //Full State Name
    char city[15]={0}; //City Name
    char zip[6]={0}; //ZIP CODE
    char latitude[10]={0}; //latitude
    char longitude[10]={0}; //longitude
    char timeZone[30]={0}; //timeZone
    int j=0;
    HTTPResult r = httpClient.get("http://ip-api.com/csv",httpGetData,128); //GET GEOLOCATION DATA (CSV)
    
    if (r==HTTP_OK) { //IF THE DATA WAS RECIEVED
        j=0;
        //parse and display each of the API's location information strings on the LCD
        parse(httpGetData, &j, success); 
        parse(httpGetData,&j,countryFull);
        parse(httpGetData,&j,countryAbrv);
        parse(httpGetData,&j,stateAbrv);
        parse(httpGetData,&j,stateFull);
        parse(httpGetData,&j,city);
        parse(httpGetData,&j,zip);
        parse(httpGetData,&j,latitude);
        parse(httpGetData,&j,longitude);
        parse(httpGetData,&j,timeZone);
    } 
    else { //HTTP GET REQUEST ERRORED
        uLCD.cls();
        uLCD.printf("HTTP Error %d", r);
        return -1;
    }
    sdlog(0, Clock.read(), 2, latitude, longitude, city);// Save info to SD card
    eth.disconnect();      //DISCONNECT FROM THE NETWORK 
        //Print Location Information
    uLCD.locate(0,0);
    uLCD.textbackground_color(BLACK);
    uLCD.printf("%s, %s\n",city,countryFull); //Print City and Country
    uLCD.printf("LAT:%s\nLONG:%s\n",latitude,longitude); //LATITUDE AND LONGITUDE 
    return 1;
    }
  
  
  
void accel_thread(){
        
        float X=accel.readX();
        float Y=accel.readY();
        
        while(true){ 
        if((X <-0.6 && X>=-0.9)||(X >0.6&&X<=0.9)||(Y <-0.6 && Y>=-0.9)||(Y >0.6 && Y<=0.9)){
            uLCD.textbackground_color(RED);
            uLCD.locate(0, 5);      // setting  cursor on LED
            uLCD.printf("WARNING");
            uLCD.locate(0,6);
            uLCD.printf("CONTAINER UNSTABLE");
            uLCD.locate(0,7);
            uLCD.printf("CHECK CONTAINER");
                        }
        else if ((X<-0.9)||(X>0.9)||(Y<-0.9)||(Y>0.9)){
           sdlog(2, Clock.read(), 0,0,0,0); //Records tipping to SD card with timestamp
            uLCD.textbackground_color(RED);
            uLCD.locate(0,5);      // Move cursor
            uLCD.printf("WARNING");
            uLCD.locate(0,6);
            uLCD.printf("CONTAINER INVERTED");
            uLCD.locate(0,7);
            uLCD.textbackground_color(BLUE);
            uLCD.printf("Press to clear");  
            soundalarm(); //Sounds alarm  
            }
            else{
            uLCD.textbackground_color(BLACK);
            uLCD.locate(0,5);      // setting  cursor on LED
            uLCD.printf("--------------");
            uLCD.locate(0,6);
            uLCD.printf("Container Stable");
            uLCD.locate(0,7);
            uLCD.printf("--------------");
                }
        }
  }
  
    
void tempchange_thread(){ //Constantly checking if temperature goes above 20C
    
    float tempnotright;
    float change;
    change = ain1.read() * 3.3;
    tempnotright = (change - 0.5) * 100.0;
    
    if (tempnotright > 20) {
        uLCD.locate(0,9);
        uLCD.textbackground_color(BLACK);
        uLCD.printf("%fs: %f C", Clock.read(), tempnotright);
        uLCD.locate(0,10);
        uLCD.textbackground_color(RED);
        uLCD.printf("CORRECTION NEEDED!");
        sdlog(1, Clock.read(), tempnotright,0,0,0);
        soundalarm();
          }
         Thread:: wait(5);
    }


    void temperature(){ //Sort LCD
        float voltage_in;
        float degrees_c;
        int i;
                for(i = 0; i < 1000; i++) {
            voltage_in = ain * 3.3;
            degrees_c = (voltage_in - 0.5) * 100.0;
            uLCD.locate(0,9);
            uLCD.textbackground_color(BLACK);
            uLCD.printf("%fs: %f C", Clock.read(), degrees_c);
            
            if(degrees_c <= 20){ //Correct Temp Range
                sdlog(1, Clock.read(), degrees_c,0,0,0);
                uLCD.locate(0,10);
                uLCD.textbackground_color(GREEN);
                uLCD.printf("Correct Temperature");

            }
            else{ //Incorrect Temp Range
                sdlog(1, Clock.read(), degrees_c,0,0,0);
                uLCD.textbackground_color(RED);
                uLCD.locate(0,10);
                uLCD.printf("CORRECTION NEEDED!");
                soundalarm();
            }
        }
        }