diff --git a/reflow_plate_fw/include/ILI9341_STM32.h b/reflow_plate_fw/include/ILI9341_STM32.h index 77c8225..7729c3a 100644 --- a/reflow_plate_fw/include/ILI9341_STM32.h +++ b/reflow_plate_fw/include/ILI9341_STM32.h @@ -90,8 +90,8 @@ // Nucleo-F767ZI has a ~216MHZ CPU clock, this is divided by 4, 8, 16 etc -#define SPI_FREQUENCY 27000000 // 27MHz SPI clock -//#define SPI_FREQUENCY 55000000 // 55MHz is over-clocking ILI9341 but seems to work reliably! +//#define SPI_FREQUENCY 27000000 // 27MHz SPI clock +#define SPI_FREQUENCY 55000000 // 55MHz is over-clocking ILI9341 but seems to work reliably! #define SPI_READ_FREQUENCY 15000000 // Reads need a slower SPI clock, probably ends up at 13.75MHz (CPU clock/16) diff --git a/reflow_plate_fw/platformio.ini b/reflow_plate_fw/platformio.ini index 555b5bf..23170b5 100644 --- a/reflow_plate_fw/platformio.ini +++ b/reflow_plate_fw/platformio.ini @@ -14,6 +14,7 @@ board = blackpill_f411ce framework = arduino upload_protocol = stlink debug_tool = stlink +monitor_speed = 115200 lib_deps = yuriisalimov/MAX6675_Thermocouple@^2.0.2 bodmer/TFT_eSPI@^2.3.70 @@ -22,5 +23,6 @@ build_flags = -D USER_SETUP_LOADED=1 -include include/ILI9341_STM32.h -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC + -D USBCON -D PIO_FRAMEWORK_ARDUINO_USB_FULLSPEED_FULLMODE diff --git a/reflow_plate_fw/src/lcd.cpp b/reflow_plate_fw/src/lcd.cpp index b2b9ee4..4215764 100644 --- a/reflow_plate_fw/src/lcd.cpp +++ b/reflow_plate_fw/src/lcd.cpp @@ -1,29 +1,166 @@ #include "lcd.h" +#include "thermo.h" -#include // Include the graphics library +#include // Include the graphics library -TFT_eSPI tft = TFT_eSPI(); // Create object "tft" -TFT_eSprite touch_spr = TFT_eSprite(&tft); +TFT_eSPI tft = TFT_eSPI(); // Create object "tft" +TFT_eSprite looptime_spr = TFT_eSprite(&tft); -#define WIDTH 240 -#define HEIGHT 60 +//chart data +TFT_eSprite chartbg_spr = TFT_eSprite(&tft); +TFT_eSprite chartActual_spr = TFT_eSprite(&tft); +TFT_eSprite chartTarget_spr = TFT_eSprite(&tft); + +//buttons +String buttonNames[] = {"START", "STOP", "SET"}; +char buttonlabels[BUTTONS_N][10] = {"", "", ""}; +TFT_eSPI_Button key[BUTTONS_N]; + +uint16_t calData[5] = {549, 3080, 343, 3159, 4}; + +void prep_chart(void) +{ + chartbg_spr.createSprite(CHART_W, CHART_H); + //draw X-axis + chartbg_spr.drawLine(0, CHART_H - CHART_X_AXIS_OFFSET, CHART_W, CHART_H - CHART_X_AXIS_OFFSET, CHART_LINE_COLOR); + //draw Y-axis + chartbg_spr.drawLine(CHART_Y_AXIS_OFFSET, 0, CHART_Y_AXIS_OFFSET, CHART_H, CHART_LINE_COLOR); + + //draw Y axis labels + uint16_t tickIndex = (CHART_H - CHART_X_AXIS_OFFSET) / CHART_Y_TICKS; + chartbg_spr.setTextColor(CHART_TEXT_COLOR); + for (int i = 0; i < CHART_Y_TICKS + 1; i++) + { + //tick value + uint16_t y_tick_step = CHART_TEMP_MAX - ((CHART_TEMP_MAX - CHART_TEMP_MIN) / CHART_Y_TICKS * i) - CHART_TEMP_MIN; + chartbg_spr.drawLine(CHART_Y_AXIS_OFFSET - 2, tickIndex * (i + 1), CHART_Y_AXIS_OFFSET + 2, tickIndex * (i + 1), CHART_LINE_COLOR); + chartbg_spr.setTextDatum(BR_DATUM); + chartbg_spr.drawString(String(y_tick_step), CHART_Y_AXIS_OFFSET - 3, tickIndex * (i + 1), CHART_FONT); + } + + //draw X axis labels + tickIndex = (CHART_W - CHART_Y_AXIS_OFFSET) / CHART_X_TICKS; + for (int i = 0; i < CHART_X_TICKS + 1; i++) + { + uint16_t x_tick_step = (CHART_TIME_MAX / CHART_Y_TICKS * i); + chartbg_spr.drawLine(tickIndex * i + CHART_Y_AXIS_OFFSET, CHART_H - CHART_X_AXIS_OFFSET + 2, tickIndex * i + CHART_Y_AXIS_OFFSET, CHART_H - CHART_X_AXIS_OFFSET - 2, CHART_LINE_COLOR); + chartbg_spr.setTextDatum(TR_DATUM); + chartbg_spr.drawString(String(x_tick_step),tickIndex * i + CHART_Y_AXIS_OFFSET,CHART_H - CHART_X_AXIS_OFFSET + 3,CHART_FONT); + } + + chartbg_spr.pushSprite(CHART_X, CHART_Y); +} + +void prep_sprite(void) +{ + looptime_spr.createSprite(20, tft.fontHeight(1) + 1); +} + +void prep_buttons(void) +{ + const uint32_t button_width = tft.width() / BUTTONS_N; + + for (int i = 0; i < BUTTONS_N; i++) + { + key[i].initButtonUL(&tft, + (button_width * i) + BUTTON_PADDING, + tft.height() - BUTTON_H, + button_width - (BUTTON_PADDING * 2), + BUTTON_H, + TFT_BLUE, // Outline + TFT_SKYBLUE, // Fill + TFT_BLACK, // Text + buttonlabels[i], // 10 Byte Label + KEY_TEXTSIZE); + + key[i].setLabelDatum(0, 2, MC_DATUM); + key[i].drawButton(false, buttonNames[i]); + } +} + +void touch_calibrate() +{ + uint16_t calData[5]; + uint8_t calDataOK = 0; + + // Calibrate + tft.fillScreen(TFT_BLACK); + tft.setCursor(20, 0); + tft.setTextFont(2); + tft.setTextSize(1); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + + tft.println("Touch corners as indicated"); + + tft.setTextFont(1); + tft.println(); + + tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15); + + // Use this calibration code in setup():"); + // uint16_t calData[5] = { 0,0,0,0,0 }; + // tft.setTouch(calData); + + //String calDatastr = ""; + for (uint8_t i = 0; i < 5; i++) + { + tft.printf("%d,", calData[i]); + } + + while (1) + ; +} + +void updateGUIButtons(void) +{ + uint16_t t_x = 0, t_y = 0; // To store the touch coordinates + bool pressed = tft.getTouch(&t_x, &t_y); + + for (uint8_t b = 0; b < BUTTONS_N; b++) + { + if (pressed && key[b].contains(t_x, t_y)) + { + key[b].press(true); // tell the button it is pressed + } + else + { + key[b].press(false); // tell the button it is NOT pressed + } + } + + // Check if any key has changed state + for (uint8_t b = 0; b < BUTTONS_N; b++) + { + // If button was just pressed, redraw inverted button + if (key[b].justPressed()) + { + key[b].drawButton(true, buttonNames[b]); + } + + // If button was just released, redraw normal color button + if (key[b].justReleased()) + { + key[b].drawButton(false, buttonNames[b]); + } + } +} // ------------------------------------------------------------------------- // Setup // ------------------------------------------------------------------------- -void prep_sprite(void) +void initLCD(void) { - touch_spr.createSprite(WIDTH,HEIGHT); -} - -void initLCD(void) { tft.init(); tft.setRotation(2); tft.setTextFont(2); tft.fillScreen(TFT_BLACK); tft.invertDisplay(false); + //touch_calibrate(); + tft.setTouch(calData); prep_sprite(); + prep_buttons(); + prep_chart(); } // ------------------------------------------------------------------------- @@ -31,16 +168,10 @@ void initLCD(void) { // ------------------------------------------------------------------------- void handleLCD() { - touch_spr.fillSprite(TFT_BLACK); - uint16_t t_x = 0, t_y = 0; - touch_spr.setTextColor(TFT_WHITE); - touch_spr.setTextDatum(MC_DATUM); - bool pressed = tft.getTouch(&t_x, &t_y); - String touchxy = "touch x="; - touchxy += t_x; - touchxy += ",touch y="; - touchxy += t_y; - touch_spr.drawString(touchxy, WIDTH / 2, HEIGHT / 4, 2); - touch_spr.drawNumber(getLooptime(), WIDTH / 2, (HEIGHT / 4)*2, 2); - touch_spr.pushSprite(1,1); -} \ No newline at end of file + looptime_spr.fillSprite(TFT_BLACK); + looptime_spr.setTextDatum(MC_DATUM); + looptime_spr.drawNumber(getLooptime(), looptime_spr.width() / 2, looptime_spr.height() / 2, 1); + looptime_spr.pushSprite(1, 1); + updateGUIButtons(); + //tft.drawString(showValue("Temp", getTemperature(), "grC"), 10, 10); +} \ No newline at end of file diff --git a/reflow_plate_fw/src/lcd.h b/reflow_plate_fw/src/lcd.h index da8bdc2..d3edc3f 100644 --- a/reflow_plate_fw/src/lcd.h +++ b/reflow_plate_fw/src/lcd.h @@ -3,6 +3,31 @@ #include "status.h" +// #define WIDTH 240 +// #define HEIGHT 60 +#define BUTTON_H 60 +#define BUTTON_W 240 +#define BUTTONS_N 3 +#define BUTTON_PADDING 2 +#define BUTTON_RADIUS 8 +#define BUTTON_COLOR TFT_BLUE +#define KEY_TEXTSIZE 1 // Font size multiplier + +#define CHART_X 0 +#define CHART_Y 30 +#define CHART_W 240 +#define CHART_H 200 +#define CHART_FONT 1 +#define CHART_Y_AXIS_OFFSET 24 +#define CHART_X_AXIS_OFFSET 10 +#define CHART_TIME_MAX 360 //time scale in seconds +#define CHART_TEMP_MIN 20 //offset in degrees +#define CHART_TEMP_MAX 360 //degrees +#define CHART_Y_TICKS 10 +#define CHART_X_TICKS 10 +#define CHART_LINE_COLOR TFT_WHITE +#define CHART_TEXT_COLOR TFT_RED + void initLCD(void); diff --git a/reflow_plate_fw/src/main.cpp b/reflow_plate_fw/src/main.cpp index e61e1ab..8a20718 100644 --- a/reflow_plate_fw/src/main.cpp +++ b/reflow_plate_fw/src/main.cpp @@ -10,11 +10,12 @@ void setup() { // put your setup code here, to run once: + initStatus(); initLCD(); initThermo(); initButton(); initHeater(); - initStatus(); + } diff --git a/reflow_plate_fw/src/status.cpp b/reflow_plate_fw/src/status.cpp index d9241a5..94706ba 100644 --- a/reflow_plate_fw/src/status.cpp +++ b/reflow_plate_fw/src/status.cpp @@ -10,6 +10,7 @@ uint32_t looptimelast = 0; void initStatus(void) { pinMode(LED_BUILTIN, OUTPUT); + Serial.begin(115200); } void handleStatus(void) diff --git a/reflow_plate_fw/src/thermo.cpp b/reflow_plate_fw/src/thermo.cpp index 7af83c7..7c80d13 100644 --- a/reflow_plate_fw/src/thermo.cpp +++ b/reflow_plate_fw/src/thermo.cpp @@ -1,12 +1,32 @@ #include "thermo.h" +Thermocouple *thermocouple = NULL; -void initThermo(void) +uint32_t thermo_lastTime = 0; + +double lastTemperature = 0; + +// the setup function runs once when you press reset or power the board +void initThermo() { - + Thermocouple *originThermocouple = new MAX6675_Thermocouple(THERM_CL, THERM_CS, THERM_SO); + thermocouple = new SmoothThermocouple(originThermocouple, SMOOTHING_FACTOR); } +// the loop function runs over and over again forever void handleThermo(void) { + // Reads temperature + uint32_t timeNow = millis(); + if (timeNow - thermo_lastTime > THERMO_INTERVAL) + { + lastTemperature = thermocouple->readCelsius(); + } -} \ No newline at end of file + //delay(100); // optionally, only to delay the output of information in the example. +} + +double getTemperature(void) +{ + return lastTemperature; +} diff --git a/reflow_plate_fw/src/thermo.h b/reflow_plate_fw/src/thermo.h index d285d1f..3e890c3 100644 --- a/reflow_plate_fw/src/thermo.h +++ b/reflow_plate_fw/src/thermo.h @@ -2,6 +2,13 @@ #include "Arduino.h" #include "board.h" +#include +#include +#include + +#define THERMO_INTERVAL 200 +#define SMOOTHING_FACTOR 5 void initThermo(void); -void handleThermo(void); \ No newline at end of file +void handleThermo(void); +double getTemperature(void);