#include "ssd1306.h" #include "nano_gfx.h" #include
/* * define structure for the material list */ typedef struct { int temperature; int motorSpeed; char* materialName; } profile_t; /* * define material profiles */ const profile_t materials[] PROGMEM = { // {temperature (deg.
int avgTemp = 0; for(int i = 0; i<16; i++){ avgTemp += analogRead(TEMP_IN); } // read averaged analog value of temperature long tempADU = avgTemp >> 4; // convert ADU into temperature // constants could slightly change for different ceramic tip tempADU -= 1692; // increase this value when temperature is too high and vice versa tempADU <<= 7; tempADU /= (-557); return tempADU; } /* * load actual material profile */ void loadMaterial(int id){ profile_t profile; char text[10]; // load material profile from
* basic PID routine to get output value */ int getPIDoutput(int setPoint, int actualValue, int maxValue, int minValue){ static float sumE = 0; static int16_t error, previousError = 0; float outputValue; static int pidAvg[4] = {0,0,0,0}; static int pidAvgIndex = 0; // reset sumE when actualValue exceed setPoint by 5 static int noWaitCycles = 0; if(actualValue > setPoint + 5){ ++noWaitCycles; if(noWaitCycles >= 30){ sumE = 100; noWaitCycles = 0; } } else{ noWaitCycles = 0; } // PID implementation error =
// average last n output values int sumPIDavg = 0; for(int i = 0; i<4; i++){ sumPIDavg += pidAvg[i]; } sumPIDavg >>= 2; return sumPIDavg; } #define NO_AVERAGES_VALUES 64 /* * heating function for heater driving by PID regulator */ int heating(){ static int tempAvg[NO_AVERAGES_VALUES]; // temperature array for averaging it static int tempAvgIter = 0; // current index in temperature array static char firstTime = 0; // if is 1, this function ran at least one time char text[30]; // buffer for text
for(int i = 0; i
statusHeating = STATE_COOLING; ssd1306_printFixedN(116, 16, "C", STYLE_NORMAL, FONT_SIZE_2X); } // tolerant zone where temperature is OK for extrusion/reverse else if(actualTemperature > setTemperature - 10){ statusHeating = STATE_READY; ssd1306_printFixedN(116, 16, "R", STYLE_NORMAL, FONT_SIZE_2X); digitalWrite(LED_NANO, HIGH); // turn the LED on (HIGH is the voltage level) } // tolerant zone where temperature is LOW for extrusion/reverse else{ statusHeating = STATE_HEATING; ssd1306_printFixedN(116, 16
stateMotor = MOTOR_REVERSE_AFTER_EXTRUSION; timeMotorReverse = 20; // reverse time is 50ms * timeMotorReverse (20 = 1s) } } break; } case STATE_HEATING: // if happened that heater has so low temperature, motor stop digitalWrite(MOTOR_DIR, LOW); analogWrite(MOTOR_PWM, 0); stateMotor = MOTOR_STOP; break; } // resolve motor states (Extrusion, Reverse, Stop, ...
digitalWrite(MOTOR_DIR, HIGH); analogWrite(MOTOR_PWM, pwmSpeed/100); } else{ stateMotor = MOTOR_STOP; } break; } lastMotorState = stateMotor; // one time action, mainly for material change static char buttonsPressed = 0; // button UP pressed if(!digitalRead(BTN_UP) && digitalRead(BTN_DOWN)){ if(!(buttonsPressed & 0x01)){ if(materialID < MATERIAL_COUNT-1){ ++materialID; } else{ materialID = 0; } loadMaterial(materialID); } // save that this button UP was already pressed and used buttonsPressed |= 0x01; } el
buttonsPressed |= 0x02; } else{ // save that this button DOWN was released buttonsPressed &= 0xFD; } } /* * GPIO, OLED initialize * load material profile * preset timer */ void setup() { // initialize OLED display ssd1306_128x32_i2c_init(); ssd1306_clearScreen(); // initialize outputs pinMode(LED_NANO, OUTPUT); pinMode(MOTOR_DIR, OUTPUT); pinMode(MOTOR_PWM, OUTPUT); pinMode(MOTOR_SLEEP, OUTPUT); pinMode(HEATER_EN, OUTPUT); // initialize inputs pinMode(BTN_UP, INPUT_PULLUP); pinMode(BTN_DOWN, I
// initialize outputs digitalWrite(MOTOR_SLEEP, HIGH); Serial.begin(9600); } /* * main loop */ void loop() { // call timer each preset period timer.