16A_Autopancakemaker
Dependencies: DigitDisplay Servo ds1307 mbed stepper
main.cpp
- Committer:
- pruek
- Date:
- 2015-12-12
- Revision:
- 0:e7aedcbababd
File content as of revision 0:e7aedcbababd:
#include "mbed.h" #include "stepper.h" #include "Servo.h" #include <string> #include "DigitDisplay.h" #include "ds1307.h" #define ACCEL_ON 1 #define ACCEL_OFF 0 #define SPEED_X 300 #define SPEED_Y 300 #define X_STEPS_PER_MM 86 #define Y_STEPS_PER_MM 86 #define PI 3.14 #define Resolution 500 #define CURVE_SECTION_MM 5 #define Curve_feq_MM 5 //Communication Serial pc(SERIAL_TX,SERIAL_RX); Serial Nucleo(D8,D2); DS1307 thistime(D14,D15); //clock DigitalOut buzz(D6); DigitDisplay display(D7, D5); Ticker tick; int year = 1; int month = 1; int date =1; int day = 1; int hour = 17; int minute = 28; int second = 0; int Coundown = 30; //Servo Servo Pen_1(A0); //Servo Pen_2(A1); //Stepper stepper x(PB_13,PB_14); stepper y(PA_12,PC_5); //Limit Switch DigitalIn X_MIN(PC_0,PullUp); DigitalIn X_MAX(PC_1,PullUp); DigitalIn Y_MIN(PB_0,PullUp); DigitalIn Y_MAX(PA_4,PullUp); struct FloatPoint { float x; float y; float sum; }; FloatPoint current_steps; FloatPoint target_steps; FloatPoint delta_steps; FloatPoint current_mm; FloatPoint target_mm; FloatPoint delta_mm; FloatPoint fp; FloatPoint MAX; FloatPoint MIN; float z; float curve_section = CURVE_SECTION_MM; int Set = 0; bool x_direction; bool y_direction; long max_delta; long x_counter; long y_counter; int Mode_G = 0; int Mode_$ = 0; int SIZE = 0; int s; int state_pen; float i,j; int serch(char ch,string cmd); void Taonoi_Begin (); bool Taonoican_Step_x(long current, long target, int8_t direction_x); bool Taonoican_Step_y(long current, long target, int8_t direction_y); void Taonoi_Move(); void calculate_deltas(); void Curve (float i, float j); void Taonoi_Square(float X_MAX, float X_MIN, float Y_MAX, float Y_MIN); void Taonoi_Around(float X_MAX, float X_MIN, float Y_MAX, float Y_MIN); void Taonoi_Ellipse(float X_MAX, float X_MIN, float Y_MAX, float Y_MIN); void beatup(); void percent_coundown(); int main() { pc.baud(115200); Nucleo.baud(9600); pc.printf("Hello\n"); string data ; Taonoi_Begin(); //Taonoi_Around(50,0,70,0); //Taonoi_Square(50,0,70,0); //Taonoi_Oval(50,0,100,30); MAX.x = 0; MAX.y = 0; MIN.x = 200; MIN.x = 200; thistime.gettime( &second, &minute, &hour, &day, &date, &month, &year); display.write(0, hour / 10); display.write(1, hour % 10); display.write(2, minute / 10); display.write(3, minute % 10); display.setColon(true); tick.attach(&beatup, 0.5); while(1) { fp.x = 0.0; fp.y = 0.0; if(Nucleo.readable()) { char ch = Nucleo.getc(); if(ch!='\r') { pc.putc(ch); data.push_back(ch); } else { if(data.find('G') != std::string::npos) { Mode_G = serch('G',data); } if(data.find('$') != std::string::npos) { Mode_$ = serch('$',data); } if(data.find('X') != std::string::npos) { //target_steps.x = serch('X',data); target_mm.x = serch('X',data); fp.x = target_mm.x; } if(data.find('Y') != std::string::npos) { target_mm.y = serch('Y',data); fp.y = target_mm.y; } if(data.find('Z') != std::string::npos) { z = serch('Z',data); } if(data.find('I') != std::string::npos) { i = serch('I',data); } if(data.find('J') != std::string::npos) { j = serch('J',data); } if(data.find('S') != std::string::npos) { s = serch('S',data); if(s==1) SIZE = 0; else if (s==2) SIZE = 20; else if (s==3) SIZE = 40; } data.clear(); if(Mode_G == 2 || Mode_G == 3) { Pen_1 = z; if(state_pen == 1 && z == 0) wait(0.5); else if (state_pen == 0 && z == 1) wait(0.5); state_pen = z; Curve(i,j); Nucleo.putc('#'); Mode_G = 0; } else { calculate_deltas(); Pen_1 = z; if(state_pen == 1 && z == 0) wait(0.5); else if (state_pen == 0 && z == 1) wait(0.5); state_pen = z; Taonoi_Move(); Nucleo.putc('#'); } if(Mode_$ == 1) { Taonoi_Square(MAX.x,MIN.x,MAX.y,MIN.y); Nucleo.putc('$'); Mode_$ = 0; } else if(Mode_$ == 2) { Taonoi_Around(MAX.x,MIN.x,MAX.y,MIN.y); Nucleo.putc('$'); Mode_$ = 0; } else if(Mode_$ == 3) { Taonoi_Ellipse(MAX.x,MIN.x,MAX.y,MIN.y); Nucleo.putc('$'); Mode_$ = 0; } } } } } int serch(char ch,string cmd) { size_t pos = cmd.find(ch); size_t epos = cmd.find(' '); string temp = cmd.substr(pos+1,epos-pos); //pc.printf("\n===: %s\n\n",temp.c_str()); return atoi(temp.c_str()); } void Taonoi_Begin() { Pen_1 = 1; target_mm.x = -400; target_mm.y = -400; calculate_deltas(); Taonoi_Move(); current_steps.x = 0; current_steps.y = 0; target_mm.x = 50;//50; target_mm.y = 100;//100; calculate_deltas(); Taonoi_Move(); current_steps.x = 0; current_steps.y = 0; target_mm.x = 0; target_mm.y = 0; target_steps.x = 0; target_steps.y = 0; Set = 1; } bool Taonoican_Step_x(long current, long target, int8_t direction_x) { if (target == current) return false; //stop us if we're at home and still going else if (!X_MIN.read() && !direction_x) return false; //stop us if we're at max and still going else if (!X_MAX.read() && direction_x) return false; //default to being able to step return true; } bool Taonoican_Step_y(long current, long target, int8_t direction_y) { if (target == current) return false; //stop us if we're at home and still going else if (!Y_MIN.read() && !direction_y) return false; //stop us if we're at max and still going else if (!Y_MAX.read() && direction_y) return false; //default to being able to step return true; } void Taonoi_Move() { //figure out our deltas max_delta = delta_steps.x > delta_steps.y ? delta_steps.x : delta_steps.y; //init stuff. long x_counter = -max_delta / 2; long y_counter = -max_delta / 2; //our step flags bool x_can_step = 0; bool y_can_step = 0; int A = 0; int B = 0; do { x_can_step = Taonoican_Step_x(current_steps.x, target_steps.x, x_direction); y_can_step = Taonoican_Step_y(current_steps.y, target_steps.y, y_direction); if (x_can_step) { x_counter += delta_steps.x; if (x_counter > 0) { x.step(1,x_direction,SPEED_X,ACCEL_OFF); x_counter -= max_delta; if (x_direction) current_steps.x++; else current_steps.x--; } else A++; } if (y_can_step) { y_counter += delta_steps.y; if (y_counter > 0) { y.step(1,y_direction,SPEED_Y,ACCEL_OFF); y_counter -= max_delta; if (y_direction) current_steps.y++; else current_steps.y--; } else B++; } if(A > 10000 || B>10000) break; //wait for next step. } while (x_can_step || y_can_step); //set our points to be the same current_steps.x = target_steps.x; current_steps.y = target_steps.y; current_mm.x = target_mm.x; current_mm.y = target_mm.y; calculate_deltas(); } void calculate_deltas() { delta_mm.x = abs(target_mm.x - current_mm.x); delta_mm.y = abs(target_mm.y - current_mm.y); target_steps.x = X_STEPS_PER_MM * target_mm.x; target_steps.y = Y_STEPS_PER_MM * target_mm.y; if(Set == 1) { if(target_mm.x > MAX.x) MAX.x = target_mm.x; if(target_mm.x < MIN.x) MIN.x = target_mm.x; if(target_mm.y > MAX.y) MAX.y = target_mm.y; if(target_mm.y < MIN.y) MIN.y = target_mm.y; } delta_steps.x = abs(target_steps.x - current_steps.x); delta_steps.y = abs(target_steps.y - current_steps.y); x_direction = (target_steps.x >= current_steps.x); y_direction = (target_steps.y >= current_steps.y); } void Curve (float i, float j) { FloatPoint cent; cent.x = i+current_mm.x; cent.y = j+current_mm.y; // Centre coordinates are always relative float angleA, angleB, angle, radius, length, aX, aY, bX, bY; aX = (current_mm.x - cent.x); aY = (current_mm.y - cent.y); bX = (fp.x - cent.x); bY = (fp.y - cent.y); if (Mode_G == 2) { // Clockwise angleA = atan2(bY, bX); angleB = atan2(aY, aX); } else { // Counterclockwise angleA = atan2(aY, aX); angleB = atan2(bY, bX); } // Make sure angleB is always greater than angleA // and if not add 2PI so that it is (this also takes // care of the special case of angleA == angleB, // ie we want a complete circle) if (angleB <= angleA) angleB += 2 * PI; angle = angleB - angleA; radius = sqrt(aX * aX + aY * aY); length = radius * angle; int steps, s, step; steps = (int) ceil(length / curve_section); //FloatPoint newPoint; for (s = 1; s <= steps; s++) { step = (Mode_G == 3) ? s : steps - s; // Work backwards for CW target_mm.x = cent.x + radius * cos(angleA + angle * ((float) step / steps)); target_mm.y = cent.y + radius * sin(angleA + angle * ((float) step / steps)); calculate_deltas(); Taonoi_Move(); } } void Curve_Ex (float i, float j) { FloatPoint cent; cent.x = i+current_mm.x; cent.y = j+current_mm.y; // Centre coordinates are always relative float angleA, angleB, angle, radius, length, aX, aY, bX, bY; aX = (current_mm.x - cent.x); aY = (current_mm.y - cent.y); bX = (fp.x - cent.x); bY = (fp.y - cent.y); if (Mode_G == 2) { // Clockwise angleA = atan2(bY, bX); angleB = atan2(aY, aX); } else { // Counterclockwise angleA = atan2(aY, aX); angleB = atan2(bY, bX); } // Make sure angleB is always greater than angleA // and if not add 2PI so that it is (this also takes // care of the special case of angleA == angleB, // ie we want a complete circle) if (angleB <= angleA) angleB += 2 * PI; angle = angleB - angleA; radius = sqrt(aX * aX + aY * aY); length = radius * angle; int steps, s, step; steps = (int) ceil(length / curve_section); //FloatPoint newPoint; for (s = 1; s <= steps; s++) { step = (Mode_G == 3) ? s : steps - s; // Work backwards for CW target_mm.x = cent.x + 2*radius * cos(angleA + angle * ((float) step / steps)); target_mm.y = cent.y + radius * sin(angleA + angle * ((float) step / steps)); calculate_deltas(); Taonoi_Move(); } } void Curve_Ey (float i, float j) { FloatPoint cent; cent.x = i+current_mm.x; cent.y = j+current_mm.y; // Centre coordinates are always relative float angleA, angleB, angle, radius, length, aX, aY, bX, bY; aX = (current_mm.x - cent.x); aY = (current_mm.y - cent.y); bX = (fp.x - cent.x); bY = (fp.y - cent.y); if (Mode_G == 2) { // Clockwise angleA = atan2(bY, bX); angleB = atan2(aY, aX); } else { // Counterclockwise angleA = atan2(aY, aX); angleB = atan2(bY, bX); } // Make sure angleB is always greater than angleA // and if not add 2PI so that it is (this also takes // care of the special case of angleA == angleB, // ie we want a complete circle) if (angleB <= angleA) angleB += 2 * PI; angle = angleB - angleA; radius = sqrt(aX * aX + aY * aY); length = radius * angle; int steps, s, step; steps = (int) ceil(length / curve_section); //FloatPoint newPoint; for (s = 1; s <= steps; s++) { step = (Mode_G == 3) ? s : steps - s; // Work backwards for CW target_mm.x = cent.x + radius * cos(angleA + angle * ((float) step / steps)); target_mm.y = cent.y + 2*radius * sin(angleA + angle * ((float) step / steps)); calculate_deltas(); Taonoi_Move(); } } void Taonoi_Square(float X_MAX, float X_MIN, float Y_MAX, float Y_MIN) { float Delta_X = abs(X_MAX - X_MIN); float Delta_Y = abs(Y_MAX - Y_MIN); int Max = (Delta_X > Delta_Y) ? ceil(Delta_X) : ceil(Delta_Y); float Cen_X = (X_MAX + X_MIN) / 2; float Cen_Y = (Y_MAX + Y_MIN) / 2; Coundown = ceil((Max/5)*(Max/5+1)*(0.115)); target_mm.x = Cen_X; target_mm.y = Cen_Y; calculate_deltas(); Taonoi_Move(); Pen_1 = 0; //percent_coundown(Coundown); //timer.start(); for(int i = 0; i < Max + 4 + SIZE; i += 5) { if(i % 2 != 0) { target_mm.x = current_mm.x + i; calculate_deltas(); Taonoi_Move(); target_mm.y = current_mm.y + i; calculate_deltas(); Taonoi_Move(); } else { target_mm.x = current_mm.x - i; calculate_deltas(); Taonoi_Move(); target_mm.y = current_mm.y - i; calculate_deltas(); Taonoi_Move(); } } Pen_1 = 1; for(int k=0; k<5; k++) { buzz=1; wait(0.5); buzz=0; } MAX.x = MAX.y = 0; MAX.x = MAX.y = 200; } void Taonoi_Around(float X_MAX, float X_MIN, float Y_MAX, float Y_MIN) { float Delta_X = abs(X_MAX - X_MIN); float Delta_Y = abs(Y_MAX - Y_MIN); int Max = (Delta_X > Delta_Y) ? ceil(Delta_X) : ceil(Delta_Y); float Cen_X = (X_MAX + X_MIN) / 2; float Cen_Y = (Y_MAX + Y_MIN) / 2; int R_max = Max/2+Curve_feq_MM; int Num_c = R_max/Curve_feq_MM+1; Coundown = ceil((12.5*Num_c+5*(Num_c-1)*(Num_c))*0.094); float R1 = Curve_feq_MM; float R2 = R1/2; //int Coundown = ceil((Max/5)*(Max/5+1)*(0.115)); target_mm.x = Cen_X; target_mm.y = Cen_Y; calculate_deltas(); Taonoi_Move(); Pen_1 = 0; // percent_coundown(Coundown_c); target_mm.x = Cen_X + R1; target_mm.y = Cen_Y; calculate_deltas(); Taonoi_Move(); do { Mode_G = 3; fp.x = Cen_X-R1; fp.y = Cen_Y; Curve(-R1,0); fp.x = Cen_X+R1+Curve_feq_MM; fp.y = Cen_Y; Curve(R1 + R2,0); R1 = R1 + Curve_feq_MM; } while(R1 <= R_max + SIZE); Pen_1 = 1; for(int k=0; k<5; k++) { buzz=1; wait(0.5); buzz=0; } Mode_G = 0; MAX.x = MAX.y =0; MIN.x = MIN.y =200; } void Taonoi_Ellipse(float X_MAX, float X_MIN, float Y_MAX, float Y_MIN) { float Delta_X = abs(X_MAX - X_MIN); float Delta_Y = abs(Y_MAX - Y_MIN); int Max = (Delta_X > Delta_Y) ? ceil(Delta_X) : ceil(Delta_Y); float Cen_X = (X_MAX + X_MIN) / 2; float Cen_Y = (Y_MAX + Y_MIN) / 2; int R_max = Max/2+Curve_feq_MM; int Num_c = R_max/Curve_feq_MM+1; Coundown = ceil((12.5*Num_c+5*(Num_c-1)*(Num_c))*0.094); float R1 = Curve_feq_MM; float R2 = R1/2; target_mm.x = Cen_X; target_mm.y = Cen_Y; calculate_deltas(); Taonoi_Move(); Pen_1 = 0; //percent_coundown(Coundown_c); target_mm.x = Cen_X + R1; target_mm.y = Cen_Y; calculate_deltas(); Taonoi_Move(); do { Mode_G = 3; fp.x = Cen_X-R1; fp.y = Cen_Y; Curve_Ey(-R1,0); fp.x = Cen_X+R1+Curve_feq_MM; fp.y = Cen_Y; Curve_Ey(R1 + R2,0); R1 = R1 + Curve_feq_MM; } while(R1<=R_max + SIZE); Pen_1 = 1; for(int k=0; k<5; k++) { buzz=1; wait(0.5); buzz=0; } //timer.stop(); /*} else { do { Mode_G = 3; fp.x = Cen_X-2*R1; fp.y = Cen_Y; Curve_Ex(-R1,0); fp.x = Cen_X+2*R1+2*Curve_feq_MM; fp.y = Cen_Y; Curve_Ex(R1 + R2,0); R1 = R1 + Curve_feq_MM; } while(R1<=R_max + SIZE); Pen_1 = 1; Mode_G = 0; }*/ Mode_G = 0; MAX.x = MAX.y =0; MIN.x = MIN.y =200; } void beatup() { static uint8_t colon = 0; display.setColon(colon); if (colon) { second++; if (second >= 60) { second = 0; minute++; if (minute >= 60) { minute = 0; hour++; if (hour >= 24) { hour = 0; } display.write(0, hour / 10); display.write(1, hour % 10); } display.write(2, minute / 10); display.write(3, minute % 10); } } colon = 1 - colon; } /*void percent_coundown() static uint8_t colon = 0; int current_time = 0 ; int current_percent =0; display.setColon(colon); if (colon) { } colon = 1 - colon; } { int current_time = 0 ; int current_percent =0; display.write(0, 0); do { current_time=timer.read(); current_percent = current_time*100/time; display.write(1, current_percent/100); display.write(2, (current_percent%100)/10); display.write(3, current_percent%10); } while(time<=current_time); display.write(1, 1); display.write(2, 0); display.write(3, 0); for(int k=0; k<5; k++) { buzz=1; wait(5); buzz=0; } display.setColon(true); tick.attach(&beatup, 0.5); current_time=0; }*/