State machine

Dependencies:   mbed Adafruit_GFX BioroboticsMotorControl MODSERIAL BioroboticsEMGFilter

EMG_calibration.h

Committer:
brass_phoenix
Date:
2018-11-01
Revision:
46:0be634ee10e8
Parent:
39:f119ca6fc821

File content as of revision 46:0be634ee10e8:

#pragma once

#include "mbed.h"
#include "MODSERIAL.h"
#include "Screen.h"
#include "EMGFilter.h"

const double emg_calibration_time = 3.0;

class EMG_calibration
{
private:
    Ticker      calibration_timer;
    Timeout     adjustment_time;
    Timeout     calibration_bicep;      // Timeout to get to relax state
    Timeout     end_of_calibration;     // Timeout to get to final state
    Screen*     screen;

    //variables
    volatile float emg_signal;
    volatile float EMG_min_relax;
    volatile float EMG_min_tense;
    volatile float EMG_max_relax;
    volatile float EMG_max_tense;
    volatile float EMG_threshold;
    // IN STATE MACHINE:
    EMGFilter *emg_input;         // Voor kalibratie van bicep 1
    //EMGFilter emg_input = EMGFilter(A1);         // Voor kalibratie van bicep 2
    
    volatile float calibration_complete;

public:
    EMG_calibration(Screen *new_screen, EMGFilter *new_emg_input) {
        screen= new_screen;
        emg_input = new_emg_input;
        EMG_min_relax=1.000;
        EMG_min_tense=1.000;
        EMG_max_relax=0.000;
        EMG_max_tense=0.000;
        
        calibration_complete = false;
    }
    
    void start() {
        tense_measure();
    }
    
    bool is_calibrated() {
        return calibration_complete;
    }

private:
    void tense_calibration() {
        emg_signal = emg_input->get_envelope_emg();
        if (EMG_max_tense < emg_signal) {
            EMG_max_tense=emg_signal;
        }
        if (EMG_min_tense > emg_signal) {
            EMG_min_tense=emg_signal;
        }
        screen->get_screen_handle()->setTextCursor(0, 0);
        screen->get_screen_handle()->printf("Tense                ");
        screen->get_screen_handle()->printf("EMG maximum= %.6f",EMG_max_tense);
        screen->get_screen_handle()->printf("EMG minimum= %.6f",EMG_min_tense);
        screen->get_screen_handle()->printf("                     ",EMG_min_tense);
        screen->display();
    }

    void relax_calibration() {
        emg_signal = emg_input->get_envelope_emg();
        if (EMG_max_relax < emg_signal) {
            EMG_max_relax=emg_signal;
        }
        if (EMG_min_relax > emg_signal) {
            EMG_min_relax=emg_signal;
        }
        EMG_threshold=(((EMG_min_tense-EMG_max_relax)/2)+EMG_max_relax);
        screen->get_screen_handle()->setTextCursor(0, 0);
        screen->get_screen_handle()->printf("Relax                ");
        screen->get_screen_handle()->printf("EMG maximum= %.6f",EMG_max_relax);
        screen->get_screen_handle()->printf("EMG minimum= %.6f",EMG_min_relax);
        screen->get_screen_handle()->printf("threshold= %.6f",EMG_threshold);
        screen->display();
    }

    void TheFinalCalibration() {
        calibration_bicep.detach();
        calibration_timer.detach();
        screen->get_screen_handle()->setTextCursor(0, 0);
        screen->get_screen_handle()->printf("Threshold= %.6f",EMG_threshold);
        screen->get_screen_handle()->printf("                     ");
        screen->get_screen_handle()->printf("                     ");
        screen->get_screen_handle()->printf("                     ");
        screen->display();
        emg_input->set_threshold(EMG_threshold);
        
        calibration_complete = true;
    }

    void relax_measure() {
        calibration_timer.detach();
        screen->get_screen_handle()->setTextCursor(0, 0);
        screen->get_screen_handle()->printf("Relax muscle         ",EMG_max_relax);
        screen->get_screen_handle()->printf("                     ",EMG_min_tense);
        screen->get_screen_handle()->printf("                     ",EMG_min_tense);
        screen->get_screen_handle()->printf("                     ",EMG_min_tense);
        screen->display();
        adjustment_time.attach(callback(this, &EMG_calibration::start_relax),2.5f);
    }
    void start_relax() {
        calibration_timer.attach(callback(this, &EMG_calibration::relax_calibration), 0.1);
        end_of_calibration.attach(callback(this, &EMG_calibration::TheFinalCalibration), emg_calibration_time);
    }

    void tense_measure() {
        calibration_timer.detach();
        screen->get_screen_handle()->setTextCursor(0, 0);
        screen->get_screen_handle()->printf("Tense muscle         ",EMG_max_relax);
        screen->get_screen_handle()->printf("                     ",EMG_min_tense);
        screen->get_screen_handle()->printf("                     ",EMG_min_tense);
        screen->get_screen_handle()->printf("                     ",EMG_min_tense);
        screen->display();
        adjustment_time.attach(callback(this, &EMG_calibration::start_tense),2.5f);
    }
    void start_tense() {
        calibration_timer.attach(callback(this, &EMG_calibration::tense_calibration),0.1);
        calibration_bicep.attach(callback(this, &EMG_calibration::relax_measure), emg_calibration_time);
    }
};