Satoshi Tohda
/
BodySwap2
Prototype program for the Body Swap Machine
Revision 0:19ea917e5234, committed 2017-03-25
- 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