Плавное управление скоростью коллекторного двигателя

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Собственно стоит задача в следующем, кручу ручку потенциометра и обороты двигателя медленно растут до установленных потенциометром, по аналогии и с уменьшением оборотов. Вот нашёл в сети код:

#define motor_pin 9

int value, prev_value, slow_value, wait = 10;

void output_data(){
  String dataString = "";
  dataString += value;
  dataString += ","; 
  dataString += prev_value;
  dataString += ","; 
  dataString += slow_value;
  Serial.println(dataString);
}

void setup() 
{ 
  Serial.begin(4800);
} 

void loop() 
{ 
  value = analogRead(0)/4;
  
  if(prev_value > value){ 
    for(slow_value = prev_value;slow_value > value; slow_value--) {
      analogWrite(motor_pin,slow_value); 
      delay(wait); 
    }
  }

  if(prev_value < value){  
    for(slow_value = prev_value; slow_value<value; slow_value++) {
      analogWrite(motor_pin,slow_value); 
      delay(wait);  
    }
  }
  
  prev_value = value;
  output_data();
}

Но есть парочка непоняток:
При положении потенциометра в 0 - обороты то медленно падают, но двигатель слегка ещё пищит, тоесть ШИМ не ровен нулю.
Так же при положении макс, если двигатель остановить то слышно писк, тоесть ШИМ не равен 255.

Помогите разобраться ато мозги совсем не варят, частота почему-то упала и не хватает производительности.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

не смог пройти мимо

Сидят в кинотеатре два наркомана. Свет медленно, медленно гаснет. Один

говорит: "Почему свет так медленно гаснет?". Второй отвечает: "Вот,

представь себе, заходит киномеханик к себе в будку и м-е-е-дленно тянет

вилку из розетки".

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

По сути нужно имитировать инерцию ротора.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

ну я думаю что потенцуометр не выдает  прямо НОЛЬ.. и 255.. имеет смысл програмно притягивать к нулю и к 255 когда есть для этого основания..

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

В сериале видно нули:

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

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

попробуйте насильно принуждать в нулю  или к 255. будут ли те же самые симтомы? 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
#define motor_pin 9

int value, prev_value, slow_value, wait = 10;

/*
void output_data(){
  String dataString = "";
  dataString += value;
  dataString += ","; 
  dataString += prev_value;
  dataString += ","; 
  dataString += slow_value;
  Serial.println(dataString);
}
*/

void setup() 
{ 
  //Serial.begin(9600);
} 

void loop() 
{ 
  value = analogRead(0)/4;
  
 if(value < 254){
    if(prev_value > value){
      for(slow_value = prev_value;slow_value > value; slow_value--) {
        analogWrite(motor_pin,slow_value); 
        delay(wait);
      }
    }
  }
  else{
    analogWrite(motor_pin,255); 
  }
  if(value > 1){ 
    if(prev_value < value){ 
      for(slow_value = prev_value; slow_value<value; slow_value++) {
        analogWrite(motor_pin,slow_value); 
        delay(wait); 
      }
    }
  }
  else{
   analogWrite(motor_pin,0); 
  }
 
  prev_value = value;
  //output_data();
}

Вот так вроде как работает.

leshak
Offline
Зарегистрирован: 29.09.2011

А зачем так сложно?

loop(){
  int rawValue=analogRead();
  static int speed=0; // текущая скорость мотора
  int sensorValue=map(rawValue,0,1023,0,255); // переводим показания сенсора в скорость мотора
  if(sensorValue<speed)speed--; 
  if(sensorValue>speed)speed++;
  analogWrite(motor_pin,speed);
  delya(30);
}

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Хах, действительно.

Спасибо.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

leshak пишет:

А зачем так сложно?

loop(){
  int rawValue=analogRead();
  static int speed=0; // текущая скорость мотора
  int sensorValue=map(rawValue,0,1023,0,255); // переводим показания сенсора в скорость мотора
  if(sensorValue<speed)speed--; 
  if(sensorValue>speed)speed++;
  analogWrite(motor_pin,speed);
  delya(30);
}

 

Увы, Ваш код неподошёл мне.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013
axill
Offline
Зарегистрирован: 05.09.2011

Особенность ШИМ в AVR-ках описан в даташите, при установке нулевого заполнения на выходе будут импульсы логической единицы

Поэтому для полноценного нуля надо при желаемом нуле в порт записывать цифровой ноль, типа так:

