#include "ssd1306.h"
#include "nano_gfx.h"
/* * 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 HEATER_EN 9 // heater/power output
#define TEMP_IN A0 // temperature measure ADC input
/* * define heating states
MOTOR_REVERSE_AFTER_EXTRUSION
/* * define structure for the material list
/* * define material profiles
*/ const profile_t materials[] PROGMEM = {
// {temperature (deg. C), motorSpeed (%), materialName}
/* * define number of materials in list and variables
*/ #define MATERIAL_COUNT 2
int materialID = 0; // chosen material profile
int setTemperature = 225; // set heater temperature
int setMotorSpeed = 60; // set motor speed in %
/* * create timer for main loop
/* * 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);
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
/* * load actual material profile
*/ void loadMaterial(int id){
// load material profile from PROGMEM and assign variables
memcpy_P(&profile, &materials[id], sizeof(profile_t));
setTemperature = profile.temperature;
setMotorSpeed = profile.motorSpeed;
// clear display and show all information
sprintf(text, "%d %%", setMotorSpeed);
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 int16_t error, previousError = 0;
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){
error = setPoint - actualValue;
sumE += (float) error * dT;
outputValue = Kp*error + Ki*sumE + Kd*(error - previousError)/dT;
// restrict output PID value into range between minValue and maxValue
if(outputValue > maxValue)
else if(outputValue < minValue)
// store n output values for averaging
pidAvg[pidAvgIndex] = outputValue;