From 1f03cdf1a735b362a17d68cb4be86cb310384137 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Fri, 24 Aug 2018 21:08:13 +0200 Subject: [PATCH 01/25] (init) Implemented UP/DOWN as on-Release-buttons This also works a lot better with my pen for some reason. But then again, I should maybe avoid to short-out all those pins on the back side with my hand (oddly, this was never an issue with the ExtRev buttons) ... --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 455 +++++++++++++++++++ 1 file changed, 455 insertions(+) create mode 100644 FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino new file mode 100644 index 0000000..f7559b7 --- /dev/null +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -0,0 +1,455 @@ +/* + * WIP - A alternative control mode that does not use predefined material profiles. + * But allows de-/increasing the temperature in steps of 5, from 0 to maximum. + * Later: UP and DOWN pressed together: change control mode to set motor speed the same way + * Therefore the Up-Down-Buttons need to do their thing On Release (not while pressed) + * my Comments are just my personal notes... + */ + +/* + * ssd1306 128x32 Alexey Dinda Library + */ +#include "ssd1306.h" +#include "nano_gfx.h" +#include + +/* + * define Input/Outputs + */ + +#define LED_NANO 13 // LED placed on Arduino Nano board + +#define BTN_UP 11 // controlling button UP/PLUS +#define BTN_DOWN 12 // controlling button DOWN/MINUS +#define BTN_EXT 8 // button for material extrusion +#define BTN_REV 7 // button for material reverse + +#define MOTOR_DIR 6 // motor direction output +#define MOTOR_PWM 10 // motor PWM output for power driving +#define MOTOR_SLEEP 5 +#define HEATER_EN 9 // heater/power output + +#define TEMP_IN A0 // temperature measure ADC input + +/* + * define heating states + */ +enum { + STATE_HEATING, + STATE_COOLING, + STATE_READY, +} STATE_e; + +enum { + MOTOR_STOP, + MOTOR_EXTRUSION, + MOTOR_REVERSE, + MOTOR_CONTINUOUS, + MOTOR_REVERSE_AFTER_EXTRUSION +} MOTOR_STATE_e; + +/* TODO + * define structure for the material list + */ +typedef struct { + int temperature; + int motorSpeed; + char* materialName; +} profile_t; + +/* TODO + * define material profiles + */ +const profile_t materials[] PROGMEM = { + // {temperature (deg. C), motorSpeed (%), materialName} + {0, 0, "OFF"}, /* NEW! BEGIN OFF - BUT IF YOU SELECT THIS AFTER PETG, 3DPEN COOLS TO 153º PRIOR TO SHUTDOWN*/ + {210, 40, "PLA"}, + {230, 30, "ABS"}, + {235, 40, "PETG"} +}; + +/* TODO + * define number of materials in list and variables + */ +#define MATERIAL_COUNT 4 + +#define MAXTEMP 255 // not sure whats better: define or cont, also not sure about the actual max temp... testing with 255 +#define MINTEMP 0 + +int materialID = 0; // chosen material profile +int setTemperature = 0; // set heater temperature +int setMotorSpeed = 0; // set motor speed in % + +/* + * create timer for main loop + */ +EveryTimer timer; + +/* + * function for measuring temperature of the tip + */ +int getTemperature(){ // get temperature in deg. Celsius from ADU value + // set reference for ADC to power supply (5V) + analogReference(DEFAULT); + + 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; +} + +/* TODO Change into update_display funtion. will be callled after button updown press and simply draws speed and temp + * load actual material profile + */ +void loadMaterial(int id){ + profile_t profile; + char text[10]; + + // load material profile from PROGMEM and assign variables + memcpy_P(&profile, &materials[id], sizeof(profile_t)); + setTemperature = profile.temperature; // !!! IMPORTANT + setMotorSpeed = profile.motorSpeed; + + // clear display and show all information TODO: Move + sprintf(text, "%d %%", setMotorSpeed); + ssd1306_clearScreen(); + ssd1306_setFixedFont(ssd1306xled_font6x8); + ssd1306_printFixedN(0, 0, profile.materialName, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(80, 0, text, STYLE_NORMAL, FONT_SIZE_2X); +} + +/* + * PID variables and constants for tuning + */ +float Kp=15, Ki=1, Kd=1.0, dT = 0.1, Hz=10; + +/* + * 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 = setPoint - actualValue; + sumE += (float) error * dT; + outputValue = Kp*error + Ki*sumE + Kd*(error - previousError)/dT; + previousError = error; + + // restrict output PID value into range between minValue and maxValue + if(outputValue > maxValue) + outputValue = maxValue; + else if(outputValue < minValue) + outputValue = minValue; + + // store n output values for averaging + pidAvg[pidAvgIndex] = outputValue; + ++pidAvgIndex; + if(pidAvgIndex >= 4) + pidAvgIndex = 0; + + // 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 + + // variables initialization + if(!firstTime){ + memset(tempAvg, 0, sizeof(tempAvg)*sizeof(int)); + firstTime = 1; + } + + // resolve PID value for heater PWM + int temperature = getTemperature(); + int valuePID = getPIDoutput(setTemperature, temperature, 255, 0); // !!! IMPORTANT + + analogWrite(HEATER_EN, valuePID); + + // save actual temperature for averaging + tempAvg[tempAvgIter] = temperature; + if(++tempAvgIter>=NO_AVERAGES_VALUES) + tempAvgIter = 0; + + // make temperature average from NO_AVERAGES_VALUES + int sumTemp = 0; + for(int i = 0; i setTemperature + 10){ + 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, "H", STYLE_NORMAL, FONT_SIZE_2X); + digitalWrite(LED_NANO, !digitalRead(LED_NANO)); // turn the LED on (HIGH is the voltage level) + } + } + + // assing functions according to heating state (mainly button function) + switch(statusHeating){ + case STATE_COOLING: + case STATE_READY:{ + // button EXTRUSION is pressed, extrude material + if(!digitalRead(BTN_EXT) && digitalRead(BTN_REV)){ + stateMotor = MOTOR_EXTRUSION; + } + + // button REVERSE is pressed, retract material + else if(digitalRead(BTN_EXT) && !digitalRead(BTN_REV)){ + stateMotor = MOTOR_REVERSE; + timeMotorReverse = 400; // reverse time is 50ms * timeMotorReverse (400 = 20s) + } + + // both buttons are pressed, motor stopped + else if(!digitalRead(BTN_EXT) && !digitalRead(BTN_REV)){ + stateMotor = MOTOR_STOP; + } + + // not buttons are pressed + else{ + if(lastMotorState == MOTOR_EXTRUSION){ + 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, ...) + switch(stateMotor){ + case MOTOR_STOP: + digitalWrite(MOTOR_DIR, LOW); + analogWrite(MOTOR_PWM, 0); + break; + + case MOTOR_EXTRUSION:{ + int pwmSpeed = setMotorSpeed*255; + digitalWrite(MOTOR_DIR, LOW); + analogWrite(MOTOR_PWM, pwmSpeed/100); + break; + } + + case MOTOR_REVERSE: + --timeMotorReverse; + if(timeMotorReverse > 0){ + digitalWrite(MOTOR_DIR, HIGH); + analogWrite(MOTOR_PWM, 0); + } + else{ + stateMotor = MOTOR_STOP; + } + break; + + case MOTOR_REVERSE_AFTER_EXTRUSION: + --timeMotorReverse; + if(timeMotorReverse > 0){ + int pwmSpeed = (100-setMotorSpeed)*255; + 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 increases profile on release + if (digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { + // save that this button UP was already pressed + buttonsPressed |= 0x01; // This might be efficient, but it's obscure. Bitwise "flags" or something... + // What |= 0x01 does: sets the last bit to true, no matter what + // Note: http://www.hw2sw.com/2011/09/13/arduino-bitwise-operators-and-advanced-tricks/ + } else { + if (buttonsPressed & 0x01) { // "Was I pressed in the last cycle?" + if (materialID < MATERIAL_COUNT-1){ + ++materialID; + } else { + materialID = 0; + } + loadMaterial(materialID); + } + + // save that this button UP was released + buttonsPressed &= 0xFE; + + // ToDo: okay I'm puzzled, it's a mask for the bitwise flag thingy, I guess. + // But why this huge HEX number... why not "2"... maybe to support future buttons? + // what it does: "and" sets only true if both are true. wtf it actually does with the 0xFE?! black magic... + // 0xFE = 11111110, I see now... it sets the last bit to false + } + + // button DOWN change profile down on release + if (!digitalRead(BTN_UP) && digitalRead(BTN_DOWN)) { + // save that this button DOWN was already pressed and used + buttonsPressed |= 0x02; + } else { + if (buttonsPressed & 0x02) { + if (materialID > 0){ + --materialID; + } else { + materialID = MATERIAL_COUNT-1; + } + loadMaterial(materialID); + } + // 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(); + ssd1306_flipHorizontal(1); /* oled_ssd1306.h NEW! rotate screen in X */ + ssd1306_flipVertical(1); /* oled_ssd1306.h NEW! rotate screen in Y */ + + + // 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, INPUT_PULLUP); + pinMode(BTN_EXT, INPUT_PULLUP); + pinMode(BTN_REV, INPUT_PULLUP); + +/* TODO + * TODO material ID + */ + // load material profile + loadMaterial(materialID); + + // preset timer period every 50 ms and call timerAction function when time expire + timer.Every(50, timerAction); + + // initialize outputs + digitalWrite(MOTOR_SLEEP, HIGH); + + Serial.begin(9600); +} + +/* + * main loop + */ +void loop() { + // call timer each preset period + timer.Update(); +} From 847951b25b1c31799ded11b4ecce49fdff3ca502 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Sat, 25 Aug 2018 12:26:29 +0200 Subject: [PATCH 02/25] =?UTF-8?q?Working:=20Change=20Temperature=20in=205?= =?UTF-8?q?=C2=B0C=20steps=20with=20Up=20&=20Down=20buttons?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit no code cleanup yet. But it seems to work. New: - MINTEMP, MAXTEMP - setMotorSpeed hardcoded to 40% TODO - displayControls() function to display setMotorSpeed and setTemperature and not display Material Profile names. TODO make it look nicer - TODO remove the old unused code, let Up&&Down change the Control Mode between Temperature and Motor, let Up||Down change setMotorSpeed --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 35 ++++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index f7559b7..b52ba2a 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -78,7 +78,8 @@ const profile_t materials[] PROGMEM = { int materialID = 0; // chosen material profile int setTemperature = 0; // set heater temperature -int setMotorSpeed = 0; // set motor speed in % +int setMotorSpeed = 40; // set motor speed in % // hardcoded at 40% for now (will be changeable later) + // ToDo maybe add icrement step value (hardcoded at 5) /* * create timer for main loop @@ -129,6 +130,16 @@ void loadMaterial(int id){ ssd1306_printFixedN(80, 0, text, STYLE_NORMAL, FONT_SIZE_2X); } +void displayControls() { + char text[10]; + // clear display and show all information TODO: Move + sprintf(text, "%d %%", setMotorSpeed); // string format: %d = int, %% = "%" for the motor value + ssd1306_clearScreen(); + ssd1306_setFixedFont(ssd1306xled_font6x8); + // ssd1306_printFixedN(0, 0, profile.materialName, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(80, 0, text, STYLE_NORMAL, FONT_SIZE_2X); +} + /* * PID variables and constants for tuning */ @@ -368,17 +379,14 @@ void timerAction(){ // Note: http://www.hw2sw.com/2011/09/13/arduino-bitwise-operators-and-advanced-tricks/ } else { if (buttonsPressed & 0x01) { // "Was I pressed in the last cycle?" - if (materialID < MATERIAL_COUNT-1){ - ++materialID; - } else { - materialID = 0; + if (setTemperature <= MAXTEMP - 5){ + setTemperature += 5; + displayControls(); } - loadMaterial(materialID); } // save that this button UP was released - buttonsPressed &= 0xFE; - + buttonsPressed &= 0xFE; // ToDo: okay I'm puzzled, it's a mask for the bitwise flag thingy, I guess. // But why this huge HEX number... why not "2"... maybe to support future buttons? // what it does: "and" sets only true if both are true. wtf it actually does with the 0xFE?! black magic... @@ -391,12 +399,10 @@ void timerAction(){ buttonsPressed |= 0x02; } else { if (buttonsPressed & 0x02) { - if (materialID > 0){ - --materialID; - } else { - materialID = MATERIAL_COUNT-1; + if (setTemperature >= MINTEMP + 5){ + setTemperature -= 5; + displayControls(); } - loadMaterial(materialID); } // save that this button DOWN was released buttonsPressed &= 0xFD; @@ -435,7 +441,8 @@ void setup() { * TODO material ID */ // load material profile - loadMaterial(materialID); + // loadMaterial(materialID); + displayControls(); // setMotor&Temp should work globally, only display remains // preset timer period every 50 ms and call timerAction function when time expire timer.Every(50, timerAction); From 895738d41579a0e47c3c27ede3ab3e8b8c72cb7f Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Sun, 26 Aug 2018 14:28:16 +0200 Subject: [PATCH 03/25] Display Layout pretty - shuffled text on the display around to prepare it for ControlMode change - selected ControlMode will be inverted - pretty details: small units, nice alignment, more status text, change symbol in the middle - also: corrected the name of the ssd1306 author from Dinda to Dynda (so you can find the correct github when googling his name) --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 47 ++++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index b52ba2a..69b8542 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -7,7 +7,7 @@ */ /* - * ssd1306 128x32 Alexey Dinda Library + * ssd1306 128x32 Alexey Dynda Library */ #include "ssd1306.h" #include "nano_gfx.h" @@ -112,7 +112,7 @@ int getTemperature(){ // get temperature in deg. Celsius from ADU value /* TODO Change into update_display funtion. will be callled after button updown press and simply draws speed and temp * load actual material profile - */ + * void loadMaterial(int id){ profile_t profile; char text[10]; @@ -128,16 +128,29 @@ void loadMaterial(int id){ ssd1306_setFixedFont(ssd1306xled_font6x8); ssd1306_printFixedN(0, 0, profile.materialName, STYLE_NORMAL, FONT_SIZE_2X); ssd1306_printFixedN(80, 0, text, STYLE_NORMAL, FONT_SIZE_2X); -} +} */ void displayControls() { - char text[10]; - // clear display and show all information TODO: Move - sprintf(text, "%d %%", setMotorSpeed); // string format: %d = int, %% = "%" for the motor value + + char textSetTemp[5]; // Buffer for line 2: The user Input / Controls: setTemperature and setMotorSpeed + char textSetMotor[5]; + sprintf(textSetTemp,"%3d ", setTemperature); + sprintf(textSetMotor,"%3d ",setMotorSpeed); + + // clear display and show all information ssd1306_clearScreen(); ssd1306_setFixedFont(ssd1306xled_font6x8); - // ssd1306_printFixedN(0, 0, profile.materialName, STYLE_NORMAL, FONT_SIZE_2X); - ssd1306_printFixedN(80, 0, text, STYLE_NORMAL, FONT_SIZE_2X); + + // TODO: change Selection (negativeMode) according to ControlMode + ssd1306_negativeMode(); + ssd1306_printFixedN(0, 16, textSetTemp, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(36+3, 24, "C", STYLE_NORMAL, FONT_SIZE_NORMAL); + ssd1306_positiveMode(); + ssd1306_printFixedN(128-4*12, 16, textSetMotor, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(128-12+3, 24, "%", STYLE_NORMAL, FONT_SIZE_NORMAL); + ssd1306_printFixedN(60, 16, "<", STYLE_NORMAL, FONT_SIZE_NORMAL); + ssd1306_printFixedN(60, 24, ">", STYLE_NORMAL, FONT_SIZE_NORMAL); + } /* @@ -206,7 +219,7 @@ 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 + char text[5]; // buffer for text // variables initialization if(!firstTime){ @@ -233,9 +246,10 @@ int heating(){ sumTemp /= NO_AVERAGES_VALUES; // show on display actual and preset temperature - sprintf(text, "%3d/%3dC", sumTemp, setTemperature); + sprintf(text, "%3d ", sumTemp); ssd1306_setFixedFont(ssd1306xled_font6x8); - ssd1306_printFixedN(0, 16, text, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(0, 0, text, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(36+3, 8, "C", STYLE_NORMAL, FONT_SIZE_NORMAL); /* * debug output into display and to serial @@ -271,20 +285,20 @@ void timerAction(){ // but it is possible to do extrusion/reverse if(actualTemperature > setTemperature + 10){ statusHeating = STATE_COOLING; - ssd1306_printFixedN(116, 16, "C", STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(128-4*12, 0, "COOL", 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); + ssd1306_printFixedN(128-4*12, 0, "DONE", 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, "H", STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(128-4*12, 0, "HEAT", STYLE_NORMAL, FONT_SIZE_2X); digitalWrite(LED_NANO, !digitalRead(LED_NANO)); // turn the LED on (HIGH is the voltage level) } } @@ -437,11 +451,6 @@ void setup() { pinMode(BTN_EXT, INPUT_PULLUP); pinMode(BTN_REV, INPUT_PULLUP); -/* TODO - * TODO material ID - */ - // load material profile - // loadMaterial(materialID); displayControls(); // setMotor&Temp should work globally, only display remains // preset timer period every 50 ms and call timerAction function when time expire From 16eb561f40530b7dc5a2e6b9151b2935b962583b Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Sun, 26 Aug 2018 14:52:18 +0200 Subject: [PATCH 04/25] some cleanup, material profiles removed --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 56 +++----------------- 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index 69b8542..4445572 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -48,35 +48,9 @@ enum { MOTOR_REVERSE_AFTER_EXTRUSION } MOTOR_STATE_e; -/* TODO - * define structure for the material list - */ -typedef struct { - int temperature; - int motorSpeed; - char* materialName; -} profile_t; - -/* TODO - * define material profiles - */ -const profile_t materials[] PROGMEM = { - // {temperature (deg. C), motorSpeed (%), materialName} - {0, 0, "OFF"}, /* NEW! BEGIN OFF - BUT IF YOU SELECT THIS AFTER PETG, 3DPEN COOLS TO 153º PRIOR TO SHUTDOWN*/ - {210, 40, "PLA"}, - {230, 30, "ABS"}, - {235, 40, "PETG"} -}; - -/* TODO - * define number of materials in list and variables - */ -#define MATERIAL_COUNT 4 - #define MAXTEMP 255 // not sure whats better: define or cont, also not sure about the actual max temp... testing with 255 #define MINTEMP 0 -int materialID = 0; // chosen material profile int setTemperature = 0; // set heater temperature int setMotorSpeed = 40; // set motor speed in % // hardcoded at 40% for now (will be changeable later) // ToDo maybe add icrement step value (hardcoded at 5) @@ -110,29 +84,13 @@ int getTemperature(){ // get temperature in deg. Celsius from ADU value return tempADU; } -/* TODO Change into update_display funtion. will be callled after button updown press and simply draws speed and temp - * load actual material profile - * -void loadMaterial(int id){ - profile_t profile; - char text[10]; - - // load material profile from PROGMEM and assign variables - memcpy_P(&profile, &materials[id], sizeof(profile_t)); - setTemperature = profile.temperature; // !!! IMPORTANT - setMotorSpeed = profile.motorSpeed; - - // clear display and show all information TODO: Move - sprintf(text, "%d %%", setMotorSpeed); - ssd1306_clearScreen(); - ssd1306_setFixedFont(ssd1306xled_font6x8); - ssd1306_printFixedN(0, 0, profile.materialName, STYLE_NORMAL, FONT_SIZE_2X); - ssd1306_printFixedN(80, 0, text, STYLE_NORMAL, FONT_SIZE_2X); -} */ - +/** + * Updates the lower line of the display which shows the user inputs for Controls + * left set Temperature - center <> icon that indicates how to change mode - right set Motor Speed + */ void displayControls() { - char textSetTemp[5]; // Buffer for line 2: The user Input / Controls: setTemperature and setMotorSpeed + char textSetTemp[5]; // Buffers for formatted control input text char textSetMotor[5]; sprintf(textSetTemp,"%3d ", setTemperature); sprintf(textSetMotor,"%3d ",setMotorSpeed); @@ -148,7 +106,7 @@ void displayControls() { ssd1306_positiveMode(); ssd1306_printFixedN(128-4*12, 16, textSetMotor, STYLE_NORMAL, FONT_SIZE_2X); ssd1306_printFixedN(128-12+3, 24, "%", STYLE_NORMAL, FONT_SIZE_NORMAL); - ssd1306_printFixedN(60, 16, "<", STYLE_NORMAL, FONT_SIZE_NORMAL); + ssd1306_printFixedN(60, 16, "<", STYLE_NORMAL, FONT_SIZE_NORMAL); // icon in the middle ssd1306_printFixedN(60, 24, ">", STYLE_NORMAL, FONT_SIZE_NORMAL); } @@ -291,7 +249,7 @@ void timerAction(){ // tolerant zone where temperature is OK for extrusion/reverse else if(actualTemperature > setTemperature - 10){ statusHeating = STATE_READY; - ssd1306_printFixedN(128-4*12, 0, "DONE", STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(128-4*12, 0, "DONE", STYLE_NORMAL, FONT_SIZE_2X); // "DONE"... need a word with 4 chars... "REDY"?... nup digitalWrite(LED_NANO, HIGH); // turn the LED on (HIGH is the voltage level) } From 236facceb55cbf0bf28f2e7fe9fa31f6392d71e9 Mon Sep 17 00:00:00 2001 From: AnTi-ArT Date: Sun, 26 Aug 2018 23:04:14 +0200 Subject: [PATCH 05/25] Button Patch: true/false corrected LOW=pressed! - changed pins 11 & 12 back for right hand - the if checks for UP & DOWN changed back to "!" - some WIP for two-button-press - typo "assing" fix --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 91 ++++++++++++-------- 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index 4445572..59f3747 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -14,13 +14,14 @@ #include /* - * define Input/Outputs + * define Input/Outputs. + * Buttons: LOW/false/0 = pressed, HIGH/true/1 = not pressed! */ #define LED_NANO 13 // LED placed on Arduino Nano board -#define BTN_UP 11 // controlling button UP/PLUS -#define BTN_DOWN 12 // controlling button DOWN/MINUS +#define BTN_UP 12 // controlling button UP/PLUS // pin 11 & 12 changed for right hand use +#define BTN_DOWN 11 // controlling button DOWN/MINUS #define BTN_EXT 8 // button for material extrusion #define BTN_REV 7 // button for material reverse @@ -48,12 +49,18 @@ enum { MOTOR_REVERSE_AFTER_EXTRUSION } MOTOR_STATE_e; +enum { + MODE_TEMP, + MODE_SPEED +} MODE_CONTROL_e; + #define MAXTEMP 255 // not sure whats better: define or cont, also not sure about the actual max temp... testing with 255 #define MINTEMP 0 -int setTemperature = 0; // set heater temperature -int setMotorSpeed = 40; // set motor speed in % // hardcoded at 40% for now (will be changeable later) - // ToDo maybe add icrement step value (hardcoded at 5) +int setTemperature = 0; // set heater temperature +int setMotorSpeed = 40; // set motor speed in % // hardcoded at 40% for now (will be changeable later) + // ToDo maybe add icrement step value (hardcoded at 5) +char controlMode = MODE_TEMP; // ToDo: maybe not global... somewhere static? /* * create timer for main loop @@ -100,12 +107,22 @@ void displayControls() { ssd1306_setFixedFont(ssd1306xled_font6x8); // TODO: change Selection (negativeMode) according to ControlMode - ssd1306_negativeMode(); - ssd1306_printFixedN(0, 16, textSetTemp, STYLE_NORMAL, FONT_SIZE_2X); - ssd1306_printFixedN(36+3, 24, "C", STYLE_NORMAL, FONT_SIZE_NORMAL); - ssd1306_positiveMode(); - ssd1306_printFixedN(128-4*12, 16, textSetMotor, STYLE_NORMAL, FONT_SIZE_2X); - ssd1306_printFixedN(128-12+3, 24, "%", STYLE_NORMAL, FONT_SIZE_NORMAL); + if (controlMode == MODE_TEMP) { + ssd1306_negativeMode(); + ssd1306_printFixedN(0, 16, textSetTemp, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(36+3, 24, "C", STYLE_NORMAL, FONT_SIZE_NORMAL); + ssd1306_positiveMode(); + ssd1306_printFixedN(128-4*12, 16, textSetMotor, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(128-12+3, 24, "%", STYLE_NORMAL, FONT_SIZE_NORMAL); + } else { + ssd1306_printFixedN(0, 16, textSetTemp, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(36+3, 24, "C", STYLE_NORMAL, FONT_SIZE_NORMAL); + ssd1306_negativeMode(); + ssd1306_printFixedN(128-4*12, 16, textSetMotor, STYLE_NORMAL, FONT_SIZE_2X); + ssd1306_printFixedN(128-12+3, 24, "%", STYLE_NORMAL, FONT_SIZE_NORMAL); + ssd1306_positiveMode(); + } + ssd1306_printFixedN(60, 16, "<", STYLE_NORMAL, FONT_SIZE_NORMAL); // icon in the middle ssd1306_printFixedN(60, 24, ">", STYLE_NORMAL, FONT_SIZE_NORMAL); @@ -261,7 +278,7 @@ void timerAction(){ } } - // assing functions according to heating state (mainly button function) + // assign functions according to heating state (mainly button function) switch(statusHeating){ case STATE_COOLING: case STATE_READY:{ @@ -344,41 +361,45 @@ void timerAction(){ // button UP increases profile on release - if (digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { + if (!digitalRead(BTN_UP) && digitalRead(BTN_DOWN)) { // save that this button UP was already pressed buttonsPressed |= 0x01; // This might be efficient, but it's obscure. Bitwise "flags" or something... // What |= 0x01 does: sets the last bit to true, no matter what // Note: http://www.hw2sw.com/2011/09/13/arduino-bitwise-operators-and-advanced-tricks/ - } else { - if (buttonsPressed & 0x01) { // "Was I pressed in the last cycle?" - if (setTemperature <= MAXTEMP - 5){ - setTemperature += 5; - displayControls(); - } - } - + } else if ((buttonsPressed & 0x01) && digitalRead(BTN_DOWN)) { + if (setTemperature <= MAXTEMP - 5){ + setTemperature += 5; + displayControls(); + } // save that this button UP was released buttonsPressed &= 0xFE; - // ToDo: okay I'm puzzled, it's a mask for the bitwise flag thingy, I guess. - // But why this huge HEX number... why not "2"... maybe to support future buttons? - // what it does: "and" sets only true if both are true. wtf it actually does with the 0xFE?! black magic... - // 0xFE = 11111110, I see now... it sets the last bit to false + // what it does: "and" sets only true if both are true. + // since 0xFE = 11111110 last bit is false. will set to false no matter whats in the var } // button DOWN change profile down on release - if (!digitalRead(BTN_UP) && digitalRead(BTN_DOWN)) { + if (digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { // save that this button DOWN was already pressed and used buttonsPressed |= 0x02; - } else { - if (buttonsPressed & 0x02) { - if (setTemperature >= MINTEMP + 5){ - setTemperature -= 5; - displayControls(); - } - } + } else if ((buttonsPressed & 0x02) && digitalRead(BTN_UP)) { + if (setTemperature >= MINTEMP + 5){ + setTemperature -= 5; + displayControls(); + } // save that this button DOWN was released - buttonsPressed &= 0xFD; + buttonsPressed &= 0xFD; // 0xFE = 11111101 } + + // WIP both UP&DOWN are pressed and released: change mode + /*if ((buttonsPressed & 0x03) && !digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { + if (controlMode == MODE_TEMP) { + controlMode = MODE_SPEED; + } else { + controlMode = MODE_TEMP; + } + displayControls(); + buttonsPressed &= 0xFC; // set to XXXXXX00 + }*/ } From 5bbfc9f14430f778b9f00ad9cdd87cf58566861b Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Mon, 27 Aug 2018 12:40:26 +0200 Subject: [PATCH 06/25] states for all 4 buttons and as binary bits - Because I can't hex - BUG: for some reason the Nano reboots when I hit EXT. Only happens with motor... But did not happen yesterday o_O --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 27 ++++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index 59f3747..f16245f 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -250,6 +250,7 @@ void timerAction(){ static char statusHeating = STATE_HEATING; static char stateMotor = MOTOR_STOP, lastMotorState = MOTOR_STOP; static int timeMotorReverse = 0; + static byte buttonsPressed = 0; // an 8 bit number, that stores the states of the buttons as flags in the last 4 bits (1,2,4,8) = UP, DOWN, EXT, REV // decide temperature state (heating, cooling, ready) and show it on display if(++elapsedTime==2){ // 100ms @@ -285,21 +286,27 @@ void timerAction(){ // button EXTRUSION is pressed, extrude material if(!digitalRead(BTN_EXT) && digitalRead(BTN_REV)){ stateMotor = MOTOR_EXTRUSION; + buttonsPressed |= B00000100; // yes, the Hex values are shorter and quicker to write. + buttonsPressed &= B11110111; // But I spent too much time in the calculator app and it's extremely hard to debug } // button REVERSE is pressed, retract material else if(digitalRead(BTN_EXT) && !digitalRead(BTN_REV)){ stateMotor = MOTOR_REVERSE; timeMotorReverse = 400; // reverse time is 50ms * timeMotorReverse (400 = 20s) + buttonsPressed |= B00001000; // press of btn REV + buttonsPressed &= B11111011; // release of btn EXT } // both buttons are pressed, motor stopped else if(!digitalRead(BTN_EXT) && !digitalRead(BTN_REV)){ stateMotor = MOTOR_STOP; + buttonsPressed |= B00001100; } // not buttons are pressed else{ + buttonsPressed &= B11110011; if(lastMotorState == MOTOR_EXTRUSION){ stateMotor = MOTOR_REVERSE_AFTER_EXTRUSION; timeMotorReverse = 20; // reverse time is 50ms * timeMotorReverse (20 = 1s) @@ -353,41 +360,39 @@ void timerAction(){ } break; } - lastMotorState = stateMotor; + lastMotorState = stateMotor; // one time action, mainly for material change - static char buttonsPressed = 0; - - // button UP increases profile on release + // button UP increases temperature/speed on release if (!digitalRead(BTN_UP) && digitalRead(BTN_DOWN)) { // save that this button UP was already pressed - buttonsPressed |= 0x01; // This might be efficient, but it's obscure. Bitwise "flags" or something... + buttonsPressed |= B00000001; // This might be efficient, but it's obscure. Bitwise "flags" or something... // What |= 0x01 does: sets the last bit to true, no matter what // Note: http://www.hw2sw.com/2011/09/13/arduino-bitwise-operators-and-advanced-tricks/ - } else if ((buttonsPressed & 0x01) && digitalRead(BTN_DOWN)) { + } else if ((buttonsPressed & B00000001) && digitalRead(BTN_DOWN)) { if (setTemperature <= MAXTEMP - 5){ setTemperature += 5; displayControls(); } // save that this button UP was released - buttonsPressed &= 0xFE; + buttonsPressed &= B11111110; // what it does: "and" sets only true if both are true. // since 0xFE = 11111110 last bit is false. will set to false no matter whats in the var } - // button DOWN change profile down on release + // button DOWN cdecreases temperature/speed on release if (digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { // save that this button DOWN was already pressed and used - buttonsPressed |= 0x02; - } else if ((buttonsPressed & 0x02) && digitalRead(BTN_UP)) { + buttonsPressed |= B00000010; + } else if ((buttonsPressed & B00000010) && digitalRead(BTN_UP)) { if (setTemperature >= MINTEMP + 5){ setTemperature -= 5; displayControls(); } // save that this button DOWN was released - buttonsPressed &= 0xFD; // 0xFE = 11111101 + buttonsPressed &= B11111101; } // WIP both UP&DOWN are pressed and released: change mode From a200ade526f545a04323871152f898d3f55aa498 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Mon, 27 Aug 2018 15:00:13 +0200 Subject: [PATCH 07/25] Bugged: buttonPressed, WIP - need to go, will fix later - Reworked the whole UP-DOWN condition tree. - the if seems to work (testable with LED), but the buttonPressed flags are not - idea: Print the damn 8 bits to the display for debugging - when finished: uncomment the LED in ln 271 - WIP: EXT and REV are commented out, need to finish next --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 89 +++++++++++--------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index f16245f..6d3b1ce 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -250,7 +250,7 @@ void timerAction(){ static char statusHeating = STATE_HEATING; static char stateMotor = MOTOR_STOP, lastMotorState = MOTOR_STOP; static int timeMotorReverse = 0; - static byte buttonsPressed = 0; // an 8 bit number, that stores the states of the buttons as flags in the last 4 bits (1,2,4,8) = UP, DOWN, EXT, REV + static byte buttonsPressed = B00000000; // an 8 bit number, that stores the states of the buttons as flags in the last 4 bits (1,2,4,8) = UP, DOWN, EXT, REV // decide temperature state (heating, cooling, ready) and show it on display if(++elapsedTime==2){ // 100ms @@ -268,7 +268,7 @@ void timerAction(){ else if(actualTemperature > setTemperature - 10){ statusHeating = STATE_READY; ssd1306_printFixedN(128-4*12, 0, "DONE", STYLE_NORMAL, FONT_SIZE_2X); // "DONE"... need a word with 4 chars... "REDY"?... nup - digitalWrite(LED_NANO, HIGH); // turn the LED on (HIGH is the voltage level) + //DEBUG digitalWrite(LED_NANO, HIGH); // turn the LED on (HIGH is the voltage level) } // tolerant zone where temperature is LOW for extrusion/reverse @@ -280,7 +280,7 @@ void timerAction(){ } // assign functions according to heating state (mainly button function) - switch(statusHeating){ + /*switch(statusHeating){ case STATE_COOLING: case STATE_READY:{ // button EXTRUSION is pressed, extrude material @@ -321,7 +321,7 @@ void timerAction(){ analogWrite(MOTOR_PWM, 0); stateMotor = MOTOR_STOP; break; - } + }*/ // resolve motor states (Extrusion, Reverse, Stop, ...) switch(stateMotor){ @@ -364,47 +364,52 @@ void timerAction(){ lastMotorState = stateMotor; // one time action, mainly for material change - - // button UP increases temperature/speed on release - if (!digitalRead(BTN_UP) && digitalRead(BTN_DOWN)) { - // save that this button UP was already pressed - buttonsPressed |= B00000001; // This might be efficient, but it's obscure. Bitwise "flags" or something... - // What |= 0x01 does: sets the last bit to true, no matter what - // Note: http://www.hw2sw.com/2011/09/13/arduino-bitwise-operators-and-advanced-tricks/ - } else if ((buttonsPressed & B00000001) && digitalRead(BTN_DOWN)) { - if (setTemperature <= MAXTEMP - 5){ - setTemperature += 5; - displayControls(); - } - // save that this button UP was released - buttonsPressed &= B11111110; - // what it does: "and" sets only true if both are true. - // since 0xFE = 11111110 last bit is false. will set to false no matter whats in the var - } - - // button DOWN cdecreases temperature/speed on release - if (digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { - // save that this button DOWN was already pressed and used - buttonsPressed |= B00000010; - } else if ((buttonsPressed & B00000010) && digitalRead(BTN_UP)) { - if (setTemperature >= MINTEMP + 5){ - setTemperature -= 5; - displayControls(); + // The Mode Control Buttons (note: buttons are LOW/0/false when PRESSED!) + // UP && DOWN are pressed + if(!digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { // Are both Buttons down? + if (buttonsPressed & B00000011 == B00000000) { // was I pressed in the LAST cycle? = onRelease + if (controlMode == MODE_TEMP) { + controlMode = MODE_SPEED; + } else { + controlMode = MODE_TEMP; + } } - // save that this button DOWN was released - buttonsPressed &= B11111101; - } - - // WIP both UP&DOWN are pressed and released: change mode - /*if ((buttonsPressed & 0x03) && !digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { - if (controlMode == MODE_TEMP) { - controlMode = MODE_SPEED; + buttonsPressed |= B00000011; // set both buttons to "pressed" + + } else { // else = not BOTH are pressed at the same time -> UP || DOWN || NONE + digitalWrite(LED_NANO, LOW); + // UP Button on Release Action + if(!digitalRead(BTN_UP)) { // if UP pressed + buttonsPressed |= B00000001; // set UP to pressed } else { - controlMode = MODE_TEMP; + if (buttonsPressed & B00000001 == B00000000) { // was I pressed in the LAST cycle? = onRelease + digitalWrite(LED_NANO, HIGH); // BUG: the ifs work, the buttonPressed does not + delay(200); + if (setTemperature <= MAXTEMP - 5){ + setTemperature += 5; + displayControls(); + } + } + buttonsPressed &= B11111110; // set DOWN to released } - displayControls(); - buttonsPressed &= 0xFC; // set to XXXXXX00 - }*/ + + // DOWN Button on Release action + if(!digitalRead(BTN_DOWN)) { // if DOWN pressed + buttonsPressed |= B00000010; // set DOWN to pressed + } else { + if (buttonsPressed & B00000010 == B00000000) { // was I pressed in the LAST cycle? = onRelease + if (setTemperature >= MINTEMP + 5){ + setTemperature -= 5; + displayControls(); + } + } + buttonsPressed &= B11111101; // set DOWN to released + } + + // NONE is pressed.. wait, no code. the elses above should handle the release of BOTH press? + // will they fire single button-events after release of BOTH? yes? -> idea: "if (buttonsPressed & B00000011..." in UP and DOWN + + } // end of if-UP&&DOWN-are-pressed-else... } From d8202ea7dfec54486967431d1b38e133e295187f Mon Sep 17 00:00:00 2001 From: AnTi-ArT Date: Mon, 27 Aug 2018 20:10:56 +0200 Subject: [PATCH 08/25] Awesome Press and Release events for UP, DOWN, BOTH - looks good so far! - new flag bit for the BOTH state. Lesser errors... - for some reason it did not work to only check the bitflag, I had to no-press-check the other button (ln 403, 390) --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 39 ++++++++++---------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index 6d3b1ce..a6fb243 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -250,7 +250,7 @@ void timerAction(){ static char statusHeating = STATE_HEATING; static char stateMotor = MOTOR_STOP, lastMotorState = MOTOR_STOP; static int timeMotorReverse = 0; - static byte buttonsPressed = B00000000; // an 8 bit number, that stores the states of the buttons as flags in the last 4 bits (1,2,4,8) = UP, DOWN, EXT, REV + static char buttonsPressed = 0; // an 8 bit number, that stores the states of the buttons as flags in the last 4 bits (1,2,4,8) = UP, DOWN, EXT, REV // decide temperature state (heating, cooling, ready) and show it on display if(++elapsedTime==2){ // 100ms @@ -365,40 +365,43 @@ void timerAction(){ // one time action, mainly for material change // The Mode Control Buttons (note: buttons are LOW/0/false when PRESSED!) - // UP && DOWN are pressed - if(!digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { // Are both Buttons down? - if (buttonsPressed & B00000011 == B00000000) { // was I pressed in the LAST cycle? = onRelease + // + //// UP && DOWN are pressed + if(!digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { // Are both Buttons pressed? + + if ((~buttonsPressed & B10000000)) { // was I NOT pressed in the LAST cycle? = on time only if (controlMode == MODE_TEMP) { controlMode = MODE_SPEED; } else { controlMode = MODE_TEMP; } - } - buttonsPressed |= B00000011; // set both buttons to "pressed" - + displayControls(); + } + buttonsPressed |= B10000000; // set both buttons to "was pressed", new flag instead of 00000011! + } else { // else = not BOTH are pressed at the same time -> UP || DOWN || NONE - digitalWrite(LED_NANO, LOW); - // UP Button on Release Action + + buttonsPressed &= B01111111; // BOTH release + + //// UP Button on Release Action if(!digitalRead(BTN_UP)) { // if UP pressed buttonsPressed |= B00000001; // set UP to pressed } else { - if (buttonsPressed & B00000001 == B00000000) { // was I pressed in the LAST cycle? = onRelease - digitalWrite(LED_NANO, HIGH); // BUG: the ifs work, the buttonPressed does not - delay(200); + if ((buttonsPressed & B00000001) && digitalRead(BTN_DOWN)) { // was I pressed in the LAST cycle? = onRelease if (setTemperature <= MAXTEMP - 5){ setTemperature += 5; displayControls(); } } - buttonsPressed &= B11111110; // set DOWN to released + buttonsPressed &= B11111110; // set UP to released } - // DOWN Button on Release action + //// DOWN Button on Release action if(!digitalRead(BTN_DOWN)) { // if DOWN pressed buttonsPressed |= B00000010; // set DOWN to pressed } else { - if (buttonsPressed & B00000010 == B00000000) { // was I pressed in the LAST cycle? = onRelease - if (setTemperature >= MINTEMP + 5){ + if ((buttonsPressed & B00000010) && digitalRead(BTN_UP)) { // was I pressed in the LAST cycle? = onRelease + if (setTemperature >= MINTEMP + 5) { setTemperature -= 5; displayControls(); } @@ -406,10 +409,8 @@ void timerAction(){ buttonsPressed &= B11111101; // set DOWN to released } - // NONE is pressed.. wait, no code. the elses above should handle the release of BOTH press? - // will they fire single button-events after release of BOTH? yes? -> idea: "if (buttonsPressed & B00000011..." in UP and DOWN - } // end of if-UP&&DOWN-are-pressed-else... + } From 0e6b06b704954984f16b792afb3496cf18d6feb4 Mon Sep 17 00:00:00 2001 From: AnTi-ArT Date: Mon, 27 Aug 2018 21:27:47 +0200 Subject: [PATCH 09/25] ControlMode change functioning. SetMotorSpeed controlable --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 25 +++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index a6fb243..5f097f4 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -388,10 +388,17 @@ void timerAction(){ buttonsPressed |= B00000001; // set UP to pressed } else { if ((buttonsPressed & B00000001) && digitalRead(BTN_DOWN)) { // was I pressed in the LAST cycle? = onRelease - if (setTemperature <= MAXTEMP - 5){ - setTemperature += 5; - displayControls(); + if (controlMode == MODE_TEMP) { + if (setTemperature <= MAXTEMP - 5){ + setTemperature += 5; + displayControls(); + } + } else { + if (setMotorSpeed <= 100 - 5) { + setMotorSpeed += 5; + } } + displayControls(); } buttonsPressed &= B11111110; // set UP to released } @@ -401,10 +408,16 @@ void timerAction(){ buttonsPressed |= B00000010; // set DOWN to pressed } else { if ((buttonsPressed & B00000010) && digitalRead(BTN_UP)) { // was I pressed in the LAST cycle? = onRelease - if (setTemperature >= MINTEMP + 5) { - setTemperature -= 5; - displayControls(); + if (controlMode == MODE_TEMP) { + if (setTemperature >= MINTEMP + 5) { + setTemperature -= 5; + } + } else { + if (setMotorSpeed >= 0 +5) { + setMotorSpeed -= 5; + } } + displayControls(); } buttonsPressed &= B11111101; // set DOWN to released } From f6ba0b00b3aa82874040452a789411aa7e84dd38 Mon Sep 17 00:00:00 2001 From: AnTi-ArT Date: Mon, 27 Aug 2018 22:00:37 +0200 Subject: [PATCH 10/25] EXP and REV back functional. Everything works so far! - removed double flag from both button press. No more reboot bugs at EXT. --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index 5f097f4..268b132 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -280,7 +280,7 @@ void timerAction(){ } // assign functions according to heating state (mainly button function) - /*switch(statusHeating){ + switch(statusHeating){ case STATE_COOLING: case STATE_READY:{ // button EXTRUSION is pressed, extrude material @@ -301,11 +301,11 @@ void timerAction(){ // both buttons are pressed, motor stopped else if(!digitalRead(BTN_EXT) && !digitalRead(BTN_REV)){ stateMotor = MOTOR_STOP; - buttonsPressed |= B00001100; + // buttonsPressed |= B00001100; } - // not buttons are pressed - else{ + // no buttons are pressed + else { buttonsPressed &= B11110011; if(lastMotorState == MOTOR_EXTRUSION){ stateMotor = MOTOR_REVERSE_AFTER_EXTRUSION; @@ -321,7 +321,7 @@ void timerAction(){ analogWrite(MOTOR_PWM, 0); stateMotor = MOTOR_STOP; break; - }*/ + } // resolve motor states (Extrusion, Reverse, Stop, ...) switch(stateMotor){ From 7c3cf415425479bb2326c70311ef1f98db37a234 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Mon, 27 Aug 2018 22:48:35 +0200 Subject: [PATCH 11/25] Readme with usage guide --- FW/3DsimoKit_Freemode/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 FW/3DsimoKit_Freemode/README.md diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md new file mode 100644 index 0000000..d7ce919 --- /dev/null +++ b/FW/3DsimoKit_Freemode/README.md @@ -0,0 +1,21 @@ +# FREEMODE +### Alternative Control scheme for the 3Dsimo Kit pen + +Freely set Temperature and Motor Speed. +#### Buttons: +- Extrude Pressed: extrudes filament (when hot). +- Extrude Release: Filament will be pulled back slightly. +- Extrude AND Revert: Pauses the motor without pull back. +- Revert Pressed (you can release) ejects the filament. +- Up AND Down pressed: Will change the control mode. Release one or both buttons and push both again to change back. +- Up Released: Increase either Temperature or Motor Speed. +- Down Released: Decrease either Temperature or Motor Speed. + +#### Screen: +- Screen is tiled in four parts. +- Upper line Left: Actual Temperature. (there seems to be a bug, shown minimum is 153 atm) +- Upper line Right: State of the nozzle: HEAT, COOL, DONE. You can only extrude in done or cooling states. +- Lower line: User input settings. Selected mode is shown inverted. +- Lower Left: Target temperaturen. (0 to 254°C (placeholder)) +- Lower Right: Motor Speed setting. (0 - 100 %) +- Lower Middle: Icon that indicates how to change mode. From c6c9c03d62af636f64d41143f6ac1c1ef28ffac7 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Tue, 28 Aug 2018 11:43:32 +0200 Subject: [PATCH 12/25] added WIP and bugs info --- FW/3DsimoKit_Freemode/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index d7ce919..2c52bb5 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -19,3 +19,9 @@ Freely set Temperature and Motor Speed. - Lower Left: Target temperaturen. (0 to 254°C (placeholder)) - Lower Right: Motor Speed setting. (0 - 100 %) - Lower Middle: Icon that indicates how to change mode. + +### Work in Progress +- Default Settings, Min and Max Settings are Placeholders. e.g.: It does not make sense to keep 0°C as Minimum Temperature. +- There is an [issue that the measured temperature on the display never shows below 153°C](https://github.com/3dsimo/3dsimo_kit/issues/4). The actual temperature can be below 153 degrees. This value, however, also drives the heating wich means that the pen thinks that set values like 70°C are already exceeded with 153°C (while, in reality, the tip doesn't heat at all). +- When using Up AND Down to switch between control modes: It can happen that you accidentally change the value due to single-button-presses. I will test it myself and if it is annoying I might try to prevent them. +- There might be bugs. From 4eb26679c4d0b03f20094c59699e97092fc9e056 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Tue, 28 Aug 2018 15:05:36 +0200 Subject: [PATCH 13/25] =?UTF-8?q?OFF=20mode=20for=20temperatures=20under?= =?UTF-8?q?=20153=C2=B0C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New State "OFF" that prevents extrusion - Temperature setting will step from 0 directly to 155 and vice versa - Display updated to show the status --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 51 ++++++++++++++------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index 268b132..5c109cb 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -39,6 +39,7 @@ enum { STATE_HEATING, STATE_COOLING, STATE_READY, + STATE_OFF } STATE_e; enum { @@ -54,13 +55,14 @@ enum { MODE_SPEED } MODE_CONTROL_e; -#define MAXTEMP 255 // not sure whats better: define or cont, also not sure about the actual max temp... testing with 255 -#define MINTEMP 0 +#define MAXTEMP 300 // not sure whats better: define or const, also not sure about the actual max temp... testing with 300 +#define MINTEMP 155 // 153/154 is the lowest measurement possible. actual temperature can be lower. + // We can use this to put heater in off mode (COOLING) if we choose "150°C" aka "LOW". However: hot temperatures will start at 155°C -int setTemperature = 0; // set heater temperature -int setMotorSpeed = 40; // set motor speed in % // hardcoded at 40% for now (will be changeable later) +int setTemperature = 0; // set heater temperature (we raise this directly to "155" when up button is pressed once. and drop it down to "0" if the user goes below "155") +int setMotorSpeed = 40; // set motor speed in % // ToDo maybe add icrement step value (hardcoded at 5) -char controlMode = MODE_TEMP; // ToDo: maybe not global... somewhere static? +char controlMode = MODE_TEMP; // Control Mode: MODE_TEMP or MODE_SPEED. selects which values the UP-DOWN buttons change /* * create timer for main loop @@ -99,7 +101,12 @@ void displayControls() { char textSetTemp[5]; // Buffers for formatted control input text char textSetMotor[5]; - sprintf(textSetTemp,"%3d ", setTemperature); + if (setTemperature >= MINTEMP) { + sprintf(textSetTemp,"%3d ", setTemperature); + } else { + sprintf(textSetTemp,"OFF "); + } + sprintf(textSetMotor,"%3d ",setMotorSpeed); // clear display and show all information @@ -221,7 +228,11 @@ int heating(){ sumTemp /= NO_AVERAGES_VALUES; // show on display actual and preset temperature - sprintf(text, "%3d ", sumTemp); + if (sumTemp >= MINTEMP) { + sprintf(text, "%3d ", sumTemp); + } else { + sprintf(text, "LOW "); + } ssd1306_setFixedFont(ssd1306xled_font6x8); ssd1306_printFixedN(0, 0, text, STYLE_NORMAL, FONT_SIZE_2X); ssd1306_printFixedN(36+3, 8, "C", STYLE_NORMAL, FONT_SIZE_NORMAL); @@ -256,10 +267,18 @@ void timerAction(){ if(++elapsedTime==2){ // 100ms elapsedTime = 0; int actualTemperature = heating(); + if (actualTemperature < 155) { + actualTemperature = 30; // doesn't really matter, but high enough above "0" + } // tolerant zone where temperature is ABOVE preset temperature, // but it is possible to do extrusion/reverse - if(actualTemperature > setTemperature + 10){ + if (setTemperature < 155) { + statusHeating = STATE_OFF; + ssd1306_printFixedN(128-4*12, 0, "OFF!", STYLE_NORMAL, FONT_SIZE_2X); + } + + else if(actualTemperature > setTemperature + 10){ statusHeating = STATE_COOLING; ssd1306_printFixedN(128-4*12, 0, "COOL", STYLE_NORMAL, FONT_SIZE_2X); } @@ -268,7 +287,6 @@ void timerAction(){ else if(actualTemperature > setTemperature - 10){ statusHeating = STATE_READY; ssd1306_printFixedN(128-4*12, 0, "DONE", STYLE_NORMAL, FONT_SIZE_2X); // "DONE"... need a word with 4 chars... "REDY"?... nup - //DEBUG digitalWrite(LED_NANO, HIGH); // turn the LED on (HIGH is the voltage level) } // tolerant zone where temperature is LOW for extrusion/reverse @@ -314,7 +332,7 @@ void timerAction(){ } break; } - + case STATE_OFF: case STATE_HEATING: // if happened that heater has so low temperature, motor stop digitalWrite(MOTOR_DIR, LOW); @@ -389,16 +407,17 @@ void timerAction(){ } else { if ((buttonsPressed & B00000001) && digitalRead(BTN_DOWN)) { // was I pressed in the LAST cycle? = onRelease if (controlMode == MODE_TEMP) { - if (setTemperature <= MAXTEMP - 5){ - setTemperature += 5; - displayControls(); + if (setTemperature == 0) { + setTemperature = MINTEMP; + } else if (setTemperature <= MAXTEMP - 5){ + setTemperature += 5; } } else { if (setMotorSpeed <= 100 - 5) { setMotorSpeed += 5; } } - displayControls(); + displayControls(); // updates display, even when there are no changes... TODO? } buttonsPressed &= B11111110; // set UP to released } @@ -409,7 +428,9 @@ void timerAction(){ } else { if ((buttonsPressed & B00000010) && digitalRead(BTN_UP)) { // was I pressed in the LAST cycle? = onRelease if (controlMode == MODE_TEMP) { - if (setTemperature >= MINTEMP + 5) { + if (setTemperature == MINTEMP) { + setTemperature = 0; + } else if (setTemperature >= MINTEMP + 5) { setTemperature -= 5; } } else { From 9f01386dbba51ff26c958c50d1aa1906a0b4f828 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Tue, 28 Aug 2018 15:31:31 +0200 Subject: [PATCH 14/25] Off mode guide. Some fixes. --- FW/3DsimoKit_Freemode/README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index 2c52bb5..73716e8 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -13,15 +13,21 @@ Freely set Temperature and Motor Speed. #### Screen: - Screen is tiled in four parts. -- Upper line Left: Actual Temperature. (there seems to be a bug, shown minimum is 153 atm) -- Upper line Right: State of the nozzle: HEAT, COOL, DONE. You can only extrude in done or cooling states. +- Upper line Left: Actual Temperature. Or "LOW" if it is below 153°C. +- Upper line Right: State of the nozzle: HEAT, COOL, DONE, OFF!. You can only extrude in done or cooling states. - Lower line: User input settings. Selected mode is shown inverted. -- Lower Left: Target temperaturen. (0 to 254°C (placeholder)) +- Lower Left: Target temperatures: "LOW", 155 - 300 (maximum is placeholder) - Lower Right: Motor Speed setting. (0 - 100 %) - Lower Middle: Icon that indicates how to change mode. +#### OFF mode: +- WARNING: "LOW" or "OFF!" does not indicate that the nozzle IS cold. It needs some time to cool down, even if LOW is diplayed. +- [The temperature measurement can't go below 153°C on an unmodified 3Dsimp Kit](https://github.com/3dsimo/3dsimo_kit/issues/4). +- Freemode will start in OFF mode. Extruding is prevented and the pen tries to cool down to target 0°C. +- Increasing the Temperature one step with the UP button will directly set 155°C as target temperature and the pen heats up. If the pen reaches 155°C and more, it will display the actual temperature (might take a while). +- In reverse: Going one step DOWN from 155°C target temperature will set 0°C as next target. The heater will turn OFF. As soon as the actual, measured temperature falls below 155°C it will diplay "LOW". TAKE CARE!! 154°C is still pretty hot to the touch! Colling down takes a while, too. + ### Work in Progress -- Default Settings, Min and Max Settings are Placeholders. e.g.: It does not make sense to keep 0°C as Minimum Temperature. -- There is an [issue that the measured temperature on the display never shows below 153°C](https://github.com/3dsimo/3dsimo_kit/issues/4). The actual temperature can be below 153 degrees. This value, however, also drives the heating wich means that the pen thinks that set values like 70°C are already exceeded with 153°C (while, in reality, the tip doesn't heat at all). +- Maximum temperature is a placeholder. I still need to figure out if there is a limit on the heater. - When using Up AND Down to switch between control modes: It can happen that you accidentally change the value due to single-button-presses. I will test it myself and if it is annoying I might try to prevent them. - There might be bugs. From 2111ed92624144502a9181cd9f767067aa0f5c9a Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Tue, 28 Aug 2018 15:43:52 +0200 Subject: [PATCH 15/25] just linked the firmware update guide. --- FW/3DsimoKit_Freemode/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index 73716e8..1b5b811 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -2,6 +2,8 @@ ### Alternative Control scheme for the 3Dsimo Kit pen Freely set Temperature and Motor Speed. +[How to change the firmware on the 3Dsimo Kit Pen.](../../documents/pdf/HW_FW_manualEN.pdf) + #### Buttons: - Extrude Pressed: extrudes filament (when hot). - Extrude Release: Filament will be pulled back slightly. From ed8da8f1886e946d839859e7cb951bb684b91037 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Tue, 28 Aug 2018 15:44:19 +0200 Subject: [PATCH 16/25] typo --- FW/3DsimoKit_Freemode/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index 1b5b811..e378cf9 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -1,7 +1,7 @@ # FREEMODE ### Alternative Control scheme for the 3Dsimo Kit pen -Freely set Temperature and Motor Speed. +Freely set Temperature and Motor Speed. [How to change the firmware on the 3Dsimo Kit Pen.](../../documents/pdf/HW_FW_manualEN.pdf) #### Buttons: From d467f8bc53b5e1d2caedb2ae02a77699b54e1d50 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Wed, 29 Aug 2018 12:04:55 +0200 Subject: [PATCH 17/25] added some warnings, fixed some typos. --- FW/3DsimoKit_Freemode/README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index e378cf9..f37397f 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -1,8 +1,9 @@ # FREEMODE ### Alternative Control scheme for the 3Dsimo Kit pen -Freely set Temperature and Motor Speed. -[How to change the firmware on the 3Dsimo Kit Pen.](../../documents/pdf/HW_FW_manualEN.pdf) +Freely set Temperature and Motor Speed. For right-handed use. +[How to change the firmware on the 3Dsimo Kit Pen.](../../documents/pdf/HW_FW_manualEN.pdf) +⚠️ Be very careful when setting the temperature and speed. Wrong settings can damage the nozzle. Take the profile settings from the official firmware as a starting point (notice how the speed is around 40%). If the heat is too low and the speed is too high your nozzle can overflow! ⚠️ #### Buttons: - Extrude Pressed: extrudes filament (when hot). @@ -18,18 +19,19 @@ Freely set Temperature and Motor Speed. - Upper line Left: Actual Temperature. Or "LOW" if it is below 153°C. - Upper line Right: State of the nozzle: HEAT, COOL, DONE, OFF!. You can only extrude in done or cooling states. - Lower line: User input settings. Selected mode is shown inverted. -- Lower Left: Target temperatures: "LOW", 155 - 300 (maximum is placeholder) +- Lower Left: Target temperatures: "LOW", 155 - 255 - Lower Right: Motor Speed setting. (0 - 100 %) - Lower Middle: Icon that indicates how to change mode. #### OFF mode: -- WARNING: "LOW" or "OFF!" does not indicate that the nozzle IS cold. It needs some time to cool down, even if LOW is diplayed. -- [The temperature measurement can't go below 153°C on an unmodified 3Dsimp Kit](https://github.com/3dsimo/3dsimo_kit/issues/4). +- ⚠️ WARNING: "LOW" or "OFF!" does not indicate that the nozzle IS cold. It needs some time to cool down, even if LOW is diplayed. +- [The temperature measurement can't go below 153°C on an unmodified 3Dsimo Kit](https://github.com/3dsimo/3dsimo_kit/issues/4). - Freemode will start in OFF mode. Extruding is prevented and the pen tries to cool down to target 0°C. - Increasing the Temperature one step with the UP button will directly set 155°C as target temperature and the pen heats up. If the pen reaches 155°C and more, it will display the actual temperature (might take a while). -- In reverse: Going one step DOWN from 155°C target temperature will set 0°C as next target. The heater will turn OFF. As soon as the actual, measured temperature falls below 155°C it will diplay "LOW". TAKE CARE!! 154°C is still pretty hot to the touch! Colling down takes a while, too. +- In reverse: Going one step DOWN from 155°C target temperature will set 0°C as next target. The heater will turn OFF. As soon as the actual, measured temperature falls below 155°C it will diplay "LOW". ⚠️ TAKE CARE!! 154°C is still pretty hot to the touch! Colling down takes a while, too. ### Work in Progress -- Maximum temperature is a placeholder. I still need to figure out if there is a limit on the heater. - When using Up AND Down to switch between control modes: It can happen that you accidentally change the value due to single-button-presses. I will test it myself and if it is annoying I might try to prevent them. - There might be bugs. +- I will probably write a few lines for Left-handed users. + From de3cc44d9c2b82634710ec3d76b650d0f9ec9f13 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Wed, 29 Aug 2018 12:24:46 +0200 Subject: [PATCH 18/25] forgot to push... Cleanup, left-hand notes, max temperature --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 37 +++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index 5c109cb..eeadac1 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -1,9 +1,8 @@ /* - * WIP - A alternative control mode that does not use predefined material profiles. - * But allows de-/increasing the temperature in steps of 5, from 0 to maximum. - * Later: UP and DOWN pressed together: change control mode to set motor speed the same way + * An alternative control mode that does not use predefined material profiles. + * But allows de-/increasing the temperature and speed in steps of 5 + * UP and DOWN pressed together: change control mode to switch between speed and temperature * Therefore the Up-Down-Buttons need to do their thing On Release (not while pressed) - * my Comments are just my personal notes... */ /* @@ -22,9 +21,11 @@ #define BTN_UP 12 // controlling button UP/PLUS // pin 11 & 12 changed for right hand use #define BTN_DOWN 11 // controlling button DOWN/MINUS +/* LEFT-HAND: uncomment the two lines below, comment away the two lines above! */ +// #define BTN_UP 11 // controlling button UP/PLUS +// #define BTN_DOWN 12 // controlling button DOWN/MINUS #define BTN_EXT 8 // button for material extrusion #define BTN_REV 7 // button for material reverse - #define MOTOR_DIR 6 // motor direction output #define MOTOR_PWM 10 // motor PWM output for power driving #define MOTOR_SLEEP 5 @@ -55,7 +56,7 @@ enum { MODE_SPEED } MODE_CONTROL_e; -#define MAXTEMP 300 // not sure whats better: define or const, also not sure about the actual max temp... testing with 300 +#define MAXTEMP 255 // not sure whats better: define or const, also not sure about the actual max temp... testing with 300 #define MINTEMP 155 // 153/154 is the lowest measurement possible. actual temperature can be lower. // We can use this to put heater in off mode (COOLING) if we choose "150°C" aka "LOW". However: hot temperatures will start at 155°C @@ -113,7 +114,6 @@ void displayControls() { ssd1306_clearScreen(); ssd1306_setFixedFont(ssd1306xled_font6x8); - // TODO: change Selection (negativeMode) according to ControlMode if (controlMode == MODE_TEMP) { ssd1306_negativeMode(); ssd1306_printFixedN(0, 16, textSetTemp, STYLE_NORMAL, FONT_SIZE_2X); @@ -201,7 +201,7 @@ 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[5]; // buffer for text + char text[5]; // buffer for text // variables initialization if(!firstTime){ @@ -211,7 +211,7 @@ int heating(){ // resolve PID value for heater PWM int temperature = getTemperature(); - int valuePID = getPIDoutput(setTemperature, temperature, 255, 0); // !!! IMPORTANT + int valuePID = getPIDoutput(setTemperature, temperature, 255, 0); analogWrite(HEATER_EN, valuePID); @@ -319,12 +319,12 @@ void timerAction(){ // both buttons are pressed, motor stopped else if(!digitalRead(BTN_EXT) && !digitalRead(BTN_REV)){ stateMotor = MOTOR_STOP; - // buttonsPressed |= B00001100; + buttonsPressed |= B01000000; } // no buttons are pressed else { - buttonsPressed &= B11110011; + buttonsPressed &= B10110011; if(lastMotorState == MOTOR_EXTRUSION){ stateMotor = MOTOR_REVERSE_AFTER_EXTRUSION; timeMotorReverse = 20; // reverse time is 50ms * timeMotorReverse (20 = 1s) @@ -382,8 +382,9 @@ void timerAction(){ lastMotorState = stateMotor; // one time action, mainly for material change - // The Mode Control Buttons (note: buttons are LOW/0/false when PRESSED!) - // + + // The Mode Control Buttons + // (note: buttons are LOW/0/false when PRESSED!) //// UP && DOWN are pressed if(!digitalRead(BTN_UP) && !digitalRead(BTN_DOWN)) { // Are both Buttons pressed? @@ -405,7 +406,7 @@ void timerAction(){ if(!digitalRead(BTN_UP)) { // if UP pressed buttonsPressed |= B00000001; // set UP to pressed } else { - if ((buttonsPressed & B00000001) && digitalRead(BTN_DOWN)) { // was I pressed in the LAST cycle? = onRelease + if ((buttonsPressed & B00000001) && digitalRead(BTN_DOWN)) { // was I pressed in the LAST cycle? = onRelease if (controlMode == MODE_TEMP) { if (setTemperature == 0) { setTemperature = MINTEMP; @@ -417,7 +418,7 @@ void timerAction(){ setMotorSpeed += 5; } } - displayControls(); // updates display, even when there are no changes... TODO? + displayControls(); } buttonsPressed &= B11111110; // set UP to released } @@ -426,7 +427,7 @@ void timerAction(){ if(!digitalRead(BTN_DOWN)) { // if DOWN pressed buttonsPressed |= B00000010; // set DOWN to pressed } else { - if ((buttonsPressed & B00000010) && digitalRead(BTN_UP)) { // was I pressed in the LAST cycle? = onRelease + if ((buttonsPressed & B00000010) && digitalRead(BTN_UP)) { // was I pressed in the LAST cycle? = onRelease if (controlMode == MODE_TEMP) { if (setTemperature == MINTEMP) { setTemperature = 0; @@ -458,9 +459,11 @@ void setup() { // initialize OLED display ssd1306_128x32_i2c_init(); ssd1306_clearScreen(); + /* LEFT-HAND: comment away the two lines below! */ ssd1306_flipHorizontal(1); /* oled_ssd1306.h NEW! rotate screen in X */ ssd1306_flipVertical(1); /* oled_ssd1306.h NEW! rotate screen in Y */ + // initialize outputs pinMode(LED_NANO, OUTPUT); @@ -475,7 +478,7 @@ void setup() { pinMode(BTN_EXT, INPUT_PULLUP); pinMode(BTN_REV, INPUT_PULLUP); - displayControls(); // setMotor&Temp should work globally, only display remains + displayControls(); // preset timer period every 50 ms and call timerAction function when time expire timer.Every(50, timerAction); From fd18e3fe77ff5135ef97a17e83ff53a12c58695a Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Wed, 29 Aug 2018 12:32:44 +0200 Subject: [PATCH 19/25] Left-hand information --- FW/3DsimoKit_Freemode/README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index f37397f..6be005d 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -1,9 +1,9 @@ # FREEMODE ### Alternative Control scheme for the 3Dsimo Kit pen -Freely set Temperature and Motor Speed. For right-handed use. +Freely set Temperature and Motor Speed. For right-handed use, see below how to change for left-hand. [How to change the firmware on the 3Dsimo Kit Pen.](../../documents/pdf/HW_FW_manualEN.pdf) -⚠️ Be very careful when setting the temperature and speed. Wrong settings can damage the nozzle. Take the profile settings from the official firmware as a starting point (notice how the speed is around 40%). If the heat is too low and the speed is too high your nozzle can overflow! ⚠️ +⚠️ Be very careful when setting the temperature and speed. Wrong settings can damage the nozzle. Use the profile settings from the official firmware as a starting point (notice how the speed is around 40%). If the heat is too low and the speed is too high your nozzle can overflow! ⚠️ #### Buttons: - Extrude Pressed: extrudes filament (when hot). @@ -30,8 +30,13 @@ Freely set Temperature and Motor Speed. For right-handed use. - Increasing the Temperature one step with the UP button will directly set 155°C as target temperature and the pen heats up. If the pen reaches 155°C and more, it will display the actual temperature (might take a while). - In reverse: Going one step DOWN from 155°C target temperature will set 0°C as next target. The heater will turn OFF. As soon as the actual, measured temperature falls below 155°C it will diplay "LOW". ⚠️ TAKE CARE!! 154°C is still pretty hot to the touch! Colling down takes a while, too. +#### Left-handed use: +- It is easy to change the code to left-hand mode. Just follow those lines: +- see line 24 +- see line 462 +- This will rotate the display and change the UP and DOWN buttons to fit the display reading direction. + ### Work in Progress - When using Up AND Down to switch between control modes: It can happen that you accidentally change the value due to single-button-presses. I will test it myself and if it is annoying I might try to prevent them. -- There might be bugs. -- I will probably write a few lines for Left-handed users. +- There might be bugs. 🐞 From 0a5092a55755feb27cef38dc32d57c3e930f608f Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Wed, 29 Aug 2018 12:36:02 +0200 Subject: [PATCH 20/25] those typos... --- FW/3DsimoKit_Freemode/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index 6be005d..5429543 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -27,8 +27,8 @@ Freely set Temperature and Motor Speed. For right-handed use, see below how to c - ⚠️ WARNING: "LOW" or "OFF!" does not indicate that the nozzle IS cold. It needs some time to cool down, even if LOW is diplayed. - [The temperature measurement can't go below 153°C on an unmodified 3Dsimo Kit](https://github.com/3dsimo/3dsimo_kit/issues/4). - Freemode will start in OFF mode. Extruding is prevented and the pen tries to cool down to target 0°C. -- Increasing the Temperature one step with the UP button will directly set 155°C as target temperature and the pen heats up. If the pen reaches 155°C and more, it will display the actual temperature (might take a while). -- In reverse: Going one step DOWN from 155°C target temperature will set 0°C as next target. The heater will turn OFF. As soon as the actual, measured temperature falls below 155°C it will diplay "LOW". ⚠️ TAKE CARE!! 154°C is still pretty hot to the touch! Colling down takes a while, too. +- Increasing the Temperature one step with the UP button will directly set 155°C as target temperature and the pen heats up. If the pen reaches 155°C and more, it will display the actual temperature (might take a moment). +- In reverse: Going one step DOWN from 155°C target temperature will set 0°C as next target. The heater will turn OFF. As soon as the actual, measured temperature falls below 155°C it will diplay "LOW". ⚠️ TAKE CARE!! 154°C is still pretty hot to the touch! Cooling down takes a while, too. #### Left-handed use: - It is easy to change the code to left-hand mode. Just follow those lines: From 56d815618d99388b70f7a9713abf28b4bd91a92d Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Wed, 29 Aug 2018 12:50:07 +0200 Subject: [PATCH 21/25] Releasing UP&DOWN buttons after mode change will not fire a single button action any more --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index eeadac1..38dd19d 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -400,13 +400,11 @@ void timerAction(){ } else { // else = not BOTH are pressed at the same time -> UP || DOWN || NONE - buttonsPressed &= B01111111; // BOTH release - //// UP Button on Release Action if(!digitalRead(BTN_UP)) { // if UP pressed buttonsPressed |= B00000001; // set UP to pressed } else { - if ((buttonsPressed & B00000001) && digitalRead(BTN_DOWN)) { // was I pressed in the LAST cycle? = onRelease + if (!(buttonsPressed & B10000000) && (buttonsPressed & B00000001) && digitalRead(BTN_DOWN)) { // was I pressed in the LAST cycle? = onRelease if (controlMode == MODE_TEMP) { if (setTemperature == 0) { setTemperature = MINTEMP; @@ -427,7 +425,7 @@ void timerAction(){ if(!digitalRead(BTN_DOWN)) { // if DOWN pressed buttonsPressed |= B00000010; // set DOWN to pressed } else { - if ((buttonsPressed & B00000010) && digitalRead(BTN_UP)) { // was I pressed in the LAST cycle? = onRelease + if (!(buttonsPressed & B10000000) && (buttonsPressed & B00000010) && digitalRead(BTN_UP)) { // was I pressed in the LAST cycle? = onRelease if (controlMode == MODE_TEMP) { if (setTemperature == MINTEMP) { setTemperature = 0; @@ -443,6 +441,11 @@ void timerAction(){ } buttonsPressed &= B11111101; // set DOWN to released } + + //// NONE + if (digitalRead(BTN_UP) && digitalRead(BTN_DOWN)) { + buttonsPressed &= B01111111; // BOTH release + } } // end of if-UP&&DOWN-are-pressed-else... From 72a4efe3582bb45a2f3bdf3897b230a041b4bf8c Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Wed, 29 Aug 2018 12:55:41 +0200 Subject: [PATCH 22/25] Removed WIP: everything done! --- FW/3DsimoKit_Freemode/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index 5429543..c018163 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -36,7 +36,7 @@ Freely set Temperature and Motor Speed. For right-handed use, see below how to c - see line 462 - This will rotate the display and change the UP and DOWN buttons to fit the display reading direction. -### Work in Progress -- When using Up AND Down to switch between control modes: It can happen that you accidentally change the value due to single-button-presses. I will test it myself and if it is annoying I might try to prevent them. -- There might be bugs. 🐞 + + +There might be bugs. 🐞 From acd9bffdbf3d7bd508c6cbe2b9da5a14ebdfdbb6 Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Tue, 4 Sep 2018 21:24:10 +0200 Subject: [PATCH 23/25] maximum Motorspeed limit to 60%. Safety first. To prevent overflow of the nozzle. You should stick to a motor speed around 40 +- 10. If you really need a higher speed: change MAXSPEED in line 59. --- FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino index 38dd19d..b87ea44 100644 --- a/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino +++ b/FW/3DsimoKit_Freemode/3DsimoKit_Freemode.ino @@ -56,6 +56,7 @@ enum { MODE_SPEED } MODE_CONTROL_e; +#define MAXSPEED 60 // for safety. change this up to 100 (%), if you know what you are doing. #define MAXTEMP 255 // not sure whats better: define or const, also not sure about the actual max temp... testing with 300 #define MINTEMP 155 // 153/154 is the lowest measurement possible. actual temperature can be lower. // We can use this to put heater in off mode (COOLING) if we choose "150°C" aka "LOW". However: hot temperatures will start at 155°C @@ -412,7 +413,7 @@ void timerAction(){ setTemperature += 5; } } else { - if (setMotorSpeed <= 100 - 5) { + if (setMotorSpeed <= MAXSPEED - 5) { setMotorSpeed += 5; } } From 2dc06405d6f57224fe580d781fed4bc62ac742fa Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Tue, 4 Sep 2018 21:28:38 +0200 Subject: [PATCH 24/25] Added info about maximum MotorSpeed --- FW/3DsimoKit_Freemode/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index c018163..e7b1762 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -3,7 +3,7 @@ Freely set Temperature and Motor Speed. For right-handed use, see below how to change for left-hand. [How to change the firmware on the 3Dsimo Kit Pen.](../../documents/pdf/HW_FW_manualEN.pdf) -⚠️ Be very careful when setting the temperature and speed. Wrong settings can damage the nozzle. Use the profile settings from the official firmware as a starting point (notice how the speed is around 40%). If the heat is too low and the speed is too high your nozzle can overflow! ⚠️ +⚠️ Be very careful when setting the temperature and speed. Wrong settings can damage the nozzle. Use the profile settings from the official firmware as a starting point (notice how the speed is around 40%). If the heat is too low and the speed is too high your nozzle can overflow! ⚠️ As a precaution the maximum speed is limited to 60%. You can change MAXSPEED in line ~59. #### Buttons: - Extrude Pressed: extrudes filament (when hot). @@ -20,7 +20,7 @@ Freely set Temperature and Motor Speed. For right-handed use, see below how to c - Upper line Right: State of the nozzle: HEAT, COOL, DONE, OFF!. You can only extrude in done or cooling states. - Lower line: User input settings. Selected mode is shown inverted. - Lower Left: Target temperatures: "LOW", 155 - 255 -- Lower Right: Motor Speed setting. (0 - 100 %) +- Lower Right: Motor Speed setting: 0 - 60 % - Lower Middle: Icon that indicates how to change mode. #### OFF mode: From 84ae2419695c670d231ed3ac9ffb1a5da15124af Mon Sep 17 00:00:00 2001 From: Anna Timm Date: Tue, 4 Sep 2018 21:45:56 +0200 Subject: [PATCH 25/25] Corrected line number, added a clear link to the ino file --- FW/3DsimoKit_Freemode/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FW/3DsimoKit_Freemode/README.md b/FW/3DsimoKit_Freemode/README.md index e7b1762..e0674e3 100644 --- a/FW/3DsimoKit_Freemode/README.md +++ b/FW/3DsimoKit_Freemode/README.md @@ -2,7 +2,9 @@ ### Alternative Control scheme for the 3Dsimo Kit pen Freely set Temperature and Motor Speed. For right-handed use, see below how to change for left-hand. +Download or copy the [3DsimoKit_Freemode.ino](3DsimoKit_Freemode.ino) file and... [How to change the firmware on the 3Dsimo Kit Pen.](../../documents/pdf/HW_FW_manualEN.pdf) + ⚠️ Be very careful when setting the temperature and speed. Wrong settings can damage the nozzle. Use the profile settings from the official firmware as a starting point (notice how the speed is around 40%). If the heat is too low and the speed is too high your nozzle can overflow! ⚠️ As a precaution the maximum speed is limited to 60%. You can change MAXSPEED in line ~59. #### Buttons: @@ -33,7 +35,7 @@ Freely set Temperature and Motor Speed. For right-handed use, see below how to c #### Left-handed use: - It is easy to change the code to left-hand mode. Just follow those lines: - see line 24 -- see line 462 +- see line 466 - This will rotate the display and change the UP and DOWN buttons to fit the display reading direction.