Библиотека PID

Янсун
Сб, 05 января 2019 13:51
Всем привет,

Я пытался использовать библиотеку PID Arduino:

https: // github.com/br3ttb/arduino-pid-library

Я строю настройку сначала Arduino, а затем та же настройка с STM32F1C8.

Arduino Code: #include #define MotEnable 9 //Motor Enamble pin Runs on PWM signal #define MotFwd 6 // Motor Forward pin #define MotRev 7 // Motor Reverse pin String readString; //This while store the user input data int User_Input = 0; // This while convert input string into integer int encoderPin1 = 2; //Encoder Output 'A' must connected with intreput pin of arduino. int encoderPin2 = 3; //Encoder Otput 'B' must connected with intreput pin of arduino. volatile int lastEncoded = 0; // Here updated value of encoder store. volatile long encoderValue = 0; // Raw encoder value int PPR = 2400; // Encoder Pulse per revolution. int angle = 360; // Maximum degree of motion. int REV = 0; // Set point REQUIRED ENCODER VALUE int lastMSB = 0; int lastLSB = 0; double kp = 4 , ki = 0 , kd = 1; // modify for optimal performance double input = 0, output = 0, setpoint = 0; PID myPID(&input, &output, &setpoint, kp, ki, kd, DIRECT); void setup() { pinMode(MotEnable, OUTPUT); pinMode(MotFwd, OUTPUT); pinMode(MotRev, OUTPUT); Serial.begin(9600); //initialize serial comunication pinMode(encoderPin1, INPUT_PULLUP); pinMode(encoderPin2, INPUT_PULLUP); digitalWrite(encoderPin1, HIGH); //turn pullup resistor on digitalWrite(encoderPin2, HIGH); //turn pullup resistor on //call updateEncoder() when any high/low changed seen //on interrupt 0 (pin 2), or interrupt 1 (pin 3) attachInterrupt(0, updateEncoder, CHANGE); attachInterrupt(1, updateEncoder, CHANGE); //TCCR1B = TCCR1B & 0b11111000 | 1; // set 31KHz PWM to prevent motor noise myPID.SetMode(AUTOMATIC); //set PID in Auto mode myPID.SetSampleTime(1); // refresh rate of PID controller myPID.SetOutputLimits(-250, 250); // this is the MAX PWM value to move motor, here change in value reflect change in speed of motor. }//end setup void loop() { while (Serial.available()) { //Check if the serial data is available. delay(3); // a small delay char c = Serial.read(); // storing input data readString += c; // accumulate each of the characters in readString } if (readString.length() >0) { //Verify that the variable contains information Serial.println(readString.toInt()); //printing the input data in integer form User_Input = readString.toInt(); // here input data is store in integer form } /* if( input<5){ User_Input = 360; } if(input > 2350){ User_Input = 0; } */ REV = map (User_Input, 0, angle, 0, PPR); // mapping degree into pulse setpoint = REV; //PID while work to achive this value consider as SET value input = encoderValue ; // data from encoder consider as a Process value //myPID.Compute(); // calculate new output //pwmOut(output); Serial.print(" enc: "); Serial.println(input); }//end loop void pwmOut(int out) { if (out > 0) { // if REV > encoderValue motor move in forward direction. analogWrite(MotEnable, out); // Enabling motor enable pin to reach the desire angle forward(); // calling motor to move forward } else { analogWrite(MotEnable, abs(out)); // if REV < encoderValue motor move in forward direction. reverse(); // calling motor to move reverse } readString=""; // Cleaning User input, ready for new Input }//End pwmOut void updateEncoder(){ int MSB = digitalRead(encoderPin1); //MSB = most significant bit int LSB = digitalRead(encoderPin2); //LSB = least significant bit int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++; if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --; lastEncoded = encoded; //store this value for next time } void forward () { digitalWrite(MotFwd, HIGH); digitalWrite(MotRev, LOW); } void reverse () { digitalWrite(MotFwd, LOW); digitalWrite(MotRev, HIGH); } void finish () { digitalWrite(MotFwd, LOW); digitalWrite(MotRev, LOW); }

Mrburnette
Сб 05 января 2019 г. 16:37
[Янсун - Сб 05 января 2019 г. 13:51] - ...
Теперь Arduino работает нормально, а код STM32 не. Я строю все одинаково, и с STM32 двигатель продолжает вращаться. ICANT Найдите что -нибудь в коде, и для меня это выглядит так, как будто код LIB должен быть совместим с STMDUINO? Направление энкодера - это OKE, но выход PID не реагирует, как код Arduino.

Кто -то подсказка?
«Подсказка» - это эскиз не работает, как и ожидалось; Поэтому ваш код или библиотека виноват. Если 8-битные доски AVR & Работа о коде, вероятно, проблема связана с тем, что обычно называют портированием - коррекция кода и корректировка для архитектурных предположений, сделанных библиотеками. Примером является то, что целое число AVR составляет 16 бит, а целое число STM32-32-битный.

Несколько лет назад участники были перенесены ряд общих библиотек: здесь

Кроме того, участники опубликовали успехи на форуме здесь

ИМО, самой большой проблемой является участники, которые «хотят» патикулярную библиотеку, но не имеют знаний, чтобы выполнить порт сами. Вероятно, именно здесь Ардуино, как концепция, наносит наибольший вред; Концепция библиотеки позволяет программистам работать за пределами своего уровня квалификации и быть удовлетворенными своими посредственными навыками кодирования.

