Ваш браузер устарел. Рекомендуем обновить его до последней версии.




 



 


Delphi

 

 


 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 Управление электродвигателями

Подключим к плате маломощный электродвигатель напрямую. Главное требование к такому двигателю заключается в том чтобы потребляемый им ток не превышал 40 мА. При изменении полярности подключения вал двигателя будет вращаться в противоположном направлении. Помни что у двигателя с вентилятором для компьютера необходимо соблюдать полярность. На фото электродвигатель подключен к десятому пину и на землю GND. Для управления маломощным двигателем скетч принципиально не будет отличаться от скетча для светодиода.

Где можно применить такой маломощный двигатель? Например, можно на водный катер поставить мотор с пропеллером. Или на легкий автомобиль. Если у тебя два двигателя то можно написать скетч по командам которого автомобиль будет двигаться по прямой, поворачивать влево и вправо. Необходимо будет задействовать два пина. Тогда можно будет запрограммировать любою сложную траекторию движения и затем остановку автомобиля. После остановки автомобиля можно заставить его вновь двигаться, причем уже по другой траектории. Но для поворотов прийдется устроить отдельные приводы на левое и правое ведущие колеса. Еще понадобится третье заднее  пассивное колесо-вертушка.

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

 

// ___Двигатель___

void setup()
{
pinMode(12, OUTPUT);
}

void loop()
{
digitalWrite(12, HIGH);
delay(1000);
digitalWrite(12, LOW);
delay(3000);
}

 

Ниже привожу скетч по командам которого будет гореть синий светодиод во время работы двигателя и красный светодиод при остановке.

 

// ___Двигатель + Два светодиода___

void setup()
{
pinMode(12, OUTPUT); // мотор
pinMode(9, OUTPUT); // синий светодиод
pinMode(8, OUTPUT); // красный светодиод
}

