Il n'y a pas si longtemps, j'étais préoccupé par la question de savoir comment faire un entraînement pour des systèmes CNC sur un moteur de collecteur, et même avec un retour, et cela fonctionnerait sur Modbus RTU.
J'avais à ma disposition, Arduino UNO, Driver pour L298N, un moteur collecteur d'un lecteur de siège auto AEG pour 12V, interrupteur photo à 2 espaces.
Dès le début, j'ai soudé une écharpe avec 2 photo-interrupteurs, selon ce schéma.

Sous sa forme finale, tout ressemble à ceci:

L'essence de cette chose laide - une allumette traverse le premier disjoncteur depuis le début, puis le second, de sorte que le microcontrôleur comprend dans quelle direction le moteur tourne.
Toutes les connexions ressemblent à ceci:
d2 est le premier interrupteur photo;
d3 est le deuxième interrupteur photo;
d5 - Sortie PWM pour rotation vers la gauche;
d6 - Sortie PWM pour rotation vers la droite;
Tout était connecté et je me suis assis pour écrire du code, à la fin de mon tourment a donné naissance à ce qui suit:
#include <ModbusRtu.h> #define ID 1 // , , TX Modbus slave(ID, 0, 0); int8_t state = 0; // uint16_t au16data[11];// modbus #include <PID_v1.h> // double Setpoint1, Input1, Output1; double Setpoint2, Input2, Output2; double Kp = 1, Ki = 2.5, Kd = 0.5; PID myPID1(&Input1, &Output1, &Setpoint1, Kp, Ki, Kd, DIRECT); //1- PID myPID2(&Input2, &Output2, &Setpoint2, Kp, Ki, Kd, REVERSE); //2- int LeftPWM = 5; // int RightPWM = 6; // volatile byte EncA, EncB = 0; // volatile int Position = 0; // int SetPosition = 0; // void setup() { slave.begin(9600); pinMode (LeftPWM, OUTPUT); pinMode (RightPWM, OUTPUT); attachInterrupt(0, ChangePosition1, FALLING); // 0-(pin2) ChangePosition1() attachInterrupt(1, ChangePosition2, FALLING); // 1-(pin3) ChangePosition2() Setpoint1 = 0; Setpoint2 = 0; digitalWrite (LeftPWM, LOW); digitalWrite (RightPWM, LOW); } // 0 void ChangePosition1() // ! { EncA = 1; if (EncA == 1 && EncB == 1) { EncA = 0; EncB = 0; Position++; } } // 1 void ChangePosition2() { EncB = 1; if (EncA == 1 && EncB == 1) { EncA = 0; EncB = 0; Position--; } } void loop() { // ModBus // state = slave.poll(au16data, 11); // au16data[2] = Position;// // SetPosition = au16data[3];// // au16data[8] = slave.getInCnt(); // au16data[9] = slave.getOutCnt(); // au16data[10] = slave.getErrCnt();// if (SetPosition == Position) // { myPID1.SetMode(MANUAL); myPID2.SetMode(MANUAL); Output1 = 0; Output2 = 0; digitalWrite (LeftPWM, LOW); digitalWrite (RightPWM, LOW); } if (SetPosition < Position) { myPID2.SetMode(AUTOMATIC); Setpoint2 = SetPosition; Input2 = Position; myPID2.Compute(); analogWrite (LeftPWM, Output2); digitalWrite (RightPWM, LOW); } if (SetPosition > Position) { myPID1.SetMode(AUTOMATIC); Setpoint1 = SetPosition; Input1 = Position; myPID1.Compute(); analogWrite (RightPWM, Output1); digitalWrite (LeftPWM, LOW); } }
Et maintenant, c'est partie par partie sur l'ordinateur. SinplLight SCADA a été choisi par les gars pour que tout bouge gratuitement. Donc - c'est à quoi ressemblent les paramètres dans le scud.



L'interface a été réalisée comme ceci:

En conséquence, nous avons obtenu le moteur subordonné au curseur dans le scud, accélère et freine le moteur en douceur, si vous faites défiler manuellement l'ancre du moteur, cela ne permet pas de le faire et revient. Merci de votre attention. Et voici une vue générale du gâchis.