if(speed) analogWrite(motor_pin,speed);
else digitalWrite(motor_pin, LOW);

 

axill
Offline
Зарегистрирован: 05.09.2011

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

void analogWrite(uint8_t pin, int val)
{
	// We need to make sure the PWM output is enabled for those pins
	// that support it, as we turn it off when digitally reading or
	// writing with them.  Also, make sure the pin is in output mode
	// for consistenty with Wiring, which doesn't require a pinMode
	// call for the analog output pins.
	pinMode(pin, OUTPUT);
	if (val == 0)
	{
		digitalWrite(pin, LOW);
	}
	else if (val == 255)
	{
		digitalWrite(pin, HIGH);
	}

 

art100
Offline
Зарегистрирован: 09.03.2014

HWman пишет:

ШИМ

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

а то я не могу решить что мне прикручивать

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Лампочка 40 Вт, на других частях видео есть маленький двиг. на 5 Вт и большой, от печки, с крыльчаткой жрёт около 4-х Амперов, если же остановить то целых 15 А.
Как-то случайно было закоротил выход и тинька сгорела, транзистор и всё другое, включая 78l05 осталось цело.
Схема:

Только диода не хватает, позже прикручу.

Транзистор при токах до 4.5 А почти не греется, при любой скважности ШИМ, частота ~70 Гц.

Leshiy
Offline
Зарегистрирован: 19.07.2014

А почему не подошёл? Вроде как всё верно, код стремится "занулить" sensorValue, увеличивая, или уменьшая speed, delay(30) обеспечивает тот самый эффект инерции, когда потенциометр уже упёрся в ограничитель, а скорость вращения двигателя\яркость свечения лампы ещё меняется. Как по мне, так шикарный код. В чём загвоздка?

И чтобы не палить аттини может стоит развязать его с силовой цепью, например оптроном?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Leshiy пишет:

А почему не подошёл? Вроде как всё верно, код стремится "занулить" sensorValue, увеличивая, или уменьшая speed, delay(30) обеспечивает тот самый эффект инерции, когда потенциометр уже упёрся в ограничитель, а скорость вращения двигателя\яркость свечения лампы ещё меняется. Как по мне, так шикарный код. В чём загвоздка?

И чтобы не палить аттини может стоит развязать его с силовой цепью, например оптроном?

Вообще непашет Ваш код.
Думаете имеет смысл заменить транзистор Q2 на PC817, аля класика?

Megawollt
Offline
Зарегистрирован: 06.12.2015

Сейчас тоже планирую организовать управление двигателем ардуиной, но вот двигатель очень мощный. До 100а на старте. Если н-мост не разорвет, буду эксперементировать с программой

blik
Offline
Зарегистрирован: 07.02.2016

Добрый день.

Люди добрые, подскажите начинающему!

Не пойму, как в этом скетче (пост 6) добавить второй переменный резистор (на вход А1), для независимого  управления вторым мотором, допустим на 6-м пине?

Подскажите, в каком направлении начать.

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

FL
Offline
Зарегистрирован: 24.11.2015

blik пишет:

... Не пойму, как в этом скетче (пост 6) добавить ...

Самое простое - код скопировать еще раз и переменные переименовать

void loop() {
  int motor_pin1=10;
  int motor_pin2=11;

  int rawValue1=analogRead(A1);
  int rawValue2=analogRead(A2);
  
  static int speed1=0;
  int sensorValue1=map(rawValue1,0,1023,0,255);
  if(sensorValue1<speed1)speed1--;
  if(sensorValue1>speed1)speed1++;
  
  static int speed2=0;
  int sensorValue2=map(rawValue2,0,1023,0,255);
  if(sensorValue2<speed2)speed2--;
  if(sensorValue2>speed2)speed2++;

  analogWrite(motor_pin1,speed1);
  analogWrite(motor_pin2,speed2);
  
  delay(30);
}

 

blik
Offline
Зарегистрирован: 07.02.2016

Спасибо, вчера уже разобрался! Просто была загвоздка в том, у меня регулировались сразу оба выхода, с любого входа. Я экспериментировал на одной паре резистор-мотор, переключая их на разные пины. Добавляю строки, переключаю на другой вход, а он регулирует оба выхода. Ненагруженный вход ведет себя неадекватно.  В общем, дошло нагрузить оба входа, и всё встало на свои места.

Кстати, получилось всего одной строкой для одной пары:

analogWrite(MOTOR_UP, analogRead(POT_UP) / 4);