
Prototype program for the Body Swap Machine
main.cpp
- Committer:
- moshi
- Date:
- 2017-03-25
- Revision:
- 0:19ea917e5234
File content as of revision 0:19ea917e5234:
#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]); } }