Переключение управления между двумя разными методами

Я реализовал ПИД-регулятор регулятора генератора для поддержания постоянной скорости вращения с помощью Arduino Uno. Это работает довольно хорошо, но есть компромисс между стабильностью и временем отклика. Использование значений PID, которые позволяют ему реагировать без колебаний, также примерно вдвое медленнее, чем старый механический регулятор.

Я придумал план использовать CT для обнаружения усилителей переменного тока и заставить Uno ускорять сервопривод дроссельной заслонки до известного значения, определенного вручную. Либо используя справочную таблицу, либо алгоритм интерполяции, я еще не проверил линейность усилителей в зависимости от угла дроссельной заслонки. Идея состоит в том, чтобы использовать таблицу (или интерполяцию), чтобы приблизить регулятор, а затем позволить ПИД-регулятору точно настроить его.

Моя проблема заключается в том, что я не знаю, как при необходимости переключаться между управлением поиском и ПИД-регулированием.

Псевдокод:

аналоговое чтение(AMPS); myservo.write(table_Val); как-то_переключить_на_PID; myservo.write(PID_value);

, 👍2

Обсуждение

Вы можете использовать условие if, проверяя, достигли ли вы целевого числа оборотов в минуту в пределах диапазона точной настройки., @chrisl

Если я использую какой-либо метод приближения оборотов, не будет ли PID просто колебаться в одну крайность или другую, пытаясь отрегулировать значение без успеха, потому что операция «приближения» находится под контролем? Я имею в виду, что PID смотрит на обороты и выдает выходные данные, но эти выходные данные игнорируются, потому что другая операция имеет сервоуправление. К тому времени, когда ПИД-регулятор находится под управлением, не должен ли выходной сигнал сделать полный ход, пытаясь внести изменения, и теперь сервопривод просто захлопнется до этого ошибочного значения?, @Nick Lacarno


1 ответ


1

PID смотрит на обороты и выдает результат, но этот вывод игнорируется, потому что другая операция имеет сервоуправление.

PID — это не то, что происходит где-то в фоновом режиме без вашего контроля. На Arduino это делается программно, так что вы можете полностью им управлять. Зачем вам выполнять расчет PID, если вы не используете значение? Решение состоит в том, чтобы просто выполнить соответствующий расчет в зависимости от числа оборотов в минуту в любой момент времени. Не нужно делать 2 расчета одновременно. Я сформулирую это в код с пояснениями:

У вас есть 2 способа расчета необходимых значений сервопривода:

  1. Ваш метод «сближения»
  2. Метод PID

Чтобы переключаться между этими методами, необходимо принять решение на основе RPM. Если RPM выходит за пределы вашего интервала, используется первый метод. Если он внутри, будет использоваться второй. Решение/условия часто записываются с оператором if else. Посмотрите на этот (не проверенный) фрагмент кода:

int target_rpm = 700;
int half_interval = 20;
int current_servo_pos = 0;

void loop(){
    current_rpm = analogRead(AMPS);

    if(current_rpm > target_rpm - half_interval && current_rpm < target_rpm + half_interval){
        // Здесь делаем расчет PID и сохраняем результат в current_servo_pos
    } else {
        // Здесь делаем расчет "приближения" и сохраняем результат в current_servo_pos
    }

    myservo.write(current_servo_pos);
}

Я не стал вдаваться в подробности фактического расчета, так как это здесь не важно. Вы можете использовать любой расчет, который вам нравится. Для PID вы можете найти библиотеки, которые сделают расчет за вас, например, здесь на github.

Код просто решит на основе RPM, какой расчет следует использовать. Если RPM по какой-то причине выходит за пределы интервала (возможно, его потревожили и потеряли скорость), он автоматически будет использовать метод «сближения», пока снова не окажется внутри интервала.

Примечание. Цифры, которые я здесь использовал, произвольны. Вы должны изменить их на то, что вам нужно.

,

Еще раз спасибо Крис! Мне не удалось использовать PID за пределами void loop(). Если я помещу параметры PID в другое место, он не ответит. Я получу код, который сейчас используется, позже сегодня. Но именно поэтому я спросил о вычислении PID, уже имеющем выход. Я могу записать вывод PID во что угодно в любой функции, но попытка вызвать PID вне void loop() оказалась бесплодной., @Nick Lacarno

Да, пожалуйста, добавьте свой код к вашему вопросу. Таким образом, я могу добавить больше к своему ответу, чтобы помочь вам в этом., @chrisl