Version 3 is with update to the test rig with a linear actuator

Dependencies:   SPTE_10Bar_5V mbed AS5048 SDFileSystem MODSERIAL PinDetect LCM101 LinearActuator

main.cpp

Committer:
surajgiri
Date:
2020-10-20
Revision:
13:219c16e7d32c
Parent:
11:fc82dd22a527

File content as of revision 13:219c16e7d32c:

/**
* Author: Allan Veale
* Date: 27/11/19
* Purpose: Datalog from the active wearable test rig fitted with the first
* realistic (foam tissue) leg
*/

//Both the general mbed header and the test rig bench header are needed 
#include "mbed.h"
#include "bench.h"
 
//Example experiment method 
void runFatigueExperiment0(int cycles, float targetkPa, float inflateTimeOut,float deflateTimeOut);
void runFailureExp0(float targetkPa);
void runBenchmarkExperiment0();
void runBenchmarkExperiment1(int pwm, int cycles, int logHz);

//Methods for testing DAC chip - leave for now
void selectDACB();
void deselectDACB();

void testDAC();
void testToggleChannel();

DigitalOut myled(LED1);
DigitalOut CSA(DAC_CSA);    
DigitalOut CSB(DAC_CSB);
SPI spi(DAC_MOSI,DAC_MISO,DAC_SCLK);

// Create bench object - this is used to control the test rig
Bench leg;

/**
 * Main loop
 */
int main()
{   
    leg.setLoggingFrequency(10); //Set datalogging frequency
    
    /* Two extra columns of data will be recorded in this experiment.
    One for the target pressure, and the other for the number of sit and 
    stand cycles currently completed in the experiment */ 
    string colNames[] = {"Target pressure (kPa)","Cycle",}; //add data headings
    leg.setExtraColumns(colNames,2);
    
    float targetP = 300;                                                                                                                                                                                        
    int expCycles = 40; //Number of sit to stand to sit cycles 
    float vals[] = {targetP,0}; //set initial values of data that will be logged
    leg.setExtraData(vals);
    
    /* Setup all peripherals on rig, display info about SD card and the 
    user interface menu */ 
    leg.initialise(); //this gives the 10MHz, normal clock polarity, mode 1 spi we need, pins are same as for encoder
    

      
    /*Run an experiment when the button is pressed to start datalogging and 
    stop it if the button is pressed again to stop datalogging 
    (or when experiment stops - then datalogging stops by itself) */
    while (true) {
        if (leg.isLogging()) {
            leg.pc.printf("Logging started");
            runFatigueExperiment0(expCycles,targetP,10,10);
            //runBenchmarkExperiment0();
            runBenchmarkExperiment1(75, 1, 10);    
            //runFailureExp0(targetP);        
        }
        wait(0.5);
    }
}

/**
 * Shows how a demo experiment works. This experiment pressurises the leg to 
 * pressure targetkPa, depressurises it, and then repeats the process cycles 
 * number of times
 * @param cycles: the number of cycles the leg goes up and down
 * @param targetkPa: the pressure at which the valve is opened to let the leg go down
 */
