Code for Browonout Generator box

main.cpp

Committer:
el16ba
Date:
2020-02-17
Revision:
10:a0212b37673b
Parent:
9:71eab0a4ceef

File content as of revision 10:a0212b37673b:


//By Barnaby Ayriss
//Owned by Buhler UK Ltd

#include "mbed.h"
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <FileHandle.h>
#include <vector>
#include <iostream>
#include <cstdio>
#include <cstdlib>

DigitalOut led1(LED1, 0);
DigitalOut led2(LED2, 0);
DigitalOut led3(LED3, 0);
DigitalOut led4(LED4, 0);
DigitalOut do21(p21, 0);
InterruptIn di22(p22,PullDown); //removing di22 and its related calls and functions causes a major fault for unknown reasons so it has been left in dispite not being used.
Timeout toOn;
Timeout toOff;
Ticker tickOn;
Ticker tickOff;

Serial pc(USBTX, USBRX);  // for PC debug
LocalFileSystem fs("local");

#define NUMCONFIGPARAM  3

bool flg_start = 0;
bool flg_END = false;
bool flg_loop0 = false;
bool flg_loop1 = false;
long double configData[NUMCONFIGPARAM];
string strData[NUMCONFIGPARAM];

//function prototypes
void init();
bool is_num_char(char c);
bool print_config();
void get_config_data();
void power(char pwr = 0);
void cycle_wait(long double tOn = configData[0], long double tOff = configData[2]);
void cycle_loopw(long double tOn = configData[0], long double tOff = configData[2]);
string read_serial_input();
bool is_num_str(string str);
long double get_num_input();
void powerOn();
void powerOff();
void cycle_timeout(long double tOn = configData[0], long double tOff = configData[2]);
void cycle_loopto(long double tOn = configData[0], long double tOff = configData[2]);
void loop_tick ();
void cycle_looptick(long double tOn = configData[0], long double tOff = configData[2]);
void serial_mode();


//returns if the given character is a number or decimal point character
bool is_num_char(char c)
{
    bool isChar = false;
    if((c >= '0' and c <= '9') or c == '.') {
        isChar = true;
    }
    return isChar;
}

//From: https://os.mbed.com/questions/83075/Is-it-possible-to-read-a-small-text-file/
//Reads config.txt from local drive
bool print_config()
{
    bool flg_error;
    pc.printf("Opening file 'config.txt'... ");
    FILE*   fp = fopen("/local/config.txt", "r");
    pc.printf("%s\n\r", (!fp ? "Fail :(" : "OK"));
    pc.printf("\r\n==========\r\n");
    if (!fp) {
        error("error: %s (%d)\n", strerror(errno), -errno);
        flg_error = 1;
    }
    while (!feof(fp)) {
        int c = fgetc(fp);
        pc.printf("%c", c);
    }

    fclose(fp);
    pc.printf("\r\n==========\r\n");
    return flg_error;
}

//Reads reads and converts data from config file
//Once a timed function (e.g. wait(), sleep_for(), ticker, timer e.t.c) is called opening another File pointer will cause the LPC1768 to crash with a Hard Fault.
void get_config_data()
{
    pc.printf("Get Config Data \r\n");
    char c; //Current character being read
    char strData_index = 0;
    char* pEnd;
    bool isReading = false;
    bool isNumChar;
    string currentStr;
    FILE*   fp = fopen("/local/config.txt", "r");

    while (!feof(fp)) {                                                         //loop till end of file

        c = fgetc(fp);
        isNumChar = is_num_char(c);
        if(isNumChar) {                                                         //at number character?
            currentStr.push_back(c);
            isReading = true;
        } else if(!isNumChar and isReading) {                                   //at end of number string?
            isReading = false;
            strData[strData_index] = currentStr;
            configData[strData_index] = strtod(currentStr.c_str(), &pEnd);
            strData_index++;
            currentStr = "";
        }
        if (strData_index >= NUMCONFIGPARAM ) {                                 //Read all nessesary data?
            break;
        }

    }
    fclose(fp);
    pc.printf("Data: %Lf, %Lf, %Lf\r\n",configData[0],configData[1],configData[2]);
}

//initialization function
void init()
{
    pc.printf("Initializing \r\n");
    do21 = 0;
    led1 = 0;
    pc.baud(9600);
    print_config();
    get_config_data();
}

//Sets the pin to control te machines power and its representative LED
void power(char pwr)
{
    do21 = pwr;
    led1 = pwr;
}

//runs a power cycle using sleep commands
void cycle_wait(long double tOn, long double tOff)
{
    power(1);
    ThisThread::sleep_for(tOn);
    power(0);
    ThisThread::sleep_for(tOff);
    power(1);
}

//runs an infinate powercycle loop
void cycle_loopw(long double tOn, long double tOff)
{
    while(1) {
        cycle_wait(tOn,tOff);
    }
}

// ouputs a string from the serial input using a
string read_serial_input()
{
    bool flg_read = true;
    char c;
    string str = "";

    while(flg_read) {
        c = pc.getc();
        pc.putc(c);
        if(c == 8 or c == 127) {                                                //If back space or delete remove last character
            str.pop_back();
        } else if (c == '\n') {                                                 //If new line character
            str.pop_back();                                                     // removes return carriage character
            flg_read = false;
            break;
//        } else if(c < ' ') {                                                  //If none visible character, bar backspace or delete
//            flg_read = false;
//            break;
        } else {
            str.push_back(c);
        }
    }
    return str;
}

