aboutsummaryrefslogtreecommitdiffhomepage
path: root/source/Core/Threads/UI/logic/SolderingProfile.cpp
blob: 3746ae5e29764a6ff262d1c89d98cb5fc728bc3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

#include "OperatingModes.h"
#include "SolderingCommon.h"
#include "ui_drawing.hpp"

OperatingMode gui_solderingProfileMode(const ButtonState buttons, guiContext *cxt) {
  /*
   * * Soldering
   * -> Main loop where we draw temp, and animations
   * --> Long hold back button to exit
   * --> Double button to exit
   */

  uint16_t tipTemp = 0;

  // If this is during init, start at preheat
  if (cxt->scratch_state.state1 == 0) {
    cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePreheatTemp);
  }
  uint16_t phaseTicksPerDegree      = TICKS_SECOND / getSettingValue(SettingsOptions::ProfilePreheatSpeed);
  uint16_t profileCurrentTargetTemp = 0;

  switch (buttons) {
  case BUTTON_BOTH:
  case BUTTON_B_LONG:
    cxt->transitionMode = TransitionAnimation::Right;
    return OperatingMode::HomeScreen; // exit on back long hold
  case BUTTON_F_LONG:
  case BUTTON_F_SHORT:
  case BUTTON_B_SHORT:
  case BUTTON_NONE:
    // Not used yet
    break;
  default:
    break;
  }

  if (getSettingValue(SettingsOptions::TemperatureInF)) {
    tipTemp = TipThermoModel::getTipInF();
  } else {
    tipTemp = TipThermoModel::getTipInC();
  }
  // If time of entering is unknown; then we start now
  if (cxt->scratch_state.state3 == 0) {
    cxt->scratch_state.state3 = xTaskGetTickCount();
  }

  // if start temp is unknown (preheat), we're setting it now
  if (cxt->scratch_state.state6 == 0) {
    cxt->scratch_state.state6 = tipTemp;
    // if this is hotter than the preheat temperature, we should fail
    if (cxt->scratch_state.state6 >= 55) {
      warnUser(translatedString(Tr->TooHotToStartProfileWarning), buttons);
      return OperatingMode::HomeScreen;
    }
  }
  uint16_t phaseElapsedSeconds = (xTaskGetTickCount() - cxt->scratch_state.state3) / TICKS_SECOND;

  // have we finished this phase?
  if (phaseElapsedSeconds >= cxt->scratch_state.state2 && tipTemp == cxt->scratch_state.state5) {
    cxt->scratch_state.state1++;
    cxt->scratch_state.state6 = cxt->scratch_state.state5;
    cxt->scratch_state.state3 = xTaskGetTickCount();
    phaseElapsedSeconds       = 0;
    if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
      // done with all phases, lets go to cooldown
      cxt->scratch_state.state2 = 0;
      cxt->scratch_state.state5 = 0;
      phaseTicksPerDegree       = TICKS_SECOND / getSettingValue(SettingsOptions::ProfileCooldownSpeed);
    } else {
      // set up next phase
      switch (cxt->scratch_state.state1) {
      case 1:
        cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase1Duration);
        cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase1Temp);
        break;
      case 2:
        cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase2Duration);
        cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase2Temp);
        break;
      case 3:
        cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase3Duration);
        cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase3Temp);
        break;
      case 4:
        cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase4Duration);
        cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase4Temp);
        break;
      case 5:
        cxt->scratch_state.state2 = getSettingValue(SettingsOptions::ProfilePhase5Duration);
        cxt->scratch_state.state5 = getSettingValue(SettingsOptions::ProfilePhase5Temp);
        break;
      default:
        break;
      }
      if (cxt->scratch_state.state6 < cxt->scratch_state.state5) {
        phaseTicksPerDegree = (cxt->scratch_state.state2 * TICKS_SECOND) / (cxt->scratch_state.state5 - cxt->scratch_state.state6);
      } else {
        phaseTicksPerDegree = (cxt->scratch_state.state2 * TICKS_SECOND) / (cxt->scratch_state.state6 - cxt->scratch_state.state5);
      }
    }
  }

  // cooldown phase done?
  if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
    if (TipThermoModel::getTipInC() < 55) {
      // we're done, let the buzzer beep too
      setStatusLED(LED_STANDBY);
      if (cxt->scratch_state.state4 == 0) {
        setBuzzer(true);
        cxt->scratch_state.state4 = xTaskGetTickCount() + TICKS_SECOND / 3;
      }
    }
  }

  // determine current target temp
  if (cxt->scratch_state.state6 < cxt->scratch_state.state5) {
    if (profileCurrentTargetTemp < cxt->scratch_state.state5) {
      profileCurrentTargetTemp = cxt->scratch_state.state6 + ((xTaskGetTickCount() - cxt->viewEnterTime) / phaseTicksPerDegree);
    }
  } else {
    if (profileCurrentTargetTemp > cxt->scratch_state.state5) {
      profileCurrentTargetTemp = cxt->scratch_state.state6 - ((xTaskGetTickCount() - cxt->viewEnterTime) / phaseTicksPerDegree);
    }
  }

  // Draw in the screen details
  if (getSettingValue(SettingsOptions::DetailedSoldering)) {
    ui_draw_soldering_profile_advanced(tipTemp, profileCurrentTargetTemp, phaseElapsedSeconds, cxt->scratch_state.state1, cxt->scratch_state.state2);
    ui_draw_soldering_power_status(false);
  } else {
    ui_draw_soldering_basic_status(false);
  }

  // Update the setpoints for the temperature
  if (getSettingValue(SettingsOptions::TemperatureInF)) {
    currentTempTargetDegC = TipThermoModel::convertFtoC(profileCurrentTargetTemp);
  } else {
    currentTempTargetDegC = profileCurrentTargetTemp;
  }

  if (checkExitSoldering() || (cxt->scratch_state.state4 != 0 && xTaskGetTickCount() >= cxt->scratch_state.state4)) {
    setBuzzer(false);
    return OperatingMode::HomeScreen;
  }
  if (heaterThermalRunaway) {
    currentTempTargetDegC = 0; // heater control off
    heaterThermalRunaway  = false;
    return OperatingMode::ThermalRunaway;
  }

  // Update LED status
  if (cxt->scratch_state.state1 == 0) {
    setStatusLED(LED_HEATING);
  } else if (cxt->scratch_state.state1 > getSettingValue(SettingsOptions::ProfilePhases)) {
    setStatusLED(LED_COOLING_STILL_HOT);
  } else {
    setStatusLED(LED_HOT);
  }
  return OperatingMode::SolderingProfile;
}