new battery bar

Dependencies:   CAN_IDs CanControl Dashboard PinDetect PowerControl mbed-rtos mbed

main.cpp

Committer:
Marrkk_92
Date:
2017-05-23
Revision:
28:63ef4790703f
Parent:
27:6ffb44623906

File content as of revision 28:63ef4790703f:

/*******************************************************************************
This software is especially designed for Solarboat Twente for the use in their Solarboat v1.0

Written by:
Niels Leijen, Jesse van Rhijn, Bram Seinhorst, Mark Bruijn

Thanks to:
Jasper Admiraal, Hidde Pik (hihihihi), Lisa Postma, Heleen Jeurink, Ruben Peters,
Martijn Groot Jebbink, Martijn Wilpshaar, Bram Seinhorst, Robert Geels, Arnoud Meutstege,
Jeroen te Braake, Ids de Vos, Jesse van Rhijn, Sam Benou, Niels Leijen and Mark Bruijn

DISCLAIMER:
THIS SOFTWARE IS SUPPLIED "AS IS" WITHOUT ANY WARRANTIES AND SUPPORT. 
SOLARBOATTWENTE ASSUMES NO RESPONSIBILITY OR LIABILITY FOR THE USE OF THE SOFTWARE.
*******************************************************************************/

// uncomment to send debug information
//#define DEBUG

//include 3rd party libraries
#include "mbed.h" //needs to be revision 136 else SD filesystem will not work
#include "rtos.h"

// include Solarboat libraries
#include "pinout.h"
#include "CAN_IDs.h"
#include "PowerControl.h"
#include "TelemetryAndDaq.h"
#include "Dashboard.h"

#define SPEED_THRESH 0.02 //threshold for setting speed to prevent CAN spam
#define DEBUG
// initialize serial connection for debug and file retrieval
RawSerial pc(SERIAL_TX, SERIAL_RX);

// initialize canbus
CAN can(CAN_RD, CAN_TD);

//init throttle
AnalogIn analogThrottle(STEER_THROTTLE);

//initialize steering wheel buttons

//NEEDS FIXING!!!!!!!!!!!
DigitalIn menu_button(STEER_MENU);
DigitalIn fly_button(STEER_FLY);
DigitalIn reverse_button(STEER_REV);

// initialze onboard leds
DigitalOut ledError(LED3);
DigitalOut ledSD(LED1);
DigitalOut ledFona(LED5);
DigitalOut led24V(LED4);

DigitalOut buckXSens(BUCK3);
DigitalOut buckScreen(BUCK4);
DigitalOut buck24V(BUCK5);

//external classes
extern DataAcquisition daq;
extern Telemetrics telemetrics;
extern Dashboard dash;

//external variables
extern long long int starttime;

//external threads
extern Thread threadbg;

//global var for speed; ugly solution but works
float speed = 0;

//thread function declarations
void readThrottle();
void power();
void test();
void background();
void screens();
void resetScreens();

//varables for screens
extern batterydata * battery;
extern variable * velocitysqrd;
extern variable * motortemp;
//ticker for resetting screens
Ticker ticker;

//screen function declarations
void readEssentials();

//Screen placeholder variables
int battery_percentage_left = 0;
int battery_minutes_left = 0;
int race_percentage_left = 0;
int race_minutes_left = 0;
int race_minutes_done = 0;
int throttle_power = 0;
int advised_throttle_power = 0;
int power_in = 0;
int power_out = 0;
int voltage_in = 0;
int motor_temperature = 0;
int battery_temperature = 0;
int velocity = 0;
int rpm_motor = 0;
int checkIfButtonPressed(int current_menu);
int battery_voltage = 0;
int current_menu = 0;
time_t start = time(0);
void readEssentials();
bool menu_button_pressed = true;
bool reverse_button_pressed = true;
bool fly_request = true;
bool transmitting = false;
bool reverse = false;

