#1 2017-03-14 01:31:41

LightDiode
Учасник
Зареєстрований: 2016-10-02
Повідомлень: 5

Проблема управления двумя моторами через L298N

Всем привет.
Есть у меня Arduino Uno, и драйвер двигателей L298N.
Интересуюсь у гугла, как же это все связать, он мне отвечает статьями с примерами. Я захожу интересуюсь, беру готовый скретч, заливаю его в Arduino (предварительно указав порты к которым подключено все).
Запускаю все, питаю драйвер от кроны(9 вольт), Arduino от USB от компа.
И отнюдь, работает только один двигатель.

Отключаю провода рабочего двигателя (ENA, IN1, IN2) от Arduino, изменяю скретч (удаляю строки с указанными выходами), заливаю - вуаля, второй двигатель работает. Проделываю все наоборот(второй отключаю первый возвращаю) все опять работает. А вместе не хочет..
Магия? Не думаю. Но как решать эту проблему хотелось бы узнать. smile

Неактивний

#2 2017-03-14 08:38:53

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 875

Re: Проблема управления двумя моторами через L298N

сказок не бывает.
если рабочий драйвер и правильный код - всё должно работать.
а вот питание драйвера кроной совсем не правильно.
крона - зло, фигня и гадость)))
или блок питания или аккумуляторы.
часто у народа несведущего проблемы именно из-за отсутствия правильного питания.

Неактивний

#3 2017-03-14 11:35:41

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема управления двумя моторами через L298N

vvr, та ладно, крона это хорошо )
вы только вспомните вкус кроны с полной емкостью) и все прощаете этому типоразмеру )

LightDiode,  учитываю входные данные - только с помощью поллитры )

Неактивний

#4 2017-03-14 21:35:48

LightDiode
Учасник
Зареєстрований: 2016-10-02
Повідомлень: 5

Re: Проблема управления двумя моторами через L298N

vvr пише:

сказок не бывает.
если рабочий драйвер и правильный код - всё должно работать.
а вот питание драйвера кроной совсем не правильно.
крона - зло, фигня и гадость)))
или блок питания или аккумуляторы.
часто у народа несведущего проблемы именно из-за отсутствия правильного питания.

Интересно вы про сказки задвинули. Но только к чему? Я не говорю что все возникает само собой, и ищу здесь ответа от опытных товарищей которые возможно сталкивались с такой проблемой и могут сказать что может послужить причиной данного поведения.
А вы мне про сказки... hmm

NoName пише:

LightDiode,  учитываю входные данные - только с помощью поллитры )

С помощью чего? что? Здесь могут дать внятный ответ, или форум создан для общения на уровне "бэ-мэ, ага-угу"?
Вроде бы модератор, а топикового смысла в сообщении ноль. neutral

Остання редакція LightDiode (2017-03-14 21:36:03)

Неактивний

#5 2017-03-14 21:50:31

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 875

Re: Проблема управления двумя моторами через L298N

LightDiode пише:
vvr пише:

сказок не бывает.
если рабочий драйвер и правильный код - всё должно работать.
а вот питание драйвера кроной совсем не правильно.
крона - зло, фигня и гадость)))
или блок питания или аккумуляторы.
часто у народа несведущего проблемы именно из-за отсутствия правильного питания.

Интересно вы про сказки задвинули. Но только к чему? Я не говорю что все возникает само собой, и ищу здесь ответа от опытных товарищей которые возможно сталкивались с такой проблемой и могут сказать что может послужить причиной данного поведения.
А вы мне про сказки... hmm

NoName пише:

LightDiode,  учитываю входные данные - только с помощью поллитры )

С помощью чего? что? Здесь могут дать внятный ответ, или форум создан для общения на уровне "бэ-мэ, ага-угу"?
Вроде бы модератор, а топикового смысла в сообщении ноль. neutral

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

Неактивний

#6 2017-03-15 00:28:27

LightDiode
Учасник
Зареєстрований: 2016-10-02
Повідомлень: 5

Re: Проблема управления двумя моторами через L298N

vvr пише:

вы свой код показали, схему подключения выложили , обидчивый вы наш))))

Никто не обижается, тут было возмущение по поводу отсутствия диалога по теме.
Код? Не знаю чем он тут поможет, но вот(как было сказано выше, если кто не вычитал, он из гугла):

