;=============================================================================== ; Title: Soldering Station keys and calibration functions. ; ; Author: Rob Jansen, Copyright (c) 2021..2021, all rights reserved. ; ; Revisions ; --------- ; 2021-04-25 : Initial version. ; ; Description: Functions and procedure that handle the keys and the calibration ; of the soldering station. The calibration values are stored as ; ADC values in the EEPROM. ; ; Sources: - ; ; --------------------------------- Pins --------------------------------------- const bit KEY_PRESSED = LOW const bit KEY_RELEASED = HIGH ; Keys (or swithes). These are active LOW. alias key_variable is pin_A4 pin_A4_direction = input alias key_preset_1 is pin_A3 pin_A3_direction = input alias key_preset_2 is pin_A2 pin_A2_direction = input ; ================== Constant and variable declarations ======================= ; ========================= Functions and Procedures ========================== ; See if any key was pressed. If a key is pressed short, switch the operation mode ; and if possible get the temperature setting from the EEPROM. If a preset ; key is pressed long then the current temperature is stored as preset in EEPROM. procedure handle_keys() is var word new_temperature var byte new_operation_mode = operation_mode var byte store_counter if (key_preset_1 == KEY_PRESSED) then key_debounce() if (key_preset_1 == KEY_PRESSED) then ; We have the option to retrieve or to store a preset. store_counter = 0 while (key_preset_1 == KEY_PRESSED) & (store_counter < PRESET_STORE_TIME) loop ; Make sure that the watchdog will not bite while waiting for a long key press. kick_the_watchdog() key_debounce() store_counter = store_counter + 1 end loop if (store_counter == PRESET_STORE_TIME) then ; Pressed long so store this setting eeprom_write_word(EEPROM_ADDRESS_PRESET_1, set_temperature) else ; No store of setting, get preset value 1 from EEPROM. new_temperature = eeprom_read_word(EEPROM_ADDRESS_PRESET_1) if (new_temperature != EEPROM_NO_WORD_DATA) then ; Set new temperature and always show it on the display. set_temperature_changed = TRUE set_temperature = new_temperature end if end if key_was_released = FALSE new_operation_mode = SETTING_PRESET_1 end if ; Not preset 1, check preset 2. elsif (key_preset_2 == KEY_PRESSED) then key_debounce() if (key_preset_2 == KEY_PRESSED) then ; We have the option to retrieve or to store a preset. store_counter = 0 while (key_preset_2 == KEY_PRESSED) & (store_counter < PRESET_STORE_TIME) loop ; Make sure that the watchdog will not bite while waiting for a long key press. kick_the_watchdog() key_debounce() store_counter = store_counter + 1 end loop if (store_counter == PRESET_STORE_TIME) then ; Pressed long so store this setting eeprom_write_word(EEPROM_ADDRESS_PRESET_2, set_temperature) else ; No store of setting, get preset value 1 from EEPROM. new_temperature = eeprom_read_word(EEPROM_ADDRESS_PRESET_2) if (new_temperature != EEPROM_NO_WORD_DATA) then ; Set new temperature and always show it on the display. set_temperature_changed = TRUE set_temperature = new_temperature end if end if key_was_released = FALSE new_operation_mode = SETTING_PRESET_2 end if ; Not preset 2, check the variable key. This key also clears any ; sensor or heater errors. elsif (key_variable == KEY_PRESSED) then key_debounce() if (key_variable == KEY_PRESSED) then new_operation_mode = SETTING_VARIABLE set_temperature_changed = TRUE ; Also clear errors if present. error_reset() end if end if ; If this is a new operation mode, store it as last setting. if new_operation_mode != operation_mode then operation_mode = new_operation_mode eeprom_write_byte(EEPROM_ADDRESS_OPERATION_MODE, operation_mode) end if end procedure ; Handle the low calibration step. This step should be called when the ; soldering iron is at room temperature. All this step does is to get ; the current actual temperature, displays it and copies it to the ; set temperature. This procedure ends when the variable key is pressed. ; Note that we use ADC values here and not actual temperatures since ; we cannot yet calculate them. procedure handle_low_calibration_step(word in out adc_calibration) is ; We need this temporary variable. Seems like a compiler bug when we ; would only use adc_calibration. var word new_calibration = adc_calibration while (key_variable == KEY_RELEASED) loop _usec_delay(100_000) ; This is the repetition time of this loop. if adc_data_available() then new_calibration = adc_get_value() ; For stabilization average the ADC value. adc_calibration = get_average_actual_temperature(new_calibration) display_temperature(adc_calibration) else ; No data, start a new conversion. if adc_ready() then adc_start_conversion() end if end if end loop end procedure ; Handle the high calibration steps and adjust the temperature accordingly. This ; procedure ends when the variable key is pressed. Note that we use ADC ; values here and not actual temperatures since we cannot yet calculate them. procedure handle_high_calibration_step(word in out adc_calibration) is ; We need this temporary variable. Seems like a compiler bug when we ; would only use adc_calibration. var word new_calibration var word adc_actual var word adc_average new_calibration = adc_calibration ; Preset 1 key will lower the temperature while preset 2 key will increase ; the temperature. Pressing the variable key will exit this loop. while (key_variable == KEY_RELEASED) loop _usec_delay(100_000) ; This is the repetition time of this loop. if (key_preset_1 == KEY_PRESSED) then ; Lower the temperature. if new_calibration > ADC_CAL_MIN then new_calibration = new_calibration - 1 end if elsif (key_preset_2 == KEY_PRESSED) then ; Increase the temperature. if new_calibration < ADC_CAL_MAX then new_calibration = new_calibration + 1 end if end if ; Control the current set temperature but do that after we received ; a new ADC value. In this way we are sure the both the target and ; current are set. Also display the ADC value so that the user knows ; something is happening. if adc_data_available() then ; We are reading the sensor value. adc_actual = adc_get_value() ; We need to show the actual temperature on the display in ADC value. ; For stabilization average the ADC value. adc_average = get_average_actual_temperature(adc_actual) display_temperature(adc_average) ; Set the heater using the ADC calibration values. set_heater_current_temperature(adc_actual) set_heater_target_temperature(new_calibration) else ; No data, start a new conversion. if adc_ready() then adc_start_conversion() end if end if end loop ; Before we leave, get the last calibration value. adc_calibration = new_calibration end procedure ; Handle the calibration of the solder station. This is done when both preset ; keys are pressed at the same time. We skip the key check if the parameter ; 'force_calibration' it TRUE. The calibration values are stored as ADC ; values in the EEPROM not temperatures. procedure handle_calibration(bit in force_calibration) is var word adc_calibration if ((key_preset_1 == KEY_PRESSED) & (key_preset_2 == KEY_PRESSED)) | force_calibration then key_debounce() if ((key_preset_1 == KEY_PRESSED) & (key_preset_2 == KEY_PRESSED)) | force_calibration then ; With the decimal points on we show that we are in a different mode. ; We then show ADC value from the sensor, not temperatures. adc_select_sensor_input() ; Start from minimum ADC values, store for now in the temp adc_calibration = ADC_CAL_MIN display_decimal_points_on() heater_disable() ; We are now in the calibration mode. display_calibrate_message() ; Wait for both keys to be released. Skip when calibration is forced. while ((key_preset_1 == KEY_PRESSED) | (key_preset_2 == KEY_PRESSED)) & !force_calibration loop key_debounce() end loop wait_some_time() ; Start with the low temperature. Show that message. display_calibrate_message_low() wait_some_time() handle_low_calibration_step(adc_calibration) ; Store the calibration low value. Note this is an ADC value! eeprom_write_word(EEPROM_ADDRESS_CALIBRATION_LOW, adc_calibration) ; Now the high temperature. display_calibrate_message_high() ; Now we should heat up to 300 degrees. heater_enable() ; For this the heater needs to be on. wait_some_time() handle_high_calibration_step(adc_calibration) ; Store the calibration high value. Note this is an ADC value! eeprom_write_word(EEPROM_ADDRESS_CALIBRATION_HIGH, adc_calibration) display_decimal_points_off() heater_disable() end if end if end procedure