// Thread 0 - DO NOT CHANGE THIS!
int main() {  
#ifdef DEBUG
    pc.baud(115200);
    pc.printf("Starting SOS V1.0\n");
#endif
    // change CAN frequency
    can.frequency(250000);
    
    // initialze threads
    Thread threadpower;
    Thread threadtest;
    Thread threadthrottle;
    Thread threaddash;
    Thread threadresetscr;
        
    // start threads
    threadpower.start(&power);
    Thread::wait(50);
    threadbg.start(&background);
    Thread::wait(50);
    threadtest.start(&test);
    Thread::wait(50);
    
    toggleControlSys(0x01);
    
    threaddash.start(&screens);
    Thread::wait(50);
    threadthrottle.start(&readThrottle);
    Thread::wait(50);
    telemetrics.enable();
    Thread::wait(50);
    daq.enable(starttime);
    
    //BMS message parser, now imlpemented in DAQ lib
    /*CANMessage msg;
    while(1) {
        if(can.read(msg)) {
            pc.printf("Message received: 0x %x; %u %u%u %d%d %c %u %u\n", msg.id, msg.data[0], msg.data[1], msg.data[2], msg.data[3], msg.data[4], msg.data[5], msg.data[6], msg.data[7]);
        }
        Thread::wait(10); 
    }*/
    Thread::wait(osWaitForever);
}

//send motor command
void sendMotorSpeed(float throttle) {
    if ((abs(throttle - speed)) > SPEED_THRESH) {
        union {
            char msg[4];
            float value;
        } packet;
        packet.value = throttle;
        can.write(CANMessage(MOTOR_COMMAND, packet.msg));
        printf("Sent motor speed: %f\r\n", packet.value);
        speed = throttle;
    }
}

//thread functions
void readThrottle() {
    float throttleread;
    int rev;
    while(1) {
        if (reverse) {
            rev = -1;   
        } else {
            rev = 1;
        }
        throttleread = rev*(1 - analogThrottle.read());
        sendMotorSpeed(throttleread);
        Thread::wait(10);   
    }
}  



void power() {
    PowerControl powercontrol(PUSH_GREEN); 
    
#ifdef DEBUG
    pc.printf("Thread 1 - Power started\r\n ");
#endif

    Thread::wait(osWaitForever);
}

void test() {
    ledError = 0;
    ledSD = 0;
    ledFona = 0 ;
    led24V=1;

//DigitalOut buckCan(BUCK2);
    buckXSens = 1;
    buckScreen = 1;
    buck24V = 1;
}

void resetScreens() {
    
    Thread::wait(10000);

    dash.powerOnOLED(1);
    dash.powerOnOLED(2);
    dash.powerOnOLED(3);
    
    dash.clearDisplay(1);
    dash.clearDisplay(2);
    dash.clearDisplay(3); 
}