То, что здесь сломано, это не библиотека AVR, а ваше ожидание. Вам просто нужно вступить в изучение того, как работают библиотеки и как изменить код библиотеки, чтобы соответствовать вашим ожиданиям. Это усилие сделает вас гораздо более осведомленным и гораздо лучшим программистом, способным перемещаться через архитектуру чипов и наборы инструментов программного обеспечения.

Или вы можете просто попросить форум, чтобы кто -то «исправил» библиотеку для вас.

Луча

Эдогальдо
Сб, 05 января 2019 г., 17:29
Я вижу несколько различий в двух версиях, например, использование 2 внешних прерываний в версии Arduino, что я могу’T СИТИТЕ В версии STM, так что два наброска Дон’t кажется эквивалентным на первой проверке..

Стивестронг
Сб 05 января 2019 г., 18:05
Вы не установили режим контактов PB6/7.

Янсун
Сб, 05 января 2019 г. 20:01
[Стивестронг - Сб 05 января 2019 г., 18:05] - Вы не установили режим контактов PB6/7.
Спасибо!
[Эдогальдо - Сб 05 января 2019 г., 17:29] - Я вижу несколько различий в двух версиях, например, использование 2 внешних прерываний в версии Arduino, что я могу’T СИТИТЕ В версии STM, так что два наброска Дон’t кажется эквивалентным на первой проверке..
Я не могу использовать код энкодера, такой как код Arduino (Google Direct Manipulation Port Why), эта часть действительно отличается, но похоже, что эта часть работает.
[Mrburnette - Сб 05 января 2019 г. 16:37] - То, что здесь сломано, это не библиотека AVR, а ваше ожидание. Вам просто нужно вступить в изучение того, как работают библиотеки и как изменить код библиотеки, чтобы соответствовать вашим ожиданиям. Это усилие сделает вас гораздо более осведомленным и гораздо лучшим программистом, способным перемещаться через архитектуру чипов и наборы инструментов программного обеспечения.
Я работаю над этим. То, что я уже сделал, скопировал LIB на отдельную вкладку, чтобы я мог изменить библиотеку и «отлаживать». Я надеялся на глупость, как упомянул Стевенстронг, но, к сожалению, это не решило проблему. Я не люблю просить кого -то другого, чтобы решить мой код, но я на несколько уроков C ++ : Geek:

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

.час: #ifndef Led_h #define Led_h #include "Arduino.h" class Led{ public: Led(int pin); void init(); void toggleLed(); void handler_led(); private: }; #endif

Дэнниф
Сб, 05 января 2019 г., 21:36
Библиотека PID Arduino Вам может быть полезным вернуться к тому, что вы имели в виду под «библиотекой».

В целом, вы хотите, чтобы библиотека была черным ящиком с соответствующими входами и выходами. И когда это возможно, имейте хорошую границу, которая отделяет сторону программного обеспечения от аппаратной стороны.

Процедура PID - это та, которая должна быть полностью реализована в программном обеспечении с четко определенным вводом и выходным набором переменных. В среде MCU такая подпрограмма может периодически называться аппаратным обеспечением для выполнения сбора данных, расчетов и ослабления выхода.

С этой точки зрения бесполезно иметь набор процедур библиотеки PID, которые 1) приходят ваш аппаратный и программный реализацию - такая подпрограмма является специфичной для приложения и трудно переносить в следующее приложение / платформу; и/или 2) имеет предварительные сетки, которые пользователь не может повлиять на.

Вот пример моей реализации PID: https: // dannyelectronics.WordPress.ком/ ... -attiny85/

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

Очевидно, все это зависит от вашего конкретного определения «библиотеки». Мой не абсолютный или единственный способ сделать это.

Стивестронг
Сб, 05 января 2019 22:50
[Янсун - Сб, 05 января 2019 г. 20:01] - Ошибка: no matching function for call to 'HardwareTimer::attachCompare1Interrupt()'

Янсун
Солнце 06 января 2019 11:11
[Стивестронг - Сб 05 января 2019 г. 22:50] -
[Янсун - Сб, 05 января 2019 г. 20:01] - Ошибка: no matching function for call to 'HardwareTimer::attachCompare1Interrupt()'

Стивестронг
Солнце 06 января 2019 13:57
Ах, это вообще не будет работать, потому что функция, которую вы хотите прикрепить, является членом класса. И указывать на функцию члена класса очень сложно...
Сделать эту функцию автономной, и она будет работать.

Моду
Солнце 06 января 2019 14:26
[Стивестронг - Солнце 06 января 2019 г., 13:57] - и указывать на функцию члена класса очень сложно...
Да, это еще один слой сложности на этом этапе.

Еда для размышлений, Если вы следите за поездом C ++ соуса.

Янсун
Пн, 07 января 2019 г., 18:01
[Стивестронг - Солнце 06 января 2019 13:57] - Ах, это вообще не будет работать, потому что функция, которую вы хотите прикрепить, является членом класса. И указывать на функцию члена класса очень сложно...
Сделать эту функцию автономной, и она будет работать.
Конечно, почему я этого не увидел? Может, мне нужно взглянуть на то, как указать на функцию в другом классе для начала. Но.. На данный момент не нужно для этого этапа, я собираюсь поместить таймер на вкладку «Настройка на кулаке», сделаю работу.

Спасибо!

Прогемем