Проблемы с ШИМ и подключением прерываний
Я пытаюсь управлять скоростью двигателя постоянного тока с помощью ШИМ.
Я использую Arduino UNO для отправки ШИМ-сигнала на мосфет Velleman vma411, чтобы изменить среднее напряжение моего двигателя, который подключен к стабилизированному источнику питания (около 10 В).
Чтобы получить частоту вращения моего двигателя, у меня есть датчик Холла рядом с осью вращения. Каждые пол-оборота датчик меняет значение (0 или 5 В).
Чтобы обнаружить изменения, я использую attachInterrupt()
для обнаружения изменений.
Когда Arduino не отправляет ШИМ-сигнал, измеренная частота в порядке (я проверил это с помощью осциллографа). НО когда я посылаю сигнал ШИМ на двигатель, частота больше не имеет смысла (примерно 1 значение из 3 в 10 раз превышает ожидаемое).
Чтобы решить эту проблему, я попробовал три разных способа:
- установка конденсатора (от 100 до 2200 микроФ) между Arduino и сигнальным портом МОП-транзистора,
- используя среднее значение последних 10 измеренных частот.
- добавление числового фильтра,
- используя один контакт
земля
для мосфета и другой для порта датчика,
Тем не менее, любая из этих идей действительно сработала для меня.
Полагаю, это может быть связано с какими-то проблемами с электрическим отражением? Может быть, мне стоит сменить мосфет или использовать L298N?
Заранее спасибо
Мой код, цель которого — точно измерить частоту вращения при отправке ШИМ-сигнала на МОП-транзистор:
/*
alimentation du capteur : 4V
mesure précise jusqu'à au moins 10V
*/
//порты
int rotation_port = 3;
int mosfet_sig_port = 11;
int debug_port = 10;
//меры:
volatile long t_new;
volatile long t_old;
volatile long res;
volatile float frequence;
volatile float old_frequence;
// утверждающий
float rapport_cyclique = 127; //вход 0 и 255
void setup() {
pinMode(rotation_port, INPUT_PULLUP); // прерывание заливки
attachInterrupt(digitalPinToInterrupt(rotation_port), capteur_hall_changement, FALLING);
pinMode(debug_port, OUTPUT);
pinMode(mosfet_sig_port, OUTPUT);
Serial.begin(115200);
old_frequence = 100;
}
void capteur_hall_changement() {
t_new = micros();
res = 1.0 / (t_new - t_old) * 1000000;
if (res/old_frequence <= 1.5) {
frequence = res;
old_frequence=frequence;
}
t_old = t_new;
Serial.println(frequence);
}
void loop() {
// Отправка сигнала PWM при цифровой вылете mosfet_sig_port
analogWrite(mosfet_sig_port, int(rapport_cyclique));
}
1 ответ
Когда вы используете прерывания, ваш ШИМ может работать неправильно, поэтому не используйте их оба одновременно.
- Управление скоростью вентилятора с помощью библиотеки Arduino PID
- Как устранить шум от вентилятора 12 В с ШИМ-управлением на низкой скорости
- Как управлять 6 шаговыми двигателями с помощью Arduino?
- Не могу контролировать скорость двигателей постоянного тока с помощью analogWrite()
- Как Arduino Uno может поддерживать до 12 сервоприводов, если у него всего 6 цифровых выводов ШИМ?
- L298N издает звуковые сигналы и дает сбой при получении определенных значений AnalogWrite
- Ускорение двигателя постоянного тока с помощью ШИМ
- Контакты ШИМ серводвигателей, Arduino Uno
1. Не используйте Serial.println() в контексте прерывания. 2.
frequence
иold_frequence
избыточны (они всегда одни и те же). 3. В чем смысл «if (res/old_frequence <= 1.5)»?, @Edgar Bonetцель
if (res/old_frequence <= 1.5)
— удалить меры, которые не должны появляться. Я хочу измерить частоту около 100 Гц, но некоторые измерения без причины дают частоту 200 Гц, поэтому целью была их численная фильтрация., @Grégoire Lefebvre