commit
Dependencies: PID SDFileSystem Stepper_Motor_X27168 mbed-rtos mbed millis
main.cpp
- Committer:
- ebeauchemin3
- Date:
- 2016-04-29
- Revision:
- 1:d6183c8b01de
- Parent:
- 0:3a7cef09ad54
File content as of revision 1:d6183c8b01de:
#include "mbed.h" #include <stdio.h> #include <stdlib.h> #include <math.h> #include <assert.h> #include "SDFileSystem.h" #include "StepperMotor_X27168.h" #include <mbed.h> #include <mpr121.h> #include "rtos.h" #include "PID.h" #include "millis/millis.h" DigitalOut myled(LED1); Serial pc(USBTX, USBRX); SDFileSystem sd(p5, p6, p7, p8, "sd"); float xNowPrint; float yNowPrint; float zNowPrint; #define DEFAULT_Kp 5//mess with these to increase speed, was 1, .002, 20 #define DEFAULT_Ki 0.01 #define DEFAULT_Kd 20 #define THERMISTORNOMINAL 100000 // 100k // temp. for nominal resistance (almost always 25 C) #define TEMPERATURENOMINAL 25 // The beta coefficient of the thermistor (usually 3000-4000) #define BCOEFFICIENT 3950 // the value of the 'other' resistor #define SERIESRESISTOR 4700 #define AUTOMATIC 1 #define MANUAL 0 #define DIRECT 0 #define REVERSE 1 #define thermistor A3 // FRDM-K64F Analog input pin A3 - Adjust to your particular board #define driver PTC3 // FRDM-K64F PWM output pin PTC3 - Adjust to your particular board AnalogIn Thermistor(p20);//thermistor); // Read temperature value from thermistor on A3 PwmOut Driver(p25); // PWM drive FET heater on PTC3 values are 0-1.0 // For 0-100% float Input, Output, Setpoint, currTemp =0; PID controller(&Input, &Output, &Setpoint, DEFAULT_Kp , DEFAULT_Ki , DEFAULT_Kd , DIRECT); #define RATE 1.0 // Print rate Once per second float scaleX = .05; float scaleY = .1; float scaleZ = .1; StepperMotor_X27168 smotor1(p23, p24, p22, p21); StepperMotor_X27168 smotor2(p9, p10, p29, p30); StepperMotor_X27168 smotor3(p14, p15, p13, p12); StepperMotor_X27168 smotor4(p17, p16, p18, p19); // Setup the i2c bus on pins 9 and 10 I2C i2c(p28, p27); // Setup the Mpr121: // constructor(i2c object, i2c address of the mpr121) Mpr121 mpr121(&i2c, Mpr121::ADD_VSS); enum moveMotor { NONE, XPLUS, XMINUS, YPLUS, YMINUS, ZPLUS, ZMINUS }; moveMotor motorMove = NONE; //all motors initially stopped int motor1Go = 2; int motor2Go = 2; int motor3Go = 2; int motor4Go = 2; char *strdup (const char *s) { char *d = (char*)malloc (strlen (s) + 1); // Space for length plus nul if (d == NULL) return NULL; // No memory strcpy (d,s); // Copy the characters return d; // Return the new string } //split a string on a delimiter char** str_split(char* a_str, const char a_delim) { char** result = 0; size_t count = 0; char* tmp = a_str; char* last_comma = 0; char delim[2]; delim[0] = a_delim; delim[1] = 0; /* Count how many elements will be extracted. */ while (*tmp) { if (a_delim == *tmp) { count++; last_comma = tmp; } tmp++; } /* Add space for trailing token. */ count += last_comma < (a_str + strlen(a_str) - 1); /* Add space for terminating null string so caller knows where the list of returned strings ends. */ count++; result = (char**)malloc(sizeof(char*) * count); if (result) { size_t idx = 0; char* token = strtok(a_str, delim); while (token) { assert(idx < count); *(result + idx++) = strdup(token); token = strtok(0, delim); } assert(idx == count - 1); *(result + idx) = 0; } return result; } void motorXYprint() { //smotor1.set_speed(xNowPrint/yNowPrint*200); int spinvar = 0; float xSpot = 0; float ySpot = 0; xNowPrint = floor(xNowPrint); yNowPrint = floor(yNowPrint); float product = abs(xNowPrint*yNowPrint); if ((xNowPrint > 0) and (xNowPrint > 0)) { while(spinvar <= product) { spinvar ++; if (xSpot < spinvar) { smotor1.step(0); xSpot = xSpot + product/yNowPrint; } if (ySpot < spinvar) { smotor2.step(0); ySpot = ySpot + product/xNowPrint; } } } else if ((xNowPrint > 0)and(xNowPrint < 0)) { while(spinvar <= product) { spinvar ++; if (xSpot < spinvar) { smotor1.step(0); xSpot = xSpot + abs(product/yNowPrint); } if (ySpot < spinvar) { smotor2.step(1); ySpot = ySpot + abs(product/xNowPrint); } //Thread::wait(50.0); } } else if ((xNowPrint < 0)and(xNowPrint > 0)) { while(spinvar <= product) { spinvar ++; if (xSpot < spinvar) { smotor1.step(1); xSpot = xSpot + abs(product/yNowPrint); } if (ySpot < spinvar) { smotor2.step(0); ySpot = ySpot + abs(product/xNowPrint); } //Thread::wait(50.0); } } else if ((xNowPrint < 0)and(xNowPrint < 0)) { while(spinvar <= product) { spinvar ++; if (xSpot < spinvar) { smotor1.step(1); xSpot = xSpot - (product/yNowPrint); } if (ySpot < spinvar) { smotor2.step(1); ySpot = ySpot - (product/xNowPrint); } //Thread::wait(50.0); } } smotor1.step(2); smotor2.step(2); } void motorZprint() { //smotor2.set_speed(yNowPrint/xNowPrint*200); int spinvar2 = 0; if (zNowPrint > 0) { while(spinvar2 <= zNowPrint) { spinvar2 ++; //smotor3.step(0); Thread::wait(50.0); } } else if (zNowPrint < 0) { while(spinvar2 >= zNowPrint) { spinvar2 --; //smotor3.step(1); Thread::wait(50.0); } } smotor3.step(2); } void print() //read from gcode file { FILE *fp = fopen("/sd/text/gCode.txt", "r"); pc.printf("Hello World!\n"); //FILE *stream; char line[200]; char g[2]="G"; char m[2]="M"; char x[2]="X"; char y[2]="Y"; char z[2]="Z"; char e[2]="E"; char f[2]="F"; char** tokens; char** astrktokens; float extruderX = 0; float extruderY = 0; float extruderZ = 0; float extruderE = 0; float extruderF = 0; pc.printf("here\n"); //end the 4 motor threads motor1Go=3; motor2Go=3; motor3Go=3; motor4Go=3; while (fgets(line, 200, fp)) { //get a line wait(.5); char firstLet[sizeof(line)]; strncpy(firstLet, line,1); firstLet[1] = 0; if (strcmp(firstLet,g) * strcmp(firstLet,m) == 0) { astrktokens = str_split(line, ';'); char* tempdata = *(astrktokens); //pc.printf("Temp data: %s", tempdata); char fullData[100]; //char singleVariable[100]; strcpy(fullData, tempdata); tokens = str_split(tempdata, ' '); if (tokens) { int i = 0; //ssize_t char* data = *(tokens + i); pc.printf("Data: %s ", data); wait(.5); if (strcmp(data,"G0") * strcmp(data,"G1") == 0) { //Move: X,Y,Z-postions to move to, E-extrude amount, F-feedrate pc.printf("Move to: "); i = 1; float newX = 0; float newY = 0; float newZ = 0; float newE = 0; float newF = 0; while(strcmp(*(tokens + i),"\0") != 0) { data = *(tokens + i); //strcpy(singleVariable, data); //pc.printf("Deep Data: %s ", data); char firstLet[sizeof(data)]; strncpy(firstLet, data,1); firstLet[1] = 0; if (strcmp(firstLet,x) == 0) { memmove(data, data+1, strlen(data)); newX = strtof(data, NULL); pc.printf("X: %f", newX); if (extruderX == 0) { extruderX = newX; } } else if (strcmp(firstLet,y) == 0) { memmove(data, data+1, strlen(data)); newY = strtof(data, NULL); pc.printf("Y: %f", newY); if (extruderY == 0) { extruderY = newY; } } else if (strcmp(firstLet,z) == 0) { memmove(data, data+1, strlen(data)); newZ = strtof(data, NULL); pc.printf("Z: %f", newZ); if (extruderZ == 0) { extruderZ = newZ; } } else if (strcmp(firstLet,e) == 0) { memmove(data, data+1, strlen(data)); newE = strtof(data, NULL); pc.printf("E: %f", newE); } else if (strcmp(firstLet,f) == 0) { memmove(data, data+1, strlen(data)); newF = strtof(data, NULL); pc.printf("F: %f", newF); } newX = newX-extruderX; newY = newY-extruderY; newZ = newZ-extruderZ; xNowPrint = newX*scaleX; yNowPrint = newY*scaleY; zNowPrint = newZ*scaleZ; if ((xNowPrint != 0) and (yNowPrint != 0)) { pc.printf("xNow: %f", xNowPrint); pc.printf("yNow: %f", yNowPrint); motorXYprint(); } if (zNowPrint != 0) { pc.printf("yNow: %f", yNowPrint); motorZprint(); } i = i+1; } } } } myled = 1; wait(0.2); myled = 0; wait(0.2); } fclose(fp); return; } void motor1Thread(void const *args) { smotor1.set_speed(80); int spinvar = 0; while(motor1Go<3) { //3 stops the thread while(motor1Go != 2) { spinvar = 0; if (motor1Go == 0) { smotor1.step(0); } else if(motor1Go == 1) { smotor1.step(1); } } smotor1.step(2); Thread::wait(50.0); } } void motor2Thread(void const *args) { smotor2.set_speed(80); int spinvar2 = 0; while(motor2Go<3) { //3 stops the thread while(motor2Go != 2) { spinvar2 = 0; if (motor2Go == 0) { smotor2.step(0); } else if(motor2Go == 1) { smotor2.step(1); } } smotor2.step(2); Thread::wait(50.0); } } void motor3Thread(void const *args) { smotor3.set_speed(80); int spinvar3 = 0; while(motor3Go<3) { //3 stops the thread while(motor3Go != 2) { spinvar3 = 0; if (motor3Go == 0) { smotor3.step(0); } else if(motor3Go == 1) { smotor3.step(1); } } smotor3.step(2); Thread::wait(50.0); } } void motor4Thread(void const *args) { smotor4.set_speed(80); //unnecessary but oh well int spinvar4 = 0; while(motor4Go<3) { while(motor4Go != 2) { spinvar4 = 0; if (motor4Go == 0) { smotor4.step(0); } else if(motor4Go == 1) { smotor4.step(1); } } smotor4.step(2); Thread::wait(50.0); } } void getTemperature(void const *args) { // This routine calculates the temperature // using the Steinhart-Hart equation for thermistors // https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation float temperature, resistance; float steinhart; int a; Setpoint = 200; // Set target temperature in degrees Celcius. controller.SetMode(AUTOMATIC); // Turn PID controller on. while(1) { controller.Compute(); // Process PID loop. //Driver = Output/1000; // Sent PWM value scaled 0 - 1.0 as mbed requires ***originally divided by 1000 if (Input < 270) { Driver = .9; } else { Driver = 0; } a = Thermistor.read_u16(); // Read 16bit Analog value // pc.printf("Raw Analog Value for Thermistor = %d\r\n",a); /* Calculate the resistance of the thermistor from analog votage read. */ resistance = (float) SERIESRESISTOR / ((65536.0 / a) - 1); // pc.printf("Resistance for Thermistor = %f\r\n",resistance); steinhart = resistance / THERMISTORNOMINAL; // (R/Ro) steinhart = log(steinhart); // ln(R/Ro) steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro) steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To) steinhart = 1.0 / steinhart; // Invert temperature = steinhart - 273.15; // convert to C // pc.printf("Extruder Temperature is %f\r\n", temperature); Input = temperature; pc.printf("Input Output Setpoint Kp Ki Kd time\r\n"); pc.printf("%f, %f, %f, %f, %f, %f, %d \r\n", temperature, Output, Setpoint, controller.GetKp() , controller.GetKi() , controller.GetKd() , millis() ); Thread::wait(1000); } } int main() { int x = 0; int key_code=0; int i=0; int value; startMillis(); // Initialize timer. //terminal prints status data pc.baud(115200); pc.printf("\r\nThermistor PID Test - Build " __DATE__ " " __TIME__ "\r\n"); //motors 1-3 are x,y,or z Thread thread1(motor1Thread); Thread thread2(motor2Thread); Thread thread3(motor3Thread); //motor 4 is the feeder motor Thread thread4(motor4Thread); while(1) { //use keypad for controlling motors and temperature while debugging value=mpr121.read(0x00); value +=mpr121.read(0x01)<<8; if((value>>0)&0x01) { //zero button pressed myled = 1; motor1Go = 0; //x motor move back } else if((value>>1)&0x01) { //one button pressed myled = 0; motor1Go = 1; //x motor move forwards } else { motor1Go = 2; //x motor stop } if(((value>>2)&0x01)==1) { //two button pressed myled = 1; motor2Go = 0; //y motor move backward } else if(((value>>3)&0x01)==1) { //three button pressed myled = 0; motor2Go = 1; //y motor forward } else { motor2Go = 2; //else stop y motor }//end if if(((value>>4)&0x01)==1) { //four button pressed myled = 1; motor3Go = 0; //z motor back } else if(((value>>5)&0x01)==1) { myled = 0; motor3Go = 1; //z motor forward } else { motor3Go = 2; //else stop z motor }//end if if((value>>6)&0x01) { //6 button pressed myled = 1; motor4Go = 0; } else if((value>>7)&0x01) { //7 button pressed myled = 0; motor4Go = 1; //motor 4 forwards } else { motor4Go = 2; //stop motor 4 }//end if if(((value>>8)&0x01)==1) { //8 button pressed myled = !myled; Setpoint +=1; //increase set temp (C) by 1 } else if(((value>>9)&0x01)==1) { //button 9 pressed myled = !myled; Setpoint -= 1; //decrease set point by 1 } if((value>>10)&0x01) { //10 button pressed myled = 1; print(); } Thread::wait(100); }//end while(1) }