//outputs if a string is comprised entirely of number characters
bool is_num_str(string str)
{
    bool isNumC = false;
    bool output = true;
    for(int i = 0; i < str.length(); i++) {
        isNumC = is_num_char(str[i]);
        if(!isNumC) {
            output = false;
        }
    }
    return output;
}

//gets a string of only number characters from the serial input
long double get_num_input()
{
    long double output;
    bool flg_gotStr = false;
    string str_v = "";
    char* pEnd;

    while(!flg_gotStr) {
        pc.puts("value: ");
        str_v = read_serial_input();
        if (is_num_str(str_v)) {
            output = strtod(str_v.c_str(), &pEnd);
            flg_gotStr = true;
            break;
        } else {
            pc.printf("entry contained non number characters please try again: \r\n");
        }

    }
    return output;
}

//power on call back function, as callbacks donot support functions with parameters
void powerOn()
{
    power(1);
    flg_loop1 = true;
}

//power off call back function, as callbacks donot support functions with parameters
void powerOff()

{
    power(0);
    flg_loop0 = true;
}


//powercycles the machine utilizing timouts for time keeping
void cycle_timeout(long double tOn, long double tOff)

{
    long int t1,t2;
    toOn.detach();
    toOff.detach();
    t1 = tOn*1000;
    t2 = (tOff*1000) + t1;
    flg_loop0 = false;
    flg_loop1 = false;
    power(1);
    toOn.attach_us(&powerOff,t1);
    toOff.attach_us(&powerOn,t2);
}

//powercycles the machine, utilizing timouts for time keeping
void cycle_loopto(long double tOn, long double tOff)
{
    bool flg_lend = true;
    string str = "";
    flg_loop0 = 0;
    flg_loop1 = 0;

    cycle_timeout(tOn,tOff);
    while(flg_lend) {
        led2 = !led2;                                                           //does not run without led2 flashing for unknown reasons
        if(flg_loop0 and flg_loop1) {
            cycle_timeout(tOn,tOff);
        }
    }
}

//call back function for cycle_looptick
void loop_tick ()
{
    toOn.attach(&powerOn, (configData[2]/1000) );
    powerOff();
    flg_loop0 = 1;
}

//Allows the user to set the machine to powercycle and exit the loop via serial commands
//utilizes a ticker and a timeout for time keeping
void cycle_looptick(long double tOn, long double tOff)
{
    long double t1,t2;
    bool flg_exit = false;
    string str;
    t1 = tOn/1000;
    t2 = (tOff/1000);
    power(1);
    tickOff.attach(&loop_tick, t1+t2);

    while(!flg_exit) {
        flg_loop0 = 0;
        flg_loop1 = 0;
        str = read_serial_input();
        if (str == "end") {
            tickOff.detach();
            toOn.detach();
            pc.printf("loop ended\r\n");
            power(1);
            flg_exit = true;
            break;
        } else {
            pc.printf("Unknown Command, enter \"end\" to end loop\r\n");
            str = "";
        }
    }
}



// Allows the user to operate the LPC1768 via serial communications
void serial_mode()
{
    pc.printf("Serial Mode \r\n");
    bool flg_read = true;
    char c;
    string str_c = "";

    while(flg_read) {
        str_c = read_serial_input();
        if (str_c == "on") {                                                    // turns machine on
            power(1);
            pc.printf("power on\r\n");

        } else if(str_c == "off") {                                             // turns machine off
            power(0);
            pc.printf("power off\r\n");

        } else if(str_c == "cyclew") {                                          // runs a powercycle
            cycle_wait();
            pc.printf("cycled \r\n");

        } else if(str_c == "loopw") {                                            // runs a continuous powercycle loop
            pc.printf("Looping. Restart unit to end loop \r\n");
            cycle_loopw();

        } else if (str_c == "cycleto") {
            cycle_timeout();
            while(flg_loop0 == 0 or flg_loop1 == 0) {
                led2 = !led2;
                ThisThread::sleep_for(100);
            }
            printf("cycleto finish\r\n");

        } else if (str_c == "loopto") {
            pc.printf("starting loopto, Restart unit to end loop \r\n");
            cycle_loopto();

        } else if (str_c == "looptick") {
            pc.printf("starting looptick \r\n");
            cycle_looptick();

        } else if(str_c == "newval") {                                          // cahnges cycle time values
            pc.printf("enter your new on and off times(ms)\r\n");
            pc.puts("Time on\r\n");
            configData[0] = get_num_input();
            pc.puts("Time off\r\n");
            configData[2] = get_num_input();
            pc.printf("Data: %Lf, %Lf, %Lf\r\n",configData[0],configData[1],configData[2]);

        } else {
            pc.printf("Unknown command: [%s], see README for commands \r\n", str_c.c_str());
        }
        str_c = "";
    }

}

int main()
{
    init();

    while(!flg_END) {
        switch((int)configData[1]) {
            case(1):                                                            //Cut the power to the machine once
                cycle_wait();
                pc.printf("cycled \r\n");
                break;

            case(2):                                                            //Cut the power to the machine in a loop
                pc.printf("Beginning power cycle loop, to end loop press restart button \r\n");
                cycle_loopw();
                break;

            case(3):                                                            //Launch in serial command mode
                serial_mode();
                break;
        }

    }

    pc.printf("Program End \r\n");

    return 0;
}