diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..3357244 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.16.0) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(ESPIron-PTS200) diff --git a/ESPIron/CMakeLists.txt b/ESPIron/CMakeLists.txt new file mode 100644 index 0000000..370e94a --- /dev/null +++ b/ESPIron/CMakeLists.txt @@ -0,0 +1,6 @@ +# This file was automatically generated for projects +# without default 'CMakeLists.txt' file. + +FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/ESPIron/*.*) + +idf_component_register(SRCS ${app_sources}) diff --git a/ESPIron/config.h b/ESPIron/config.h index 2041dec..fc07866 100644 --- a/ESPIron/config.h +++ b/ESPIron/config.h @@ -14,14 +14,14 @@ #define SCREEN_OFFSET 2 // Pins -#define SENSOR_PIN 1 // tip temperature sense 烙铁头温感 -#define VIN_PIN 6 // input voltage sense 检测输入电压 -#define BUZZER_PIN 3 // buzzer 蜂鸣器 -#define BUTTON_ACTION GPIO_NUM_0 // middle push-button -#define BUTTON_INCR GPIO_NUM_2 // incrementer “+” push-button -#define BUTTON_DECR GPIO_NUM_4 // decrementer “-” push-button -#define HEATER_PIN GPIO_NUM_5 // heater MOSFET PWM control 加热器MOSFET PWM控制 -#define SH1107_RST_PIN 7 // display reset pin +#define TIP_ADC_SENSOR_PIN 1 // tip temperature sense 烙铁头温感 +#define VIN_PIN 6 // input voltage sense 检测输入电压 +#define BUZZER_PIN 3 // buzzer 蜂鸣器 +#define BUTTON_ACTION GPIO_NUM_0 // middle push-button +#define BUTTON_INCR GPIO_NUM_2 // incrementer “+” push-button +#define BUTTON_DECR GPIO_NUM_4 // decrementer “-” push-button +#define HEATER_PIN GPIO_NUM_5 // heater MOSFET PWM control 加热器MOSFET PWM控制 +#define SH1107_RST_PIN 7 // display reset pin // CH224K USB PD chip pins connection // https://components101.com/sites/default/files/component_datasheet/WCH_CH224K_ENG.pdf diff --git a/ESPIron/dusputed/adc_idf.cpp_ b/ESPIron/dusputed/adc_idf.cpp_ new file mode 100644 index 0000000..cf05efe --- /dev/null +++ b/ESPIron/dusputed/adc_idf.cpp_ @@ -0,0 +1,154 @@ +// *** ADCSensor_OneShot *** + +ADCSensor_OneShot::~ADCSensor_OneShot(){ + if (_cal_handle){ + _adc_calibration_deinit(); + _cal_handle = nullptr; + } + + if (_adc_handle){ + adc_oneshot_del_unit(_adc_handle); + _adc_handle = nullptr; + } +}; + +esp_err_t ADCSensor_OneShot::init(int gpio, bool cal){ + //SOC_GPIO_PIN_COUNT + + // get AD chan and unit + esp_err_t err = adc_oneshot_io_to_channel(gpio, &_unit, &_chan); + if (err != ESP_OK) { + log_e("gpio %u is not ADC pin!", gpio); + return err; + } + + adc_oneshot_unit_init_cfg_t cfg; + cfg.unit_id = _unit; + adc_unit_t a; + err = adc_oneshot_new_unit(&cfg, &_adc_handle); + if (err != ESP_OK) + return err; + + // use defaults + // https://github.com/espressif/arduino-esp32/blob/master/docs/en/api/adc.rst + adc_oneshot_chan_cfg_t config = { ADC_ATTEN_DB_12, ADC_BITWIDTH_DEFAULT }; + err = adc_oneshot_config_channel(_adc_handle, _chan, &config); + if (err != ESP_OK) + return err; + + if (cal){ + // set calibration + err = _adc_calibration_init(); + if (err == ESP_OK){ + _cal_enabled = true; + //ADC_LOGD(T_ADC, println, "ADC Init success"); + } else { + _cal_enabled = false; + //ADC_LOGD(T_ADC, println, "ADC Init was not complete"); + } + } + + return err; +} + + +esp_err_t ADCSensor_OneShot::_adc_calibration_init(){ + esp_err_t ret = ESP_FAIL; + bool _cal_enabled = false; + +#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED + if (!_cal_handle) { + //ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting"); + adc_cali_curve_fitting_config_t cali_config = { + .unit_id = _unit, + .chan = _chan, + .atten = ADC_ATTEN_DB_12, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + ret = adc_cali_create_scheme_curve_fitting(&cali_config, &_cal_handle); + if (ret == ESP_OK) { + _cal_enabled = true; + } + } else + ret = ESP_OK; +#endif + +#if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED + if (!_cal_handle) { + //ESP_LOGI(TAG, "calibration scheme version is %s", "Line Fitting"); + adc_cali_line_fitting_config_t cali_config = { + .unit_id = _unit, + .atten = ADC_ATTEN_DB_12, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + ret = adc_cali_create_scheme_line_fitting(&cali_config, &_cal_handle); + if (ret == ESP_OK) { + _cal_enabled = true; + } + } else + ret = ESP_OK; +#endif + + if (ret == ESP_OK) { + ADC_LOGD(T_ADC, println, "ADC Calibration enabled"); + } else if (ret == ESP_ERR_NOT_SUPPORTED || !_cal_enabled) { + ADC_LOGD(T_ADC, println, "eFuse not burnt, skip software calibration"); + } else { + ADC_LOGD(T_ADC, println, "Invalid arg or no memory"); + } + return ret; +} + +void ADCSensor_OneShot::_adc_calibration_deinit(){ +#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED + //ESP_LOGI(T_Sensor, "deregister %s calibration scheme", "Curve Fitting"); + adc_cali_delete_scheme_curve_fitting(_cal_handle); + +#elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED + //ESP_LOGI(T_Sensor, "deregister %s calibration scheme", "Line Fitting"); + adc_cali_delete_scheme_line_fitting(_cal_handle); +#endif +} + +int32_t ADCSensor_OneShot::read(){ +// https://docs.espressif.com/projects/esp-idf/en/v5.2.2/esp32s2/api-reference/peripherals/adc_calibration.html +// https://docs.espressif.com/projects/esp-idf/en/v5.2.2/esp32s2/api-reference/peripherals/adc_oneshot.html + esp_err_t ret; + ret = adc_oneshot_read(_adc_handle, _chan, &adc_raw); + if (ret != ESP_OK) + return -1; + + if(_cal_enabled){ + ret = adc_cali_raw_to_voltage(_cal_handle, adc_raw, &adc_voltage); + //ADC_LOGV(T_ADC, printf, "ADC%d Channel[%d] raw:%d Cali Voltage: %d mV, cv:%d\n", _unit, _chan, adc_raw, adc_voltage, _convertmv()); + if (ret == ESP_OK) + return adc_voltage; + } + + // otherwise return uncalibrated value + return _convertmv(); +} + +int32_t ADCSensor_OneShot::readraw(){ + esp_err_t ret; + ret = adc_oneshot_read(_adc_handle, _chan, &adc_raw); + if (ret != ESP_OK) + return -1; + + return adc_raw; +}; + +int32_t ADCSensor_OneShot::readmv(){ + esp_err_t ret; + ret = adc_oneshot_read(_adc_handle, _chan, &adc_raw); + if (ret != ESP_OK) + return -1; + return _convertmv(); +} + +int32_t ADCSensor_OneShot::_convertmv(){ + // for ADC_ATTEN_DB_12 Vref is 2500 mV on ESP32-S2 + // https://github.com/espressif/arduino-esp32/blob/master/docs/en/api/adc.rst + return adc_raw * 2500 / (1 << ADC_BITWIDTH_12); +} + diff --git a/ESPIron/dusputed/adc_idf.hpp b/ESPIron/dusputed/adc_idf.hpp new file mode 100644 index 0000000..1d0c7a5 --- /dev/null +++ b/ESPIron/dusputed/adc_idf.hpp @@ -0,0 +1,58 @@ +/** + * @brief Class provides an instance of ESP32 oneshot ADC sampler with calibration + * + */ +class ADCSensor_OneShot { + // do calibration + bool _cal_enabled; + + //static adc_unit_t _adc_units[SOC_ADC_PERIPH_NUM]; + // ADC Unit + adc_unit_t _unit; + // ADC channel to sample + adc_channel_t _chan; + static adc_oneshot_unit_handle_t _adc_handle[SOC_ADC_PERIPH_NUM]; + adc_cali_handle_t _cal_handle{nullptr}; + + esp_err_t _adc_calibration_init(); + void _adc_calibration_deinit(); + + int32_t _convertmv(); + +protected: + int adc_raw, adc_voltage; + +public: + ~ADCSensor_OneShot(); + + // initialize ADC + esp_err_t init(int gpio, bool cal = true); + + bool calibarationEnabled() const { return _cal_enabled; } + + /** + * @brief returns calibrated mV reading + * on read error returns -1 + * on calibration error returns readmv() + * + * @return int32_t + */ + int32_t read(); + + /** + * @brief returns raw adc reading + * on error returns -1 + * + * @return int32_t + */ + int32_t readraw(); + + /** + * @brief returns uncalibrated mV + * on error returns -1 + * + * @return int32_t + */ + int32_t readmv(); + +}; \ No newline at end of file diff --git a/ESPIron/heater.cpp b/ESPIron/heater.cpp index 7db8f9b..6152aaf 100644 --- a/ESPIron/heater.cpp +++ b/ESPIron/heater.cpp @@ -2,7 +2,6 @@ #include "const.h" #include "evtloop.hpp" #include "heater.hpp" -//#include "main.h" #include "log.h" #define HEATER_TASK_PRIO tskIDLE_PRIORITY+1 // task priority @@ -19,7 +18,7 @@ #define HEATER_LEDC_FREQUENCY HEATER_FREQ #define HEATER_LEDC_RAMPUP_TIME 3000 // time duration to fade in-for PWM ramping, ms -#define HEATER_OPAMP_STABILIZE_MS 5 // how long to wait after disabling PWM to let OpAmp stabilize +#define HEATER_OPAMP_STABILIZE_MS 8 // how long to wait after disabling PWM to let OpAmp stabilize #define HEATER_ADC_SAMPLES 8 // number of ADC reads to averate tip tempearture @@ -34,6 +33,12 @@ constexpr TickType_t long_measure_delay_ticks = pdMS_TO_TICKS(500); // idle interval between temp measurments constexpr TickType_t idle_delay_ticks = pdMS_TO_TICKS(1000); +// a simple constrain function +template +T clamp(T value, T min, T max){ + return (value < min)? min : (value > max)? max : value; +} + TipHeater::~TipHeater(){ // unsubscribe from event bus if (_evt_cmd_handler){ @@ -50,8 +55,6 @@ TipHeater::~TipHeater(){ } void TipHeater::init(){ - adc_sensor.attach(SENSOR_PIN); - // set PID output range _pid.setOutputRange(0, 1<(data)); - LOGD(T_HEAT, printf, "set target T:%d\n", _t.target); return; } @@ -124,6 +126,10 @@ void TipHeater::_evt_picker(esp_event_base_t base, int32_t id, void* data){ } } +void TipHeater::setTargetTemp(int32_t t){ + _t.target = t; + LOGD(T_HEAT, printf, "set target T:%d\n", _t.target); +}; void TipHeater::_start_runner(){ // Prepare and then apply the LEDC PWM timer configuration @@ -182,8 +188,9 @@ void TipHeater::_heaterControl(){ TickType_t delay_time = measure_delay_ticks; for (;;){ // sleep to accomodate specified measuring rate - // if task has been delayed, than we can't keep up with desired measure rate, let's give other tasks time to run anyway - if ( xTaskDelayUntil( &xLastWakeTime, delay_time ) ) taskYIELD(); + if ( xTaskDelayUntil( &xLastWakeTime, delay_time ) != pdTRUE ) continue; + // if task has not been delayed actually, than we can't keep up with desired measure rate, or thread was suspended from the outside + // I can skip this measurment cycle switch (_state){ case HeaterState_t::notip : @@ -199,8 +206,6 @@ void TipHeater::_heaterControl(){ ledc_update_duty(HEATER_LEDC_SPEEDMODE, _pwm.channel); // idle while OpAmp stabilizes vTaskDelay(pdMS_TO_TICKS(HEATER_OPAMP_STABILIZE_MS)); - // reset run time (need to avoid extra consecutive runs with xTaskDelayUntil if thread was suspended from the outside) - xLastWakeTime = xTaskGetTickCount(); } break; } @@ -229,7 +234,7 @@ void TipHeater::_heaterControl(){ // check if we've get the Tip back if (_state == HeaterState_t::notip && t < TEMP_NOTIP){ - _state = HeaterState_t::inactive; + _state = HeaterState_t::active; EVT_POST(SENSOR_DATA, e2int(evt::iron_t::tipInsert)); LOGW(T_HEAT, println, "Iron Tip inserted"); continue; @@ -254,7 +259,7 @@ void TipHeater::_heaterControl(){ // note: this is ugly external function, I will rework it later //_t.calibrated = calculateTemp(_t.avg); _t.calibrated = _t.avg; - ADC_LOGD(printf, "avg T: %5.1f, cal T: %d, tgt T:%d\n", _t.avg, _t.calibrated, _t.target); + ADC_LOGV(T_ADC, printf, "avg T: %5.1f, cal T: %d, tgt T:%d\n", _t.avg, _t.calibrated, _t.target); EVT_POST_DATA(SENSOR_DATA, e2int(evt::iron_t::tiptemp), &_t.calibrated, sizeof(_t.calibrated)); // if PID algo should be engaged @@ -271,7 +276,7 @@ void TipHeater::_heaterControl(){ ledc_set_duty(HEATER_LEDC_SPEEDMODE, _pwm.channel, _pwm.duty); ledc_update_duty(HEATER_LEDC_SPEEDMODE, _pwm.channel); - PWM_LOGV(printf, "Duty:%u\n", _pwm.duty); + PWM_LOGV(T_HEAT, printf, "Duty:%u\n", _pwm.duty); } // Task must self-terminate (if ever) vTaskDelete(NULL); @@ -326,7 +331,7 @@ bool TipHeater::_cb_ledc_fade_end_event(const ledc_cb_param_t *param, void *arg) // do not care what was the event, I need to unblock heater control anyway // if (param->event == LEDC_FADE_END_EVT) - BaseType_t task_awoken; + BaseType_t task_awoken{0}; // notify that rampUp has been complete EVT_POST_ISR(IRON_NOTIFY, e2int(evt::iron_t::statePWRRampCmplt), &task_awoken); task_awoken |= xTaskResumeFromISR(static_cast(arg)->_task_hndlr); @@ -337,10 +342,10 @@ bool TipHeater::_cb_ledc_fade_end_event(const ledc_cb_param_t *param, void *arg) // 对32个ADC读数进行平均以降噪 // VP+_Ru = 100k, Rd_GND = 1K float TipHeater::_denoiseADC(){ - std::array samples; + std::array samples; for (auto &i : samples){ - i = adc_sensor.readMiliVolts(); + i = analogReadMilliVolts(TIP_ADC_SENSOR_PIN); // value = constrain(0.4432 * raw_adc + 29.665, 20, 1000); } @@ -349,9 +354,7 @@ float TipHeater::_denoiseADC(){ for (size_t i = 0; i < samples.size(); ++i){ for (size_t j = i + 1; j < samples.size(); ++j){ if (samples[i] > samples[j]) { - auto temp = samples[i]; - samples[i] = samples[j]; - samples[j] = temp; + std::swap(samples[i], samples[j]); } } } @@ -361,10 +364,11 @@ float TipHeater::_denoiseADC(){ for (uint8_t i = 2; i < 6; i++) { result += samples[i]; } + result /= 4; // convert mV to Celsius - auto t = constrain(0.5378 * result / 4 + 6.3959, 20.0, 1000.0); - ADC_LOGV(printf, "avg mV:%u / Temp C:%6.1f\n", result / 4, t); + float t = clamp(0.5378 * result + 6.3959, 20.0, 1000.0); + ADC_LOGV(T_ADC, printf, "avg mV:%u / Temp C:%6.1f\n", result, t); //// resultArray[i] = constrain(0.5378 * raw_adc + 6.3959, 20, 1000); // y = 0.5378x + 6.3959; return t; } diff --git a/ESPIron/heater.hpp b/ESPIron/heater.hpp index 7f047fc..f2d4cd0 100644 --- a/ESPIron/heater.hpp +++ b/ESPIron/heater.hpp @@ -3,7 +3,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/ledc.h" -#include #include "FastPID.h" #define HEATER_MEASURE_RATE 10 // Tip temperature measuring rate in working mode, Hz @@ -56,9 +55,6 @@ class TipHeater { esp_event_handler_instance_t _evt_cmd_handler = nullptr; esp_event_handler_instance_t _evt_ntf_handler = nullptr; - - ESP32AnalogRead adc_sensor; - // Specify variable pointers and initial PID tuning parameters // 指定变量指针和初始PID调优参数 FastPID _pid = FastPID(consKp, consKi, consKd, HEATER_MEASURE_RATE); @@ -125,7 +121,7 @@ class TipHeater { * * @param t */ - void setTargetTemp(int32_t t){ _t.target = t; }; + void setTargetTemp(int32_t t); /** * @brief Get the Target heater temperature diff --git a/ESPIron/hid.cpp b/ESPIron/hid.cpp index 610c383..a5a97e5 100644 --- a/ESPIron/hid.cpp +++ b/ESPIron/hid.cpp @@ -325,6 +325,9 @@ ViSet_MainScreen::ViSet_MainScreen(GPIOButton &button, PseudoRot encdr.setCounter(TEMP_DEFAULT, TEMP_STEP, TEMP_MIN, TEMP_MAX); encdr.setMultiplyFactor(2); + // load configured temperatures + nvs_blob_read(T_IRON, T_temperatures, static_cast(&_temp), sizeof(Temperatures)); + // request working temperature from IronController EVT_POST(IRON_GET_EVT, e2int(iron_t::workTemp)); } @@ -491,12 +494,14 @@ void ViSet_MainScreen::_evt_notify(int32_t id, void* data){ } void ViSet_MainScreen::_evt_cmd(int32_t id, void* data){ +/* not used currently switch(static_cast(id)){ case evt::iron_t::workTemp : _temp.working = *reinterpret_cast(data); encdr.setCounter(_temp.working, TEMP_STEP, TEMP_MIN, TEMP_MAX); break; } +*/ } void ViSet_MainScreen::_evt_state(int32_t id, void* data){ @@ -599,12 +604,12 @@ void MuiMenu::_evt_encoder(ESPButton::event_t e, const EventMsg* m){ void MuiMenu::drawScreen(){ if (!_rr) return; - Serial.printf("st:%lu\n", millis()); + //Serial.printf("st:%lu\n", millis()); u8g2.clearBuffer(); // call Mui renderer render(); u8g2.sendBuffer(); - Serial.printf("en:%lu\n", millis()); + //Serial.printf("en:%lu\n", millis()); // take a screenshot //u8g2.writeBufferXBM(Serial); _rr = false; @@ -1258,9 +1263,14 @@ void ViSet_PwrSetup::_qc_voltage_step(bool inc){ } -// ***************************** -// *** MUI entities +// ************************************** +// *** USB MSC functions *** + +#ifdef CONFIG_TINYUSB_MSC_ENABLED +void ViSet_USBMSC_attach_fwupdater(){ +} +#endif // CONFIG_TINYUSB_MSC_ENABLED diff --git a/ESPIron/hid.hpp b/ESPIron/hid.hpp index 9a5611e..cef75fc 100644 --- a/ESPIron/hid.hpp +++ b/ESPIron/hid.hpp @@ -17,6 +17,7 @@ #include "espasyncbutton.hpp" #include "muipp_u8g2.hpp" #include "lang/lang_en_us.h" +#include "FirmwareMSC.h" /** @@ -359,6 +360,27 @@ class ViSet_PwrSetup : public MuiMenu { }; +class ViSet_USBMSC : public MuiMenu { + +#if CONFIG_TINYUSB_MSC_ENABLED + std::unique_ptr< FirmwareMSC > _fwMSC; +#endif //CONFIG_TINYUSB_MSC_ENABLED + + // menu builder function + void _buildMenu(); + +#ifdef CONFIG_TINYUSB_MSC_ENABLED + void _attach_fwupdater(); +#endif // CONFIG_TINYUSB_MSC_ENABLED + +public: + // c-tor + ViSet_USBMSC(GPIOButton &button, PseudoRotaryEncoder &encoder); + // d-tor + ~ViSet_USBMSC(); + +}; + // ************************** diff --git a/ESPIron/ironcontroller.cpp b/ESPIron/ironcontroller.cpp index d7527c6..f2a14fc 100644 --- a/ESPIron/ironcontroller.cpp +++ b/ESPIron/ironcontroller.cpp @@ -142,7 +142,7 @@ void IronController::_mode_switcher(){ _state = ironState_t::standby; LOGI(T_CTRL, printf, "Engage standby mode due to sleep timeout of %u ms. Temp:%u\n", _timeout.standby, _temp.standby); // switch heater temperature to standby value - EVT_POST_DATA(IRON_SET_EVT, e2int(iron_t::heaterTargetT), &_temp.standby, sizeof(_temp.standby)); + EVT_POST_DATA(IRON_HEATER, e2int(iron_t::heaterTargetT), &_temp.standby, sizeof(_temp.standby)); // notify other componets that we are switching to 'standby' mode EVT_POST(IRON_NOTIFY, e2int(iron_t::stateStandby)); } @@ -156,13 +156,18 @@ void IronController::_mode_switcher(){ LOGI(T_CTRL, printf, "Engage idle mode due to idle timeout of %u ms\n", _timeout.idle); // notify other componets that we are switching to 'idle' mode EVT_POST(IRON_NOTIFY, e2int(iron_t::stateIdle)); + // disable heater + EVT_POST(IRON_HEATER, e2int(iron_t::heaterDisable)); } else if (pdTICKS_TO_MS(xTaskGetTickCount()) - pdTICKS_TO_MS(_xTicks.motion) < _timeout.standby){ // standby cancelled _state = ironState_t::working; LOGI(T_CTRL, println, "cancel Standby mode"); // notify other componets that we are switching to 'work' mode EVT_POST(IRON_NOTIFY, e2int(iron_t::stateWorking)); - EVT_POST_DATA(IRON_SET_EVT, e2int(iron_t::heaterTargetT), &_temp.working, sizeof(_temp.working)); + // switch on heater + EVT_POST(IRON_HEATER, e2int(iron_t::heaterEnable)); + // set target T for heater + EVT_POST_DATA(IRON_HEATER, e2int(iron_t::heaterTargetT), &_temp.working, sizeof(_temp.working)); } return; } @@ -197,6 +202,8 @@ void IronController::_mode_switcher(){ // notify other componets that we are switching to 'working' mode EVT_POST(IRON_NOTIFY, e2int(iron_t::stateWorking)); LOGI(T_CTRL, printf, "Engage work mode due to boost timeout of %u ms\n", _timeout.boost); + // set target T for heater + EVT_POST_DATA(IRON_HEATER, e2int(iron_t::heaterTargetT), &_temp.working, sizeof(_temp.working)); } else { // send notification with time left till boost is disabled (in seconds) unsigned time_left = _timeout.boost - t; @@ -287,7 +294,7 @@ void IronController::_evt_commands(esp_event_base_t base, int32_t id, void* data EVT_POST_DATA(IRON_NOTIFY, e2int(iron_t::stateBoost), &_timeout.boost, sizeof(_timeout.boost)); // set heater to boost temperature int32_t t = _temp.working + _temp.boost; - EVT_POST_DATA(IRON_SET_EVT, e2int(iron_t::heaterTargetT), &t, sizeof(t)); + EVT_POST_DATA(IRON_HEATER, e2int(iron_t::heaterTargetT), &t, sizeof(t)); _xTicks.boost = xTaskGetTickCount(); break; } @@ -298,7 +305,7 @@ void IronController::_evt_commands(esp_event_base_t base, int32_t id, void* data // notify other components LOGI(T_CTRL, println, "switch to Work mode"); EVT_POST(IRON_NOTIFY, e2int(iron_t::stateWorking)); - EVT_POST_DATA(IRON_SET_EVT, e2int(iron_t::heaterTargetT), &_temp.working, sizeof(_temp.working)); + EVT_POST_DATA(IRON_HEATER, e2int(iron_t::heaterTargetT), &_temp.working, sizeof(_temp.working)); break; } break; @@ -327,7 +334,7 @@ void IronController::_evt_commands(esp_event_base_t base, int32_t id, void* data nvs_blob_write(T_IRON, T_temperatures, static_cast(&_temp), sizeof(Temperatures)); } if (_state == ironState_t::working) - EVT_POST_DATA(IRON_SET_EVT, e2int(iron_t::heaterTargetT), &_temp.working, sizeof(_temp.working)); + EVT_POST_DATA(IRON_HEATER, e2int(iron_t::heaterTargetT), &_temp.working, sizeof(_temp.working)); break; } diff --git a/ESPIron/log.h b/ESPIron/log.h index d214b7e..8b4a944 100644 --- a/ESPIron/log.h +++ b/ESPIron/log.h @@ -2,6 +2,7 @@ LOG macro will enable/disable logs to serial depending on LAMP_DEBUG build-time flag */ #pragma once +#include "Arduino.h" static constexpr const char* S_V = "V: "; static constexpr const char* S_D = "D: "; @@ -69,25 +70,25 @@ static constexpr const char* S_E = "E: "; // Per app macros #if defined(ADC_DEBUG_LEVEL) && ADC_DEBUG_LEVEL > 3 - #define ADC_LOGD(func, ...) PTS200_DEBUG_PORT.print(S_D); PTS200_DEBUG_PORT.print(T_ADC); PTS200_DEBUG_PORT.print((char)0x9); PTS200_DEBUG_PORT.func(__VA_ARGS__) + #define ADC_LOGD(tag, func, ...) PTS200_DEBUG_PORT.print(S_D); PTS200_DEBUG_PORT.print(T_ADC); PTS200_DEBUG_PORT.print((char)0x9); PTS200_DEBUG_PORT.func(__VA_ARGS__) #else #define ADC_LOGD(...) #endif #if defined(ADC_DEBUG_LEVEL) && ADC_DEBUG_LEVEL == 5 - #define ADC_LOGV(func, ...) PTS200_DEBUG_PORT.print(S_V); PTS200_DEBUG_PORT.print(T_ADC); PTS200_DEBUG_PORT.print((char)0x9); PTS200_DEBUG_PORT.func(__VA_ARGS__) + #define ADC_LOGV(tag, func, ...) PTS200_DEBUG_PORT.print(S_V); PTS200_DEBUG_PORT.print(T_ADC); PTS200_DEBUG_PORT.print((char)0x9); PTS200_DEBUG_PORT.func(__VA_ARGS__) #else #define ADC_LOGV(...) #endif #if defined(CTRL_DEBUG_LEVEL) && CTRL_DEBUG_LEVEL == 5 - #define CTRL_LOGV(func, ...) PTS200_DEBUG_PORT.print(S_V); PTS200_DEBUG_PORT.print(T_CTRL); PTS200_DEBUG_PORT.print((char)0x9); PTS200_DEBUG_PORT.func(__VA_ARGS__) + #define CTRL_LOGV(tag, func, ...) PTS200_DEBUG_PORT.print(S_V); PTS200_DEBUG_PORT.print(T_CTRL); PTS200_DEBUG_PORT.print((char)0x9); PTS200_DEBUG_PORT.func(__VA_ARGS__) #else #define CTRL_LOGV(...) #endif #if defined(PWM_DEBUG_LEVEL) && PWM_DEBUG_LEVEL == 5 - #define PWM_LOGV(func, ...) PTS200_DEBUG_PORT.print(S_V); PTS200_DEBUG_PORT.print(T_PWM); PTS200_DEBUG_PORT.print((char)0x9); PTS200_DEBUG_PORT.func(__VA_ARGS__) + #define PWM_LOGV(tag, func, ...) PTS200_DEBUG_PORT.print(S_V); PTS200_DEBUG_PORT.print(T_PWM); PTS200_DEBUG_PORT.print((char)0x9); PTS200_DEBUG_PORT.func(__VA_ARGS__) #else #define PWM_LOGV(...) #endif diff --git a/ESPIron/main.cpp b/ESPIron/main.cpp index c4b9358..6f69057 100644 --- a/ESPIron/main.cpp +++ b/ESPIron/main.cpp @@ -22,9 +22,9 @@ TipHeater heater(HEATER_PIN, HEATER_CHANNEL, HEATER_INVERT); // acceleration sensor GyroSensor accel; +#endif // DEVELOP_MODE // input voltage sensor VinSensor vin; -#endif // DEVELOP_MODE // Default value can be changed by user and stored in EEPROM // 用户可以更改并存储在EEPROM中的默认值 @@ -35,12 +35,11 @@ bool MSC_Updating_Flag = false; - // *** Arduino setup *** void setup() { // tip sensor pin - pinMode(SENSOR_PIN, INPUT_PULLUP); + pinMode(TIP_ADC_SENSOR_PIN, INPUT_PULLUP); // buzzer in pinMode(BUZZER_PIN, OUTPUT); @@ -84,15 +83,6 @@ void setup() { // event bus sniffer //evt::debug(); -/* - // if all 3 buttons are pressed on boot, reset EEPROM configuration to defaults - // this does not makes much sense 'cause pressed gpio0 will put MCU into fash mode - if (digitalRead(BUTTON_P_PIN) == LOW && digitalRead(BUTTON_N_PIN) == LOW && - digitalRead(BUTTON_PIN) == HIGH) { - write_default_EEPROM(); - } -*/ - // Initialize Iron Controller espIron.init(); @@ -107,9 +97,9 @@ void setup() { // initialize acceleration sensor accel.init(); +#endif //DEVELOP_MODE // init voltage sensor vin.init(); -#endif //DEVELOP_MODE // initialize HID (buttons controls and navigation, screen) LOGI(T_IRON, println, "Init HID"); diff --git a/ESPIron/sensors.cpp b/ESPIron/sensors.cpp index efb4ffa..2825fb8 100644 --- a/ESPIron/sensors.cpp +++ b/ESPIron/sensors.cpp @@ -232,8 +232,6 @@ void GyroSensor::_temperature_poll(){ void VinSensor::init(){ LOGI(T_Sensor, println, "Init Voltage sensor"); - // input voltage pin ADC - adc_vin.attach(VIN_PIN); // start voltage polling if (!_tmr_runner){ @@ -275,15 +273,14 @@ VinSensor::~VinSensor(){ void VinSensor::_runner(){ uint32_t voltage = 0; - for (uint8_t i = 0; i < 4; i++) { // get 32 readings 得到32个读数 - voltage += adc_vin.readMiliVolts(); + for (uint32_t i = 0; i < 4; i++) { // get 32 readings 得到32个读数 + voltage += analogReadMilliVolts(VIN_PIN); } - voltage = voltage / 4 * 31.3f; + voltage = voltage / 4 * 31.3f; // not sure where this 31.3 comes from, need real schematics of this Iron - // log and publish Vin value - ADC_LOGV(T_ADC, printf, "Vin: %u mV\n", voltage); - EVT_POST_DATA(SENSOR_DATA, e2int(evt::iron_t::vin), &voltage, sizeof(voltage)); + ADC_LOGV(T_ADC, printf, "Vin: %d mV\n", voltage); + EVT_POST_DATA(SENSOR_DATA, e2int(evt::iron_t::vin), &voltage, sizeof(voltage)); // some calibration calc // // VIN_Ru = 100k, Rd_GND = 3.3K diff --git a/ESPIron/sensors.hpp b/ESPIron/sensors.hpp index 2977bea..35f4dae 100644 --- a/ESPIron/sensors.hpp +++ b/ESPIron/sensors.hpp @@ -2,7 +2,6 @@ #include #include "common.hpp" #include "SparkFun_LIS2DH12.h" // https://github.com/sparkfun/SparkFun_LIS2DH12_Arduino_Library -#include "ESP32AnalogRead.h" // https://github.com/madhephaestus/ESP32AnalogRead #include "evtloop.hpp" #include "freertos/timers.h" @@ -111,9 +110,6 @@ class VinSensor { //esp_event_handler_instance_t _evt_set_handler = nullptr; - // ADC Calibrated Reader - ESP32AnalogRead adc_vin; - // events handler void _eventHandler(esp_event_base_t base, int32_t id, void* data); diff --git a/ESPIron/usb-msc.cpp_ b/ESPIron/usb-msc.cpp_ new file mode 100644 index 0000000..6b480b2 --- /dev/null +++ b/ESPIron/usb-msc.cpp_ @@ -0,0 +1,14 @@ +/* + This file is a part of ESPIron-PTS200 project + https://github.com/vortigont/ESPIron-PTS200 + + Copyright © 2024 Emil Muratov (vortigont) + + ESPIron-PTS200 is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +*/ + +#include "msc.hpp" + diff --git a/ESPIron/usb-msc.hpp b/ESPIron/usb-msc.hpp new file mode 100644 index 0000000..75e5dc7 --- /dev/null +++ b/ESPIron/usb-msc.hpp @@ -0,0 +1,31 @@ +/* + This file is a part of ESPIron-PTS200 project + https://github.com/vortigont/ESPIron-PTS200 + + Copyright © 2024 Emil Muratov (vortigont) + + ESPIron-PTS200 is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +*/ + +#pragma once + +#ifdef ARDUINO_USB_MODE + +#if ARDUINO_USB_MODE == 1 +#warning This code intended for TinyUSB/OTG mode (ARDUINO_USB_MODE == 0) +#else +#warning Using USB in TinyUSB/OTG mode +#endif // ARDUINO_USB_MODE == 1 + + +#ifdef CONFIG_TINYUSB_MSC_ENABLED +#warning Building with FirmwareMSC enabled +#include "USB.h" +#include "FirmwareMSC.h" +#endif // CONFIG_TINYUSB_MSC_ENABLED + +//FirmwareMSC MSC_Update; +#endif // ARDUINO_USB_MODE diff --git a/platformio.ini b/platformio.ini index b838afc..198e12c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,9 +6,11 @@ extra_configs = [pts200_base] framework = arduino -platform = espressif32 +; Tasmota's platform, based on Arduino Core v3.0.4 +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.08.10/platform-espressif32.zip board_build.filesystem = littlefs board = PTS200 +monitor_speed = 115200 [env:pts200] extends = pts200_base @@ -17,14 +19,14 @@ lib_deps = https://github.com/vortigont/MuiPlusPlus vdeconinck/QC3Control @ ^1.4.1 olikraus/U8g2 @ ^2.34.17 - madhephaestus/ESP32AnalogRead @ ^0.2.1 - ;br3ttb/PID @ ^1.2.1 mike-matera/FastPID @ ~1.3 sparkfun/SparkFun LIS2DH12 Arduino Library @ ^1.0.3 + ;br3ttb/PID @ ^1.2.1 ;build_src_flags = ; -std=gnu++17 build_unflags = -std=gnu++11 + -DARDUINO_USB_MSC_ON_BOOT build_flags = -std=gnu++17 diff --git a/sdkconfig.defaults b/sdkconfig.defaults new file mode 100644 index 0000000..56d9d39 --- /dev/null +++ b/sdkconfig.defaults @@ -0,0 +1,17 @@ +CONFIG_FREERTOS_HZ=1000 + +CONFIG_SOC_LEDC_SUPPORTED=y + + + +CONFIG_SPIRAM=n +CONFIG_SOC_PCNT_SUPPORTED=n +CONFIG_SOC_WIFI_SUPPORTED=n +CONFIG_SOC_TWAI_SUPPORTED=n +CONFIG_SOC_DAC_SUPPORTED=n + +CONFIG_ESP32_WIFI_ENABLED=n +CONFIG_LWIP_IPV4=n +CONFIG_LWIP_IPV6=n + +CONFIG_MBEDTLS_TLS_DISABLED=y