Расчеты оборотов 14-ступенчатого шагового двигателя не соответствуют показаниям оборотов.

Я учусь в группе продленного дня в своей школе, и она основана на STEM. В настоящее время мы работаем над проектом, похожим на ховерборд, который питается от 4 аккумуляторов для квадроциклов и включает в себя магниты внутри 14-ступенчатого шагового двигателя. Мы используем Arduino-Uno с потенциометром для изменения скорости. Мы используем часть скрипта для считывания оборотов шагового двигателя. Я давно не программировал на C++, но знаю другие языки. Обороты подскакивают до 80000, и явно не до такой скорости. После того, как он ускорится быстрее, чем когда RPM показывает 80000, он переходит к 0 RPM, а затем иногда после этого, примерно через несколько секунд, он будет читать RPM, которые выглядят точными. Код какой-то неправильный или это физическая проблема? Вот код:

#include <Servo.h> //Используем библиотеку Servo для генерации ШИМ
Servo ESC; //имя сервообъекта, здесь ESC

int hallsensor = 2;                // Датчик Холла на выводе 2

volatile unsigned int counter;

unsigned long rpm;

unsigned long passedtime;

unsigned long intermediatevlue, timeSinceLastMeasurement;

int loopcounter;

void isr()

{

  //Каждое вращение эта функция прерывания запускается дважды, так что примите это во внимание для

  // вычисление RPM

  // Количество обновлений

  counter++;


}


void setup()
{
  ESC.attach(9, 1000, 2000); //Сгенерировать ШИМ на выводе 9 Arduino с шириной импульса 1000-2000

  Serial.begin(9600);

  //Инициирует последовательную связь

  attachInterrupt(0, isr, RISING); //Прерывания вызываются при росте входного сигнала

  pinMode(hallsensor, INPUT); //Устанавливает датчик Холла в качестве входных данных

  counter = 0;
  loopcounter = 0;

  rpm = 0;

  passedtime = 0; //Инициализируем значения

}
void loop()
{

  int throttle = analogRead(A0); //Чтение напряжения с потенциометра
  throttle = map(throttle, 0, 1023, 0, 180); // Сопоставьте значения 0-102 от горшка с 0-180 bcs, сервопривод работает только от 0-180
  ESC.write(throttle); //на основе значения дроссельной заслонки генерируем ШИМ-сигнал
  loopcounter++;


  if (loopcounter >= 5000)
  {
    detachInterrupt(digitalPinToInterrupt(hallsensor)); //Прерывания отключены

    timeSinceLastMeasurement = millis() - passedtime;

    intermediatevlue = 60000 / timeSinceLastMeasurement;

    rpm = (intermediatevlue * counter) / 14;

    //об/мин = 60*1000/(millis() - прошедшее время)*counter;



    // Serial.print("прошло время =");
    // Serial.println(прошедшее время);
    // Serial.print("счетчик =");
    // Serial.println(счетчик);

    counter = 0;


    Serial.print("RPM=");

    Serial.println(rpm); //Выводим результат для мониторинга

    passedtime = millis();
    attachInterrupt(0, isr, RISING);   //Перезапускаем обработку прерывания
    loopcounter = 0;
  }
}

, 👍0

Обсуждение

Похоже, вы получаете больше прерываний, чем можете обработать. Два предложения: просто установите флаг в процедуре прерывания и дайте основному коду обработать его. Во-вторых, в этой части есть таймер счетчика, который будет работать намного быстрее, чем прерывания, вы можете это проверить., @Gil

Ваше описание меня немного смущает. Вы управляете скоростью двигателя с помощью ШИМ-сигнала. Используете ли вы специальную плату драйвера для управления шаговым двигателем с помощью ШИМ, или это всего лишь своего рода датчик для определения оборотов? Ваш код обрабатывает прерывания для перехода датчика Холла. Это означает, что в сигнале датчика Холла есть четкий нарастающий фронт. Если вы используете катушки / магниты шагового двигателя, сигналы могут быть странными, а прерывания могут срабатывать чаще, чем вы думаете., @Peter Paul Kiefer

Возможно, вы могли бы добавить скетч вашей установки, что вы подключаете к контакту датчика Холла? Что управляет ШИМ-сигналом? Влияет ли сигнал ШИМ на показания датчика? Это несколько открытых вопросов для меня., @Peter Paul Kiefer

@Gil: при 80000 об/мин вы ожидаете одно прерывание каждые 53,6 мкс, что должно подойти для Uno. Этот ISR уже очень короткий. Замена его ISR, который только устанавливает флаг, не является хорошим вариантом. Мало того, что вы не получите многого, это также приведет к потере импульсов, так как analogRead() занимает более 104 мкс., @Edgar Bonet

Вы можете посмотреть на сигнал датчика Холла на прицеле? Насколько он чистый?, @Edgar Bonet

Серийный. Печать занимает около 400~600 микросекунд., @Gil