Arduino функции мешают друг другу

Есть код со снятием данных температуры, пид регулятора нагревателя, и 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);

}

кому надо?

“Плохому ардуинщику функции мешают”.
Это не я, это поговорка народная)
В каком месте не работает?

1 лайк

Мне надо

Ну я задаю скорость а вместо того чтобы разгоняться двигатель дергается( getsensor и пид регулятор прерывают разгон)

Ну так мы ж не запрещаем, делай, раз надо.

1 лайк

Понял спасибо

Остроумно однако

А что ты хотел при таком подходе к делу?

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

Только оплатить не забудь.

что-то вы придумываете. У вас в loop() вообще нет обращений к ПИД и сенсорам, исключая первые 10 секунд работы. Одни только моторы и ничего больше.

Так что дело не в том, что ПИД или сенсоры мешают, у вас похоже код для степперов нерабочий.

Моторы проверены в отдельном скетче

Ок, у вас ПИД и сенсоры только в первом (нулевом ) кейсе в лупе. Если их закомментировать - моторы работают?

Да, работают

Тогда значит переписывайте функцию getsensors() как неблокирующую. То есть один раз вошли - только кинули запрос на измерение и сразу вышли. Еще через секунду зашли - прочитали значение.
И не считывайте значений слишком часто. Раз в десять -двадцать секунд более чем достаточно.

ПИД пока можете не трогать, если он и влияет на моторы, то крайне мало.

Это у Вас было

Вы что-нибудь поняли? Каков алгоритм работы должен быть. Как работает на самом деле? Что не устраивает? Нам самим догадываться? Так у меня кофейный автомат - в нём гущи нет.

Или Вам в лом подробно описать? Ну, если Вам в лом решать свою проблему, то с чего Вы взяли, что кому-то не в лом решать чужую?

Иной раз просто поражаюсь людЯм! Это, ведь, тебе же надо! Так чё ж ты, собака, языком то пошевелить не можешь? Ну не пиздец ли?

2 лайка

Так для гущи там специальный лоток.

1 лайк

Так она там сухая, на ней хрен погадаешь.