void runFatigueExperiment0(int cycles, float targetkPa, float inflateTimeOut, float deflateTimeOut) 
{
    //leg.pc.printf("\r\nEntered experiment");
    //The experiment starts when logging does
    Timer flowT;//used to time flow into and out of actuator
    float loopTime = 0.1; //(s) time between checking pressure
    int num_file = 1; //number of data files to save 
    
    for (int i=0; i<num_file; i++) {
        
    leg.StartLogging();
    //Stop the Bench class from printing, so this method can print
    leg.pausePrint();
    
    // Pressurise and depressurise the leg cycles number of times
        for (int i=0; i<cycles; i++) {
            leg.pc.printf("\r\nCycle: \t%i out of \t%i",i+1,cycles);
            
            //Update cycles logged
            float data[] = {targetkPa,i+1};
            leg.setExtraData(data);

            //Pressurise
            leg.setValve(true);
            flowT.reset();
            flowT.start();// start inflation timer
            
            //Wait until measured pressure reaches target pressure
            
            while(leg.getPressure0()*100 < targetkPa && flowT.read() < inflateTimeOut) {
    
                //Keep checking logging is going
                //experimentRunning = leg.isLogging(); 
                //leg.pc.printf("\r\nPressure (kPa): \t%7.2f",leg.getPressure0()*100);
                if (!leg.isLogging()) {
                    leg.pc.printf("\r\nExit A");
                    //Logging stopped
                    //leg.pc.printf("\r\nPressurising exit"); 
                    leg.setValve(false); //Depressurise
                    leg.StopLogging(); //Stop logging data
                    leg.resumePrint(); //Let the Bench class print
                    return;
                }
                
                leg.LogData();
                wait(loopTime);//Wait a bit
            }
            
        leg.pc.printf("\r\nTimer inflate: \t%7.2f",flowT.read());
        if(flowT.read() >= inflateTimeOut) {
            leg.pc.printf("\r\nExit B");
            //Logging stopped
            leg.setValve(false); //Depressurise
            leg.StopLogging(); //Stop logging data
            leg.resumePrint(); //Let the Bench class print
            return;
        }

        //Depressurise
        leg.pausePrint();
        leg.setValve(false);
        flowT.reset();

        /*Wait until depressurised (completely depressurised is
        around 10-12 kPa due to current sensor calibration)*/
        while(leg.getPressure0()*100 > 15 && flowT.read() < deflateTimeOut) {
            //leg.pc.printf("\r\nDepressurising");
            //Keep checking logging is going
            //experimentRunning = leg.isLogging();
            //leg.pc.printf("\r\nPressure (kPa): \t%7.2f",leg.getPressure0()*100);
            if (!leg.isLogging()) {
                leg.pc.printf("\r\nExit C");
                //Logging stopped
                leg.setValve(false); //Depressurise
                leg.StopLogging(); //Stop logging data
                leg.resumePrint(); //Let the Bench class print
                return;
            }

            leg.LogData();
            wait(loopTime);//Wait a bit
        }

        leg.pc.printf("\r\nTimer deflate: \t%7.2f",flowT.read());
        if(flowT.read() >= deflateTimeOut) {
            leg.pc.printf("\r\nExit D");
            //Logging stopped
            leg.setValve(false); //Depressurise
            leg.StopLogging(); //Stop logging data
            leg.resumePrint(); //Let the Bench class print
            return;
        }
    }

    // Logging stopped as experiment is fully completed
    leg.pc.printf("\r\nExit D");
    leg.setValve(false); //Depressurise
    leg.StopLogging(); //Stop logging data
    leg.resumePrint(); //Let the Bench class print
    }
}


void runBenchmarkExperiment0()
{
    //Pressurise
    leg.StartLogging();
    while(leg.isLogging()) {
        leg.setValve(true);
        leg.pc.printf("\r\nPressure (kPa): \t%7.2f",leg.getPressure0()*100);
        leg.LogData();
        wait(0.1);
    }
    //Depressurise
    leg.pc.printf("\r\nExit Benchmarking Test");
    leg.setValve(false);
    leg.StopLogging(); //Stop logging data
    leg.resumePrint(); //Let the Bench class print
}

/**
 * A performance test with the linear actuator
 * @param pwm: actuator speed
 * @param cycles: the number of up and down cycles of the leg
 * @param logHz: datalogging frequency
 */
void runBenchmarkExperiment1(int pwm, int cycles, int logHz)
{
    int minForce = 5; //N force at which cycle goes from extension to flexion
    int maxAngle = 70; //deg angle at which cycle goes from flexion to extension
    double logTime = 1/logHz;//s interval between logging data

    //Stop the Bench class from printing, so this method can print
    leg.pausePrint();

    //Pressurise
    leg.setValve(true);
    Timer t;
    t.reset();
    t.start();
    while(leg.isLogging() && t.read() < 3) {
        leg.pc.printf("\r\nPressure (kPa): \t%7.2f",leg.getPressure0()*100);
        wait(0.2);
    }

    leg.StartLogging();
    // in loop
    for (int i=0; i<cycles; i++) {
        //allow leg to go up until force is below threshold
        leg.setPWM(pwm);
        leg.setDir(0);
        leg.pc.printf("\r\nExtending: \t%i",cycles);
        while((leg.getForce() >= minForce) && leg.isLogging()) {
            leg.pc.printf("\r\nForce (N): \t%7.2f",leg.getForce());
            leg.LogData();
            wait(logTime);
        }
        if (!leg.isLogging()) {
            leg.pc.printf("\r\nExit A");
            //Logging stopped
            leg.setPWM(0); 
            leg.setValve(false);//Depressurise
            leg.StopLogging(); //Stop logging data
            leg.resumePrint(); //Let the Bench class print
            return;
        }

        //allow leg to go down until angle is greater than threshold
        leg.setPWM(pwm);
        leg.setDir(1);
        leg.pc.printf("\r\nFlexing: \t%i",cycles);
        while((leg.getDegrees(0) <= maxAngle) && leg.isLogging()) {
            leg.pc.printf("\r\nAngle (deg): \t%7.2f",leg.getDegrees(0));
            leg.LogData();
            wait(logTime);
        }
        if (!leg.isLogging()) {
            leg.pc.printf("\r\nExit B");
            //Logging stopped
            leg.setPWM(0); 
            leg.setValve(false);//Depressurise
            leg.StopLogging(); //Stop logging data
            leg.resumePrint(); //Let the Bench class print
            return;
        }
    }
    //Depressurise
    leg.pc.printf("\r\nExit Benchmarking Test");
    leg.setPWM(0);
    leg.setValve(false);
    leg.StopLogging(); //Stop logging data
    leg.resumePrint(); //Let the Bench class print
}

