mirror of
https://github.com/ArduinoHannover/Maiskolben.git
synced 2025-09-01 09:02:53 +02:00
V3.0
- Geänderte Display-Bibliothek (vgl. Abschnitt Bibliotheken der Readme) - Mehr Strings im Flash statt im RAM - Anpassungen um einen Maiskolben V3.2 im LiPo-Betrieb vollständig abzuschalten - Limitierung der Minimaltemperatur auf 200°C - `°C` wird mit bei Soll- und Ist-Temperatur angezeigt - Interne Temperatur-Kalibrierung für jeden Maiskolben individuell (bisher nur für Kalibrierung ab Werk)
This commit is contained in:
24
.gitignore
vendored
24
.gitignore
vendored
@@ -1,5 +1,19 @@
|
|||||||
**.indd
|
# Internals
|
||||||
**.gpi
|
Makefile
|
||||||
**.$$$
|
/build/
|
||||||
**.s#*
|
*.indd
|
||||||
**.b#*
|
|
||||||
|
# EAGLE
|
||||||
|
*.gpi
|
||||||
|
*.$$$
|
||||||
|
*.s#*
|
||||||
|
*.b#*
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <Adafruit_GFX.h>
|
#include <TFT_ILI9163C.h>
|
||||||
#include <Adafruit_ST7735.h>
|
|
||||||
#include <PID_v1.h>
|
#include <PID_v1.h>
|
||||||
#include <EEPROM.h>
|
#include <EEPROM.h>
|
||||||
#include "TimerOne.h"
|
#include "TimerOne.h"
|
||||||
@@ -14,20 +13,24 @@
|
|||||||
//#define USE_TFT_RESET
|
//#define USE_TFT_RESET
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If red is blue and blue is red change this (2.0 and above have new display types)
|
* If red is blue and blue is red change this
|
||||||
* If not sure, leave commented, you will be shown a setup screen
|
* If not sure, leave commented, you will be shown a setup screen
|
||||||
*/
|
*/
|
||||||
//#define HARDWARE_DEFINED_TFT 2
|
//#define HARDWARE_DEFINED_TFT 2
|
||||||
/*
|
/*
|
||||||
* Based on your Hardware-Revision there may be modifications to the PCB.
|
* Based on your Hardware-Revision there may be modifications to the PCB.
|
||||||
* In V3 and up is a second voltage measurement circuit.
|
* In V3 and up is a second voltage measurement circuit.
|
||||||
|
* HW REVS:
|
||||||
|
* 1.5 - 2.8:
|
||||||
* For THT this should be set to anything < 3
|
* For THT this should be set to anything < 3
|
||||||
* Normally leave this commented as it is stored in EEPROM
|
* Normally leave this commented as it is stored in EEPROM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// V 1.5 - 2.11, Maiskolben THT
|
||||||
|
//#define HARDWARE_REVISION 2
|
||||||
|
// V 3.0 and 3.1
|
||||||
//#define HARDWARE_REVISION 3
|
//#define HARDWARE_REVISION 3
|
||||||
//#ifndef PIN_A7
|
|
||||||
//#define HARDWARE_REVISION 1
|
|
||||||
//#endif
|
|
||||||
/*
|
/*
|
||||||
* Only used for testing, do not use.
|
* Only used for testing, do not use.
|
||||||
*/
|
*/
|
||||||
@@ -39,7 +42,7 @@ volatile uint8_t pwm, threshold_counter;
|
|||||||
volatile int16_t cur_t, last_measured;
|
volatile int16_t cur_t, last_measured;
|
||||||
volatile error_type error = NO_ERROR;
|
volatile error_type error = NO_ERROR;
|
||||||
error_type error_old;
|
error_type error_old;
|
||||||
int16_t stored[3] = {250, 300, 350}, set_t = 150, set_t_old, cur_t_old, target_t;
|
int16_t stored[3] = {300, 350, 450}, set_t = TEMP_MIN, set_t_old, cur_t_old, target_t;
|
||||||
double pid_val, cur_td, set_td;
|
double pid_val, cur_td, set_td;
|
||||||
uint8_t store_to = 255;
|
uint8_t store_to = 255;
|
||||||
p_source power_source, power_source_old = NO_INIT;
|
p_source power_source, power_source_old = NO_INIT;
|
||||||
@@ -55,20 +58,38 @@ boolean autopower = true, bootheat = false;
|
|||||||
uint8_t revision = 1;
|
uint8_t revision = 1;
|
||||||
boolean menu_dismissed = false;
|
boolean menu_dismissed = false;
|
||||||
boolean autopower_repeat_under = false;
|
boolean autopower_repeat_under = false;
|
||||||
|
boolean force_redraw = false;
|
||||||
|
boolean power_down = false;
|
||||||
|
uint16_t charge = 0;
|
||||||
|
float adc_offset = ADC_TO_TEMP_OFFSET;
|
||||||
|
float adc_gain = ADC_TO_TEMP_GAIN;
|
||||||
|
|
||||||
|
#define RGB_DISP 0x0
|
||||||
|
#define BGR_DISP 0x2
|
||||||
|
|
||||||
#ifdef USE_TFT_RESET
|
#ifdef USE_TFT_RESET
|
||||||
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, STBY_NO);
|
TFT_ILI9163C tft = TFT_ILI9163C(TFT_CS, TFT_DC, STBY_NO);
|
||||||
#else
|
#else
|
||||||
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, 0);
|
TFT_ILI9163C tft = TFT_ILI9163C(TFT_CS, TFT_DC);
|
||||||
#endif
|
#endif
|
||||||
#define ST7735_GRAY 0x94B2
|
#define BLACK 0x0000
|
||||||
|
#define BLUE 0x001F
|
||||||
|
#define RED 0xF800
|
||||||
|
#define GREEN 0x07E0
|
||||||
|
#define CYAN 0x07FF
|
||||||
|
#define MAGENTA 0xF81F
|
||||||
|
#define YELLOW 0xFFE0
|
||||||
|
#define WHITE 0xFFFF
|
||||||
|
#define GRAY 0x94B2
|
||||||
|
|
||||||
PID heaterPID(&cur_td, &pid_val, &set_td, kp, ki, kd, DIRECT);
|
PID heaterPID(&cur_td, &pid_val, &set_td, kp, ki, kd, DIRECT);
|
||||||
|
|
||||||
void setup(void) {
|
void setup(void) {
|
||||||
digitalWrite(HEATER_PWM, LOW);
|
digitalWrite(HEATER_PWM, LOW);
|
||||||
pinMode(HEATER_PWM, OUTPUT);
|
pinMode(HEATER_PWM, OUTPUT);
|
||||||
|
pinMode(POWER, INPUT_PULLUP);
|
||||||
pinMode(HEAT_LED, OUTPUT);
|
pinMode(HEAT_LED, OUTPUT);
|
||||||
|
digitalWrite(HEAT_LED, HIGH);
|
||||||
pinMode(TEMP_SENSE, INPUT);
|
pinMode(TEMP_SENSE, INPUT);
|
||||||
pinMode(SW_T1, INPUT_PULLUP);
|
pinMode(SW_T1, INPUT_PULLUP);
|
||||||
pinMode(SW_T2, INPUT_PULLUP);
|
pinMode(SW_T2, INPUT_PULLUP);
|
||||||
@@ -87,44 +108,43 @@ void setup(void) {
|
|||||||
updateEEPROM();
|
updateEEPROM();
|
||||||
force_menu = true;
|
force_menu = true;
|
||||||
}
|
}
|
||||||
//delay(1000);
|
tft.begin();
|
||||||
#ifdef HARDWARE_DEFINED_TFT
|
#ifdef HARDWARE_DEFINED_TFT
|
||||||
#if HARDWARE_DEFINED_TFT == 1
|
#if HARDWARE_DEFINED_TFT == 1
|
||||||
tft.initR(INITR_BLACKTAB);
|
EEPROM.update(EEPROM_DISPLAY, RGB_DISP);
|
||||||
EEPROM.update(EEPROM_DISPLAY, INITR_BLACKTAB);
|
setDisplayMode(0);
|
||||||
|
#else
|
||||||
|
EEPROM.update(EEPROM_DISPLAY, BGR_DISP);
|
||||||
|
setDisplayMode(1);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
tft.initR(INITR_GREENTAB);
|
if (force_menu || EEPROM.read(EEPROM_VERSION) < 23 || EEPROM.read(EEPROM_VERSION) == 255 || (EEPROM.read(EEPROM_DISPLAY) != BGR_DISP && EEPROM.read(EEPROM_DISPLAY) != RGB_DISP)) {
|
||||||
EEPROM.update(EEPROM_DISPLAY, INITR_GREENTAB);
|
tft.fillScreen(BLACK);
|
||||||
#endif
|
setDisplayMode(1);
|
||||||
#else
|
|
||||||
if (force_menu || EEPROM.read(EEPROM_VERSION) < 23 || EEPROM.read(EEPROM_VERSION) == 255 || (EEPROM.read(EEPROM_DISPLAY) != INITR_GREENTAB && EEPROM.read(EEPROM_DISPLAY) != INITR_BLACKTAB)) {
|
|
||||||
tft.initR(INITR_GREENTAB);
|
|
||||||
tft.setRotation(1);
|
|
||||||
tft.fillScreen(ST7735_BLACK);
|
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.setCursor(0,0);
|
tft.setCursor(0,0);
|
||||||
tft.setTextColor(ST7735_WHITE);
|
tft.setTextColor(WHITE);
|
||||||
tft.print(F("What color is displayed?"));
|
tft.print(F("What color is displayed?"));
|
||||||
tft.setCursor(10,112);
|
tft.setCursor(10,112);
|
||||||
tft.setTextColor(ST7735_RED);
|
tft.setTextColor(RED);
|
||||||
tft.print("RED BLUE");
|
tft.print("RED BLUE");
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!digitalRead(SW_T1)) {
|
if (!digitalRead(SW_T1)) {
|
||||||
EEPROM.update(EEPROM_DISPLAY, INITR_GREENTAB);
|
EEPROM.update(EEPROM_DISPLAY, BGR_DISP);
|
||||||
|
setDisplayMode(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!digitalRead(SW_T3)) {
|
if (!digitalRead(SW_T3)) {
|
||||||
EEPROM.update(EEPROM_DISPLAY, INITR_BLACKTAB);
|
EEPROM.update(EEPROM_DISPLAY, RGB_DISP);
|
||||||
tft.initR(INITR_BLACKTAB);
|
setDisplayMode(0);
|
||||||
tft.setRotation(1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tft.fillScreen(ST7735_BLACK);
|
tft.fillScreen(BLACK);
|
||||||
tft.setTextColor(ST7735_YELLOW);
|
tft.setTextColor(YELLOW);
|
||||||
tft.drawBitmap(0, 20, maiskolben, 160, 64, ST7735_YELLOW);
|
tft.drawBitmap(0, 20, maiskolben, 160, 64, YELLOW);
|
||||||
tft.setCursor(20,86);
|
tft.setCursor(20,86);
|
||||||
tft.setTextColor(ST7735_YELLOW);
|
tft.setTextColor(YELLOW);
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.print("Maiskolben");
|
tft.print("Maiskolben");
|
||||||
tft.setCursor(35,104);
|
tft.setCursor(35,104);
|
||||||
@@ -132,15 +152,13 @@ void setup(void) {
|
|||||||
delay(4000);
|
delay(4000);
|
||||||
while (!digitalRead(SW_T3) || !digitalRead(SW_T1)) delay(100);
|
while (!digitalRead(SW_T3) || !digitalRead(SW_T1)) delay(100);
|
||||||
} else {
|
} else {
|
||||||
tft.initR(EEPROM.read(EEPROM_DISPLAY));
|
setDisplayMode(EEPROM.read(EEPROM_DISPLAY) == BGR_DISP);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef INSTALL
|
#ifdef INSTALL
|
||||||
//EEPROM.update(EEPROM_INSTALL, 0);
|
|
||||||
if (EEPROM.read(EEPROM_INSTALL) != EEPROM_CHECK) {
|
if (EEPROM.read(EEPROM_INSTALL) != EEPROM_CHECK) {
|
||||||
tft.setRotation(1);
|
tft.fillScreen(BLACK);
|
||||||
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
|
tft.setTextColor(RED, BLACK);
|
||||||
tft.fillScreen(ST7735_BLACK);
|
|
||||||
tft.setCursor(0,0);
|
tft.setCursor(0,0);
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.println("Installation");
|
tft.println("Installation");
|
||||||
@@ -148,18 +166,46 @@ void setup(void) {
|
|||||||
analogWrite(HEAT_LED, 255-abs(i));
|
analogWrite(HEAT_LED, 255-abs(i));
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
uint16_t adc1 = 0, adc2 = 0;
|
||||||
while (digitalRead(SW_STBY)) {
|
while (digitalRead(SW_STBY)) {
|
||||||
int t = getTemperature();
|
int t = getTemperature();
|
||||||
|
uint16_t adc = analogRead(TEMP_SENSE);
|
||||||
Serial.println(t);
|
Serial.println(t);
|
||||||
digitalWrite(HEATER_PWM, !digitalRead(SW_T1) | !digitalRead(SW_T2) | !digitalRead(SW_T3) | !digitalRead(SW_UP) | !digitalRead(SW_DOWN));
|
digitalWrite(HEATER_PWM, !digitalRead(SW_T1) | !digitalRead(SW_T2) | !digitalRead(SW_T3)/* | !digitalRead(SW_UP) | !digitalRead(SW_DOWN)*/);
|
||||||
|
if (!digitalRead(SW_DOWN)) {
|
||||||
|
if (!adc) {
|
||||||
|
digitalWrite(HEATER_PWM, HIGH);
|
||||||
|
} else {
|
||||||
|
adc1 = adc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!digitalRead(SW_UP)) {
|
||||||
|
if (!adc) {
|
||||||
|
digitalWrite(HEATER_PWM, HIGH);
|
||||||
|
} else {
|
||||||
|
adc2 = adc;
|
||||||
|
}
|
||||||
|
}
|
||||||
tft.setCursor(0,18);
|
tft.setCursor(0,18);
|
||||||
tft.print(t);
|
tft.print(t);
|
||||||
tft.println(" ");
|
tft.println(" ");
|
||||||
|
tft.print(adc);
|
||||||
|
tft.println(" ");
|
||||||
|
tft.println(adc * adc_gain + adc_offset);
|
||||||
|
if (adc1 != 0 && adc2 != 0) {
|
||||||
|
adc_gain = DELTA_REF_T / (float)(adc2 - adc1);
|
||||||
|
adc_offset = REF_T1 - adc_gain * adc1;
|
||||||
|
tft.println(adc_gain);
|
||||||
|
tft.println(adc_offset);
|
||||||
|
}
|
||||||
delay(50);
|
delay(50);
|
||||||
}
|
}
|
||||||
EEPROM.update(EEPROM_OPTIONS, (bootheat << 1) | autopower);
|
EEPROM.update(EEPROM_OPTIONS, (bootheat << 1) | autopower);
|
||||||
EEPROM.update(EEPROM_VERSION, EE_VERSION);
|
EEPROM.update(EEPROM_VERSION, EE_VERSION);
|
||||||
EEPROM.update(EEPROM_INSTALL, EEPROM_CHECK);
|
EEPROM.update(EEPROM_INSTALL, EEPROM_CHECK);
|
||||||
|
EEPROM.put(EEPROM_ADCTTG, adc_gain);
|
||||||
|
EEPROM.put(EEPROM_ADCOFF, adc_offset);
|
||||||
|
|
||||||
tft.println("done.");
|
tft.println("done.");
|
||||||
delay(1000);
|
delay(1000);
|
||||||
asm volatile("jmp 0");
|
asm volatile("jmp 0");
|
||||||
@@ -168,17 +214,16 @@ void setup(void) {
|
|||||||
if (EEPROM.read(EEPROM_VERSION) != EE_VERSION) {
|
if (EEPROM.read(EEPROM_VERSION) != EE_VERSION) {
|
||||||
force_menu = true;
|
force_menu = true;
|
||||||
}
|
}
|
||||||
tft.fillScreen(ST7735_BLACK);
|
tft.fillScreen(BLACK);
|
||||||
tft.setRotation(1);
|
|
||||||
uint8_t options = EEPROM.read(EEPROM_OPTIONS);
|
uint8_t options = EEPROM.read(EEPROM_OPTIONS);
|
||||||
autopower = options & 1;
|
autopower = options & 1;
|
||||||
bootheat = (options >> 1) & 1;
|
bootheat = (options >> 1) & 1;
|
||||||
if (force_menu) optionMenu();
|
if (force_menu) optionMenu();
|
||||||
else {
|
else {
|
||||||
updateRevision();
|
updateRevision();
|
||||||
tft.drawBitmap(0, 20, maiskolben, 160, 64, ST7735_YELLOW);
|
tft.drawBitmap(0, 20, maiskolben, 160, 64, YELLOW);
|
||||||
tft.setCursor(20,86);
|
tft.setCursor(20,86);
|
||||||
tft.setTextColor(ST7735_YELLOW);
|
tft.setTextColor(YELLOW);
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.print("Maiskolben");
|
tft.print("Maiskolben");
|
||||||
tft.setCursor(50,110);
|
tft.setCursor(50,110);
|
||||||
@@ -189,8 +234,9 @@ void setup(void) {
|
|||||||
tft.print("HW Revision ");
|
tft.print("HW Revision ");
|
||||||
tft.print(revision);
|
tft.print(revision);
|
||||||
//Allow Options to be set at startup
|
//Allow Options to be set at startup
|
||||||
|
delay(100);
|
||||||
attachInterrupt(digitalPinToInterrupt(SW_STBY), optionMenu, LOW);
|
attachInterrupt(digitalPinToInterrupt(SW_STBY), optionMenu, LOW);
|
||||||
for (int i = 1; i < 11 && !menu_dismissed; i++) {
|
for (int i = 0; i < 10 && !menu_dismissed; i++) {
|
||||||
digitalWrite(HEAT_LED, i % 2);
|
digitalWrite(HEAT_LED, i % 2);
|
||||||
delay(250);
|
delay(250);
|
||||||
}
|
}
|
||||||
@@ -225,7 +271,7 @@ void setup(void) {
|
|||||||
for (uint8_t i = 0; i < 50; i++)
|
for (uint8_t i = 0; i < 50; i++)
|
||||||
measureVoltage(); //measure average 50 times to get realistic results
|
measureVoltage(); //measure average 50 times to get realistic results
|
||||||
|
|
||||||
tft.fillScreen(ST7735_BLACK);
|
tft.fillScreen(BLACK);
|
||||||
last_measured = getTemperature();
|
last_measured = getTemperature();
|
||||||
Timer1.initialize(1000);
|
Timer1.initialize(1000);
|
||||||
Timer1.attachInterrupt(timer_isr);
|
Timer1.attachInterrupt(timer_isr);
|
||||||
@@ -235,6 +281,8 @@ void setup(void) {
|
|||||||
threshold_counter = TEMP_UNDER_THRESHOLD;
|
threshold_counter = TEMP_UNDER_THRESHOLD;
|
||||||
setOff(false);
|
setOff(false);
|
||||||
}
|
}
|
||||||
|
EEPROM.get(EEPROM_ADCTTG, adc_gain);
|
||||||
|
EEPROM.get(EEPROM_ADCOFF, adc_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateRevision(void) {
|
void updateRevision(void) {
|
||||||
@@ -251,14 +299,19 @@ void updateRevision(void) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDisplayMode(boolean bgr) {
|
||||||
|
tft.colorSpace(bgr);
|
||||||
|
tft.setRotation(3);
|
||||||
|
}
|
||||||
|
|
||||||
void optionMenu(void) {
|
void optionMenu(void) {
|
||||||
tft.fillScreen(ST7735_BLACK);
|
tft.fillScreen(BLACK);
|
||||||
digitalWrite(HEAT_LED, LOW);
|
digitalWrite(HEAT_LED, LOW);
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.setCursor(0,0);
|
tft.setCursor(0,0);
|
||||||
tft.setTextColor(ST7735_WHITE);
|
tft.setTextColor(WHITE);
|
||||||
tft.println("Options\n");
|
tft.println("Options\n");
|
||||||
tft.setTextColor(ST7735_WHITE);
|
tft.setTextColor(WHITE);
|
||||||
tft.setCursor(10,112);
|
tft.setCursor(10,112);
|
||||||
tft.print("ON OFF EXIT");
|
tft.print("ON OFF EXIT");
|
||||||
uint8_t options = 2;
|
uint8_t options = 2;
|
||||||
@@ -268,26 +321,26 @@ void optionMenu(void) {
|
|||||||
if (redraw) {
|
if (redraw) {
|
||||||
tft.setCursor(0,36);
|
tft.setCursor(0,36);
|
||||||
#ifdef SHUTOFF_ACTIVE
|
#ifdef SHUTOFF_ACTIVE
|
||||||
tft.setTextColor(autopower?ST7735_GREEN:ST7735_RED);
|
tft.setTextColor(autopower?GREEN:RED);
|
||||||
#else
|
#else
|
||||||
tft.setTextColor(ST7735_GRAY);
|
tft.setTextColor(GRAY);
|
||||||
#endif
|
#endif
|
||||||
tft.println(" Autoshutdown");
|
tft.println(" Autoshutdown");
|
||||||
#ifdef BOOTHEAT_ACTIVE
|
#ifdef BOOTHEAT_ACTIVE
|
||||||
tft.setTextColor(bootheat?ST7735_GREEN:ST7735_RED);
|
tft.setTextColor(bootheat?GREEN:RED);
|
||||||
#else
|
#else
|
||||||
tft.setTextColor(ST7735_GRAY);
|
tft.setTextColor(GRAY);
|
||||||
#endif
|
#endif
|
||||||
tft.println(" Heat on boot");
|
tft.println(" Heat on boot");
|
||||||
|
|
||||||
tft.setCursor(0, (opt+2)*18);
|
tft.setCursor(0, (opt+2)*18);
|
||||||
tft.setTextColor(ST7735_WHITE);
|
tft.setTextColor(WHITE);
|
||||||
tft.print(">");
|
tft.print(">");
|
||||||
redraw = false;
|
redraw = false;
|
||||||
}
|
}
|
||||||
if (!digitalRead(SW_UP)) {
|
if (!digitalRead(SW_UP)) {
|
||||||
tft.setCursor(0, (opt+2)*18);
|
tft.setCursor(0, (opt+2)*18);
|
||||||
tft.setTextColor(ST7735_BLACK);
|
tft.setTextColor(BLACK);
|
||||||
tft.print(">");
|
tft.print(">");
|
||||||
opt = (opt+options-1)%options;
|
opt = (opt+options-1)%options;
|
||||||
while (!digitalRead(SW_UP)) delay(100);
|
while (!digitalRead(SW_UP)) delay(100);
|
||||||
@@ -295,7 +348,7 @@ void optionMenu(void) {
|
|||||||
}
|
}
|
||||||
if (!digitalRead(SW_DOWN)) {
|
if (!digitalRead(SW_DOWN)) {
|
||||||
tft.setCursor(0, (opt+2)*18);
|
tft.setCursor(0, (opt+2)*18);
|
||||||
tft.setTextColor(ST7735_BLACK);
|
tft.setTextColor(BLACK);
|
||||||
tft.print(">");
|
tft.print(">");
|
||||||
opt = (opt+1)%options;
|
opt = (opt+1)%options;
|
||||||
while (!digitalRead(SW_DOWN)) delay(100);
|
while (!digitalRead(SW_DOWN)) delay(100);
|
||||||
@@ -320,6 +373,10 @@ void optionMenu(void) {
|
|||||||
EEPROM.update(EEPROM_OPTIONS, (bootheat << 1) | autopower);
|
EEPROM.update(EEPROM_OPTIONS, (bootheat << 1) | autopower);
|
||||||
updateRevision();
|
updateRevision();
|
||||||
EEPROM.update(EEPROM_VERSION, EE_VERSION);
|
EEPROM.update(EEPROM_VERSION, EE_VERSION);
|
||||||
|
if (EEPROM.read(EEPROM_VERSION) < 30) {
|
||||||
|
EEPROM.put(EEPROM_ADCTTG, ADC_TO_TEMP_GAIN);
|
||||||
|
EEPROM.put(EEPROM_ADCOFF, ADC_TO_TEMP_OFFSET);
|
||||||
|
}
|
||||||
menu_dismissed = true;
|
menu_dismissed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,6 +391,29 @@ void updateEEPROM(void) {
|
|||||||
EEPROM.update(EEPROM_OPTIONS, (bootheat << 1) | autopower);
|
EEPROM.update(EEPROM_OPTIONS, (bootheat << 1) | autopower);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void powerDown(void) {
|
||||||
|
if (power_source != POWER_LIPO) {
|
||||||
|
power_down = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Timer1.stop();
|
||||||
|
setOff(true);
|
||||||
|
delay(10);
|
||||||
|
tft.fillScreen(BLACK);
|
||||||
|
tft.setTextSize(4);
|
||||||
|
tft.setTextColor(RED);
|
||||||
|
tft.setCursor(50,40);
|
||||||
|
tft.print("OFF");
|
||||||
|
delay(3000);
|
||||||
|
SPI.end();
|
||||||
|
digitalWrite(POWER, LOW);
|
||||||
|
pinMode(POWER, OUTPUT);
|
||||||
|
delay(100);
|
||||||
|
force_redraw = true;
|
||||||
|
power_down = false;
|
||||||
|
Timer1.start(); //unsuccessful
|
||||||
|
}
|
||||||
|
|
||||||
int getTemperature(void) {
|
int getTemperature(void) {
|
||||||
analogRead(TEMP_SENSE);//Switch ADC MUX
|
analogRead(TEMP_SENSE);//Switch ADC MUX
|
||||||
uint16_t adc = median(TEMP_SENSE);
|
uint16_t adc = median(TEMP_SENSE);
|
||||||
@@ -349,7 +429,7 @@ int getTemperature(void) {
|
|||||||
analogWrite(HEATER_PWM, pwm); //switch heater back to last value
|
analogWrite(HEATER_PWM, pwm); //switch heater back to last value
|
||||||
}
|
}
|
||||||
//return round(adc < 210 ? (((float)adc) * 0.530805 + 38.9298) : (((float)adc) * 0.415375 + 64.6123)); //old conversion
|
//return round(adc < 210 ? (((float)adc) * 0.530805 + 38.9298) : (((float)adc) * 0.415375 + 64.6123)); //old conversion
|
||||||
return round(((float) adc) * ADC_TO_TEMP_GAIN + ADC_TO_TEMP_OFFSET);
|
return round(((float) adc) * adc_gain + adc_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void measureVoltage(void) {
|
void measureVoltage(void) {
|
||||||
@@ -393,13 +473,19 @@ uint16_t median(uint8_t analogIn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void timer_sw_poll(void) {
|
void timer_sw_poll(void) {
|
||||||
|
if (power_down) return;
|
||||||
if (!digitalRead(SW_STBY)) {
|
if (!digitalRead(SW_STBY)) {
|
||||||
if (cnt_off_press == 100) {
|
if (cnt_off_press == 100) {
|
||||||
setOff(!off);
|
setOff(!off);
|
||||||
}
|
}
|
||||||
cnt_off_press = min(101, cnt_off_press+1);
|
if (cnt_off_press == 200 && power_source == POWER_LIPO) {
|
||||||
|
setOff(true);
|
||||||
|
power_down = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cnt_off_press = min(201, cnt_off_press+1);
|
||||||
} else {
|
} else {
|
||||||
if (cnt_off_press > 0 && cnt_off_press != 101) {
|
if (cnt_off_press > 0 && cnt_off_press <= 100) {
|
||||||
setStandby(!stby);
|
setStandby(!stby);
|
||||||
}
|
}
|
||||||
cnt_off_press = 0;
|
cnt_off_press = 0;
|
||||||
@@ -502,74 +588,77 @@ void setOff(boolean state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void display(void) {
|
void display(void) {
|
||||||
|
if (force_redraw) tft.fillScreen(BLACK);
|
||||||
int16_t temperature = cur_t; //buffer volatile value
|
int16_t temperature = cur_t; //buffer volatile value
|
||||||
boolean yell = stby || (stby_layoff && blink);
|
boolean yell = stby || (stby_layoff && blink);
|
||||||
tft.drawCircle(20,63,8, off?ST7735_RED:yell?ST7735_YELLOW:ST7735_GREEN);
|
tft.drawCircle(20,63,8, off?RED:yell?YELLOW:GREEN);
|
||||||
tft.drawCircle(20,63,7,off?ST7735_RED:yell?ST7735_YELLOW:ST7735_GREEN);
|
tft.drawCircle(20,63,7,off?RED:yell?YELLOW:GREEN);
|
||||||
tft.fillRect(19,55,3,3,ST7735_BLACK);
|
tft.fillRect(19,55,3,3,BLACK);
|
||||||
tft.drawFastVLine(20,53,10, off?ST7735_RED:yell?ST7735_YELLOW:ST7735_GREEN);
|
tft.drawFastVLine(20,53,10, off?RED:yell?YELLOW:GREEN);
|
||||||
if (error != NO_ERROR) {
|
if (error != NO_ERROR) {
|
||||||
if (error != error_old) {
|
if (error != error_old || force_redraw) {
|
||||||
error_old = error;
|
error_old = error;
|
||||||
tft.setTextSize(1);
|
tft.setTextSize(1);
|
||||||
tft.setTextColor(ST7735_RED, ST7735_BLACK);
|
tft.setTextColor(RED, BLACK);
|
||||||
tft.setCursor(0,96);
|
tft.setCursor(0,96);
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case EXCESSIVE_FALL:
|
case EXCESSIVE_FALL:
|
||||||
tft.print("Error: Temperature dropped\nTip slipped out?");
|
tft.print(F("Error: Temperature dropped\nTip slipped out?"));
|
||||||
break;
|
break;
|
||||||
case NOT_HEATING:
|
case NOT_HEATING:
|
||||||
tft.print("Error: Not heating\nWeak power source or short");
|
tft.print(F("Error: Not heating\nWeak power source or short"));
|
||||||
break;
|
break;
|
||||||
case BATTERY_LOW:
|
case BATTERY_LOW:
|
||||||
tft.print("Error: Battery low\nReplace or charge");
|
tft.print(F("Error: Battery low\nReplace or charge"));
|
||||||
break;
|
break;
|
||||||
case USB_ONLY:
|
case USB_ONLY:
|
||||||
tft.print("Error: Power too low\nConnect power >5V");
|
tft.print(F("Error: Power too low\nConnect power >5V"));
|
||||||
break;
|
break;
|
||||||
case NO_TIP:
|
case NO_TIP:
|
||||||
tft.print("Error: No tip connected\nTip slipped out?");
|
tft.print(F("Error: No tip connected\nTip slipped out?"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.setTextColor(ST7735_YELLOW, ST7735_BLACK);
|
tft.setTextColor(YELLOW, BLACK);
|
||||||
tft.setCursor(10,112);
|
tft.setCursor(10,112);
|
||||||
tft.print(" OK ");
|
tft.print(F(" OK "));
|
||||||
|
|
||||||
tft.setTextColor(ST7735_RED, ST7735_BLACK);
|
tft.setTextColor(RED, BLACK);
|
||||||
tft.setCursor(36,26);
|
tft.setCursor(36,26);
|
||||||
tft.setTextSize(3);
|
tft.setTextSize(3);
|
||||||
tft.print(" ERR");
|
tft.print(F(" ERR "));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (error != error_old) {
|
if (error != error_old || force_redraw) {
|
||||||
tft.fillRect(0, 96, 160, 16, ST7735_BLACK);
|
tft.fillRect(0, 96, 160, 16, BLACK);
|
||||||
error_old = NO_ERROR;
|
error_old = NO_ERROR;
|
||||||
}
|
}
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.setCursor(15,112);
|
tft.setCursor(15,112);
|
||||||
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
|
tft.setTextColor(WHITE, BLACK);
|
||||||
tft.print(stored[0]);
|
tft.print(stored[0]);
|
||||||
tft.write(' ');
|
tft.write(' ');
|
||||||
tft.print(stored[1]);
|
tft.print(stored[1]);
|
||||||
tft.write(' ');
|
tft.write(' ');
|
||||||
tft.print(stored[2]);
|
tft.print(stored[2]);
|
||||||
|
|
||||||
if (set_t_old != set_t || old_stby != (stby || stby_layoff)) {
|
if (set_t_old != set_t || old_stby != (stby || stby_layoff) || force_redraw) {
|
||||||
tft.setCursor(36,26);
|
tft.setCursor(36,26);
|
||||||
tft.setTextSize(3);
|
tft.setTextSize(3);
|
||||||
if (stby || stby_layoff) {
|
if (stby || stby_layoff) {
|
||||||
old_stby = true;
|
old_stby = true;
|
||||||
tft.setTextColor(ST7735_YELLOW, ST7735_BLACK);
|
tft.setTextColor(YELLOW, BLACK);
|
||||||
tft.print("STBY");
|
tft.print(F("STBY "));
|
||||||
} else {
|
} else {
|
||||||
old_stby = false;
|
old_stby = false;
|
||||||
set_t_old = set_t;
|
set_t_old = set_t;
|
||||||
tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
|
tft.setTextColor(WHITE, BLACK);
|
||||||
tft.write(' ');
|
tft.write(' ');
|
||||||
tft.print(set_t);
|
tft.print(set_t);
|
||||||
tft.fillTriangle(149, 50, 159, 50, 154, 38, (set_t < TEMP_MAX) ? ST7735_WHITE : ST7735_GRAY);
|
tft.write(247);
|
||||||
tft.fillTriangle(149, 77, 159, 77, 154, 90, (set_t > TEMP_MIN) ? ST7735_WHITE : ST7735_GRAY);
|
tft.write('C');
|
||||||
|
tft.fillTriangle(149, 50, 159, 50, 154, 38, (set_t < TEMP_MAX) ? WHITE : GRAY);
|
||||||
|
tft.fillTriangle(149, 77, 159, 77, 154, 90, (set_t > TEMP_MIN) ? WHITE : GRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!off) {
|
if (!off) {
|
||||||
@@ -581,7 +670,7 @@ void display(void) {
|
|||||||
} else {
|
} else {
|
||||||
tout = min(max(0,(last_temperature_drop + STANDBY_TIMEOUT - (millis())/1000)), STANDBY_TIMEOUT);
|
tout = min(max(0,(last_temperature_drop + STANDBY_TIMEOUT - (millis())/1000)), STANDBY_TIMEOUT);
|
||||||
}
|
}
|
||||||
tft.setTextColor(stby?ST7735_RED:ST7735_YELLOW, ST7735_BLACK);
|
tft.setTextColor(stby?RED:YELLOW, BLACK);
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.setCursor(46,78);
|
tft.setCursor(46,78);
|
||||||
if (tout < 600) tft.write('0');
|
if (tout < 600) tft.write('0');
|
||||||
@@ -592,33 +681,35 @@ void display(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (temperature != 999) {
|
} else if (temperature != 999) {
|
||||||
tft.fillRect(46, 78, 60, 20, ST7735_BLACK);
|
tft.fillRect(46, 78, 60, 20, BLACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cur_t_old != temperature) {
|
if (cur_t_old != temperature || force_redraw) {
|
||||||
tft.setCursor(36,52);
|
tft.setCursor(36,52);
|
||||||
tft.setTextSize(3);
|
tft.setTextSize(3);
|
||||||
if (temperature == 999) {
|
if (temperature == 999) {
|
||||||
tft.setTextColor(ST7735_RED, ST7735_BLACK);
|
tft.setTextColor(RED, BLACK);
|
||||||
tft.print(" ERR");
|
tft.print(F(" ERR "));
|
||||||
tft.setCursor(44,76);
|
tft.setCursor(44,76);
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.print("NO TIP");
|
tft.print(F("NO TIP"));
|
||||||
} else {
|
} else {
|
||||||
if (cur_t_old == 999) {
|
if (cur_t_old == 999) {
|
||||||
tft.fillRect(44,76,72,16,ST7735_BLACK);
|
tft.fillRect(44,76,72,16,BLACK);
|
||||||
}
|
}
|
||||||
tft.setTextColor(off ? temperature < TEMP_COLD ? ST7735_CYAN : ST7735_RED : tft.Color565(min(10,abs(temperature-target_t))*25, 250 - min(10,max(0,(abs(temperature-target_t)-10)))*25, 0), ST7735_BLACK);
|
tft.setTextColor(off ? temperature < TEMP_COLD ? CYAN : RED : tft.Color565(min(10,abs(temperature-target_t))*25, 250 - min(10,max(0,(abs(temperature-target_t)-10)))*25, 0), BLACK);
|
||||||
if (temperature < TEMP_COLD) {
|
if (temperature < TEMP_COLD) {
|
||||||
tft.print("COLD");
|
tft.print(F("COLD "));
|
||||||
} else {
|
} else {
|
||||||
tft.write(' ');
|
tft.write(' ');
|
||||||
if (temperature < 100) tft.write(' ');
|
if (temperature < 100) tft.write(' ');
|
||||||
tft.print(temperature);
|
tft.print(temperature);
|
||||||
|
tft.write(247);
|
||||||
|
tft.write('C');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (temperature < cur_t_old)
|
if (temperature < cur_t_old)
|
||||||
tft.fillRect(max(0, (temperature - TEMP_COLD)/2.4), 0, 160-max(0, (temperature - TEMP_COLD)/2.4), BAR_HEIGHT, ST7735_BLACK);
|
tft.fillRect(max(0, (temperature - TEMP_COLD)/2.4), 0, 160-max(0, (temperature - TEMP_COLD)/2.4), BAR_HEIGHT, BLACK);
|
||||||
else if (cur_t != 999) {
|
else if (cur_t != 999) {
|
||||||
for (int16_t i = max(0, (cur_t_old - TEMP_COLD)/2.4); i < max(0, (temperature - TEMP_COLD)/2.4); i++) {
|
for (int16_t i = max(0, (cur_t_old - TEMP_COLD)/2.4); i < max(0, (temperature - TEMP_COLD)/2.4); i++) {
|
||||||
tft.drawFastVLine(i, 0, BAR_HEIGHT, tft.Color565(min(255, max(0, i*5)), min(255, max(0, 450-i*2.5)), 0));
|
tft.drawFastVLine(i, 0, BAR_HEIGHT, tft.Color565(min(255, max(0, i*5)), min(255, max(0, 450-i*2.5)), 0));
|
||||||
@@ -627,7 +718,7 @@ void display(void) {
|
|||||||
cur_t_old = temperature;
|
cur_t_old = temperature;
|
||||||
}
|
}
|
||||||
if (v_c3 > 1.0) {
|
if (v_c3 > 1.0) {
|
||||||
tft.setTextColor(ST7735_YELLOW, ST7735_BLACK);
|
tft.setTextColor(YELLOW, BLACK);
|
||||||
tft.setCursor(122,5);
|
tft.setCursor(122,5);
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
int power = min(15,v)*min(15,v)/4.8*pwm/255;
|
int power = min(15,v)*min(15,v)/4.8*pwm/255;
|
||||||
@@ -640,22 +731,23 @@ void display(void) {
|
|||||||
} else if (v_c2 < 1.0) {
|
} else if (v_c2 < 1.0) {
|
||||||
power_source = POWER_CORD;
|
power_source = POWER_CORD;
|
||||||
} else {
|
} else {
|
||||||
power_source = POWER_LIPO;
|
power_source = POWER_LIPO; //Set charging later to not redraw if charging mode toggles
|
||||||
}
|
}
|
||||||
if (power_source != power_source_old) {
|
if (power_source != power_source_old || force_redraw) {
|
||||||
tft.fillRect(0, 5, 128, 20, ST7735_BLACK);
|
tft.fillRect(0, 5, 128, 20, BLACK);
|
||||||
tft.fillRect(11, 25, 21, 20, ST7735_BLACK);
|
tft.fillRect(11, 25, 21, 20, BLACK);
|
||||||
switch (power_source) {
|
switch (power_source) {
|
||||||
|
case POWER_CHARGING:
|
||||||
case POWER_LIPO:
|
case POWER_LIPO:
|
||||||
for (uint8_t i = 0; i < 3; i++) {
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
tft.fillRect(11, 5+i*14, 20, 12, ST7735_WHITE);
|
tft.drawRect(11, 5+i*14, 20, 12, WHITE);
|
||||||
tft.fillRect(12, 6+i*14, 18, 10, ST7735_BLACK);
|
//tft.fillRect(12, 6+i*14, 18, 10, BLACK);
|
||||||
tft.drawFastVLine(31,8+i*14,6,ST7735_WHITE);
|
tft.drawFastVLine(31,8+i*14,6,WHITE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POWER_USB:
|
case POWER_USB:
|
||||||
tft.setTextSize(1);
|
tft.setTextSize(1);
|
||||||
tft.setTextColor(ST7735_RED, ST7735_BLACK);
|
tft.setTextColor(RED, BLACK);
|
||||||
tft.setCursor(0,5);
|
tft.setCursor(0,5);
|
||||||
tft.print("USB power only\nConnect power supply.");
|
tft.print("USB power only\nConnect power supply.");
|
||||||
if (!off) setError(USB_ONLY);
|
if (!off) setError(USB_ONLY);
|
||||||
@@ -666,23 +758,30 @@ void display(void) {
|
|||||||
if (power_source == POWER_CORD) {
|
if (power_source == POWER_CORD) {
|
||||||
/*if (v > v_c3) {
|
/*if (v > v_c3) {
|
||||||
tft.setTextSize(2);
|
tft.setTextSize(2);
|
||||||
tft.setTextColor(ST7735_GREEN, ST7735_BLACK);
|
tft.setTextColor(GREEN, BLACK);
|
||||||
tft.setCursor(0,5);
|
tft.setCursor(0,5);
|
||||||
tft.print(v);
|
tft.print(v);
|
||||||
tft.print("V ");
|
tft.print("V ");
|
||||||
} else {*/
|
} else {*/
|
||||||
tft.drawBitmap(0, 5, power_cord, 24, 9, tft.Color565(max(0, min(255, (14.5-v)*112)), max(0, min(255, (v-11)*112)), 0));
|
tft.drawBitmap(0, 5, power_cord, 24, 9, tft.Color565(max(0, min(255, (14.5-v)*112)), max(0, min(255, (v-11)*112)), 0));
|
||||||
//}
|
//}
|
||||||
} else if (power_source == POWER_LIPO) {
|
} else if (power_source == POWER_LIPO || power_source == POWER_CHARGING) {
|
||||||
float volt[] = {v_c1, v_c2-v_c1, v_c3-v_c2};
|
float volt[] = {v_c1, v_c2-v_c1, v_c3-v_c2};
|
||||||
|
uint8_t volt_disp[] = {max(1,min(16,(volt[0]-3.0)*14.2)), max(1,min(16,(volt[1]-3.0)*14.2)), max(1,min(16,(volt[2]-3.0)*14.2))};
|
||||||
|
if (power_source == POWER_CHARGING) {
|
||||||
|
uint8_t p = min(16, (millis() / 100) % 20);
|
||||||
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
|
volt_disp[i] = max(0, min(volt_disp[i], p));
|
||||||
|
}
|
||||||
|
}
|
||||||
for (uint8_t i = 0; i < 3; i++) {
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
if (volt[i] < 3.20) {
|
if (volt[i] < 3.20) {
|
||||||
setError(BATTERY_LOW);
|
setError(BATTERY_LOW);
|
||||||
tft.fillRect(13, 7+14*i, max(1,min(16,(volt[i]-3.0)*14.2)), 8, blink?ST7735_RED:ST7735_BLACK);
|
tft.fillRect(13, 7+14*i, volt_disp[i], 8, blink?RED:BLACK);
|
||||||
} else {
|
} else {
|
||||||
tft.fillRect(13, 7+14*i, max(1,min(16,(volt[i]-3.0)*14.2)), 8, tft.Color565(250-min(250, max(0, (volt[i]-3.4)*1000.0)), max(0,min(250, (volt[i]-3.15)*1000.0)), 0));
|
tft.fillRect(13, 7+14*i, volt_disp[i], 8, tft.Color565(250-min(250, max(0, (volt[i]-3.4)*1000.0)), max(0,min(250, (volt[i]-3.15)*1000.0)), 0));
|
||||||
}
|
}
|
||||||
tft.fillRect(13+max(1,min(16,(volt[i]-3.0)*14.2)), 7+14*i, 17-max(1,min(16,(volt[i]-3.0)*14.2)), 8, ST7735_BLACK);
|
tft.fillRect(13+volt_disp[i], 7+14*i, 17-volt_disp[i], 8, BLACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -715,6 +814,7 @@ void display(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
blink = !blink;
|
blink = !blink;
|
||||||
|
force_redraw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compute(void) {
|
void compute(void) {
|
||||||
@@ -724,7 +824,7 @@ void compute(void) {
|
|||||||
cur_t = getTemperature();
|
cur_t = getTemperature();
|
||||||
if (off) {
|
if (off) {
|
||||||
target_t = 0;
|
target_t = 0;
|
||||||
if (cur_t < TEMP_THRESHOLD) {
|
if (cur_t < adc_offset + TEMP_RISE) {
|
||||||
threshold_counter = TEMP_UNDER_THRESHOLD; //reset counter
|
threshold_counter = TEMP_UNDER_THRESHOLD; //reset counter
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -734,9 +834,9 @@ void compute(void) {
|
|||||||
target_t = set_t;
|
target_t = set_t;
|
||||||
}
|
}
|
||||||
if (cur_t-last_measured <= -30 && last_measured != 999) {
|
if (cur_t-last_measured <= -30 && last_measured != 999) {
|
||||||
setError(EXCESSIVE_FALL); //decrease of more than 30 degree is not realistic, short of ring and gnd is common.
|
setError(EXCESSIVE_FALL); //decrease of more than 30 degree is uncommon, short of ring and gnd is possible.
|
||||||
}
|
}
|
||||||
if (cur_t < TEMP_THRESHOLD) {
|
if (cur_t < adc_offset + TEMP_RISE) {
|
||||||
if (threshold_counter == 0) {
|
if (threshold_counter == 0) {
|
||||||
setError(NOT_HEATING); //temperature is not reached in desired time, short of sensor and gnd too?
|
setError(NOT_HEATING); //temperature is not reached in desired time, short of sensor and gnd too?
|
||||||
} else {
|
} else {
|
||||||
@@ -867,6 +967,9 @@ void loop(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delay(DELAY_MAIN_LOOP);
|
delay(DELAY_MAIN_LOOP);
|
||||||
|
if (power_down) {
|
||||||
|
powerDown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t serialReadTemp() {
|
uint16_t serialReadTemp() {
|
||||||
|
@@ -1,16 +1,17 @@
|
|||||||
#define VERSION "2.8"
|
#define VERSION "3.0"
|
||||||
#define EE_VERSION 27
|
#define EE_VERSION 27
|
||||||
#define EEPROM_CHECK 42
|
#define EEPROM_CHECK 42
|
||||||
|
|
||||||
#define BAR_HEIGHT 4 //Should be no bigger than 5
|
#define BAR_HEIGHT 4 //Should be no bigger than 5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TIPS ARE SPECIFIED FOR 450 DEGREE MAX
|
* TIPS ARE SPECIFIED FOR 450 DEGREE MAX
|
||||||
* If read 1023 on Analog in, the tip is turned off automatically
|
* If read 1023 on Analog in, the tip is turned off automatically
|
||||||
*/
|
*/
|
||||||
#define TEMP_MAX 450
|
#define TEMP_MAX 450
|
||||||
#define TEMP_MIN 100
|
#define TEMP_MIN 200
|
||||||
#define TEMP_STBY 150
|
#define TEMP_STBY 150
|
||||||
#define TEMP_COLD 70
|
#define TEMP_COLD (adc_offset + 15)
|
||||||
|
|
||||||
#define SHUTOFF_ACTIVE
|
#define SHUTOFF_ACTIVE
|
||||||
#define BOOTHEAT_ACTIVE
|
#define BOOTHEAT_ACTIVE
|
||||||
@@ -18,8 +19,8 @@
|
|||||||
#define STANDBY_TIMEOUT 240 // seconds without any significant temperature drop, if exceeded it will standby
|
#define STANDBY_TIMEOUT 240 // seconds without any significant temperature drop, if exceeded it will standby
|
||||||
#define OFF_TIMEOUT 900 // seconds in standby before turning off
|
#define OFF_TIMEOUT 900 // seconds in standby before turning off
|
||||||
|
|
||||||
#define TEMP_THRESHOLD 50 //threshold voltage, that must be exceeded in given time:
|
#define TEMP_RISE 30 //threshold temperature, that must be exceeded delta in given time:
|
||||||
#define TEMP_UNDER_THRESHOLD 150 //*10ms
|
#define TEMP_UNDER_THRESHOLD 80 // x (TIME_COMPUTE_IN_MS + DELAY_BEFORE_MEASURE)
|
||||||
#define THRES_MAX_DECEED 2 //max times the threshold temperature may be undercut by the current temperature
|
#define THRES_MAX_DECEED 2 //max times the threshold temperature may be undercut by the current temperature
|
||||||
|
|
||||||
//Temperature in degree to rise at least in given time
|
//Temperature in degree to rise at least in given time
|
||||||
@@ -41,7 +42,7 @@
|
|||||||
#define SW_T1 9
|
#define SW_T1 9
|
||||||
#define TFT_CS 10
|
#define TFT_CS 10
|
||||||
// MOSI 11
|
// MOSI 11
|
||||||
#define TFT_BL 12 //use MISO PULLUP as switch
|
#define POWER 12 //use MISO PULLUP as switch
|
||||||
// SCK 13
|
// SCK 13
|
||||||
#define TEMP_SENSE A0
|
#define TEMP_SENSE A0
|
||||||
#define STBY_NO A1
|
#define STBY_NO A1
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
#define BAT_C1 A4
|
#define BAT_C1 A4
|
||||||
#define TFT_DC A5
|
#define TFT_DC A5
|
||||||
#ifdef PIN_A7
|
#ifdef PIN_A7
|
||||||
|
#define CHARGEDET A6
|
||||||
#define VIN A7
|
#define VIN A7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -64,22 +66,29 @@
|
|||||||
#define DELAY_MAIN_LOOP 10
|
#define DELAY_MAIN_LOOP 10
|
||||||
#define PID_SAMPLE_TIME 10
|
#define PID_SAMPLE_TIME 10
|
||||||
|
|
||||||
#define ADC_TO_TEMP_GAIN 0.574503
|
#define ADC_TO_TEMP_GAIN 0.54 //default value if no calibration is performed
|
||||||
#define ADC_TO_TEMP_OFFSET 43.5
|
#define ADC_TO_TEMP_OFFSET 42.8 //default value if no calibration is performed
|
||||||
|
|
||||||
#define EEPROM_SET_T 8
|
#define EEPROM_SET_T 8
|
||||||
#define EEPROM_VERSION 10
|
#define EEPROM_VERSION 10
|
||||||
#define EEPROM_DISPLAY 11
|
#define EEPROM_DISPLAY 11
|
||||||
#define EEPROM_OPTIONS 12
|
#define EEPROM_OPTIONS 12
|
||||||
#define EEPROM_REVISION 13
|
#define EEPROM_REVISION 13
|
||||||
|
#define EEPROM_ADCTTG 14
|
||||||
|
#define EEPROM_ADCOFF (EEPROM_ADCTTG + sizeof(float))
|
||||||
|
|
||||||
#define EEPROM_INSTALL 42
|
#define EEPROM_INSTALL 42
|
||||||
|
#define REF_T1 275
|
||||||
|
#define REF_T2 410
|
||||||
|
#define DELTA_REF_T (REF_T2 - REF_T1)
|
||||||
|
|
||||||
|
|
||||||
typedef enum POWER_SOURCE {
|
typedef enum POWER_SOURCE {
|
||||||
NO_INIT,
|
NO_INIT,
|
||||||
POWER_USB,
|
POWER_USB,
|
||||||
POWER_CORD,
|
POWER_CORD,
|
||||||
POWER_LIPO
|
POWER_LIPO,
|
||||||
|
POWER_CHARGING
|
||||||
} p_source;
|
} p_source;
|
||||||
typedef enum ERROR_TYPE {
|
typedef enum ERROR_TYPE {
|
||||||
NO_ERROR,
|
NO_ERROR,
|
||||||
|
@@ -1,7 +1,31 @@
|
|||||||
# Maiskolben-Selfmade
|
# Maiskolben-Selfmade
|
||||||
|
|
||||||
## Selbstbau-Version des Maiskolben mit THT-Bauteilen zum ätzen
|
## Selbstbau-Version des Maiskolben mit THT-Bauteilen
|
||||||
|
|
||||||
Die in diesem Ordner abgelegten Dateien sind für den Nachbau des Maiskolben mit THT-Bauteilen für die Make 5/16.
|
Die in diesem Ordner abgelegten Dateien sind für den Nachbau des Maiskolben mit THT-Bauteilen für die Make 5/16.
|
||||||
|
|
||||||
Bauteile dazu sind bei [Reichelt](http://sndstrm.de/maiskolbenEK) und [eBay](http://sndstrm.de/18tft) bestellbar, die [Platine kann ebenfalls online bestellt werden](https://hannio.org/produkt/maiskolben-tht/).
|
Bauteile dazu sind bei [Reichelt](http://sndstrm.de/maiskolbenEK) und [eBay](http://sndstrm.de/18tft) bestellbar, die [Platine oder das ganze Set kann ebenfalls online bestellt werden](https://hannio.org/produkt/maiskolben-tht/).
|
||||||
|
|
||||||
|
|
||||||
|
## Aufbau
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Der MOSFET (IRF5305) kann unter das Display gebogen werden, dazu vorher etwas mit Klebeband isolieren, um Kontakt zu vermeiden. Den 2N7000 dafür weit genug versenken.
|
||||||
|
|
||||||
|
## Software
|
||||||
|
|
||||||
|
Für die Software bitte [die Update-Anleitung](https://github.com/ArduinoHannover/Maiskolben#software-update) zur Hilfe nehmen.
|
||||||
|
|
||||||
|
## Problembehandlung
|
||||||
|
|
||||||
|
### Display bleibt weiß
|
||||||
|
In diesem Fall arbeitet der Reset vom Display nicht sauber. Softwareseitig ist dafür `#define USE_TFT_RESET` vorgesehen. Um einen Reset vom Arduino zu triggern, muss allerdings die Reset-Leitung zwischen Arduino und Display getrennt werden.
|
||||||
|
|
||||||
|
Bei neueren Platinen gibt es dafür einen Jumper `R A` - dieser ist standardmäßig an R (Reset) angeschlossen. Diese Verbindung muss etwa mit einem Cutter aufgetrennt werden und dann eine Brücke an `A` gesetzt werden.
|
||||||
|
|
||||||
|
Ansonsten muss die Leiterbahn aufgekratzt werden oder brutal der Reset-Pin am Arduino weggeknipst werden. Dann muss die Leiterbahn zum Display mit A0 vom Arduino verbunden werden.
|
||||||
|
|
||||||
|
### Andere Probleme
|
||||||
|
|
||||||
|
[Fehlermeldungen](https://github.com/ArduinoHannover/Maiskolben#fehlermeldungen)
|
64
README.md
64
README.md
@@ -9,14 +9,14 @@ Die Spitzen selbst sind für 40€ im Handel erhältlich, die original Weller-St
|
|||||||
Für den einfachen Maker oder Hobbyist auf keinen Fall ein Produkt, das beim Onlineshopping ohne weitere Überlegungen in den Warenkorb wandert.
|
Für den einfachen Maker oder Hobbyist auf keinen Fall ein Produkt, das beim Onlineshopping ohne weitere Überlegungen in den Warenkorb wandert.
|
||||||
Der *Maiskolben* hingegen ist eine erschwingliche Lösung für lediglich 40€, mit der die Spitzen ebenso angesteuert werden können.
|
Der *Maiskolben* hingegen ist eine erschwingliche Lösung für lediglich 40€, mit der die Spitzen ebenso angesteuert werden können.
|
||||||
|
|
||||||
* Betrieb mit 12V Netzteil oder 3s LiPo (Modellbau-Akku)
|
* Betrieb mit 12V Netzteil (oder bis zu 24V mit Fertigplatine) oder 3s LiPo (Modellbau-Akku)
|
||||||
* Spannungsüberwachung (bei Akku für alle 3 Zellen und automatische Abschaltung bei zu geringer Ladung)
|
* Spannungsüberwachung (bei Akku für alle 3 Zellen und automatische Abschaltung bei zu geringer Ladung)
|
||||||
* Einfaches Wechseln von Spitzen mittels Klinken-Buchse/-Kabel
|
* Einfaches Wechseln von Spitzen mittels Klinken-Buchse/-Kabel
|
||||||
* 3 individuelle Temperatur-Presets
|
* 3 individuelle Temperatur-Presets
|
||||||
* Temperaturbereich von 100-400°C
|
* Temperaturbereich von 200-450°C
|
||||||
* Gut ablesbares Farbdisplay mit allen nötigen Informationen
|
* Gut ablesbares Farbdisplay mit allen nötigen Informationen
|
||||||
* Auto-Standby (entweder sensor- oder zeitgesteuert auf 150°C)
|
* Auto-Standby (entweder sensor- oder zeitgesteuert auf 150°C)
|
||||||
* Auto-Wakeup (entweder sensorgesteuert oder durch berühren von Lötschwamm, Messingwolle oder Lötstelle)
|
* Auto-Wakeup (entweder sensorgesteuert oder durch Berühren von Lötschwamm, Messingwolle oder Lötstelle)
|
||||||
* USB-Schnittstelle zur Überwachung oder Steuerung mittels PC
|
* USB-Schnittstelle zur Überwachung oder Steuerung mittels PC
|
||||||
* Potentialausgleich-/ESD-Buchse (über 1MΩ an GND)
|
* Potentialausgleich-/ESD-Buchse (über 1MΩ an GND)
|
||||||
* Optisches Feedback der Heizleistung durch LED
|
* Optisches Feedback der Heizleistung durch LED
|
||||||
@@ -27,8 +27,8 @@ Der *Maiskolben* hingegen ist eine erschwingliche Lösung für lediglich 40€,
|
|||||||
|
|
||||||
## Stromzufuhr
|
## Stromzufuhr
|
||||||
|
|
||||||
Die Stromzufuhr wird wahlweise über die Hohlstecker-Buchse (10-18V) *ODER* die JST-XH4 (11,1V) Buchse angeschlossen.
|
Die Stromzufuhr wird wahlweise über die Hohlstecker-Buchse (10-24V) *ODER* die JST-XH4 (11,1V) Buchse angeschlossen.
|
||||||
Niemals beide gleichzeitig anschließen!
|
Bei Versionen < 3.0 niemals beide gleichzeitig anschließen!
|
||||||
Der Lötkolben (Weller RT-XX, z.B. RT-1 für feine Lötarbeiten) wird über die Klinkenbuchse mit einer Verlängerung angesteckt.
|
Der Lötkolben (Weller RT-XX, z.B. RT-1 für feine Lötarbeiten) wird über die Klinkenbuchse mit einer Verlängerung angesteckt.
|
||||||
|
|
||||||
## Display
|
## Display
|
||||||
@@ -44,12 +44,20 @@ Am unteren Rand sind die drei Presets zu sehen.
|
|||||||
|
|
||||||
Nach dem Anstecken von Netzteil und Lötspitze kann die Station durch halten der Power-Taste (unten rechts) eingeschaltet werden.
|
Nach dem Anstecken von Netzteil und Lötspitze kann die Station durch halten der Power-Taste (unten rechts) eingeschaltet werden.
|
||||||
Basierend auf der letzten Einstellung wird die angezeigte Soll- (Power-Symbol grün) oder die Standby-Temperatur (Symbol gelb) angefahren.
|
Basierend auf der letzten Einstellung wird die angezeigte Soll- (Power-Symbol grün) oder die Standby-Temperatur (Symbol gelb) angefahren.
|
||||||
|
|
||||||
Mittels der Tasten rechts vom Display (Pfeile) lässt sich die Soll-Temperatur nach oben und unten korrigieren.
|
Mittels der Tasten rechts vom Display (Pfeile) lässt sich die Soll-Temperatur nach oben und unten korrigieren.
|
||||||
Sollte einer der Pfeile auf dem Display ausgegraut sein, so lässt sich über diese Temperatur hinaus keine weitere Änderung mehr vornehmen (100 ≥ T ≥ 400).
|
Sollte einer der Pfeile auf dem Display ausgegraut sein, so lässt sich über diese Temperatur hinaus keine weitere Änderung mehr vornehmen (200 ≥ T ≥ 450).
|
||||||
|
|
||||||
|
### Presets
|
||||||
|
|
||||||
Mittels der Preset-Tasten unter dem Bildschirm lassen sich voreingestellte Temperaturen als Soll-Temperatur setzen und die Station gleichzeitig aus dem Standby aufwecken.
|
Mittels der Preset-Tasten unter dem Bildschirm lassen sich voreingestellte Temperaturen als Soll-Temperatur setzen und die Station gleichzeitig aus dem Standby aufwecken.
|
||||||
Durch gedrückthalten einer der drei Tasten wird der dort gespeicherte Wert durch die aktuelle Soll-Temperatur überschrieben.
|
Durch Gedrückthalten einer der drei Tasten wird der dort gespeicherte Wert durch die aktuelle Soll-Temperatur überschrieben.
|
||||||
Wird die Power-Taste nur kurz gedrückt, so wird der Standby-Zustand umgeschaltet.
|
Wird die Power-Taste nur kurz gedrückt, so wird der Standby-Zustand umgeschaltet.
|
||||||
|
|
||||||
|
### Startmenü
|
||||||
|
|
||||||
|
Es gibt ein verstecktes Menü, in dem sich der automatische Standby abschalten und ein automatisches Hochfahren auf die zuletzt gewählte Temperatur bei Spannungsversorgung aktiviert werden können. Um in dieses Menü zu gelangen, muss beim Anlegen der Spannungsversorgung während des Blinkens der LED die Power-Taste betätigt werden.
|
||||||
|
|
||||||
## Fehlermeldungen
|
## Fehlermeldungen
|
||||||
|
|
||||||
#### USB power only/Connect power supply; Power too low/Connect power >5V
|
#### USB power only/Connect power supply; Power too low/Connect power >5V
|
||||||
@@ -79,15 +87,18 @@ Um die aktuellste Software auf den Maiskolbe zu übertragen, muss zunächst die
|
|||||||
In diesem Repository befinden sich zwei Programme, zum einen Maiskolben_LCD für die Hardware-Revision 1.0 und Maiskolben_TFT für Hardware-Revisionen ab 1.5.
|
In diesem Repository befinden sich zwei Programme, zum einen Maiskolben_LCD für die Hardware-Revision 1.0 und Maiskolben_TFT für Hardware-Revisionen ab 1.5.
|
||||||
Die .ino Datei kann mit Arduino geöffnet werden.
|
Die .ino Datei kann mit Arduino geöffnet werden.
|
||||||
Der Serielle-Port muss nach Herstellen einer Verbindung zwischen Maiskolben und PC unter _Werkzeuge_ > _Port_ ausgewählt werden.
|
Der Serielle-Port muss nach Herstellen einer Verbindung zwischen Maiskolben und PC unter _Werkzeuge_ > _Port_ ausgewählt werden.
|
||||||
Unter umständen muss zuvor noch der [Treiber](http://www.wch.cn/download/CH341SER_ZIP.html) für den USB-Seriell-Wandler installiert werden.
|
Unter umständen muss zuvor noch der [CH340 Treiber](http://www.wch.cn/download/CH341SER_ZIP.html) für den USB-Seriell-Wandler installiert werden.
|
||||||
Als _Board_ sollte _Arduino Nano_ mit _Prozessor_: _ATmega328_ ausgewählt werden.
|
Als _Board_ sollte _Arduino Nano_ mit _Prozessor: ATmega328_ ausgewählt werden.
|
||||||
Über _Sketch_ > _Hochladen_ bzw. den Pfeil nach Rechts in der oberen Leiste kann das Programm übertragen werden.
|
Über _Sketch_ > _Hochladen_ bzw. den Pfeil nach Rechts in der oberen Leiste kann das Programm übertragen werden.
|
||||||
|
|
||||||
|
### Bibliotheken
|
||||||
|
|
||||||
Unter Umständen müssen vorher folgende Libraries noch über _Sketch_ > _Bibliothek einbinden_ > _.ZIP Bibliothek hinzufügen..._ eingebunden werden:
|
Unter Umständen müssen vorher folgende Libraries noch über _Sketch_ > _Bibliothek einbinden_ > _.ZIP Bibliothek hinzufügen..._ eingebunden werden:
|
||||||
|
|
||||||
* [TimerOne](https://github.com/PaulStoffregen/TimerOne)
|
* [TimerOne](https://github.com/PaulStoffregen/TimerOne)
|
||||||
* [PID_v1](https://github.com/br3ttb/Arduino-PID-Library/)
|
* [PID_v1](https://github.com/br3ttb/Arduino-PID-Library/)
|
||||||
* [Adafruit_ST7735](https://github.com/adafruit/Adafruit-ST7735-Library)
|
* ~~[Adafruit_ST7735](https://github.com/adafruit/Adafruit-ST7735-Library)~~ (Software Version < 3.0)
|
||||||
|
* [TFT_ILI9163C](https://github.com/ArduinoHannover/TFT_ILI9163C)
|
||||||
* [Adafruit_GFX](https://github.com/adafruit/Adafruit-GFX-Library)
|
* [Adafruit_GFX](https://github.com/adafruit/Adafruit-GFX-Library)
|
||||||
|
|
||||||
Dafür muss von den entsprechenden Seiten zuvor die ZIP heruntergeladen werden.
|
Dafür muss von den entsprechenden Seiten zuvor die ZIP heruntergeladen werden.
|
||||||
@@ -95,7 +106,38 @@ Diese kann dann in dem Dateibrowser, der sich nach obiger Anleitung öffnet, sel
|
|||||||
|
|
||||||
### Changelog
|
### Changelog
|
||||||
|
|
||||||
* 2.0 Initiale Version für GitHub (TFT)
|
* 3.0
|
||||||
|
* Geänderte Display-Bibliothek (vgl. [Abschnitt Bibliotheken](#Bibliotheken))
|
||||||
|
* Mehr Strings im Flash statt im RAM
|
||||||
|
* Anpassungen um einen Maiskolben V3.2 im LiPo-Betrieb vollständig abzuschalten
|
||||||
|
* Limitierung der Minimaltemperatur auf 200°C
|
||||||
|
* `°C` wird mit bei Soll- und Ist-Temperatur angezeigt
|
||||||
|
* Interne Temperatur-Kalibrierung für jeden Maiskolben individuell (bisher nur für Kalibrierung ab Werk)
|
||||||
|
* 2.8
|
||||||
|
* Zeilenhöhe des Balkens ist nun variabel
|
||||||
|
* Temperaturen als `#define` gesetzt
|
||||||
|
* Temperaturberechnung wieder angepasst
|
||||||
|
* EEPROM-Fehler behoben
|
||||||
|
* 2.7
|
||||||
|
* TFT-Reset eingebaut
|
||||||
|
* 2.6
|
||||||
|
* Schreibfehler korrigiert
|
||||||
|
* Anpassungen an unterschiedliche Hardwareausführungen verbessert
|
||||||
|
* Beim Aufruf des Menüs kommt man nach schließen direkt zum Programm
|
||||||
|
* Autopower verfeinert
|
||||||
|
* 2.5
|
||||||
|
* Interne Testroutinen hinzugefügt
|
||||||
|
* Anpassung an Hardwarerevision ≥ 3.0
|
||||||
|
* Wattanzeige hinzugefügt
|
||||||
|
* 2.4
|
||||||
|
* Spannungsanzeige gegen Steckersymbol getauscht
|
||||||
|
* 2.3
|
||||||
|
* Anpassung an unterschiedliche Display-Treiber (BGR/RGB)
|
||||||
|
* Geänderte Temperaturmessung
|
||||||
|
* 2.1
|
||||||
|
* Bidirektionale Steuerung über serielle Schnittstelle
|
||||||
|
* 2.0
|
||||||
|
* Initiale Version für GitHub (TFT)
|
||||||
* Auto-Standby hinzugefügt
|
* Auto-Standby hinzugefügt
|
||||||
* Parameter angepasst
|
* Parameter angepasst
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user