Не выполянется созданая функция
- Войдите на сайт для отправки комментариев
Ср, 30/08/2017 - 18:43
Здравствуйте ,
Подскажите пожалуйста, почему не выполняется функция "pid" в 254 строке кода.
Все данные вхлдные есть. Единственное я заметил, что коэффициент "K" всегда ноль. Хотя в настройках равен 1.0.
#include <Kalman.h>
#include <I2Cdev.h>
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// ------------ Программа для расчета угла наклона по данным гироскопа и ускорения с использованием фильтра Калмана ----------------------------------
// -------------------------- и PID-регулирование для последовательного управления двумя двигателями драйверами Sabertooth -----------------------------------------------
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "Wire.h"
#include <TroykaIMU.h> // ЭТО Я УЖЕ ОТ СЕБЯ БУДУ ДОБАВЛЯТЬ
#include <math.h>
#include <SoftwareSerial.h> // ХЗ Я ЕЩЕ НЕ ПОРЕДЕЛИЛСЯ С ДРАЙВЕРОМ
#include <SabertoothSimplified.h> // С БИБЛИОТЕКОЙ СООТВЕТСТВЕННО ТОЖЕ
SoftwareSerial SWSerial(NOT_A_PIN, 11); // RX on no pin (unused), TX on pin 11 (to S1). ЭТО ВСЕ К ТОЙ ЖЕ БИБЛИОТЕКЕ ОТНОСИТСЯ
SabertoothSimplified ST(SWSerial); // Use SWSerial as the serial port.
Gyroscope gyro; // СОЗДАЛИ ОБЬЕКТ ДЛЯ РАБОТЫ С ГИРИКОМ
// создаём объект для работы с акселерометром
Accelerometer accel;
#define Pin_Lenkung_rechts 12 // Штыревой разъем для команды управления Вправо
#define Pin_Lenkung_links 13 // Штыревой разъем для команды управления ВЛЕВО
#define Pin_Schalter_Box 3 // ПИН КОРОБКИ ВЫКЛЮЧАТЕЛЕЙ ДЛЯ ПЕРЕКЛЮЧЕНИЯ МЕЖДУ СИНХРОНИЗАЦИЕЙ МОТОРОВ И I-УПРАВЛЕНИЕМ
#define Pin_PID_Regelung_P A1 // Контактный разъем для потенциометра для изменения P-компонента
#define Pin_PID_Regelung_I A2 // Контактный разъем для потенциометра для изменения I-компонента
#define Pin_PID_Regelung_D A3 // Контактный разъем для потенциометра для изменения D-компонента
int LoopTime_Soll = 9; // Желаемое время измельчения в мс для достижения 100 Гц
int LoopTime_Angepasst = LoopTime_Soll; // Последнее время цикла с принудительной паузой
int LoopTime_Bisher = LoopTime_Soll; // Последнее время цикла без принудительного перерыва
unsigned long LoopTime_Start = 0; // ВРЕМЯ НАЧАЛА ЦИКЛА
float Winkel; // Текущий угол наклона
float Winkel_Soll; // Уставка угла наклона, т. Е. 0 °
float Winkel_Grenze; // Максимально разрешенный угол наклона, над которым Segway выключен
float Winkel1;
float ACC_angledraga; // Угол датчика ускорения ТРОЙКА
float GYRO_ratedraga; // Угол датчика Гироскопа Тройка
// Угол датчика Гироскопа Тройка
float Kp,Ki,Kd,K; // Константы для ПИД-регулирования, Разная деталь, Интегральная часть, Дифференциальная часть, Общая часть
int Motor; // От ПИД-регулятора до управления двигателем
int Motor_rechts, Motor_links; // Значения для двух двигателей
float K_Motor_links, K_Motor_rechts; // Коэффициенты коррекции синхронной работы двух двигателей
int Schalter_Box; // Переменная, которая запрашивает положение переключателя на коробке
int Lenkung_Eingang_rechts = 0; // Переменная для определения команды управления вправо
int Lenkung_Eingang_links = 0; // Переменная для определения команды управления ВЛЕВО
float Lenkung_max; // Значение, с помощью которого управление двигателем должно изменяться как максимальное значение для команды управления
float Lenkung_rechts, Lenkung_links; // Текущее и ступенчатое увеличение контрольного значения при управлении вправо или влево
// ****************************************************************************
// ****************************** SETUP ***************************************
// ****************************************************************************
void setup()
{
Wire.begin();
//SWSerial.begin(9600); // This is the baud rate you chose with the DIP switches.
Serial.begin(9600); // baud rate für den seriellen Monitor, um die Werte zu überprüfen
// initialize device
//Подпрограмма для однократной калибровки датчиков
// инициализация гироскопа
gyro.begin();
// инициализация акселерометра
accel.begin();
}
// ***********************************************************************************
// ****************************** Kalibrierung ***************************************
// ***********************************************************************************
void calibrateSensors() //Одноразовое определение значений нуля датчика (среднее значение от 50 измерений в каждом случае)
{
// =================================================
// ======== Изменение разрешения датчика ==========
// =================================================
// ===========================================================================
// read raw accel/gyro measurements from device
// Выходной сигнал: Разрешение 2g: 16384 / g Разрешение 4g: 8192 / g
// Выходной гироскоп: Разрешение 250 ° / с: 131 / ° / с Разрешение 500 ° / с: 65,5 / ° / с
// ===========================================================================
// Попытка избежать «погремушки» двух двигателей в начале
ST.motor(1, 0);
ST.motor(2, 0);
Winkel_Soll = 0.0; // Уставка для угла наклона
Winkel_Grenze = 30.0; // Максимально допустимый угол наклона
// *******************************************************
// ********** K - Werte für die PID-Regelung *************
// *******************************************************
Kp = analogRead(Pin_PID_Regelung_P) * 25.0 / 1023.0; // Разница с фиксированным Поти
Ki = 0.1; // Встроенная часть с потенциометром (переключатель, но, возможно, для коррекции двигателя, поэтому сначала установите 0,1)
Kd = analogRead(Pin_PID_Regelung_D) * 100.0 / 1023.0; // Дифференциальная часть с потенциометром
K = 1.0; // общая доля
// **************************************************
// ********** K - значения для ПИД-регулятора *************
// **************************************************
pinMode(Pin_Schalter_Box, INPUT); // Pin для выбора между I-управлением и синхронизацией двигателя
K_Motor_rechts = 1.0; // Korrekturfaktor für den rechten Motor
K_Motor_links = 0.8; // Korrekturfaktor für den linken Motor
// **********************************************
// ********** Рулевые значения *************
// **********************************************
Lenkung_max = 25.0; // Значение, с помощью которого управление двигателем должно измениться с помощью команды управления MAXIMAL
Lenkung_rechts = 0.0; // Текущее дополнительное значение в процессе рулевого управления вправо
Lenkung_links = 0.0; // Текущее дополнительное значение в процессе рулевого управления влево
pinMode(Pin_Lenkung_rechts, INPUT); // Вывод для рулевого управления ВПРАВО объявляется как вход
pinMode(Pin_Lenkung_links, INPUT); // Вывод для рулевого управления ВЛЕВО объявляется как вход
}
// ***************************************************************************************************************************************************
// ***************************************************************************************************************************************************
// ********************************************************************** HAUPTSCHLEIFE **************************************************************
// ***************************************************************************************************************************************************
// ***************************************************************************************************************************************************
void loop()
{
// *******************************************************
// ********************* Sensorabfrage *******************
// *******************************************************
// ===========================================================================
// read raw accel/gyro measurements from device
// Ausgabewerte-Acc: Auflösung 2g: 16384/g Auflösung 4g: 8192/g
// Ausgabewerte-Gyro: Auflösung 250°/s: 131/°/s Auflösung 500°/s: 65.5/°/s
// ===========================================================================
Serial.print(" ACC_angledraga = ");
Serial.print(ACC_angledraga);
Serial.print(" motor : ");
Serial.print(Motor);
Serial.print(" Winkel: ");
Serial.print(Winkel,0);
Serial.print(" Winkel_Soll : ");
Serial.print(Winkel_Soll);
Serial.print(" GYRO : ");
Serial.print(GYRO_ratedraga) ;
Serial.print(" Kp : ");
Serial.print(Kp) ;
Serial.print(" Kd : ");
Serial.print(Kd) ;
Serial.print(" Ki : ");
Serial.print(Ki) ;
Serial.print(" Schalter : ");
Serial.print(Schalter_Box) ;
Serial.print(" K : ");
Serial.println(K);
// ЕБАННАЯ БИБЛИОТЕКА ДРУГОГО ДАТЧКИА
ACC_angledraga = atan2(accel.readAX(),accel.readAZ()) * 180.0 / 3.141592654; // МОЯ КРАСАВИЦА
GYRO_ratedraga = gyro.readDegPerSecY();
// *******************************************************
// ********** K - значения для ПИД-регулятора *************
// *******************************************************
Kp = analogRead(Pin_PID_Regelung_P) * 25.0 / 1023.0; // Разница с Поти фиксирована; Максимум = 25. КОРОЧЕ МАКСИМАЛЬНЫЕ ЗНАЧЕНИЯ ДЛЯ НАСТРОЕК НЕ БОЛЬШЕ 25 И 100
Kd = analogRead(Pin_PID_Regelung_D) * 100.0 / 1023.0; // Дифференциальное соотношение с потенциометром; Максимум = 100
Schalter_Box = digitalRead(Pin_Schalter_Box); // Запросить контакт для состояния переключателя на коробке
if (Schalter_Box == HIGH) // С помощью переключателя на активированном ящике я управляю
{
Ki = analogRead(Pin_PID_Regelung_I) * 2.0 / 1023.0; // Интегральная часть с потенциометром; Максимум = 2
}
else // С помощью переключателя включено управление двигателем коробки
{
K_Motor_rechts = analogRead(Pin_PID_Regelung_I) * 2.0 / 1023.0; // Коэффициент коррекции для синхронной работы двух двигателей; Максимум = 2
}
// ********************************************************************************
// ****************** Фильтр Калмана, расчет PWM и значения двигателя *****************
// ********************************************************************************
Winkel = kalmanCalculate(ACC_angledraga, GYRO_ratedraga, LoopTime_Angepasst); // Рассчитано с помощью фильтра Калмана
if (Winkel > Winkel_Grenze || Winkel < (Winkel_Grenze * (-1)))
{
// ===============================================
// Снос из-за слишком большого угла наклона!
// ===============================================
ST.motor(1, 0); //ОТКЛЮЧИТЬ НАХЕР ОБА МОТОРА
ST.motor(2, 0);
}
else
{
// =========================
// УГОЛ НАКЛОНА В ПОРЯДОСЕ
// =========================
Motor = pid(Winkel, Winkel_Soll, GYRO_ratedraga); // Расчет значения ШИМ для управления двигателями // НЕЗАБУДЬ ЧТО ЭТО ДЛЯ ТРОЙКИ УДАЛИ DRAGA
Motor_rechts = K_Motor_rechts * Motor; // Расчет скорости двигателя, синхронизированный коэффициентом K, для правого двигателя
Motor_links = K_Motor_links * Motor; // Расчет скорости двигателя, синхронизированный коэффициентом K, для левого двигателя
// **************************************************************************************
// ***** Проверьте, активировано ли рулевое управление и измените управление двигателем *****
// **************************************************************************************
Lenkung_Eingang_rechts = digitalRead(Pin_Lenkung_rechts); // Abfrage des Pins für Lenkung nach Rechts
if (Lenkung_Eingang_rechts == HIGH)
{
// ******************************************
// *** Lenkung nach Rechts wurde gedrückt ***
// ******************************************
if (Motor_rechts >= 0) // segway fährt gerade vorwärts oder steht. Welcher Motor abgefragt wird, ist egal.
{
Motor_rechts = Motor_rechts - (int)Lenkung_rechts; // Возможно, также попробуйте с умножением вектора (например, * (1 - 0,1)
Motor_links = Motor_links + (int)Lenkung_rechts; // Возможно, попробуйте также умножить вектор (например, * (1 + 0,1))
}
else // segway fährt gerade rückwärts
{
Motor_rechts = Motor_rechts + (int)Lenkung_rechts; // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 + 0.1) versuchen
Motor_links = Motor_links - (int)Lenkung_rechts; // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 - 0.1) versuchen
}
Lenkung_rechts = Lenkung_rechts + 0.05; // Лучше только для, например, Увеличьте 0,1 на запрос, чтобы рулевое управление не было слишком резким!
if (Lenkung_rechts > Lenkung_max) Lenkung_rechts = Lenkung_max; // Максимальное значение рулевого управления не должно превышаться!
//Lenkung_rechts = constrain(Lenkung_rechts, 0, Lenkung_max); // Правое значение рулевого управления используется в интервале [0, рулевое управление]
}
else
{
Lenkung_rechts = 0.0;
}
Lenkung_Eingang_links = digitalRead(Pin_Lenkung_links); // Abfrage des Pins für Lenkung nach Links
if (Lenkung_Eingang_links == HIGH)
{
// *****************************************
// *** Lenkung nach Links wurde gedrückt ***
// *****************************************
if (Motor_links >= 0) // segway fährt gerade vorwärts oder steht. Welcher Motor abgefragt wird ist egal.
{
Motor_rechts = Motor_rechts + (int)Lenkung_links; // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 + 0.1) versuchen
Motor_links = Motor_links - (int)Lenkung_links; // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 - 0.1) versuchen
}
else // segway fährt gerade rückwärts
{
Motor_rechts = Motor_rechts - (int)Lenkung_links; // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 - 0.1) versuchen
Motor_links = Motor_links + (int)Lenkung_links; // Vielleicht auch mit Multiplikation eines Faktors (z.B. * (1 + 0.1) versuchen
}
Lenkung_links = Lenkung_links + 0.05; // Besser nur um z.B. 0.1 pro Abfrage erhöhen, damit Lenkung nicht zu abrupt erfolgt!
if (Lenkung_links > Lenkung_max) Lenkung_links = Lenkung_max; // Maximaler Lenkungswert darf nicht überschritten werden!
//Lenkung_links = constrain(Lenkung_links, 0, Lenkung_max); // linker Lenkungswert ins Intervall [0,Lenkung_max] gebracht
}
else
{
Lenkung_links = 0.0;
}
// *******************************************************************************************
// ******************************** Управление двигателями ***********************************
// *******************************************************************************************
Motor_rechts = constrain(Motor_rechts, -127, 127); // Значение правого двигателя в интервале [-127,127]
Motor_links = constrain(Motor_links, -127, 127); // Значение левого двигателя в интервале [-127,127]
/*
// Использование функции корня вместо функции линейного привода для улучшения реакции при низких значениях двигателя
// ======================================================================================================================================
if (Motor_rechts >= 0) // rechter Motor dreht vorwärts
{
Motor_rechts = sqrt(127 * Motor_rechts); // Чтобы улучшить реакцию при низких значениях двигателя
ST.motor(2, Motor_rechts);
}
else // rechter Motor dreht rückwärts
{
Motor_rechts = -sqrt(127 * -Motor_rechts); // zur Verbesserung des Ansprechverhaltens bei niedrigen Motorwerten
ST.motor(2, Motor_rechts);
}
if (Motor_links >= 0) // linker Motor dreht vorwärts
{
Motor_links = sqrt(127 * Motor_links); // zur Verbesserung des Ansprechverhaltens bei niedrigen Motorwerten
ST.motor(1, Motor_links);
}
else // linker Motor dreht rückwärts
{
Motor_links = -sqrt(127 * -Motor_links); // zur Verbesserung des Ansprechverhaltens bei niedrigen Motorwerten
ST.motor(1, Motor_links);
}
*/
ST.motor(1, Motor_links);
ST.motor(2, Motor_rechts);
}
// ************************************************************************
// *********************** Выход измеряемых величин **************************
// ************************************************************************
Werteausgabe();
// ******************************************************************
// *********************** Tastaturabfrage **************************
// ******************************************************************
// Tastatureingabe();
// **********************************************************************
// *********************** loop timing control **************************
// **********************************************************************
LoopTime_Bisher = millis() - LoopTime_Start; // Время с момента последнего цикла
if(LoopTime_Bisher < LoopTime_Soll)
{
delay(LoopTime_Soll - LoopTime_Bisher); // Задержка для получения того же времени цикла
}
LoopTime_Angepasst = millis() - LoopTime_Start; // Обновленная длительность последнего цикла должна равняться LoopTime_Soll = например. 10 мсек!
LoopTime_Start = millis(); //Новый запуск цикла
}
// ********************************************************************************************
// ****************** Вывод на последовательный интерфейс ******************************
// ********************************************************************************************
void Werteausgabe()
{
/*
Serial.print(Winkel);
Serial.print(" ");
Serial.println(Motor);
Serial.print(" ");
*/
/*
Serial.print(" Motor: ");
Serial.print(Motor);
Serial.print(" Motor_rechts: ");
Serial.print(Motor_rechts);
Serial.print(" Motor_links: ");
Serial.println(Motor_links);
*/
}
// ******************************************************************************************************
// ***************************************** PID-Steuerung **********************************************
// ******************************************************************************************************
float error;
float last_error = 0;
float pTerm;
float iTerm;
float dTerm;
float integrated_error = 0;
int GUARD_GAIN = 40; // Максимальная угловая погрешность
int pid(float Winkel_aktuell, float Winkel_Vorgabe, float Winkelgeschwindigkeit)
{
error = Winkel_Vorgabe - Winkel_aktuell;
pTerm = Kp * error; // Differenzenanteil
integrated_error = integrated_error + error;
iTerm = Ki * constrain(integrated_error, -GUARD_GAIN, GUARD_GAIN); // Integralanteil
dTerm = Kd * Winkelgeschwindigkeit / 100.0; // Дифференциальный компонент; : 100 для достижения полезных значений!
last_error = error;
return constrain(K*(pTerm + iTerm + dTerm), -127, 127); // Выходное значение двигателя для двух двигателей в пределах [-127,127]
}
// ******************************************************************************************************
// ************************************** Kalman filter module ******************************************
// ******************************************************************************************************
float Q_angle = 0.001; // E(alpha2) = 0.001
float Q_gyro = 0.003; // E(bias2) = 0.003
float R_angle = 0.001; // Sz = 0.03 !!! je größer die Zahl, desto unempfindlicher reagiert der Winkel auf Veränderungen !!!
float x_angle = 0;
float x_bias = 0;
float P_00 = 0, P_01 = 0, P_10 = 0, P_11 = 0;
float dt, y, S;
float K_0, K_1;
float kalmanCalculate(float newAngle, float newRate, int looptime)
{
dt = float(looptime)/1000; // dt in Sekunden
x_angle = x_angle + dt * (newRate - x_bias);
P_00 = P_00 - dt * (P_10 + P_01) + Q_angle * dt;
P_01 = P_01 - dt * P_11;
P_10 = P_10 - dt * P_11;
P_11 = P_11 + Q_gyro * dt;
y = newAngle - x_angle;
S = P_00 + R_angle;
K_0 = P_00 / S;
K_1 = P_10 / S;
x_angle += K_0 * y;
x_bias += K_1 * y;
P_00 -= K_0 * P_00;
P_01 -= K_0 * P_01;
P_10 -= K_1 * P_00;
P_11 -= K_1 * P_01;
return x_angle;
}
// ********************************************************************
// ******** Запрос клавиатуры для изменения параметров PUI *********
// ********************************************************************
int Tastatureingabe()
{
if(!Serial.available()) return 0;
char param = Serial.read(); // get parameter byte
if(!Serial.available()) return 0;
char cmd = Serial.read(); // get command byte
Serial.flush();
switch (param)
{
case 'p':
if(cmd=='+') Kp++;
if(cmd=='-') Kp--;
break;
case 'i':
if(cmd=='+') Ki += 0.1;
if(cmd=='-') Ki -= 0.1;
break;
case 'd':
if(cmd=='+') Kd++;
if(cmd=='-') Kd--;
break;
case 'k':
if(cmd=='+') K += 0.2;
if(cmd=='-') K -= 0.2;
break;
case 'l':
if(cmd=='+') K_Motor_links += 0.1;
if(cmd=='-') K_Motor_links -= 0.1;
break;
case 'r':
if(cmd=='+') K_Motor_rechts += 0.1;
if(cmd=='-') K_Motor_rechts -= 0.1;
break;
default:
Serial.print("?"); Serial.print(param);
Serial.print(" ?"); Serial.println(cmd);
}
Serial.println();
Serial.print("K:"); Serial.print(K);
Serial.print(" Kp:"); Serial.print(Kp);
Serial.print(" Ki:"); Serial.print(Ki);
Serial.print(" Kd:"); Serial.print(Kd);
Serial.print(" K_Motor_links:"); Serial.print(K_Motor_links);
Serial.print(" K_Motor_rechts:"); Serial.println(K_Motor_rechts);
}
А кто Вам сказал, что она не выполняется? Если компилируется, то и выполняется. Поставьте печати перед вызовом и внутри и убедитесь.
У Вас К изначально равен 0. Единица ему присваивается в процедуре calibrateSensors, которую Вы нигде не вызываете. Потому и нулевое значение...
Motor в 254 строке у меня всегда равен нулю. То есть фунция "pid" всегда возвращает ноль. Все давнные входные есть и с датчиков и с потенциметров.
У Вас К изначально равен 0. Единица ему присваивается в процедуре calibrateSensors, которую Вы нигде не вызываете. Потому и нулевое значение...
464returnconstrain(K*(pTerm + iTerm + dTerm), -127, 127);Так как он всегда 0, то и возвращает 0-ое значение? Код заимствованый, и я не могу понять в данной ситуации, от чего вообще зависит знгачение коэффициента "K".464Так как он всегда 0, то и возвращает 0-ое значение?А ожидаете получить что-то другое, умножая на 0?
Повторюсь.
В вашем случае "К" всегда равен 0.
Потому что:
Вы её объявили без инициализации, оответственно, "К" равно 0.
Далее есть процедура calibrateSensors, в которой переменной К присваивается значение 1.
Но эта процедура нигде не используется,а потому значение К так и останется равным 0, равно как всегда будут раны 0 и переменные - Kp,Ki,Kd
(которые почему-то обозваны константами). И даже ручная подстройка через сериал не спасёт - она закомментирована и потому не работает.ЗЫ. А ещё и пропорциональный коэффициент Kp обозван "разная деталь"... В общем, печально всё ))
Motor в 254 строке у меня всегда равен нулю. То есть фунция "pid" всегда возвращает ноль. Все давнные входные есть и с датчиков и с потенциметров.
Так значит она у Вас выполняется, просто её результат Вам не нравится? Ну и нафига было писать "не выполняется"? Написали бы сразу про 0, уже бы проблему решили.
Ну, что, вместо строки 464 пишем следующее:
const int result = constrain(K * (pTerm + iTerm + dTerm), -127, 127); Serial.print("pTerm="); Serial.println(pTerm); Serial.print("iTerm="); Serial.println(iTerm); Serial.print("dTerm="); Serial.println(dTerm); Serial.print("result="); Serial.println(result); Serial.println("-----------------------"); return result;И смотрим, что напечатает. Скорее всего всё станет понятным. Если не станет, то выкладываем сюда новый скетч и выданный результат.
UPDATE: прочитал пост OlegK - он 100% прав. Исправляйте, а про мой совет пока забудьте. Если после исправления результат по-прежнему не будет нравиться, то вернётесь к моему совету.
я не могу понять в данной ситуации, от чего вообще зависит знгачение коэффициента "K".
Ну, то, что код не Ваш - понятно, но хотя бы понимать общую идею Вы должны!
Коэфциент К зависит от фантазии Вашей левой пятки при взгляде на потолок через правое ухо и ни от чего другого, т.е. попросту он подбирается под задачу. Откройте гугл и почитайте что-нибудь про ПИД-регулирование, там про этот коэффициент всё написано.
В серийный монитор ничего не печает. Может из-за того, что команды располагаются в процедуре?
В серийный монитор ничего не печает. Может из-за того, что команды располагаются в процедуре?
"дело было не в бобине..."
Из процедуры тоже должно печатать - если код рабочий.
"дело было не в бобине..."
Блин угарно конечно, я уверен) Но тем не менее , не прнимаю почему не печатает.
Например следуемая за фукцией loop функция Werteausgabe выводится в серийный монитор
void Werteausgabe() { Serial.print(Winkel); Serial.print(" "); Serial.println(Motor); Serial.print(" "); }А из идущей следом процедуры - нет.
Блин угарно конечно, я уверен) Но тем не менее , не прнимаю почему не печатает.
значит ваша функция pid не вызывается. Ее вызов у вас стоит в блоке else (строка 249), видимо в этот блок программа не заходит.
Добавьте еще диагностическую печать в соответсвующий блок if и else
ЗЫ поражают люди, не умея программировать, сразу хватаются за программы в сотни строк. Начинайте с мигания диодом...
Точно.
В else (248 строка ) не заходил, так как Winkel_Grenze (239 строка), всегда была равна нулю. А нулю она была равна по той же причине, что и "K": им присваивались значение в функции calibrateSensors() (94 строка). Перенес это присвоение в функцию Setup. Теперь работает.
Что это означает фактически, как ее "раскоментировать"?
Фактически означает, что вызов функции Tastatureingabe, которая принимает из сериал порта параметры для подстройки ПИД-коэффициентов отключён комментарием в строке 389. Раскомментировать - удалить "две косые палки"
ЗЫ.
>>от чего вообще зависит знгачение коэффициента "K". N
От фантазии автора исходника - этот коэфф. к ПИД-регулированию никак не относится, т.к. вышеуказанный принцип регулирования складывается из суммы пропорциональной (Kp), интегральной (Ki) и дифференциальной(Kd) составляющих и должен нормально работать при правильном подборе этих коэффициентов. Нафига умножать на "К" - хз...
Можете, если интересно, поискать в инете книжку в ПДФ "Карпов" "ПИД регулирование в нестрогом изложении"
Что это означает фактически, как ее "раскоментировать"?
А на горшок за вас не сходить?
Через 2 дня пойдет третий год, как вы занимаетесь ардуиной... а до сих пор не знаете, как комментарии вставляют в программу7
Я тоже так подумал и удалил его.
Про Карпова слышал, спасибо зап совет.
И за помощь огромное спасибо.
У меня был большой перерыв)))
Спасибо большое за помощь!
У меня был большой перерыв)))
Спасибо большое за помощь!
на свободу с чистой совестью
Нафига умножать на "К" - хз...
Это что-то вроде ФНЧ. Позволяет смягчить управление, т.е. замаскировать некоторую небрежность в выборе трёх коэффициентов.