void runFailureExp0(float targetkPa) 
{
    
     //Pressurise
    leg.StartLogging();
    while(leg.isLogging()) {
        leg.setValve(true);
        leg.pc.printf("\r\nPressure (kPa): \t%7.2f",leg.getPressure0()*100);
        leg.LogData();
        wait(0.1);
    }
    //Depressurise
    leg.pc.printf("\r\nExit Benchmarking Test");
    leg.setValve(false);
    leg.StopLogging(); //Stop logging data
    leg.resumePrint(); //Let the Bench class print
}

    
void testDAC() {
    //setup SPI to write 8 bit words, mode 1 and turn select lines high
    spi.format(8,1);
    spi.frequency(200000);
    deselectDACB();
    wait_ms(20);
    
    //Power up DAC
    selectDACB();
    spi.write(0xE0);
    spi.write(0x00);
    deselectDACB();
    
    //Write a value to a channel
    selectDACB();
    spi.write(0x47);
    spi.write(0xFF);
    deselectDACB();
    

    
    
  /*  selectDACB();
    spi.write(0x2F);
    spi.write(0xFF);
    deselectDACB();
    
    selectDACB();
    spi.write(0x60);
    spi.write(0x00);
    deselectDACB();*/
    
    //wait(3);
    
    //Write a value to a channel
  /*  selectDACB();
    spi.write(0x40);
    spi.write(0x00);
    deselectDACB();*/
    
    while (true) {
        myled = !myled;


        wait_ms(500);
    }
}    

/** Selects DAC B (enable line goes low)
 */
void selectDACB()
{
    CSB.write(0);
    wait_us(1);
}

/** Deselects DAC B (enable line goes high)
 */
void deselectDACB()
{
    CSB.write(1);
    wait_us(1);
}
    
void testToggleChannel()
{
        // POWER up dac
    //select chip
    CSB.write(0);
    wait_us(1);

    spi.write(0b11100000);
    spi.write(0b00000000);

    //deselect chip
    CSB.write(1);
    wait_us(1);


    //write output on a
    //select chip
    CSB.write(0);
    wait_us(1);

    spi.write(0b01000011);
    spi.write(0b11111111);

    //deselect chip
    CSB.write(1);
    wait_us(1);
    
   
    //write output on b
    //select chip
    CSB.write(0);
    wait_us(1);

    spi.write(0b01011011);
    spi.write(0b11111111);

    //deselect chip
    CSB.write(1);
    wait_us(1);
    
    while (true) {
        //leg.pc.printf("Hi");
        // POWER up dac
        //select chip
        CSB.write(0);
        wait_us(1);

        spi.write(0b11100000);
        spi.write(0b00000000);

        //deselect chip
        CSB.write(1);
        wait_us(1);
        //write output on a
        //select chip
        CSB.write(0);
        wait_us(1);

        spi.write(0b01010011);
        spi.write(0b11111111);

        spi.write(0b01001011);
        spi.write(0b11111111);

        //deselect chip
        CSB.write(1);
        wait_us(1);

        wait_ms(100);


    }
    bool ch = true;
    while (true) {
        //data value
        unsigned int data = 0xFFF;

        //if more than 12 bits (0xfff) then set all bits true)
        if (data > 0xFFF) {
            data = 0xFFF;
        }

        //select chip
        //bring cs low
        CSB.write(0);
        //wait a bit (more than 40ns)
        wait_us(1);

        //transfer a command (for channel a 0x4<<12 + data masked to 12 bits, for channel b 0x5<<12 + data masked to 12 bits)

        int command = (0x01<<12);//default to channel a
        /*if (!ch) {
            command = (0x05<<12);
            } */
        data = command + (data&0xFFF);
        //spi.write(data);
        spi.write(data>>8);
        spi.write(data & 0x00FF);
        //bring cs high
        CSB.write(1);
        //wait a bit (more than 10-15ns)
        wait_us(1);
        wait_ms(10);
        //leg.pc.printf("\r\nCommand: \t%i",command);

        //leg.pc.printf("\r\nData: \t%i",data);
        ch = !ch;
    }
}