// Тестировалось на Arduino IDE 1.0.5
int IN1 = 7; // Input1 подключен к выводу 5 
int IN2 = 6;
int IN3 = 5;
int IN4 = 4;
int EN1 = 9;
int EN2 = 3;
int i;
void setup()
{
  pinMode (EN1, OUTPUT);
  pinMode (IN1, OUTPUT);
  pinMode (IN2, OUTPUT);
  pinMode (EN2, OUTPUT);
  pinMode (IN4, OUTPUT);
  pinMode (IN3, OUTPUT);
}
void loop()
{
  digitalWrite (IN2, HIGH);
  digitalWrite (IN1, LOW); 
  digitalWrite (IN4, HIGH);
  digitalWrite (IN3, LOW); 
  for (i = 20; i <= 255; ++i)
  {
      analogWrite(EN1, i);
      analogWrite(EN2, i);
      delay(30);
  }
  analogWrite (EN1, 0);
  analogWrite (EN2, 0);
  delay(500);
  digitalWrite (IN1, HIGH);
  digitalWrite (IN2, LOW); 
  digitalWrite (IN3, HIGH);
  digitalWrite (IN4, LOW);
  for (i = 20; i <= 255; ++i)
  {
      analogWrite(EN1, i);
      analogWrite(EN2, i);
      delay(30);
  }
  analogWrite (EN1, 0);
  analogWrite (EN2, 0);
  delay(8000);
}
vvr пише:

а с кроной веселитесь и смотрите просадки по питанию самостоятельно smile

"Просадки по питанию" могут повлиять на то что работает только 1 из двух подключенных двигателей?
Чуть позже подключу акк с разобранной машинки(откуда были взяты оба двигателя) и проверю на нем.

Остання редакція LightDiode (2017-03-15 00:30:25)

Неактивний

#7 2017-03-15 10:54:00

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема управления двумя моторами через L298N

