Посоветуйте как правильно управлять ШИМ по заданному алгоритму.

Life23
Offline
Зарегистрирован: 10.08.2013

Идея в следующем:

1. С матричной 4х4 клавиатуры вводим число(количество оборотов, которые должен сделать двигатель).

2. Жмем кнопку "старт".

3. Разгоним двигатель до MaxSpeed = analogRead(R1), со скоростью AccSpeed = analogRead(R2).

4. Посчитали половину введенного числа и начинаем останавливать двигатель с скоростью AccSpeed до полной остановки. при этом двигатель должен остановиться на количестве оборотов введеного в начале.

Также естm кнопки "аварийный стоп" и "продолжение".

Практики в программировании не много. с клавиатуры 4х4 вводил число, ШИМ-мом игрался, количество оборотов считал с датчика. А вот в кучу все это собрать - мозгов не хватает. Требуется помощь бывалых.

 

 

 

Life23
Offline
Зарегистрирован: 10.08.2013

управление разгоном получилось вот так:

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);
  }

Только вот как более плавный и "управляемый" разгон - не могу сообразить...((

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

двигатель с энкодером получается?

Life23
Offline
Зарегистрирован: 10.08.2013

Да, с энкодером. Один ипульс на один оборот. 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

настраиваешь прерывание на 2 или 3 пине. вешаешь на него энкодер. в прерывании измеряешь время между импульсами, время при каждом прерывании запоминаешь. так можно определить скорость и считать количество оборотов

там же в прерывании можно исходя из параметров управлять шимом, а вот измерять с аналоговых пинов сделать не в прерывании, чтобы не нагружать. хотя и управление шимом можно вынести из прерывания. зависит от того что еще у тебя делает ардуина и какая макс скорость вращения мотора, но обычно можно оставить в прерывании

Life23
Offline
Зарегистрирован: 10.08.2013

Вот рабочий мой код:

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++;
}

В коде есть мусор.. пытался плавность разгона устанавливать переменником, но так и не получилось..

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

добавить переменные. 

volatile unsigned long time = 0;
volatile unsigned long sped = 0;
boolean flag=0;

в лупе при старте flag=1 и time=micros()

в прерывании условие если flag==1 то sped=1000000/(micros()-time) и time=micros() и encodevalue++;

формула приблизительная. от балды почти написал

смысл понимаешь?

далее map значения с аналогового порта до значений скоростей

условие если скорость ниже необходимой то увеличиваем шим с шагом пересчитанной через map из аналогового порта для урпавления скоростью

также можно запоминать промежуточные скорости так как зависимоть оборотов от шима нелинейная и из них считать скорость разгона текущую