Добрый день.
Есть код. Код стабильно работал на esp32 pico d4. Сейчас плата на esp32s3 и китайцы поломали часть кода с таймером. При настройке таймера МК перезагружается с ошибкой.
Задача допилить код таймера для работы на s3
#define KILLSW_OFF digitalRead(KILL_SW)
#define KILLSW_ON !digitalRead(KILL_SW)
#define IGNBTN_ON !digitalRead(IGN_BTN_PIN)
#define IGNBTN_OFF digitalRead(IGN_BTN_PIN)
//#include "soc/rtc_wdt.h"
#include "driver/timer.h"
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include "esp32-hal-ledc.h"
hw_timer_t* IGNITION_Charging_Timer = NULL;
hw_timer_t* IGNITION_Spark_Timer = NULL;
hw_timer_t* INJECTION_Start_timer = NULL;
hw_timer_t* INJECTION_End_Timer = NULL;
hw_timer_t* SIGNAL_DURATION_Timer = NULL;
hw_timer_t* MAP_Timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
static portMUX_TYPE my_mutex;
int Vsense_PIN = 1;
int TPS_PIN = 17;
int MAP_PIN = 9;
int COIL_PIN = 2;
int PUMP_PIN = 37;
int TEMP_PIN = 8;
int HALL_PIN = 13;
int KILL_SW = 15;
int INJ_PIN = 5;
int LED_PIN = 12;
int IGN_BTN_PIN = 7;
int LIGHT_ON_PIN = 16;
int IGN_ON_PIN = 6;
int PXX_EN = 48;
int PXX_STEP = 47;
int PXX_DIR = 38;
volatile int IGN_BTN_FUNC_COUNT = 0;
volatile int INJECTION_Duration = 30000; ///////длительность впрыска в микросекундах
volatile int KEY = 0;
volatile int IGN_STATE = 0;
volatile int Ignition_Timing_Charge = 2828; /// время накопления - 172
volatile unsigned int Ignition_Timing_Charge_Calc = 0; ///////переменная для пересчета ула во время в функции таймера
volatile int Advance_MAP = 0;
volatile long HallFUNC_FALLING_micros = 0;
volatile long Hall_micros = 0;
volatile int Prev_Hall_micros = 1;
volatile int Full_Hall_micros = 1;
volatile int RPM = 1; //rpm / 100
volatile long Deegree_micros = 0;
volatile int sensor_pos = 160;
volatile int Temp = 0;
volatile int V_in = 0; ///pfvtybn
volatile int MAP = 0;
volatile int LAG = 0;
volatile int TPS = 0;
volatile int Median_Vin = 0;
int Vin_newest = 0;
int Vin_recent = 0;
int Vin_oldest = 0;
int TPS_newest = 0;
int TPS_recent = 0;
int TPS_oldest = 0;
int Temp_newest = 0;
int Temp_recent = 0;
int Temp_oldest = 0;
int OFF_TIMER = 0;
int scanTime = 1; //In seconds
BLEScan* pBLEScan;
void IRAM_ATTR HallFUNC() { ///выход метала от датчика
if (digitalRead(HALL_PIN)) {
Hall_micros = micros() - HallFUNC_FALLING_micros; /////время нахождения выступа напротив датчика
if (Hall_micros < 8666 && Hall_micros > 400) {
Deegree_micros = Hall_micros / 26;
RPM = 600000 / (Deegree_micros * 360);
if (RPM > 8 && RPM < 90) {
volatile int Advance_MAP[120]{
5, 5, 5, 5, 5, 5, 5, 3, 7, 10, ///1000 обмин
10, 10, 10, 10, 10, 15, 15, 15, 15, 15, ///2000 обмин 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, ///2000 обмин 10, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 20, 20, 20, 20, 20, 20, 25, ///3000 обмин 20, 20, 20, 20, 20, 30, 30, 30, 30, 30, ///3000 обмин
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, ///4000 обмин 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///4000 обмин
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, ///5000 обмин 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ///5000 обмин
30, 30, 30, 30, 30, 30, 30, 30, 30, 30, ///6000 обмин
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///7000 обмин
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///8000 обмин
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, ///9000 обмин......отсечка
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///10 000 обмин
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///11 000 обмин
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///12 000 обмин
};
Ignition_Timing_Charge_Calc = ((Deegree_micros * (160 - Advance_MAP[RPM])) - Ignition_Timing_Charge); ///(247 /Deegree_micros)
IGNITION_Charging_Timer = timerBegin(1, 80, true); //////делитель и.т.д
timerAttachInterrupt(IGNITION_Charging_Timer, &IGNITION_Charging_Func, false);
timerAlarmWrite(IGNITION_Charging_Timer, Ignition_Timing_Charge_Calc, false); /// ///////////задержка функции будильника IGNITION_Charging_Func 215мкс
timerAlarmEnable(IGNITION_Charging_Timer);
Serial.println("digitalRead(HALL_PIN)");
}/*
} else
Hall_micros = 0; }*/
}}
if (!digitalRead(HALL_PIN)) {// && KILLSW_OFF) {
HallFUNC_FALLING_micros = micros();
// Serial.println("!digitalRead(HALL_PIN)");
}
}
void setup() {
Serial.begin(115200);
pinMode(COIL_PIN, OUTPUT);
pinMode(PUMP_PIN, OUTPUT);
pinMode(INJ_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(LIGHT_ON_PIN, OUTPUT);
pinMode(IGN_BTN_PIN, INPUT);
pinMode(IGN_ON_PIN, OUTPUT);
pinMode(PXX_EN, OUTPUT);
pinMode(PXX_STEP, OUTPUT);
pinMode(PXX_DIR, OUTPUT);
pinMode(HALL_PIN, INPUT_PULLUP);
pinMode(MAP_PIN, INPUT);
pinMode(TPS_PIN, INPUT);
pinMode(TEMP_PIN, INPUT_PULLUP);
pinMode(KILL_SW, INPUT_PULLUP);
pinMode(Vsense_PIN, INPUT);
digitalWrite(COIL_PIN, LOW);
ledcSetup(0, 5000, 8);
ledcAttachPin(PUMP_PIN, 0);
///BLE
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
attachInterrupt(digitalPinToInterrupt(HALL_PIN), HallFUNC, CHANGE);
//xTaskCreatePinnedToCore(Print, "Print", 2048, NULL, /*приоритет*/ 1, NULL, /*ядро*/ 0);
Serial.print(" ");
Serial.print(__DATE__);
Serial.print(" ");
Serial.println("E-CARB 240608");
Serial.println();
digitalWrite(PXX_EN, HIGH);
esp_sleep_enable_ext0_wakeup(GPIO_NUM_7, LOW);
}
void IRAM_ATTR loop() {}
среда arduino 2.3.2
либа esp 2.0.13 (важно)
чип на котором работало: esp32 picod4
чип на котором поломалось: esp32s3
место поломки на изо ниже
ошибка на изо ниже
Достаточно просто назвать номер строки в приведенном коде
Это вообще ни о чем. Тексты ошибок тоже нужно приводить текстом.
Зы: обновить аддон esp32 не пробовали? Там вроде уже версия 3.0 доступна
Аддон 3.0 ломает остальные функции.
Пробовал ставить разные более старые версии - без изменений
Замкнутый круг, не иначе
уважающие себя исполнители делают делают подобные проекты заново, естественно за соответствующие деньги.
любопытно, какой аристократ будет искать иголку в чужом деревенском туалете за пачку риса. на ум приходит только одно имя - ба…ски…бол
видимо у нас с вами разное представление об уважающих себя исполнителях.
Кто хочет - тот делает. и наоборот
я добился какого то результата вынесением настройки таймера в отдельную функцию. Но МК всё еще крашится. только поисходит это чуть позже
void IRAM_ATTR IGNITION_Spark_Func() {
digitalWrite(COIL_PIN, LOW);
timerEnd(IGNITION_Spark_Timer);
Serial.println("IGNITION_Spark_Func");
}
void IRAM_ATTR IGNITION_Charging_Func() {
timerEnd(IGNITION_Charging_Timer);
digitalWrite(COIL_PIN, HIGH);
IGNITION_Spark_Timer = timerBegin(1, 80, true); //////делитель и.т.д
timerAttachInterrupt(IGNITION_Spark_Timer, &IGNITION_Spark_Func, false); ///////функция по таймеру
timerAlarmWrite(IGNITION_Spark_Timer, Ignition_Timing_Charge, false); /// задержка будильника IGNITION_Spark_Func 219мкс
timerAlarmEnable(IGNITION_Spark_Timer);
Serial.println("IGNITION_Charging_Func"); ///////////включаем таймер}
}
void IRAM_ATTR TIMER_FUNC() {
IGNITION_Charging_Timer = timerBegin(1, 80, true); //////делитель и.т.д
timerAttachInterrupt(IGNITION_Charging_Timer, &IGNITION_Charging_Func, false);
timerAlarmWrite(IGNITION_Charging_Timer, Ignition_Timing_Charge_Calc, false); /// ///////////задержка функции будильника IGNITION_Charging_Func 215мкс
timerAlarmEnable(IGNITION_Charging_Timer);
Serial.println("TIMER_FUNC");
}
void IRAM_ATTR HallFUNC() { ///выход метала от датчика
if (digitalRead(HALL_PIN)) {
Hall_micros = micros() - HallFUNC_FALLING_micros; /////время нахождения выступа напротив датчика
if (Hall_micros < 8666 && Hall_micros > 400) {
Deegree_micros = Hall_micros / 26;
RPM = 600000 / (Deegree_micros * 360);
if (RPM > 8 && RPM < 90) {
volatile int Advance_MAP[120]{
5, 5, 5, 5, 5, 5, 5, 3, 7, 10, ///1000 обмин
10, 10, 10, 10, 10, 15, 15, 15, 15, 15, ///2000 обмин 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, ///2000 обмин 10, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 20, 20, 20, 20, 20, 20, 25, ///3000 обмин 20, 20, 20, 20, 20, 30, 30, 30, 30, 30, ///3000 обмин
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, ///4000 обмин 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///4000 обмин
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, ///5000 обмин 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ///5000 обмин
30, 30, 30, 30, 30, 30, 30, 30, 30, 30, ///6000 обмин
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///7000 обмин
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///8000 обмин
38, 38, 38, 38, 38, 38, 38, 38, 38, 38, ///9000 обмин......отсечка
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///10 000 обмин
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///11 000 обмин
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, ///12 000 обмин
};
Ignition_Timing_Charge_Calc = ((Deegree_micros * (160 - Advance_MAP[RPM])) - Ignition_Timing_Charge); ///(247 /Deegree_micros)
Serial.println("HallFUNC");
TIMER_FUNC();
} /*
думаю все ломается в момент перезапуска таймера
иными словами не работает timerEnd(IGNITION_Spark_Timer);
видимо у нас с вами разное представление об уважающих себя исполнителях.
Кто хочет - тот делает. и наоборот
лол, ещё бы, без лоха и жизнь плоха, только учтите, редко бывают квалифицированные лохи. esp тридцать вторая это всё-таки не авээрка.
А может стоит таки взять esp32 и не париться?
плата изготовлена под esp32s3 generic. менять коней уже поздно к тому же нужна вся мощь этого чипа ) одноядерные варианты мне не подойдут да и проблемы там могут быть те же (а может китайцы добавят новых)
Замечательно - изготовить плату под один модуль, а код взять под другогой. И предварительно не убедиться, что он будет работать… Просто класс
С каких пор esp32 стал одноядерным?
esp32 это целый мешок разнообразных МК с разной начинкой
вот например спека на чип S2. в нем одно ядро.
использование чипа S3 продиктовано быстрым BLE и наличием второго ядра. другие чипы таким сочетанием похвастаться не могут.
изготовление платы до макетирования обусловлена сроками да и не думаю что проблема с таймерами нерешаемая. в крайнем случае перепишу софт под другой метод но это долго
С чего вы взяли, что я не в курсе?
А где я говорил про esp32s2? Код был написан (с ваших слов) под двухъядерный чип, но никто ж вам не гарантировал, что он будет работать на любом двухъядернике
Думаю, в вашем случае это самый правильный вариант
под 2.0.13 копилировалось?
Отнюдь!!!
ЗЫ нельзя починить то, что изначально не работало…
Ещё как компилировалось. Даже работало. Но работало на другом мк (О чем было написано выше).
Собственно задача не написать весь код, не спорить на тему правильности/неправильности выбора мк а найти метод правильного запуска и остановки таймера.
на данном этапе перешел на либу 3,0.
немного изменил инициализацию таймера и…
таймер запускается. один раз. при повторной инициализации таймера есп уходит в ребут