vvr,   привет , ну и как те в роли википедии? )
ты встречал нормальные курсы  по использовании поисковиков? я ввел название микрухи и первые  ответы дают более релевантную информацию чем  код из гугла, или это кто то из интернов гугла написал, нихрена непонятно (

https://arduino-ua.com/prod204-L298N_draiver_dvyh_shagovih_dvigatelei_5V

тут и схема и пример

#define D1 2          // Направление вращение двигателя 1
#define M1 3          // ШИМ вывод для управления двигателем 1
#define D2 4          // Направление вращение двигателя 2
#define M2 5          // ШИМ вывод для управления двигателем 2
 
bool direction = 0;   // Текущее направление вращения       
int value;            // Текущее значение ШИМ
  
void setup() 
{ 
    pinMode(D1, OUTPUT);
    pinMode(D2, OUTPUT);  
} 
  
void loop() 
{ 
  for(value = 0; value <= 255; value+=1) 
  { 
    digitalWrite(D1, direction);  // Задаем направление вращения
    digitalWrite(D2, direction);
    analogWrite(M1, value);       // Задаем скорость вращения
    analogWrite(M2, value);
    delay(20); 
  }  
  direction = direction ^ 1;      // Инвертируем значение, чтобы в след. цикле вращаться в другую сторону
}

Неактивний

#8 2017-03-15 11:55:40

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема управления двумя моторами через L298N

LightDiode, посмотрите на код, рабочий вариант , но не релиз,  на опечатки прошу не обращать внимания
коррекцию прийдется переделать на квадратичный полином

cpp

/*
 * file easy_boat_mtwin.cpp
 * Date create: 2016.10.05 
 * Date change: 2016.10.xx 
 * example arduino library 
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 00):
 * <devgate.info эт gmail.com> wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.   
 * Chingiz the FairSun
 *
 * ----------------------------------------------------------------------------
 source https://github.com/platisd/AndroidCar/blob/master/Car.cpp
 
 motor enabled allway  
 
 */

 #include "easy_boat_mtwin.h"

 #include <Servo.h>

 // 8 bit PWM
#define MAX_RESOLUTION_PWM  0xFF
// 16 bit PWM
// #define MAX_RESOLUTION_PWM  0xFFFF



Servo left_plus;
Servo left_minus;

Servo rigth_plus;
Servo rigth_minus;
 
 
const unsigned short easy_boat_mtwin::DEFAULT_MOTOR1_PLUS_PIN = 5;
const unsigned short easy_boat_mtwin::DEFAULT_MOTOR1_MINUS_PIN = 6;

const unsigned short easy_boat_mtwin::DEFAULT_MOTOR2_PLUS_PIN = 9;
const unsigned short easy_boat_mtwin::DEFAULT_MOTOR2_MINUS_PIN = 10;

long easy_boat_mtwin::get_value_from_percent (  long percent,  long  max_value )
{
  long  ret;
  // max_value - 100 %
  //  x      percent
  ret = ( long)(( long)max_value*( long)percent)/( long)100;
  return  (ret);
}

easy_boat_mtwin::easy_boat_mtwin( 
				unsigned short Motor_Left_plus_Pin, 
				unsigned short Motor_Left_minus_Pin, 
				unsigned short Motor_Rigth_plus_Pin, 
				unsigned short Motor_Rigth_minus_Pin) 
{
	
_Motor_Left_plus_Pin   = Motor_Left_plus_Pin;    
_Motor_Left_minus_Pin  = Motor_Left_minus_Pin;
_Motor_Rigth_plus_Pin  = Motor_Rigth_plus_Pin;
_Motor_Rigth_minus_Pin = Motor_Rigth_minus_Pin;  

/*   
   pinMode  ( _Motor_Left_plus_Pin   , OUTPUT);  
   pinMode  ( _Motor_Left_minus_Pin  , OUTPUT);  
   pinMode  ( _Motor_Rigth_plus_Pin  , OUTPUT);  
   pinMode  ( _Motor_Rigth_minus_Pin , OUTPUT);  
*/
   left_plus.attach(_Motor_Left_plus_Pin);
  left_minus.attach(_Motor_Left_minus_Pin);
  
   rigth_plus.attach(_Motor_Rigth_plus_Pin);
  rigth_minus.attach(_Motor_Rigth_minus_Pin);
  
  
  left_plus.writeMicroseconds  ( 0 );
  left_minus.writeMicroseconds ( 0 );
  rigth_plus.writeMicroseconds  ( 0 );
  rigth_minus.writeMicroseconds ( 0 );
}

int easy_boat_mtwin::get_PWM_Value_channel(  int chanel  )
{
int ret = 0;
switch ( chanel )
{
case 0: ret = _BOAT_OUTPUT.left_motor_power; break;
case 1: ret = _BOAT_OUTPUT.rigth_motor_power; break;
}	

return ret;	
}


//-------------------------------------------------
void easy_boat_mtwin::set_axis( TD_AXIS *AXIS )
{
 _AXIS.X = AXIS->X;
 _AXIS.Y = AXIS->Y;
 _AXIS.Z = AXIS->Z;
}
//-------------------------------------------------
void easy_boat_mtwin::set_new_vector  ( TD_BOAT_Input  *IN_DATA, TD_BOAT_CORRECTION *CORRECT  )
{
int   angle;
float power;
float max_power_horizont ;
float delta_cos;

// float _BOAT_OUTPUT.left_motor_power;
// float _BOAT_OUTPUT.rigth_motor_power;

	if ( CORRECT != NULL )
	{
		_BOAT_CORRECTION.left_motor_correction  = CORRECT->left_motor_correction;
		_BOAT_CORRECTION.rigth_motor_correction = CORRECT->rigth_motor_correction ;
    }

	angle = IN_DATA->degrees;
	power = IN_DATA->power;

	if ( power > 255 ) power = 255;


	
	delta_cos =  cos ( angle*M_PI/180 );

	max_power_horizont = fabs ( sin ( angle*M_PI/180 ));
	max_power_horizont *= power*0.1;
	
	power *= fabs (cos( angle*M_PI/180 ));
	power += max_power_horizont;

	if ( angle <= 90 )
	{
		_BOAT_OUTPUT.left_motor_power  =  power;
		_BOAT_OUTPUT.rigth_motor_power =  power*delta_cos;
	}
	else if ( angle <= 180 )
	{
		_BOAT_OUTPUT.left_motor_power  =  -power;
		_BOAT_OUTPUT.rigth_motor_power =  power*delta_cos;
	}
	else if ( angle <= 270 )
	{
		_BOAT_OUTPUT.left_motor_power  =  power*delta_cos;
		_BOAT_OUTPUT.rigth_motor_power =  -power;
	}
	else
	{
		_BOAT_OUTPUT.left_motor_power  =  power*delta_cos;
		_BOAT_OUTPUT.rigth_motor_power =  power;
	}

		_BOAT_OUTPUT.left_motor_power  *= _BOAT_CORRECTION.left_motor_correction;
		_BOAT_OUTPUT.rigth_motor_power *= _BOAT_CORRECTION.rigth_motor_correction;

		// no timer update 
	if ( _BOAT_OUTPUT.left_motor_power < 0 )
	 {
	 	  left_minus.writeMicroseconds (  0  );
	 	  analogWrite ( _Motor_Left_minus_Pin,  _BOAT_OUTPUT.left_motor_power );
	 }
	 else 
	 {
	 	  left_minus.writeMicroseconds (  0  );
	 	  left_plus.writeMicroseconds  ( _BOAT_OUTPUT.left_motor_power );
	 }
	 
	if ( _BOAT_OUTPUT.rigth_motor_power < 0 )
	 {
	 	  rigth_minus.writeMicroseconds (  0  );
	 	  rigth_plus.writeMicroseconds  (  _BOAT_OUTPUT.rigth_motor_power );
	 }
	 else 
	 {
	 	  rigth_minus.writeMicroseconds (  0  );
	 	  rigth_plus.writeMicroseconds  ( _BOAT_OUTPUT.rigth_motor_power );
	 }
}
//-------------------------------------------------
void easy_boat_mtwin::begin()
{
	_BOAT_CORRECTION.left_motor_correction  = 1;
    _BOAT_CORRECTION.rigth_motor_correction = 1;
	_BOAT_OUTPUT.left_motor_power  = 0;
    _BOAT_OUTPUT.rigth_motor_power = 0;

	_AXIS.X = 0;
	_AXIS.Y = 0;
	_AXIS.Z = 0;	

}
//-------------------------------------------------
// void easy_boat_mtwin::update()  {}
//-------------------------------------------------

header

// file name easy_boat_mtwin.h

#ifndef EASY_BOAT_MTWIN_H
#define EASY_BOAT_MTWIN_H
#if defined(ARDUINO) && ARDUINO >= 100
	#include <Arduino.h>
#else
	#include <WProgram.h>
	#include <pins_arduino.h>
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <Servo.h>
#include <Wire.h>

typedef struct 
{
  long  degrees;
  long  power  ;  
}  TD_BOAT_Input;

typedef struct 
{
  float  left_motor_power;
  float rigth_motor_power;
}  TD_BOAT_Output;

typedef struct 
{
  float  left_motor_correction;
  float  rigth_motor_correction;
}  TD_BOAT_CORRECTION;

typedef struct 
{
  long  X;
  long  Y;
  long  Z;
}  TD_AXIS;

class easy_boat_mtwin {
	public:
		easy_boat_mtwin( 
				unsigned short Motor_Left_plus_Pin    = DEFAULT_MOTOR1_PLUS_PIN,
				unsigned short Motor_Left_minus_Pin   = DEFAULT_MOTOR1_MINUS_PIN,
				unsigned short Motor_Rigth_plus_Pin   = DEFAULT_MOTOR2_PLUS_PIN,
				unsigned short Motor_Rigth_minus_Pin  = DEFAULT_MOTOR2_MINUS_PIN );
						 
		void begin		( void );
		// void update		( void );
		int get_PWM_Value_channel(  int chanel  );

		void set_axis( TD_AXIS *AXIS );
	    void set_new_vector     ( TD_BOAT_Input  *IN_DATA, TD_BOAT_CORRECTION *CORRECT  );
	    // void get_current_vector ( TD_BOAT_INPUT  *INPUT, TD_BOAT_OUTPUT *OUTPUT  );
	
		private:
		long _speed, _angle;
		TD_BOAT_Output      _BOAT_OUTPUT;
		TD_BOAT_CORRECTION  _BOAT_CORRECTION;
		TD_AXIS _AXIS;

		short _PWM_LeftMotor;
		short _PWM_RigthMotor;

		unsigned short _Motor_Left_plus_Pin   ;
		unsigned short _Motor_Left_minus_Pin  ;
		unsigned short _Motor_Rigth_plus_Pin  ;
		unsigned short _Motor_Rigth_minus_Pin ;	
		
		long get_value_from_percent (  long percent,  long  max_value );
		
static const unsigned short  DEFAULT_MOTOR1_PLUS_PIN  ;
static const unsigned short  DEFAULT_MOTOR1_MINUS_PIN ;
static const unsigned short  DEFAULT_MOTOR2_PLUS_PIN  ;
static const unsigned short  DEFAULT_MOTOR2_MINUS_PIN ; 		
};




#endif

add
вариант из примера  наверное лучше чем мой,  но у них есть особенность  -
при движение условно вперед двигатель крутится по переднему фронту, а назад по заднему,
этот вариант позволяет освободить 2 PWM выхода, но нужно добавлять логику управления мощностью

Остання редакція NoName (2017-03-15 12:29:01)

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму