bluetooth device with current sensor that analyzes devices and determines whether they are chargeable or not

Dependencies:   4DGL-uLCD-SE mbed

main.cpp

Committer:
mave3
Date:
2016-05-04
Revision:
3:88c08566c2cd
Parent:
2:23dffdc354f1

File content as of revision 3:88c08566c2cd:

#include "mbed.h"
//#include "SDFileSystem.h"
#include "uLCD_4DGL.h"
#include <stdlib.h> // abs
#include <stdio.h> // sprintf
 
 
AnalogIn sensor(p18);
uLCD_4DGL uLCD(p9,p10,p11);
Serial Blue(p13, p14);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
//Mutex lcd_mutex;

//Initialization of variables
float voltage = sensor;
float current = 0;
float average_voltage = 0.0f;
//const float offset = .10f;
//const float factor = 1.6f;
float offset = -2.37f;
const float factor = 8.0f; //7.69
// .54s for 25000 samples
const int sample_size = 25000;
const int max_sample_count = 20;
int sample_count = 0;
float sample_sum = 0.0f;
float initial_current = -1.0f;
float last_current = -1.0f;
bool enough_samples_taken = 0;
int samples_lt = 0;
int total_samples_lt = 0;
int device_chargeable = 0;
int device_not_chargeable = 0;
char buffer[10];
char input_char;

//Timer t;

volatile int menu = 0;

//function that receives character from bluetooth on serial
//and then determines what command is being requested with a switch statement
void parse_message()
{
    led2 = !led2;
    
    switch (Blue.getc())
    {
         case '1':
            menu = 1;
            break;
         case 'q':
            menu = 2;
            break;
         case '3':
            menu = 3;
            break;
         default:
            menu = 0;
            
            
        
    }
}

// calibrate offset s.t. the current output is 0
void calibrate() 
{        
        float average_voltage = 0.0f;
        for (int j = 0; j < 100000; j++)
        {
            voltage = sensor;
            average_voltage += voltage/float(100000);
        }
        //voltage=sensor;
    average_voltage = average_voltage * 3.3f;
    offset = -1.0f * average_voltage;
}

int main() 
{
    //Blue.baud(9600);
    
    Blue.attach(&parse_message,Serial::RxIrq);//serial interrupt with bluetooth
    
    int length = 0;
    
    uLCD.printf("Calibrating...\nPlease wait...\n \nMake sure no \ncurrent is \nconnected.\n");
    
    //Enter device identification
    //press 1 for current and voltage
        //press q to quit
    //press 2 to recalibrate
    menu = 0;//0 is device identification
    calibrate();
    wait(1.0f);
    uLCD.cls();
    //mkdir("/sd/mydir", 0777);
    while(1){
        
        //switch case that handles menu navigation
        //case 0 is the starting case, which is shown after initial calibration.
        //case 1 is when a '1' is received from the bluetooth. It contains the algorthm for detecting
        //whether a device is chargeable or not, and whether a chargable device is fully charged.
        //Algorithm done by taking several samples and comparing to an initial value over time to determine
        //if the current is changing or not.
        //case 3 is recalibration of the current sensor. 
        switch(menu)
        {
            case 0:
                uLCD.cls();
                
                uLCD.printf("Please plug \nin a device \nand press 1\n\n\n\n"); 
                //DO device calculations here.  
                uLCD.printf("To see Voltage andCurrent, press '1'\n");
                uLCD.printf("To recalibrate,\npress '3'");
            
                while (menu==0)
                {   
                }  
                break;
                
            case 1:
                wait(5);                
                uLCD.cls();
                uLCD.printf("Identifying\nDevice\n\nPlease wait...\nDo not touch \nthe device!!\n\n");
                uLCD.printf("To quit, press 'q'\n");
                while (menu == 1)
                {
                    //voltage and current calculations
                    average_voltage = 0.0f;
                    for (int j = 0; j < sample_size; j++)
                    {
                        voltage = sensor;
                        average_voltage += voltage/float(sample_size);
                    }
                    average_voltage = average_voltage * 3.3f;
                    current = (average_voltage + offset) * factor;
                    sample_sum += current;
                    sample_count++;
                    //sampling current and voltage for value comparison
                    if (sample_count >= max_sample_count)
                    {
                        if (initial_current == -1.0f)
                        {
                            initial_current = sample_sum / float(max_sample_count);
                        }
                        else
                        {
                            last_current = sample_sum / float(max_sample_count);
                            enough_samples_taken = 1;
                        }
                        sample_count = 0;
                        sample_sum = 0.0f;
                    }
                    uLCD.locate(0,12);
                    uLCD.printf("%f\n%f", abs(initial_current), abs(last_current));
                    //actual comparisons. done once enough samples have been taken
                    if (enough_samples_taken)
                    {
                        total_samples_lt++;
                        if (abs(last_current) < abs(initial_current))
                        {
                            samples_lt++;
                            enough_samples_taken = 0;
                        }
                        else
                        {
                            samples_lt = 0;
                            enough_samples_taken = 0;
                        }
                        if (samples_lt >= 5)
                        {
                            device_chargeable = 1;
                            samples_lt = 0;
                        }
                    }
                    if (total_samples_lt >= 10 && !device_chargeable && !(device_not_chargeable==-1))
                    {
                        device_not_chargeable = 1;                        
                    }
                    //Prints out current through bluetooth.
                    length = sprintf(buffer, "Current: ");
                    for (unsigned int j = 0; j < length; j++)
                    {
                        Blue.putc(buffer[j]);
                    }
                    
                    wait(1.0f);
                    
                    
                    
                    length = sprintf(buffer, "%.2f A", abs(current));
                    for (unsigned int j = 0; j < length; j++)
                    {
                        Blue.putc(buffer[j]);
                    }
                    //prints for if a device is chargeable or not, and whether
                    //a chargeable device is fully charged.
                    if (device_chargeable == 1)
                    {
                        uLCD.cls();
                        uLCD.printf("The device is\nchargable!\n");
                        uLCD.printf("To quit, press 'q'\n");
                        device_chargeable = -1;
                    }
                    else if(device_not_chargeable == 1)
                    {
                        uLCD.cls();
                        uLCD.printf("The device is not chargable\n");
                        uLCD.printf("To quit, press 'q'\n");
                        device_not_chargeable = -1;
                    }
                    if(device_chargeable == -1 && abs(current) <= 0.1f)
                    {
                        uLCD.locate(0, 8);
                        uLCD.printf("Device charged!");   
                    }
                    wait(1.0f);
                    Blue.putc('-');
                    Blue.putc('-');
                    Blue.putc('-');
                    
                    
                    //resets variables if exiting loop
                    if (menu != 1)//menu is changed to 2 through interrupts. 
                    {
                        menu = 0;   
                        
                        sample_count = 0;
                        sample_sum = 0.0f;
                        initial_current = -1.0f;
                        last_current = -1.0f;
                        enough_samples_taken = 0;
                        samples_lt = 0;
                        device_chargeable = 0;
                        total_samples_lt = 0;
                        device_not_chargeable = 0;
                    }
                }
                break;
                //recalibration
            case 3:
                uLCD.cls();
                uLCD.printf("Recalibrating...\nPlease wait...\n \nMake sure no \ncurrent is \nconnected.\n\n");
                calibrate();
                wait(1.0f);
                
                uLCD.printf("Calibration\ncomplete!!");
                wait(2.0f);
                menu = 0;
                break;
                
            default:
                menu = 0;    
        }
        
    }
}