void loop()
{
digitalWrite(12, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
delay(1000);

digitalWrite(12, LOW);
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
delay(3000);
}

Пришло время заняться более мощными электродвигателями для наших проектов. Для этого понадобится плата-драйвер двигателей. Можно воспользоваться шилдом на базе двух микросхем L293D для четырех двигателей. Имеется возможность подключения сервоприводов. Эту плату нужно посадить на плату Arduino UNO сверху, в результате получится двухэтажный бутерброд. Если светодиод не горит значит питание недостаточное и необходимо подвести на плату дополнительное питание. Перед этим нужно снять обязательно перемычку PWR. Для работы модуля понадобится библиотека AFMotor.

 

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

 

#include <AFMotor.h> // подключаем библиотеку для работы с шилдом 
int i;
AF_DCMotor motor1(1); // подключаем мотор к клеммникам M1

void setup() {
motor1.setSpeed(255); // задаем максимальную скорость вращения мотора
motor1.run(RELEASE);
}

void loop() {
				 
motor1.run(FORWARD); // задаем движение вперед
motor1.setSpeed(255); // задаем скорость движения
delay(3000); // время движения
				 
motor1.run(RELEASE); // останавливаем двигатель
delay(500); // указываем время задержки

motor1.run(BACKWARD);  // задаем движение назад
motor1.setSpeed(255);  // задаем скорость движения 
delay(3000); // указываем время движения
				    
motor1.run(RELEASE); // останавливаем двигатель
delay(500); // указываем время задержки

// разгоняем двигатель в одном направлении от нулевой скорости до максимальной
motor1.run(FORWARD); 
for (i=0; i<255; i++) {
motor1.setSpeed(i); 
delay(10);
}
				 
motor1.run(RELEASE); // останавливаем двигатель
delay(500); // указываем время задержки
				  
motor1.run(BACKWARD); // разгоняем двигатель в обратном направлении
for (i=255; i>=0; i--) {
motor1.setSpeed(i); 
delay(10);
}
				 
motor1.run(RELEASE); // останавливаем двигатель
delay(500); // указываем время задержки
}

Ниже приводится возможный скетч для автомобиля на четырех колесах в режиме автопилота. Для сборки понадобятся:

1 Arduino UNO

2 Шилд на четыре мотора

3 Серводвигатель

4 Ультразвуковой дальномер

 

 

 

 

 

 

 

#include <AFMotor.h>
#include <Servo.h>
#include <SoftwareSerial.h>
int ledPin1 = 22;
int ledPin2 = 24;
int ledPin3 = 34;
int ledPin4 = 35;
//Создаем объекты для двигателей
AF_DCMotor motor1(1); //канал М1 на Motor Shield — задний левый
AF_DCMotor motor2(2); //канал М2 на Motor Shield — задний правый
AF_DCMotor motor3(3); //канал М3 на Motor Shield — передний левый
AF_DCMotor motor4(4); //канал М4 на Motor Shield — передний правый
// Создаем объект для сервопривода
Servo vservo;
// Создаем переменные для запоминания скорости левых и правых двигателей
int vspdL, vspdR;
/* Создаем переменную, на значение которой будет уменьшаться скорость при плавных поворотах.
Текущая скорость должна быть больше этого значения. В противном случае двигатели со стороны направления поворота просто не будут вращаться */
const int vspd = 200;
// Массив для хранения углов поворота сервопривода (шаг 15 градусов)
const int vservo_array[13]={
0,15,30,45,60,75,90,105,120,135,150,165,180};
// Массив для хранения данных о расстоянии под различными углами поворота сервопривода
int vHC_SR04_array[13];
// Пины, используемые ультразвуковым дальномером
const int vTrig = 31;
const int vEcho = 30;
// Переменные, для хранения данных с дальномера
unsigned int vtime_us=0;
unsigned int vdistance_sm=0;
// Минимальное расстояние в сантиметрах, при котором нужно искать новый маршрут движения
const int vmindistance = 30;
// Переменная для циклов перебора значения массивов vservo_array и vHC_SR04_array
int vservo_int;
// Переменные для цикла поиска максимального значения в массивах
int vmaxarrayindex_int;
int vmaxarrayvalue_int;

void setup() {
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
// Устанавливаем скорость передачи данных по кабелю
Serial.begin(9600);
// Выбираем пин к которому подключен сервопривод
vservo.attach(9); // или 10, если воткнули в крайний разъём
// Поворачиваем сервопривод в положение 90 градусов при каждом включении
vservo.write(90);
// Устанавливаем максимальную скорость вращения двигателей
vspeed(255,255);
// Устанавливаем значение для пинов, к которым подключен ультразвуковой дальномер
pinMode(vTrig, OUTPUT);
pinMode(vEcho, INPUT);
}

void loop() {
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, HIGH);
vultrasoundmode();
}
/* Режим работы с использованием ультразвукового дальномера */
void vultrasoundmode(){
vservo.write(90);
delay(200);
Serial.print("Now ");
Serial.println(vHC_SR04());
// Если расстояние меньше наименьшего, то
if (vHC_SR04() < vmindistance) {
// Останавливаем двигатели
vrelease();
// Крутим серву измеряя расстояния и занося данные в массив
for (vservo_int = 0; vservo_int < 13; vservo_int = vservo_int + 1) {
vservo.write(vservo_array[vservo_int]);
delay(200);
vHC_SR04_array[vservo_int] = vHC_SR04();
// Выводим данные для отладки
Serial.print(vservo_int);
Serial.print(" ");
Serial.println(vHC_SR04_array[vservo_int]);
}
vservo.write(90);
delay(500);
// Поиск в массиве позиции с максимальным значением
vmaxarrayindex_int = 0;
vmaxarrayvalue_int = 0;
for (vservo_int = 0; vservo_int < 13; vservo_int = vservo_int + 1) {
if (vHC_SR04_array[vservo_int] > vmaxarrayvalue_int) {
vmaxarrayindex_int = vservo_int;
vmaxarrayvalue_int = vHC_SR04_array[vservo_int];
}
}
Serial.print("Max index ");
Serial.println(vmaxarrayindex_int);
// Проверка - если максимальное значение массива меньше минимального расстояния, то едем назад
if (vHC_SR04_array[vmaxarrayindex_int] < vmindistance) {
vbackward();
delay(500);
}
/* Проверка - если индекс максимального значения массива меньше 6 то поворачиваем вправо,
иначе влево */
if (vmaxarrayindex_int < 6) {
vright();
delay(500);
}
else
{
vleft();
delay(500);
}
}
else
{
// Едем прямо
vforward();
}
}

