ESP32: как запустить два независимых ПИД-регулятора, по одному на ядро?
Я хочу управлять двумя независимыми процессами с помощью двух ПИД-регуляторов. Можно ли запустить каждый контроллер на отдельном ядре? Я использую эту библиотеку PID. Согласно его документации, функция PID::Compute()
должна вызываться один раз каждые loop()
. Как этого можно добиться при использовании задач RTOS (для многоядерного выполнения)?
@glamis, 👍2
Обсуждение2 ответа
Лучший ответ:
Конечно. Существующая установка и цикл Arduino просто выполняются в своей собственной задаче:
void loopTask(void *pvParameters)
{
setup();
for(;;) {
if(loopTaskWDTEnabled){
esp_task_wdt_reset();
}
loop();
}
}
extern "C" void app_main()
{
loopTaskWDTEnabled = false;
initArduino();
xTaskCreateUniversal(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, CONFIG_ARDUINO_RUNNING_CORE);
}
Поэтому нет никаких причин не повторить это, чтобы получить полностью новую настройку и цикл или просто одну функцию, которая делает все это, если вы предпочитаете.
TaskHandle_t secondPidTaskHandle;
void secondPidLoop() {
// код установки здесь
for (;;) {
// код контура PID здесь
}
}
void setup() {
xTaskCreateUniversal(secondPidLoop, "secondPidLoop", 8192, NULL, 1, &secondPidTaskHandle, 0);
}
void loop() {
// Первый код PID
}
Последний параметр xTaskCreateUniversal()
— это ядро, на котором выполняется выполнение. Настройка/цикл по умолчанию выполняется на ядре 1:
#define CONFIG_ARDUINO_RUNNING_CORE 1
Поэтому просто используйте 0
, и он запустится на ядре 0.
esp32_technical_reference_manual_en.pdf
Страница 620
Как упоминалось ранее, только процесс с повышенными правами и PID 0/1 может инициировать переключение процесса. Новый процесс может иметь любой PID от 0 до 7 после переключения процесса. Ключом к успешному проактивному переключению процессов является то, что Эспрессиф Системы 620 Отправить отзыв о документации Техническое справочное руководство ESP32 V4.3 29. ПИД-регулятор когда последняя команда текущего процесса переключается на первую команду нового процесса, PID должен переключиться с 0/1 на новый процесс. Программная процедура проактивного переключения процессов выглядит следующим образом:
- Замаскируйте все прерывания, кроме NMI, с помощью программного обеспечения.
- Установите для регистра PIDCTRL_NMI_MASK_ENABLE_REG значение 1, чтобы сгенерировать сигнал маски прерывания ЦП NMI.
- Настройте регистры PIDCTRL_PID_DELAY_REG и PIDCTRL_NMI_DELAY_REG.
- Настройте регистр PIDCTRL_PID_NEW_REG.
- Настройте регистр PIDCTRL_LEVEL_REG и PIDCTRL_FROM_n_REG.
- Установите для регистра PIDCTRL_PID_CONFIRM_REG и регистра PIDCTRL_NMI_MASK_DISABLE_REG значение 1.
- Отменить маскирование всех прерываний, кроме NMI.
- Переключиться на новый процесс и получить инструкцию. Хотя мы можем иметь дело с вложением прерываний, процесс с повышенными правами не должен прерываться во время процесса. переключения, и поэтому прерывания были замаскированы на шаге 1 и шаге 2. На шаге 3 сконфигурированные значения регистров PIDCTRL_PID_DELAY_REG и PIDCTRL_NMI_DELAY_REG будут влияет на шаг 6. На шаге 4 сконфигурированное значение регистра PIDCTRL_PID_NEW_REG будет новым PID после шага 6. Если система в настоящее время находится во вложенном прерывании и должна вернуться к предыдущему прерыванию, зарегистрируйте PIDCTRL_LEVEL_REG должен быть восстановлен на основе информации, записанной в регистре PIDCTRL_FROM_n_REG. на шаге 5. На шаге 6 после значений регистра PIDCTRL_PID_CONFIRM_REG и регистра PIDCTRL_NMI_MASK_DISABLE_REG установлены в 1, ПИД-регулятор не будет немедленно переключать ПИД на значение зарегистрируйте PIDCTRL_PID_NEW_REG и не отключайте сигнал маски прерывания CPU NMI сразу. Вместо этого ПИД-регулятор выполняет каждую задачу после разного количества тактов. Количество тактовых циклов - это значения, указанные в регистрах PIDCTRL_PID_DELAY_REG и PIDCTRL_NMI_DELAY_REG соответственно. На шаге 7 могут быть реализованы и другие задачи. Для этого стоимость этих задач должна быть включена, когда настройка регистров PIDCTRL_PID_DELAY_REG и PIDCTRL_NMI_DELAY_REG на шаге 3. Эспрессиф Системы 621 Отправить документацию
- AccelStepper.h — Как быстро увеличить скорость двигателя NEMA 17?
- Как сделать программный код потокобезопасным?
- Как создать несколько запущенных потоков?
- Управление скоростью вентилятора с помощью библиотеки Arduino PID
- esp32, platformio A fatal error occurred: Packet content transfer stopped (received 8 bytes) *** [upload] Error 2
- Как выбрать альтернативные контакты I2C на ESP32?
- Драйверы для чипа последовательного порта CH9102X
- Как преобразовать форматированный оператор print в строковую переменную?
почему бы не поместить PID::Compute() и PID2::Compute() в цикл()? он по-прежнему будет вызываться один раз для каждого экземпляра, @Juraj
Нет, это сработает, но алгоритм вычисления PID будет работать только на одном ядре, а это не то, чего я хочу добиться., @glamis
еще одно ядро работает WiFi, @Juraj