void screens()
{
    dash.powerOnOLED(1);
    dash.powerOnOLED(2);
    dash.powerOnOLED(3);
    
    dash.clearDisplay(1);
    dash.clearDisplay(2);
    dash.clearDisplay(3);
    
    while(1) {
        
        Thread::wait(100);

        //listen to menu button
        current_menu = checkIfButtonPressed(current_menu);
        //listen to steering wheel at all time
        readEssentials();
        //check for errors at all time
        dash.checkForErrors(current_menu, velocity, battery_temperature, motor_temperature, battery_percentage_left, battery_minutes_left);
        
       
        switch (current_menu) {

            case 0:
                //circular display (1)
                //updateProgressCircle(1, race_percentage_left);
                race_minutes_done = daq.time/60000;         //TODO give starting point
                dash.showRaceMinutesDone(race_minutes_done);
                dash.showRaceMinutesLeft(race_minutes_left);
                dash.showRacePercentageLeft(race_percentage_left);

                //main display (2)
                dash.displayTime(daq.time + starttime);
                dash.checkTransmitter(transmitting);
                dash.displayVelocity(velocity);
                dash.displayThrottle(abs(throttle_power), reverse);
                //dash.updateThrottleBar(2, abs(throttle_power), 50, 20, 20, 5);
                //displayAdvisedThrottle(advised_throttle_power);
                //dash.updatePowerBars(power_out, power_in);
                dash.updateTemperatureBars(motor_temperature, battery_temperature);

                //circular display (3)
                //updateProgressCircle(3, battery_percentage_left);
                dash.showBatteryMinutesLeft(battery_minutes_left);
                dash.showBatteryPercentageLeft(battery_percentage_left);
                break;

            case 1:
                //circular display (1)
                //updateProgressCircle(1, race_percentage_left);
                race_minutes_done = daq.time/60000;         //TODO give starting point
                dash.showRaceMinutesDone(race_minutes_done);
                dash.showRaceMinutesLeft(race_minutes_left);
                dash.showRacePercentageLeft(race_percentage_left);

                //main display (2)
                dash.displayData1(rpm_motor, battery_temperature, motor_temperature, voltage_in, power_out, power_in);

                //circular display (3)
                //updateProgressCircle(3, battery_percentage_left);
                dash.showBatteryMinutesLeft(battery_minutes_left);
                dash.showBatteryPercentageLeft(battery_percentage_left);
                break;

            case 2:
                //circular display (1)
                //updateProgressCircle(1, race_percentage_left);
                race_minutes_done = daq.time/60000;         //TODO give starting point
                dash.showRaceMinutesDone(race_minutes_done);
                dash.showRaceMinutesLeft(race_minutes_left);
                dash.showRacePercentageLeft(race_percentage_left);

                //main display (2)
                dash.displayData2(battery_voltage, battery_temperature, motor_temperature, voltage_in, power_out, power_in);

                //circular display (3)
                //updateProgressCircle(3, battery_percentage_left);
                dash.showBatteryMinutesLeft(battery_minutes_left);
                dash.showBatteryPercentageLeft(battery_percentage_left);
                break;
            default:
                //empty, catch
                break;
        }
    }
}

int checkIfButtonPressed(int current_menu)
{
    //--------------MENU BUTTON--------------------
    if (menu_button == 0 && menu_button_pressed == false) {
        menu_button_pressed = true;
        start = time(0);
        current_menu++;
        if (current_menu > 2) current_menu = 0;
        
        //clear displays and reset settings
        dash.clearDisplay(1);
        dash.clearDisplay(2);
        dash.clearDisplay(3);       
        
    } else if (menu_button == 1) menu_button_pressed = false;
    //timeout for back to home screen
    /*double seconds_since_start = difftime(time(0), start);
    if (current_menu != 0 && seconds_since_start > MENU_TIMEOUT_TIME) {
        current_menu = 0;
        dash.clearDisplay(1);
        dash.clearDisplay(2);
        dash.clearDisplay(3);
    }*/

    //--------------REVERSE BUTTON--------------------
    if (reverse_button == 0 && reverse_button_pressed == false) {
        reverse_button_pressed = true;
        if (velocity < MAX_REVERSE_VELOCITY) reverse = !reverse;
    } else if (reverse_button == 1) reverse_button_pressed = false;

    //--------------FLY BUTTON--------------------
    if (fly_button == 0 && fly_request == false) {
        fly_request = true;
        if (velocity > MIN_FLY_VELOCITY) fly_request = !fly_request;
    } else if (fly_button == 1) fly_request = false;

    //return for menu
    return current_menu;
}

//power_out is now power_in minus power_out, can only fix 
void readEssentials()
{

    //get current throttle set + adjust params  -------- DEBUG
    throttle_power = 100*speed;
    power_out = (int) ((battery->current) * (battery->voltage));
    power_in = 680;
    velocity = (int) (3.6*sqrt((velocitysqrd->value))); //velocity in kph
    battery_minutes_left = throttle_power/6;
    battery_percentage_left = battery->SOC;
    motor_temperature = (int) (motortemp->value);
    battery_temperature = (int) (battery->maxtemp);
    battery_voltage = (int) (battery->voltage);
    rpm_motor = throttle_power;
    //voltage_in = 44;
    //race_minutes_left = 12;
    race_percentage_left = 100*race_minutes_done/(race_minutes_left+race_minutes_done);
}