/* Функция определения расстояния с дальномера */
int vHC_SR04() {
digitalWrite(vTrig, HIGH); // Подаем сигнал на выход микроконтроллера
delayMicroseconds(10); // Удерживаем 10 микросекунд
digitalWrite(vTrig, LOW); // Затем убираем
vtime_us=pulseIn(vEcho, HIGH); // Замеряем длину импульса
vdistance_sm=vtime_us/58; // Пересчитываем в сантиметры
return vdistance_sm; // Возвращаем значение
}

/* Функции управления двигателями */

// Вперед
void vforward() {
vspeed(vspdL,vspdR);
vforwardRL();
}

// Вперед для RL
void vforwardRL() {
motor1.run(FORWARD);
motor2.run(FORWARD);
motor3.run(FORWARD);
motor4.run(FORWARD);
}

// Назад
void vbackward() {
vspeed(vspdL,vspdR);
vbackwardRL();
}

// Назад для RL
void vbackwardRL() {
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor3.run(BACKWARD);
motor4.run(BACKWARD);
}

// Влево
void vleft() {
vspeed(vspdL,vspdR);
motor1.run(BACKWARD);
motor2.run(FORWARD);
motor3.run(BACKWARD);
motor4.run(FORWARD);
}

// Вправо
void vright() {
vspeed(vspdL,vspdR);
motor1.run(FORWARD);
motor2.run(BACKWARD);
motor3.run(FORWARD);
motor4.run(BACKWARD);
}

// Вперед и влево
void vforwardleft() {
if (vspdL > vspd) {
vspeed(vspdL-vspd,vspdR);
}
else
{
vspeed(0,vspdR);
}
vforwardRL();
}

// Вперед и вправо
void vforwardright() {
if (vspdR > vspd) {
vspeed(vspdL,vspdR-vspd);
}
else
{
vspeed(vspdL,0);
}
vforwardRL();
}

// Назад и влево
void vbackwardleft() {
if (vspdL > vspd) {
vspeed(vspdL-vspd,vspdR);
}
else
{
vspeed(0,vspdR);
}
vbackwardRL();
}

// Назад и вправо
void vbackwardright() {
if (vspdR > vspd) {
vspeed(vspdL,vspdR-vspd);
}
else
{
vspeed(vspdL,0);
}
vbackwardRL();
}

// Стоп
void vrelease(){
motor1.run(RELEASE);
motor2.run(RELEASE);
motor3.run(RELEASE);
motor4.run(RELEASE);
}

// Изменение скорости
void vspeed(int spdL,int spdR){
if (spdL == spdR) {
vspdL=spdL;
vspdR=spdR;
}
motor1.setSpeed(spdL);
motor2.setSpeed(spdR);
motor3.setSpeed(spdL);
motor4.setSpeed(spdR);
}

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

Ниже приводится пример возможного скетча.

 

// Двигатель A
intenA=9;
intin1=8;
intin2=7;
// Двигатель B
intenB=3;
intin3=5;
intin4=4;
 
voidsetup()
{
  pinMode(enA,OUTPUT);
  pinMode(enB,OUTPUT);
  pinMode(in1,OUTPUT);
  pinMode(in2,OUTPUT);
  pinMode(in3,OUTPUT);
  pinMode(in4,OUTPUT);
  digitalWrite(in1,LOW);
  digitalWrite(in2,LOW);
  digitalWrite(in3,LOW);
  digitalWrite(in4,LOW);
}
 
voidloop()
{
// Установка двигателя A и B на максимальную скорость (0 ... 255)
  analogWrite(enA,255);  
  analogWrite(enB,255);
// Вращение двигателем A и B вперед
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);
  delay(2000);
// Вращение двигателем A и B назад
  digitalWrite(in1,LOW);
  digitalWrite(in2,HIGH);
  digitalWrite(in3,LOW);
  digitalWrite(in4,HIGH);
  delay(2000);
// Отключение мотора A и B
  digitalWrite(in1,LOW);
  digitalWrite(in2,LOW);
  digitalWrite(in3,LOW);
  digitalWrite(in4,LOW);
}
 
