Tobias Kuhn
/
LCD_XpressoBoard_3_SoundSens
program for ping pong robot
Revision 0:14b64813c04d, committed 2016-06-29
- Comitter:
- pnpako
- Date:
- Wed Jun 29 00:02:00 2016 +0000
- Commit message:
- ping pong robot
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Controller.h Wed Jun 29 00:02:00 2016 +0000 @@ -0,0 +1,76 @@ +//controller class +class Controller +{ + +protected: + +public: + + int data[3]; + int output; + int P_Val; + int I_Val; + int D_Val; + + Controller(int dummy) { + output = 0; + P_Val = 0; + I_Val = 0; + D_Val = 0; + for(int i = 0; i < 3; i++) { + data[i] = 0; + } + } + + void updateData(int val) { + //first, update the DataReg + updateDataReg(val); + //calculate proportional-value + calculate_P_Val(); + //calculate Integrate-value + calculate_I_Val(); + //calculate differentiate-value + calculate_D_Val(); + //calculate output + calculateOutput(); + } + + int getOutput(void) { + return output; + } + + void updateDataReg(int val) { + data[0] = data[1]; + data[1] = data[2]; + data[2] = val; + } + + void calculate_P_Val(void) { + P_Val = data[2]/4; + } + + void calculate_I_Val(void) { + //increase the correction if the current value is + (or - ) over a long timespan + if(data[2] >= 0) { + I_Val++; + } else { + I_Val--; + } + + } + + void calculate_D_Val(void) { + //current X-coordinate - last X-coordinate = direction in which the ball is moving + //example: 3 - 4 = -1 + //ball moved from 4 to 3. its moving in the minus direction. + //a minus value will get the correction-Value down. + D_Val = (data[2] - data[1])/3; + } + + void calculateOutput() { + output = P_Val + D_Val + I_Val; + } + + +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FNCS.h Wed Jun 29 00:02:00 2016 +0000 @@ -0,0 +1,4 @@ + + + +//empty \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LCD.h Wed Jun 29 00:02:00 2016 +0000 @@ -0,0 +1,286 @@ +DigitalOut LCD_DB4(p5); +DigitalOut LCD_DB5(p6); +DigitalOut LCD_DB6(p7); +DigitalOut LCD_DB7(p8); + +DigitalOut LCD_EN(p30); +DigitalOut LCD_RW(p29); +DigitalOut LCD_RS(p28); + +unsigned int get_power2(int a) +{ + int i = 0; + + unsigned int power = 1; + for(i = 0; i < a; i++) { + power *= 2; + } + return power; +} + +unsigned int get_bit(char word, int a) +{ + unsigned int s = get_power2(a); + + if((word & s) != 0) + return(1); + else + return(0); +} + +void setDB_singleShot(unsigned short x) +{ + /* This hex number is the same as binary 0001 */ + short MASK = 0x01; + + LCD_DB4 = (MASK & x) ? 1 : 0; + MASK = MASK << 1; + LCD_DB5 = (MASK & x) ? 1 : 0; + MASK = MASK << 1; + LCD_DB6 = (MASK & x) ? 1 : 0; + MASK = MASK << 1; + LCD_DB7 = (MASK & x) ? 1 : 0; +} + +void EnableImp() +{ + wait(0.02); + LCD_EN = 1; + wait(0.02); + LCD_EN = 0; + wait(0.02); +} + +void FastEnableImp() +{ + wait(0.001); + LCD_EN = 1; + wait(0.001); + LCD_EN = 0; + wait(0.001); +} + +void init() +{ + //SET ALL BITS TO 0 + LCD_RS = 0; + LCD_RW = 0; + LCD_EN = 0; + + setDB_singleShot(0x00); //HEX 0x00 is 0000 in Binary + EnableImp(); + //DISPLAY IN 4BIT MODE + LCD_RS = 0; + LCD_RW = 0; + setDB_singleShot(0x02); //HEX 0x02 is 0010 in Binary + EnableImp(); + + setDB_singleShot(0x00); //HEX 0x00 is 0000 in Binary + EnableImp(); + //SET FUNCTION + LCD_RS = 0; + LCD_RW = 0; + setDB_singleShot(0x0C); //HEX 0x0C is 1100 in Binary + EnableImp(); + + setDB_singleShot(0x00); //HEX 0x00 is 0000 in Binary + EnableImp(); + //DISPLAY ON + LCD_RS = 0; + LCD_RW = 0; + setDB_singleShot(0x0C); //HEX 0x0F is 1111 in Binary --> Cursor ON + BLINKING + EnableImp(); //HEX 0x0C is 1100 in Binary --> Cursor OFF + NO BLINKING + + setDB_singleShot(0x00); //HEX 0x00 is 0000 in Binary + EnableImp(); + //DISPLAY CLEAR + LCD_RS = 0; + LCD_RW = 0; + setDB_singleShot(0x01); //HEX 0x01 is 0001 in Binary + EnableImp(); + + setDB_singleShot(0x00); //HEX 0x00 is 0000 in Binary + EnableImp(); + //SET ENTRY MODE + LCD_RS = 0; + LCD_RW = 0; + setDB_singleShot(0x06); //HEX 0x06 is 0110 in Binary + EnableImp(); + + +} + +void clearDispl() +{ + //DISPLAY CLEAR + LCD_RS = 0; + LCD_RW = 0; + wait(0.001); + setDB_singleShot(0x00); //HEX 0x00 is 0000 in Binary + FastEnableImp(); + + setDB_singleShot(0x01); //HEX 0x01 is 0001 in Binary + FastEnableImp(); +} + +void setCursorPos(unsigned short pos) +{ + LCD_RS = 0; + LCD_RW = 0; + + /* This hex number is the same as binary 0001 */ + short MASK = 0x01; + + MASK = MASK << 4; + LCD_DB4 = (MASK & pos) ? 1 : 0; + MASK = MASK << 1; + LCD_DB5 = (MASK & pos) ? 1 : 0; + MASK = MASK << 1; + LCD_DB6 = (MASK & pos) ? 1 : 0; + MASK = MASK << 1; + LCD_DB7 = 1; + FastEnableImp(); + + MASK = 0x01; + LCD_DB4 = (MASK & pos) ? 1 : 0; + MASK = MASK << 1; + LCD_DB5 = (MASK & pos) ? 1 : 0; + MASK = MASK << 1; + LCD_DB6 = (MASK & pos) ? 1 : 0; + MASK = MASK << 1; + LCD_DB7 = (MASK & pos) ? 1 : 0; + FastEnableImp(); +} + +void writeChar(char x) +{ + LCD_RS = 1; + LCD_RW = 0; + + LCD_DB4 = get_bit(x, 4); + LCD_DB5 = get_bit(x, 5); + LCD_DB6 = get_bit(x, 6); + LCD_DB7 = get_bit(x, 7); + EnableImp(); + + LCD_DB4 = get_bit(x, 0); + LCD_DB5 = get_bit(x, 1); + LCD_DB6 = get_bit(x, 2); + LCD_DB7 = get_bit(x, 3); + EnableImp(); +} + +void fastWriteChar(char x) +{ + LCD_RS = 1; + LCD_RW = 0; + + LCD_DB4 = get_bit(x, 4); + LCD_DB5 = get_bit(x, 5); + LCD_DB6 = get_bit(x, 6); + LCD_DB7 = get_bit(x, 7); + FastEnableImp(); + + LCD_DB4 = get_bit(x, 0); + LCD_DB5 = get_bit(x, 1); + LCD_DB6 = get_bit(x, 2); + LCD_DB7 = get_bit(x, 3); + FastEnableImp(); +} + +void writeHex(unsigned short x, unsigned short y) +{ + LCD_RS = 1; + LCD_RW = 0; + + setDB_singleShot(x); + EnableImp(); + + setDB_singleShot(y); + EnableImp(); +} + +void writeString(char str[]) +{ + while(*str) { + writeChar(*str); + str++; + } +} + +void fastWriteString(char str[]) +{ + while(*str) { + fastWriteChar(*str); + str++; + } +} + +void writeHex_RS0_RW0(unsigned short x, unsigned short y) +{ + //SET CGRAM Address + LCD_RS = 0; + LCD_RW = 0; + + setDB_singleShot(x); + EnableImp(); + + setDB_singleShot(y); + EnableImp(); +} + +void writeHex_RS1_RW0(unsigned short x, unsigned short y) +{ + LCD_RS = 1; + LCD_RW = 0; + + setDB_singleShot(x); + EnableImp(); + + setDB_singleShot(y); + EnableImp(); +} + +void write_pixel_character(void) +{ + + for(int i = 0; i < 8; i++) { + //Set the Adress to 0100 0000 to 0100 0111 + writeHex_RS0_RW0(4, i); + //Write the user specified pixel line + switch(i) { + case 0: + writeHex(0,14); + break; + case 1: + writeHex(0,14); + break; + case 2: + writeHex(0,4); + break; + case 3: + writeHex(1,15); + break; + case 4: + writeHex(0,4); + break; + case 5: + writeHex(0,14); + break; + case 6: + writeHex(0,10); + break; + case 7: + writeHex(0,10); + break; + default: + writeHex(0,0); + break; + } + } + + writeHex(0,0); + + return; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MISC.h Wed Jun 29 00:02:00 2016 +0000 @@ -0,0 +1,37 @@ + +//class for useful functions +class MISC +{ + +protected: + +public: + + //function for easy convertion int -> str + char* intToString(int x) { + char tmp[16] = " "; + sprintf(tmp, "%d", x); + return tmp; + } + + //function for easy convertion float -> str + char* floatToString(float x) { + char tmp[20] = " "; + sprintf(tmp, "%f", x); + return tmp; + } + + //funtion to cut off too high values + int ValCut(int val) { + if(val > 400) { + return 400; + } else { + return val; + } + } + +}; + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ServoClass.h Wed Jun 29 00:02:00 2016 +0000 @@ -0,0 +1,241 @@ +PwmOut PWMservo1(p21); +PwmOut PWMservo2(p22); +PwmOut PWMservo3(p23); +PwmOut PWMservo4(p24); + +class Servo +{ + +public: + + Servo(int, int, int, int, int, int, int); + int getPWforPosMax (int); + int getPWforPosIdle (void); + int getPWforPosMin (int); + int getPWforPosLow (int); + + int offset; + int cor; + int diffForPosMin; + int diffForPosLow; + int diffForPosMax; + int idlePW; + int PW; + int reverse_true; + +}; + +Servo::Servo (int of, int mn, int mx, int lw, int idl, int cr, int rev) +{ + offset = of; + cor = cr; + diffForPosMin = mn; + diffForPosMax = mx; + diffForPosLow = lw; + idlePW = idl; + reverse_true = rev; +} + +int Servo::getPWforPosMax (int cntr) +{ + if(reverse_true) { + return(idlePW + offset - diffForPosMax - cor + cntr); + } else { + return(idlePW + offset + diffForPosMax + cor - cntr); + } +} + +int Servo::getPWforPosLow (int cntr_) +{ + if(reverse_true) { + return(idlePW + offset + diffForPosLow - cor - cntr_); + } else { + return(idlePW + offset - diffForPosLow + cor + cntr_); + } +} + +int Servo::getPWforPosMin (int cntr_) +{ + if(reverse_true) { + return(idlePW + offset + diffForPosMin - cor - cntr_); + } else { + return(idlePW + offset - diffForPosMin + cor + cntr_); + } +} + +int Servo::getPWforPosIdle () +{ + if(reverse_true) { + return(idlePW + offset - cor); + } else { + return(idlePW + offset + cor); + } +} + +Servo Servo_1(0, 200, 250, 100, 1500, 0, 0); +Servo Servo_2(0, 200, 250, 100, 1500, 0, 1); +Servo Servo_3(0, 200, 250, 100, 1500, 0, 0); +Servo Servo_4(0, 200, 250, 100, 1500, 0, 1); + +//Servo Servo_1(100, 200, 250, 100, 1500, 0, 0); OLD VALUES (OFFSET) +//Servo Servo_2(30, 200, 250, 100, 1500, 0, 1); +//Servo Servo_3(-10, 200, 250, 100, 1500, 0, 0); +//Servo Servo_4(-120, 200, 250, 100, 1500, 0, 1); + +void movePosTop(void) +{ + PWMservo1.pulsewidth_us(Servo_1.getPWforPosMax(0)); + PWMservo2.pulsewidth_us(Servo_2.getPWforPosMax(0)); + PWMservo3.pulsewidth_us(Servo_3.getPWforPosMax(0)); + PWMservo4.pulsewidth_us(Servo_4.getPWforPosMax(0)); +} + +void movePosTopSlow(void) +{ + int cntr_ = 400; + while(cntr_ > 0) { + wait(0.0005); + PWMservo1.pulsewidth_us(Servo_1.getPWforPosMax(cntr_)); + PWMservo2.pulsewidth_us(Servo_2.getPWforPosMax(cntr_)); + PWMservo3.pulsewidth_us(Servo_3.getPWforPosMax(cntr_)); + PWMservo4.pulsewidth_us(Servo_4.getPWforPosMax(cntr_)); + cntr_--; + } +} + +void movePosLowSlow(void) +{ + int cntr_ = 400; + while(cntr_ > 0) { + wait(0.001); + PWMservo1.pulsewidth_us(Servo_1.getPWforPosLow(cntr_)); + PWMservo2.pulsewidth_us(Servo_2.getPWforPosLow(cntr_)); + PWMservo3.pulsewidth_us(Servo_3.getPWforPosLow(cntr_)); + PWMservo4.pulsewidth_us(Servo_4.getPWforPosLow(cntr_)); + cntr_--; + } +} + +void movePosLow(void) +{ + int cntr_ = 400; + while(cntr_ > 0) { + wait(0.0003); + PWMservo1.pulsewidth_us(Servo_1.getPWforPosLow(cntr_)); + PWMservo2.pulsewidth_us(Servo_2.getPWforPosLow(cntr_)); + PWMservo3.pulsewidth_us(Servo_3.getPWforPosLow(cntr_)); + PWMservo4.pulsewidth_us(Servo_4.getPWforPosLow(cntr_)); + cntr_--; + } +} + +void movePosBottomFast(void) +{ + PWMservo1.pulsewidth_us(Servo_1.getPWforPosMin(0)); + PWMservo2.pulsewidth_us(Servo_2.getPWforPosMin(0)); + PWMservo3.pulsewidth_us(Servo_3.getPWforPosMin(0)); + PWMservo4.pulsewidth_us(Servo_4.getPWforPosMin(0)); +} + +void movePosBottom(void) +{ + int cntr_ = 400; + while(cntr_ > 0) { + wait(0.0003); + PWMservo1.pulsewidth_us(Servo_1.getPWforPosMin(cntr_)); + PWMservo2.pulsewidth_us(Servo_2.getPWforPosMin(cntr_)); + PWMservo3.pulsewidth_us(Servo_3.getPWforPosMin(cntr_)); + PWMservo4.pulsewidth_us(Servo_4.getPWforPosMin(cntr_)); + cntr_--; + } +} + +void movePosBottomSlow(void) +{ + int cntr_ = 400; + while(cntr_ > 0) { + wait(0.0005); + PWMservo1.pulsewidth_us(Servo_1.getPWforPosMin(cntr_)); + PWMservo2.pulsewidth_us(Servo_2.getPWforPosMin(cntr_)); + PWMservo3.pulsewidth_us(Servo_3.getPWforPosMin(cntr_)); + PWMservo4.pulsewidth_us(Servo_4.getPWforPosMin(cntr_)); + cntr_--; + } +} + +void movePosIdle(void) +{ + PWMservo1.pulsewidth_us(Servo_1.getPWforPosIdle()); + PWMservo2.pulsewidth_us(Servo_2.getPWforPosIdle()); + PWMservo3.pulsewidth_us(Servo_3.getPWforPosIdle()); + PWMservo4.pulsewidth_us(Servo_4.getPWforPosIdle()); + +} + +void correctPlateToLeft(int val) +{ + int corVal = val; + Servo_1.cor += -corVal; + Servo_4.cor += -corVal; + Servo_2.cor += corVal; + Servo_3.cor += corVal; +} + +void correctPlateToRight(int val) +{ + int corVal = val; + Servo_2.cor += -corVal; + Servo_3.cor += -corVal; + Servo_1.cor += corVal; + Servo_4.cor += corVal; +} + +void correctPlateToFront(int val) +{ + int corVal = val; + Servo_1.cor += -corVal; + Servo_2.cor += -corVal; + Servo_3.cor += corVal; + Servo_4.cor += corVal; +} + +void correctPlateToBack(int val) +{ + int corVal = val; + Servo_1.cor += corVal; + Servo_2.cor += corVal; + Servo_3.cor += -corVal; + Servo_4.cor += -corVal; +} + +void resetCorrection(void) +{ + Servo_2.cor = 0; + Servo_3.cor = 0; + Servo_1.cor = 0; + Servo_4.cor = 0; +} + + +void UpDownx2(void) +{ + movePosTopSlow(); + wait(0.1); + movePosBottomSlow(); + wait(0.1); + movePosTopSlow(); + wait(0.1); + movePosBottomSlow(); + wait(0.1); +} + + + +void initServos() +{ + PWMservo1.period(0.004); // servo requires a 20ms period + PWMservo2.period(0.004); + PWMservo3.period(0.004); + PWMservo4.period(0.004); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Jun 29 00:02:00 2016 +0000 @@ -0,0 +1,236 @@ +#include "mbed.h" +#include <stdlib.h> +#include "LCD.h" +#include "MISC.h" +#include <math.h> +#include "ServoClass.h" +#include "Controller.h" +LocalFileSystem local("local"); + +MISC misc; +Controller controller_x(0); +Controller controller_y(0); + +#include "FNCS.h" + +DigitalOut myled(LED1); +DigitalOut led2(LED2); + +DigitalIn mic1(p12); +DigitalIn mic2(p13); +DigitalIn mic3(p14); +DigitalIn mic4(p15); +DigitalOut resetFF(p16); +DigitalOut PowerOn12V(p17); + + + +bool flag_mic1 = false; +bool flag_mic2 = false; +bool flag_mic3 = false; +bool flag_mic4 = false; + +int difCntr_1 = 0; +int difCntr_2 = 0; +int mic1_val = 0; +int mic2_val = 0; +int mic3_val = 0; +int mic4_val = 0; + +int valxAxis = 0; +int valyAxis = 0; + + +int data1[1001] = {0}; +FILE *fp1; +int cntr1 = 0; + +int data2[1001] = {0}; +FILE *fp2; + +int data3[100] = {0}; +FILE *fp3; + +int data4[100] = {0}; +FILE *fp4; + +int main() +{ + + init(); + initServos(); + wait(2); + PowerOn12V = 1; + + movePosTopSlow(); + wait(0.1); + movePosBottomSlow(); + wait(0.1); + movePosTopSlow(); + wait(0.1); + movePosLowSlow(); + wait(0.1); + movePosTopSlow(); + wait(0.1); + + + while(cntr1 < 1001) { + difCntr_1 = 0; + difCntr_2 = 0; + flag_mic1 = false; + flag_mic2 = false; + flag_mic3 = false; + flag_mic4 = false; + clearDispl(); + if(cntr1 < 2) { + fastWriteString("ready."); + } else { + fastWriteString(misc.intToString(cntr1 - 1)); + } + + while(!flag_mic1 || !flag_mic2 || !flag_mic3 || !flag_mic4) { + //loop until all mic signals got set. + + //check mic1 + if(mic1 && !flag_mic1) { + //reset Counter if first + if(!flag_mic2) { + difCntr_1 = 0; + } + //set the mic value to the current difCntr value. + mic1_val = difCntr_1; + flag_mic1 = true; + } + //check mic2 + if(mic2 && !flag_mic2) { + //reset Counter if first + if(!flag_mic1) { + difCntr_1 = 0; + } + //set the mic value to the current difCntr value. + mic2_val = difCntr_1; + flag_mic2 = true; + } + //check mic3 + if(mic3 && !flag_mic3) { + //reset Counter if first + if(!flag_mic4) { + difCntr_2 = 0; + } + //set the mic value to the current difCntr value. + mic3_val = difCntr_2; + flag_mic3 = true; + } + //check mic4 + if(mic4 && !flag_mic4) { + //reset Counter if first + if(!flag_mic3) { + difCntr_2 = 0; + } + //set the mic value to the current difCntr value. + mic4_val = difCntr_2; + flag_mic4 = true; + } + + difCntr_1++; + difCntr_2++; + } + + resetCorrection(); + + //valxAxis is + when the ball is near mic2 and - when the Ball is near mic1 + valxAxis = misc.ValCut(mic1_val) - misc.ValCut(mic2_val); + //update the X-axis controller + controller_x.updateData(valxAxis); + correctPlateToRight(controller_x.getOutput()); + + //valyAxis is + when the ball is near mic4 and - when the Ball is near mic3 + valyAxis = misc.ValCut(mic3_val) - misc.ValCut(mic4_val); + //update the Y-axis controller + controller_y.updateData(valyAxis); + correctPlateToBack(controller_y.getOutput()); + + movePosBottom(); + + + data1[cntr1] = valxAxis; + data2[cntr1++] = valyAxis; + + clearDispl(); + //fastWriteString("mic1: "); + fastWriteString(misc.intToString(mic1_val)); + setCursorPos(41); + //fastWriteString("mic2: "); + fastWriteString(misc.intToString(mic2_val)); + + clearDispl(); + //fastWriteString("mic3: "); + fastWriteString(misc.intToString(mic3_val)); + setCursorPos(41); + //fastWriteString("mic4: "); + fastWriteString(misc.intToString(mic4_val)); + + wait(0.01); + resetFF = 1; + while(mic1 || mic2 || mic3 || mic4); + resetFF = 0; + movePosTop(); + } + + clearDispl(); + fastWriteString("cntr1 > 100"); + + if ( NULL == (fp1 = fopen( "/local/S1.csv", "w" )) ) { + error( "" ); + } + for ( int i = 0; i < cntr1; i++ ) { + fprintf( fp1, "%d\n", data1[i] ); + } + fclose( fp1 ); + + if ( NULL == (fp2 = fopen( "/local/S2.csv", "w" )) ) { + error( "" ); + } + for ( int i = 0; i < cntr1; i++ ) { + fprintf( fp2, "%d\n", data2[i] ); + } + fclose( fp2 ); + + if ( NULL == (fp3 = fopen( "/local/S3.csv", "w" )) ) { + error( "" ); + } + for ( int i = 0; i < cntr1; i++ ) { + fprintf( fp3, "%d\n", data3[i] ); + } + fclose( fp3 ); + + if ( NULL == (fp4 = fopen( "/local/S4.csv", "w" )) ) { + error( "" ); + } + for ( int i = 0; i < cntr1; i++ ) { + fprintf( fp2, "%d\n", data4[i] ); + } + fclose( fp4 ); + + clearDispl(); + fastWriteString("data saved."); + + //END HERE + while(1); + + + +} + + + + + + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Jun 29 00:02:00 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/433970e64889 \ No newline at end of file