Посоветуйте как правильно управлять ШИМ по заданному алгоритму.
- Войдите на сайт для отправки комментариев
Пт, 12/06/2015 - 23:15
Идея в следующем:
1. С матричной 4х4 клавиатуры вводим число(количество оборотов, которые должен сделать двигатель).
2. Жмем кнопку "старт".
3. Разгоним двигатель до MaxSpeed = analogRead(R1), со скоростью AccSpeed = analogRead(R2).
4. Посчитали половину введенного числа и начинаем останавливать двигатель с скоростью AccSpeed до полной остановки. при этом двигатель должен остановиться на количестве оборотов введеного в начале.
Также естm кнопки "аварийный стоп" и "продолжение".
Практики в программировании не много. с клавиатуры 4х4 вводил число, ШИМ-мом игрался, количество оборотов считал с датчика. А вот в кучу все это собрать - мозгов не хватает. Требуется помощь бывалых.
управление разгоном получилось вот так:
if (encoderValue < encoderSet) { if (encoderValue < encoderSet / 100 * 5 && encoderValue != 0) analogWrite(pwm, 25); if (encoderValue > encoderSet / 100 * 5 && encoderValue < encoderSet / 100 * 10) analogWrite(pwm, 55); if (encoderValue > encoderSet / 100 * 5 && encoderValue > encoderSet / 100 * 10 && encoderValue < encoderSet / 100 * 20) analogWrite(pwm, 120); } if (encoderValue >= encoderSet) { analogWrite(pwm, 0); }Только вот как более плавный и "управляемый" разгон - не могу сообразить...((
двигатель с энкодером получается?
Да, с энкодером. Один ипульс на один оборот.
настраиваешь прерывание на 2 или 3 пине. вешаешь на него энкодер. в прерывании измеряешь время между импульсами, время при каждом прерывании запоминаешь. так можно определить скорость и считать количество оборотов
там же в прерывании можно исходя из параметров управлять шимом, а вот измерять с аналоговых пинов сделать не в прерывании, чтобы не нагружать. хотя и управление шимом можно вынести из прерывания. зависит от того что еще у тебя делает ардуина и какая макс скорость вращения мотора, но обычно можно оставить в прерывании
Вот рабочий мой код:
int pwm = 9; int speed = 0; int step = 1; int encoderSet = 300; //необходимое количество оборотов int accPin = 3; // потенциометр подключен к аналоговому входу 3 int accVal = 0; //начальное значение числа ускорения byte maxSpeed = 200; //максимальная скорость двигателя (0-255) int encoderValue = 0; void count(void); void setup() { Serial.begin(9600); pinMode(2, INPUT); attachInterrupt(0, count, FALLING); encoderValue = 0; Serial.print("Starting\n"); } void loop() { Serial.print("Encoder Value="); Serial.println(encoderValue); // accVal = analogRead(accPin) / 4; // читать аналоговый вход if (encoderValue == 0) { analogWrite(pwm, 10); } if (encoderValue < encoderSet) { if (encoderValue < encoderSet / 100 * 5 && encoderValue != 0) analogWrite(pwm, 25); if (encoderValue > encoderSet / 100 * 5 && encoderValue < encoderSet / 100 * 10) analogWrite(pwm, 55); if (encoderValue > encoderSet / 100 * 5 && encoderValue > encoderSet / 100 * 10 && encoderValue < encoderSet / 100 * 20) analogWrite(pwm, 120); } if (encoderValue >= encoderSet) { analogWrite(pwm, 0); } delay(50); } void count() { encoderValue++; }В коде есть мусор.. пытался плавность разгона устанавливать переменником, но так и не получилось..
добавить переменные.
в лупе при старте flag=1 и time=micros()
в прерывании условие если flag==1 то sped=1000000/(micros()-time) и time=micros() и encodevalue++;
формула приблизительная. от балды почти написал
смысл понимаешь?
далее map значения с аналогового порта до значений скоростей
условие если скорость ниже необходимой то увеличиваем шим с шагом пересчитанной через map из аналогового порта для урпавления скоростью
также можно запоминать промежуточные скорости так как зависимоть оборотов от шима нелинейная и из них считать скорость разгона текущую