Эта маленькая плата рассчитана на два двигателя постоянного тока средней мощности или один шаговый. Драйвер двигателей построен на базе двух микросхем L9110S. Напряжение питания 2,512 В. Ток 800 мА. Максимальный перегрузочный ток 1,2 А.
 
 
 
 
Ниже приведен пример скетча для управления скоростью и направлением вращения  небольшого двигателя постоянного тока с помощью энкодера. Управляющие сигналы на драйвер L9110S подаются с контактов D10 и D11 платы Uno. Вращающийся энкодер подключен к UNO напрямую через пины D2, D3 и D4.
volatilebooleanTurnDetected;  // need volatile for Interrupts
volatilebooleanup;
 
constintPinCLK=2;   // Generating interrupts using CLK signal
constintPinDT=3;    // Reading DT signal
constintPinSW=4;    // Reading Push Button switch
 
// L9110 connections
#define L9110_B_IA 10 // Pin D10 --> Motor B Input A
#define L9110_B_IB 11 // Pin D11 --> Motor B Input B
 
// Motor Speed & Direction
#define MOTOR_B_PWM L9110_B_IA // Motor PWM Speed
#define MOTOR_B_DIR L9110_B_IB // Motor Direction
 
// Interrupt routine runs if CLK goes from HIGH to LOW
voidisr()  {
delay(4);  // delay for Debouncing
if(digitalRead(PinCLK))
   up=digitalRead(PinDT);
else
   up=!digitalRead(PinDT);
TurnDetected=true;
}
 
voidsetup()  {
pinMode(PinCLK,INPUT);
pinMode(PinDT,INPUT);  
pinMode(PinSW,INPUT);
digitalWrite(PinSW,HIGH);// Pull-Up resistor for switch
 
attachInterrupt(0,isr,FALLING);// interrupt 0 always connected to pin 2 on Arduino UNO
Serial.begin(9600);
Serial.println("Start");
pinMode(MOTOR_B_DIR,OUTPUT);
pinMode(MOTOR_B_PWM,OUTPUT);
digitalWrite(MOTOR_B_DIR,LOW);// Set motor to off
digitalWrite(MOTOR_B_PWM,LOW);
}
 
