Есть код со снятием данных температуры, пид регулятора нагревателя, и 2 шаговиков управляемых ШИМ, надо чтобы все работало одновременно , а то двигатели вообще не крутятся. Код прилагаю.
#include <AccelStepper.h>
#include <ModbusRtu.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Определение пинов клапана
const int pinKZ = 46; // Пин для клапана загрузочного
const int pinKS = 48; // Пин для клапана сливного
// Пины подключения для двух двигателей (шаговых насосов)
#define DIR_PIN1 4 // НР - Направление
#define STEP_PIN1 3 // НР - Шаг
#define ENABLE_PIN1 5 // НР - Включение
#define DIR_PIN2 6 // НЗ - Направление
#define STEP_PIN2 7 // НЗ - Шаг
#define ENABLE_PIN2 8 // НЗ - Включение
#define NAGREVATEL 9
// Настройки Modbus
uint8_t id = 1;
uint8_t txenpin = 2;
Modbus modbus(id, Serial3, txenpin);
const int REGISTERS_SIZE = 64;
uint16_t modbus_registers[REGISTERS_SIZE];
//Регистры modbus
const int TEMPERATURE_1 = 0;
const int TEMPERATURE_2 = 1;
const int TEMPERATURE_3 = 2;
const int TEMPERATURE_4 = 3;
const int SPEED_ENGINE_1 = 4;
const int DIRECTION_ENGINE_1 = 5;
const int SPEED_ENGINE_2 = 6;
const int DIRECTION_ENGINE_2 = 7;
const int KZ = 8;//КЛАПАН ЗАГРУЗОЧНЫЙ
const int KP = 9;
const int POWER_OFF_ON = 10;
const int CHANGE_LIQUID = 11;
const int WORK_TIME = 12;
const int INTERVAL_EUV = 13;
const int SENSOR_EUV = 14;
const int POLL_INTERVAL = 15;
const int PH_VALUE = 16;
const int OXYGEN_VALUE = 17;
const int PROCENT = 18;
const int TEMPNAGREVATEL= 19;
// Создаем объекты stepperNR (НР) и stepperNZ (НЗ)
AccelStepper stepperNR(AccelStepper::DRIVER, STEP_PIN1, DIR_PIN1);
AccelStepper stepperNZ(AccelStepper::DRIVER, STEP_PIN2, DIR_PIN2);
// Настройки для датчика температуры DS18B20
int sensorPin1 = 22;
int sensorPin2 = 23;
int sensorPin3 = 24;
int sensorPin4 = 25;
float temperature1 = 0.0;
float temperature2 = 0.0;
float temperature3 = 0.0;
float temperature4 = 0.0;
OneWire oneWire1(sensorPin1);
DallasTemperature sensors1(&oneWire1);
OneWire oneWire2(sensorPin2);
DallasTemperature sensors2(&oneWire2);
OneWire oneWire3(sensorPin3);
DallasTemperature sensors3(&oneWire3);
OneWire oneWire4(sensorPin4);
DallasTemperature sensors4(&oneWire4);
float targetSpeed1 = 0;
float targetSpeed2 = 0;
unsigned long previousMillis = 0; // Для хранения времени последнего события
int step = 0; // Шаг алгоритма
// const uint16_t modbus_registers[POWER_OFF_ON]=0;
// const uint16_t modbus_registers[CHANGE_LIQUID]=0;
void setup() {
Serial3.begin(115200); // Инициализация основного серийного порта
sensors1.begin(); // Инициализация библиотеки DallasTemperature
sensors2.begin();
sensors3.begin();
sensors4.begin();
modbus.start();
// Устанавливаем максимальную скорость и ускорение для обоих двигателей
stepperNR.setMaxSpeed(1000); // Пример максимальной скорости
stepperNR.setAcceleration(50); // Пример ускорения
stepperNZ.setMaxSpeed(1000); // Пример максимальной скорости
stepperNZ.setAcceleration(50); // Пример ускорения
// Устанавливаем пины ENABLE_PIN как выход
pinMode(ENABLE_PIN1, OUTPUT);
pinMode(ENABLE_PIN2, OUTPUT);
// По умолчанию отключаем драйверы
digitalWrite(ENABLE_PIN1, HIGH);
digitalWrite(ENABLE_PIN2, HIGH);
pinMode(pinKZ, OUTPUT);
pinMode(pinKS, OUTPUT);
digitalWrite(pinKZ, LOW); // КЗ закрыт
digitalWrite(pinKS, LOW); // КС закрыт
}
void adjustStepper(AccelStepper &stepper, float targetSpeed, float baseAcceleration, int enablePin) {
unsigned long currentTime = millis();
static unsigned long lastUpdateTime = 0;
unsigned long elapsedTime = currentTime - lastUpdateTime;
//targetSpeed=targetSpeed*100;
if (elapsedTime > 0) {
float currentSpeed = stepper.speed();
float speedDifference = targetSpeed - currentSpeed;
float speedIncrement = baseAcceleration * (elapsedTime / 1000.0);
// Регулировка скорости с учетом направления
if (abs(speedDifference) > 0.01 || targetSpeed != 0) { // Используем небольшой порог для сравнения
float newSpeed = currentSpeed + (speedDifference > 0 ? speedIncrement : -speedIncrement);
// Ограничиваем новую скорость целевой скоростью, чтобы избежать перерегулирования
if ((speedDifference > 0 && newSpeed > targetSpeed) || (speedDifference < 0 && newSpeed < targetSpeed)) {
newSpeed = targetSpeed;
}
stepper.setSpeed(newSpeed);
} else if (targetSpeed == 0 && abs(currentSpeed) <= speedIncrement) {
// Явно останавливаем двигатель, если целевая скорость равна 0 и текущая скорость достаточно мала
stepper.setSpeed(0);
}
// Управление драйвером
if (targetSpeed != 0 || abs(stepper.speed()) > 0.01) {
digitalWrite(enablePin, LOW); // Включаем драйвер
} else {
digitalWrite(enablePin, HIGH); // Выключаем драйвер, если двигатель остановился
}
}
// Обновляем время последнего обновления
lastUpdateTime = currentTime;
stepper.runSpeed(); // Обеспечиваем движение двигателя
}
void getsensor() {
unsigned long currentMillis = millis();
sensors1.requestTemperatures(); // Запрос температуры с датчика
temperature1 = sensors1.getTempCByIndex(0);
sensors2.requestTemperatures(); // Запрос температуры с датчика
temperature2 = sensors2.getTempCByIndex(0);
sensors3.requestTemperatures(); // Запрос температуры с датчика
temperature3 = sensors3.getTempCByIndex(0);
sensors4.requestTemperatures(); // Запрос температуры с датчика
temperature4 = sensors4.getTempCByIndex(0);
modbus_registers[TEMPERATURE_1] = static_cast<uint16_t>(temperature1 * 100);
modbus_registers[TEMPERATURE_2] = static_cast<uint16_t>(temperature2 * 100);
modbus_registers[TEMPERATURE_3] = static_cast<uint16_t>(temperature3 * 100);
modbus_registers[TEMPERATURE_4] = static_cast<uint16_t>(temperature4 * 100);
}
int computePID(float input, float setpoint, float kp, float ki, float kd, float dt, int minOut, int maxOut) {
float err = setpoint - input;
static float integral = 0, prevErr = 0;
integral = constrain(integral + (float)err * dt * ki, minOut, maxOut);
float D = (err - prevErr) / dt;
prevErr = err;
return constrain(err * kp + integral + D * kd, minOut, maxOut);
}
void loop() {
unsigned long currentMillis = millis();
if (modbus_registers[POWER_OFF_ON]!=0 && currentMillis - previousMillis >= modbus_registers[WORK_TIME]*3600){
switch (modbus_registers[CHANGE_LIQUID]) {
case 0: // Ожидание активации
digitalWrite(pinKZ, LOW); // КЗ закрыт
digitalWrite(pinKS, LOW); // КС закрыт
targetSpeed1 = modbus_registers[SPEED_ENGINE_1]*100;
targetSpeed2 = modbus_registers[SPEED_ENGINE_2]*100;
// Регулировка скорости обоих двигателей
adjustStepper(stepperNR, targetSpeed1,100, ENABLE_PIN1); // 0.5 - пример базового ускорения
adjustStepper(stepperNZ,targetSpeed2 , 100, ENABLE_PIN2); // 0.5 - пример базового ускорения
getsensor();
analogWrite(NAGREVATEL, computePID(modbus_registers[TEMPERATURE_4]/100, modbus_registers[TEMPNAGREVATEL], 6.67, 1.73, 6.42, 0.01, 0, 255));
previousMillis = currentMillis; // Сброс таймера
break;
case 1: // Этап 1: КЗ закрыт, КС открыт, НР включен
digitalWrite(pinKZ, LOW);
digitalWrite(pinKS, HIGH);
adjustStepper(stepperNR, modbus_registers[SPEED_ENGINE_1]*100,100, ENABLE_PIN1); // Разгоняем НР до 1000
if (currentMillis - previousMillis >= 10000) { // Время т
step = 2;
previousMillis = currentMillis; // Сброс таймера
}
break;
case 2: // Этап 2: КЗ открыт, НЗ включен, НР выключен
digitalWrite(pinKZ, HIGH);
adjustStepper(stepperNR,0,100, ENABLE_PIN1); // Останавливаем НР
adjustStepper(stepperNZ, modbus_registers[SPEED_ENGINE_2]*100, 100, ENABLE_PIN2); // Разгоняем НЗ до 1000
if (currentMillis - previousMillis >= 15000) { // Время т1
step = 3;
previousMillis = currentMillis; // Сброс таймера
}
break;
case 3: // Этап 3: НР включается снова
adjustStepper(stepperNZ, 0, 100, ENABLE_PIN2); // Останавливаем НЗ
adjustStepper(stepperNR, modbus_registers[SPEED_ENGINE_1]*100,100, ENABLE_PIN1); // Разгоняем НР до 1000 снова
if (currentMillis - previousMillis >= 20000) { // Время т2
step = 4;
previousMillis = currentMillis; // Сброс таймера
}
break;
case 4: // Этап 4: НР выключить, КС закрыть, НР включить
adjustStepper(stepperNR, 0,100, ENABLE_PIN1); // Останавливаем НР
digitalWrite(pinKS, LOW); // КС закрыт
if (currentMillis - previousMillis >= 25000) { // Пауза перед включением НР
step = 5;
previousMillis = currentMillis; // Сброс таймера
}
break;
case 5: // Этап 5: НР включается снова
adjustStepper(stepperNR, modbus_registers[SPEED_ENGINE_1]*100,100, ENABLE_PIN1); // Разгоняем НР до 1000 снова
if (currentMillis - previousMillis >= 30000) { // Время т3
step = 6;
previousMillis = currentMillis; // Сброс таймера
}
break;
case 6: // Этап 6: НЗ выключить, завершение цикла
adjustStepper(stepperNR, 0,100, ENABLE_PIN1); // Останавливаем НР
adjustStepper(stepperNZ, 0, 100, ENABLE_PIN2); // Останавливаем НЗ
if (currentMillis - previousMillis >= 35000) { // Время т4 для остановки обоих насосов
step = 0; // Сброс шага для возможного повторения цикла
previousMillis = currentMillis; // Сброс таймера
}
break;
}
}
else{
digitalWrite(ENABLE_PIN1, HIGH);
digitalWrite(ENABLE_PIN2, HIGH);
}
modbus.poll(modbus_registers, REGISTERS_SIZE);
}