Prototype program for the Body Swap Machine

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
moshi
Date:
Sat Mar 25 10:33:36 2017 +0000
Commit message:
BodySwap

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 19ea917e5234 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Mar 25 10:33:36 2017 +0000
@@ -0,0 +1,337 @@
+#include "mbed.h"
+
+/***
+/ Body Swap Machine Program 
+***/
+
+#define actuatorFrequency 250       //Frequency of actuator vibration[Hz]
+
+#define sscTickerInterval 0.1       //Ticker Interval [s]
+#define updateFrequency 20000       //Update frequency for sine wave[Hz]
+
+#define MIN_TIME_DIFF 500           //Chatter elimination delay for tact switch [us]
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+AnalogIn ain1(p15);
+AnalogIn ain2(p16);
+
+InterruptIn buttonA(p12);           //Blue Button
+InterruptIn buttonB(p13);           //Yellow Button
+InterruptIn buttonC(p14);           //Red Button
+
+SPI spi(p5, NC, p7);                //mosi (master output slave input), miso, sclk
+DigitalOut cs(p8);                  //chip select pin
+Serial pc(USBTX, USBRX);            //tx, rx
+
+int phase[2] = {0};                 //current phase of sinusoid (int from 0 to 999)
+char phasetick[2][1000] = {0};      //how much one ticker call moves the phase
+int phasetickcounter = 0;           //which phasetick to use
+
+float ms_passed_per_t = 0;          //how many milliseconds will pass per an increase in t
+
+float amplitude[2] = {0, 0};    //Amplitude of vibration[%]
+int frequency[2] = {0, 0};          //Frequency of vibration[Hz]
+
+long int t = 0;                     //Time. Equivalent to (10^-4)s. Resets when going into state 3 or state 4
+
+short waveTable[1100] = {0};        //table for output values in case of sine wave
+                                    //waveTable[k][i] = 1/2 * ( 1 + sin( 2*PI * (i/1000 ) ), waveTable[1][i] = actual strength at those points
+
+short DA[2] = {0};                  //table for actual binary passed to DA converter
+
+short silence[4] = {4096,8192,12288,16384}; 
+                                    //pass to DAC when output is zero
+short channel[4] = {4096,8192,12288,16384};
+                                    //binary for each channel
+
+float adc1 = 0;                     //input from adc1
+float adc2 = 0;
+float volts1 = 0;                   //convert to voltage
+float volts2 = 0;                   
+
+float prev_button_press_A = -100;   //timing of previous button press[us]
+float prev_button_press_B = -100; //timing of previous button press[us]   
+float prev_button_press_C = -100; //timing of previous button press[us]     
+
+float reset_pressed_time = false;       
+
+Ticker time_ticker;                 //ticker
+
+LocalFileSystem local("local");               // Create the local filesystem under the name "local"
+FILE *fp;
+
+//for measuring time
+Timer time1;
+int ttaken[100] = {0};
+int cont = 0;
+float ave = 0;
+int max = 0;
+//for measuring time
+
+void vibration();
+void waveDefine(int);
+
+
+//time_ticker
+void time(){
+
+    //time1.start();
+
+    t++;                                                //every 50us
+    vibration();
+
+    //resets time if t is greater than 1800000000 (30 minutes)
+    
+    if(t - 1800000000 > 0){
+        t = 0;
+    }
+    
+    if(t%20 == 0){
+        
+        amplitude[0] = ain1.read();     //reads input from sensor 1 (value 0~1) and inputs value into actuator vibration amplitude
+
+    }else if(t%20 - 1 == 0){
+
+        amplitude[1] = ain2.read();
+
+    }
+
+    /*
+    time1.stop();
+    
+    if(cont < 99){
+        ttaken[cont] = time1.read_us();
+        cont++;
+    }else if(cont == 99){
+        ttaken[cont] = time1.read_us();
+        for(int i = 0; i<100;i++){
+            ave += ttaken[i];
+            if(ttaken[i] > max){
+                max = ttaken[i];
+            }
+        }
+        ave = ave/100;
+        cont = 1000;
+        pc.printf("%f\r\n",ave);
+    }
+    
+    time1.reset();
+    */
+    
+}
+
+
+void initVariables(){
+
+    ms_passed_per_t = (float)1000.000 / (float)updateFrequency;
+    t = 0;
+
+    for(int i = 0; i < 2; i++){
+        frequency[i] = actuatorFrequency;
+    }
+
+    amplitude[0] = 0.1;
+    amplitude[1] = 0.1;
+
+    buttonA.mode(PullUp);
+    buttonB.mode(PullUp);
+    buttonC.mode(PullUp);
+
+}
+
+
+void setWaveTable(){
+    
+    /***
+    / Sets the Sine Wave Table
+    ***/
+
+    double temp = 0.0;
+    double ttactual = 0.0;              //actual(optimal) value of phasetic in double
+    double ticksum = 0.0;               //sum of all ticker calls
+
+    for(int i = 0; i < 2; i++){
+
+        phase[i] = 0;
+        ttactual = 1000.0 * frequency[i] / updateFrequency;
+
+        if(ttactual == (int)ttactual){
+            for(int j = 0; j < 1000; j++){
+                phasetick[i][j] = (int)(ttactual);              //if the tick in phase is an integer, simply input the integer
+            }
+            ticksum = ttactual*100;
+            
+        }else{
+            for(int j = 0; j < 1000; j++){                      //if the tick in phase is NOT an integer
+                phasetick[i][j] = (int)(ttactual);              //cast value to integer (integer < double) and input
+                ticksum += phasetick[i][j];                     //find sum of phases
+
+                if(ttactual * (j + 1.0) - ticksum >= 0.99999){  //if difference between target and actual sum is equal to or greater than 1
+                    phasetick[i][j]++;                          //add 1
+                    ticksum++;                                  //add 1
+                    
+                }
+            }
+        }
+    }
+
+    for(int k = 0; k < 1100; k++){
+        temp = (sin(2.0*3.14159*k/1000)*0.5+0.5)*0x3FF;
+        waveTable[k] = (short)temp;
+    }
+
+}
+
+
+void vibration(){
+    phasetickcounter++;
+
+    if(phasetickcounter >= 1000)
+        phasetickcounter = 0;
+
+    for(int i = 0; i < 2; i++){                           // i=channel number
+        
+        //Part 1 : tick the phase
+        phase[i] += phasetick[i][phasetickcounter];
+
+        if(phase[i] >= 1000)
+            phase[i] -= 1000;
+        //Part 1 end
+
+        //Part 2 : change input to relevant data
+        waveDefine(i);
+        //Part 2 End.
+
+        //Part 3: write input
+        cs = 0;                 //enable clock
+        spi.write(DA[i]);
+        cs = 1;                 //disable clock and load data
+        //part 3 end
+    }
+}
+
+
+void waveDefine(int i){
+
+    double inputvalue =  0;
+
+    //amplitude[i] = 1;         //temporary measure - change this to sensor input
+    //notQuiet[i] = 1;
+
+    inputvalue = amplitude[i] * (double)waveTable[phase[i]];
+    DA[i] = (((i&0x07)+1)<<12)|((((int)inputvalue)&0x3FF)<<2);
+
+    return;
+}
+
+void writeVoltage(){
+
+    if(t - prev_button_press_A > MIN_TIME_DIFF){
+        led2 = 1;
+        prev_button_press_A = t;
+        adc1 = ain1.read();
+        adc2 = ain2.read();
+        volts1 = adc1 * 3.3;
+        volts2 = adc2 * 3.3;
+
+        fp = fopen("/local/out.csv", "a");
+        // prints sensor 1 voltage, sensor 2 voltage, time[seconds]
+        fprintf(fp, "%.5f, %.5f, %.3f\n",volts1,volts2,(float)t/20000);
+        fclose(fp);
+        led2 = 0;
+    }
+}
+
+void softReset_f(){
+
+    if(t - prev_button_press_C > MIN_TIME_DIFF){
+        prev_button_press_C = t;
+        reset_pressed_time = t;
+        led4 = 1;
+    }
+}
+
+void softReset_r(){
+
+    if(t - prev_button_press_C > MIN_TIME_DIFF){
+        prev_button_press_C = t;
+        led4 = 0;
+        if(t - reset_pressed_time > 20000){
+            NVIC_SystemReset();
+        }
+    }
+}
+/*
+void blinkLED1(){
+
+    if(t - prev_button_press_A > MIN_TIME_DIFF){
+        prev_button_press_A = t;
+        led2 = !led2;
+    }
+}
+*/
+void blinkLED2(){
+
+    if(t - prev_button_press_B > MIN_TIME_DIFF){
+        prev_button_press_B = t;
+        led3 = !led3;
+    }
+}
+
+/*
+void blinkLED3_f(){
+
+    if(t - prev_button_press_C > MIN_TIME_DIFF){
+        prev_button_press_C = t;
+        reset_pressed_time = t;
+    }
+}
+
+void blinkLED3_r(){
+
+    if(t - prev_button_press_C > MIN_TIME_DIFF){
+        prev_button_press_C = t;
+
+        if(t - reset_pressed_time > 20000){
+            led4 = !led4;
+        }
+    }
+}
+*/
+
+int main() {
+
+    initVariables();
+    setWaveTable();
+
+    // Setup SPI communications w/ DA converter
+    spi.format(16,0);
+    spi.frequency(10000000);    //10MHz
+
+    //attack ticker
+    time_ticker.attach_us(&time,1000000 / updateFrequency);  //Every (10^-4)s
+
+    //attach button
+    buttonA.fall(&writeVoltage);
+    buttonB.fall(&blinkLED2);
+
+    //attach reset button (Resets mbed if RED button is pressed for more than 1 second and released)
+    buttonC.fall(&softReset_f);
+    buttonC.rise(&softReset_r);
+
+    //test serial output
+    pc.printf("Hello, world!\n\r");
+
+    //LED1 Blink every 0.5s
+    while(1){
+        wait(0.5);
+        led1 = !led1;
+        pc.printf("S1: %f\r\n", amplitude[0]);
+        pc.printf("S2: %f\r\n", amplitude[1]);
+    }
+
+}
\ No newline at end of file
diff -r 000000000000 -r 19ea917e5234 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Mar 25 10:33:36 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e1686b8d5b90
\ No newline at end of file