voidloop()  {
staticlongRotaryPosition=0;    // STATIC to count correctly
 
if(!(digitalRead(PinSW))){   // check if button is pressed
   if(RotaryPosition==0){  // check if button was already pressed
   }else{
       RotaryPosition=0;// if YES, then reset position to ZERO
       digitalWrite(MOTOR_B_DIR,LOW);// turn motor off
       analogWrite(MOTOR_B_PWM,LOW);
       Serial.print("Reset = ");
       Serial.println(RotaryPosition);
   }
}
 
// Runs if rotation was detected
if(TurnDetected)  {
   if(up){
     if(RotaryPosition>=100){// Max value set to 100
       RotaryPosition=100;
     }
     else{
         RotaryPosition=RotaryPosition+2;
     }
   }
   else{
     if(RotaryPosition<=-100){
       // Max value set to -100        
       RotaryPosition=-100;
     }        
     else{          
       RotaryPosition=RotaryPosition-2;
      }
    }    
    TurnDetected=false;  // do NOT repeat IF loop until new rotation detected
    Serial.print("Speed = ");
    Serial.println(RotaryPosition);    
    
    // if Rotation is Clockwise    
    if(RotaryPosition>0&&RotaryPosition<11){
      digitalWrite(MOTOR_B_DIR,LOW);// turn motor off
      analogWrite(MOTOR_B_PWM,LOW);
    }
   if(RotaryPosition>10&&RotaryPosition<21){
      digitalWrite(MOTOR_B_DIR,HIGH);// direction = forward
      analogWrite(MOTOR_B_PWM,180);// PWM speed = 180
    }
    if(RotaryPosition>20&&RotaryPosition<31){
      digitalWrite(MOTOR_B_DIR,HIGH);// direction = forward
      analogWrite(MOTOR_B_PWM,160);// PWM speed = 160
    }
    if(RotaryPosition>30&&RotaryPosition<41){
      digitalWrite(MOTOR_B_DIR,HIGH);// direction = forward
      analogWrite(MOTOR_B_PWM,140);// PWM speed = 140
    }
    if(RotaryPosition>40&&RotaryPosition<51){
      digitalWrite(MOTOR_B_DIR,HIGH);// direction = forward
      analogWrite(MOTOR_B_PWM,120);// PWM speed = 120
    }
   if(RotaryPosition>50&&RotaryPosition<61){
      digitalWrite(MOTOR_B_DIR,HIGH);// direction = forward
      analogWrite(MOTOR_B_PWM,100);// PWM speed = 100
   }
   if(RotaryPosition>60&&RotaryPosition<71){
      digitalWrite(MOTOR_B_DIR,HIGH);// direction = forward
      analogWrite(MOTOR_B_PWM,80);// PWM speed = 80
   }
    if(RotaryPosition>70&&RotaryPosition<81){
      digitalWrite(MOTOR_B_DIR,HIGH);// direction = forward
      analogWrite(MOTOR_B_PWM,60);// PWM speed = 60
    }
    if(RotaryPosition>80&&RotaryPosition<91){
      digitalWrite(MOTOR_B_DIR,HIGH);// direction = forward
      analogWrite(MOTOR_B_PWM,40);// PWM speed = 40
    }
    if(RotaryPosition>90){
     digitalWrite(MOTOR_B_DIR,HIGH);// direction = forward
     analogWrite(MOTOR_B_PWM,20);// PWM speed = 20
   }
  
// if Rotation is Counter-Clockwise
  
   if(RotaryPosition<0&&RotaryPosition>-11){
       digitalWrite(MOTOR_B_DIR,LOW);// turn motor off
       analogWrite(MOTOR_B_PWM,LOW);
   }
   if(RotaryPosition<-10&&RotaryPosition>-21){
     digitalWrite(MOTOR_B_DIR,LOW);// direction = reverse
     analogWrite(MOTOR_B_PWM,40);// PWM speed = 40
   }
   if(RotaryPosition<-20&&RotaryPosition>-31){
     digitalWrite(MOTOR_B_DIR,LOW);// direction = reverse
     analogWrite(MOTOR_B_PWM,60);// PWM speed = 60
   }
   if(RotaryPosition<-30&&RotaryPosition>-41){
     digitalWrite(MOTOR_B_DIR,LOW);// direction = reverse
     analogWrite(MOTOR_B_PWM,80);// PWM speed = 80
   }
   if(RotaryPosition<-40&&RotaryPosition>-51){
     digitalWrite(MOTOR_B_DIR,LOW);// direction = reverse
     analogWrite(MOTOR_B_PWM,100);// PWM speed = 100
   }
   if(RotaryPosition<-50&&RotaryPosition>-61){
     digitalWrite(MOTOR_B_DIR,LOW);// direction = reverse
     analogWrite(MOTOR_B_PWM,120);// PWM speed = 120
   }
   if(RotaryPosition<-60&&RotaryPosition>-71){
     digitalWrite(MOTOR_B_DIR,LOW);// direction = reverse
     analogWrite(MOTOR_B_PWM,140);// PWM speed = 140
   }
   if(RotaryPosition<-70&&RotaryPosition>-81){
     digitalWrite(MOTOR_B_DIR,LOW);// direction = reverse
     analogWrite(MOTOR_B_PWM,160);// PWM speed = 160
   }
   if(RotaryPosition<-80&&RotaryPosition>-91){
     digitalWrite(MOTOR_B_DIR,LOW);// direction = reverse
     analogWrite(MOTOR_B_PWM,180);// PWM speed = 180
   }
   if(RotaryPosition<-90){
     digitalWrite(MOTOR_B_DIR,LOW);// direction = reverse
     analogWrite(MOTOR_B_PWM,200);// PWM speed = 200
   }
 }
}
 
Еще одна аналогичная плата рассчитанная уже на четыре электродвигателя средней мощности.
 
 
 
 
 
 
 
 
 
 
 
 
 
Если под рукой оказалась голая микросхема L293D, то на нее можно повесить один или два мотора как показано на рисунке.
 

Flag Counter
Яндекс.Метрика
200stran.ru: показано число посетителей за сегодня, онлайн, из каждой страны и за всё время
Besucherzahler russain brides
счетчик посещений

Выбери лучшее!

allbest