Практическое программирование Arduino/CraftDuino — драйвер двигателей L293D


Настала пора Arduino поуправлять моторчиками 🙂

Для этого воспользуемся самым популярным драйвером, используемым для управления моторчиками – микросхемой L293D.

L293D содержит два драйвера для управления электродвигателями небольшой мощности. Имеет две пары входов для управляющих сигналов и две пары выходов для подключения электромоторов. Кроме того, у L293D есть два входа для включения каждого из драйверов. Эти входы используются для управления скоростью вращения электромоторов с помощью ШИМ (PWM).

Рассмотрим блок-схему L293D, приведённую в datasheet-е (нумерация для SO-корпуса):
блок-схема L293D

К выходам OUTPUT1 и OUTPUT2 подключается электромотор MOTOR1 (для микросхемы в DIP-корпусе – ножки 3 и 6).
Соответственно MOTOR2 подключается к выходам OUTPUT3 и OUTPUT4 (ножки 11 и 14).

Сигналы, подаваемые на ENABLE1(2) управляют соответствующим драйвером (ножки 1 и 9 соответственно).

Подавая на вход ENABLE1 сигнал HIGH ( или просто соединив с плюсом источника питания +5V) – включаем драйвер 1-го моторчика.
Если при этом на входы INPUT1 и INPUT2 сигналы не подавать, то моторчик вращаться не будет.
Подавая HIGH на INPUT1 и LOW на INPUT2 мы заставим моторчик вращаться. А если теперь поменять сигналы местами и подавать на INPUT1 сигнал LOW, а на INPUT2 сигнал HIGH – мы заставим моторчик вращаться в другую сторону.

Аналогично для второго драйвера.

Выход Vss (ножка 16) отвечает за питание самой микросхемы, а выход Vs (ножка 8) отвечает за питание моторчиков – это обеспечивает разделение электропитания для микросхемы и для управляемых ею двигателей, что позволяет подключить электродвигатели с напряжением питания отличным от напряжения питания микросхемы. Разделение электропитания микросхем и электродвигателей также необходимо для уменьшения помех, вызванных бросками напряжения, связанными с работой моторов.

Четыре контакта GND (ножки 4, 5, 12,13) нужно соединить с землёй. Так же эти контакты обеспечивают теплоотвод от микросхемы.

Характеристики L293D

напряжение питания двигателей (Vs) 		от 4,5 до 36В 
напряжение питания микросхемы (Vss) 		5В
допустимый ток нагрузки 			600мА (на каждый канал) 
пиковый (максимальный) ток на выходе 		1,2A (на каждый канал) 
логический "0" входного напряжения 		до 1,5В 
логическая "1" входного напряжения 		2,3...7В 
скорость переключений 				до 5 кГц.

Если использовать микросхему L293E, то допустимый ток нагрузки на каждый канал уже будет 1А (а пиковый ток – 2А), но придётся использовать внешние защитные диоды, которые у L293D встроены в саму микросхему.

Попробуем смоделировать как Arduino справляется с управлением моторчиками 🙂

Запускаем Proteus и открываем проект с Arduino 🙂
Добавим на схему наш драйвер – L293D

Соединим выводы Vss и Vs с положительным полюсом батареи, выводы GND соединим с землёй, а к выводам 3,6 и 11,14 подсоединим моторчики – соответственно MOTOR1 и MOTOR2.

В реальной схеме — параллельно к моторчику нужно припаять конденсатор – он помогает справиться с наводками от работающего электродвигателя ( это распространённая практика — разберите любую игрушку с моторчиком и увидите, что прямо к моторчику припаян керамический конденсатор номиналом где-то в 0,1 мкф )

А как же соединить входы драйверов? Для начала, посмотрим – как вообще это работает на практике 🙂
Загрузим в МК скетч Blink или Blink_HL, а далее, как показано на рисунке, соединим INPUT1 и ENABLE1 с digital pin 13, к которому подключен светодиод, а INPUT2 соединим с землёй. Запустим симуляцию и увидим, что моторчик одну секунду вращается в одну сторону, а потом останавливается на секунду. Т.е. получили моторчиковый Blink 🙂

Итак, получается, что для управления одним моторчиком требуется три порта(один из них — PWM).
Если скоростью вращения моторчика управлять не требуется, то можно сэкономить на PWM-портах (ENABLE1 и ENABLE2). Тогда, для управления одним моторчиком нужно будет задействовать два порта.

Итак, определимся с портами (в скобках – соответствующий номер ножки МК из pin mapping ):

MOTOR1
11		(17) – PWM		ENABLE1
12		(18)			INPUT2
13		(19)			INPUT1

MOTOR2
7		(13)			INPUT3
8		(14)			INPUT4
9		(15) – PWM		ENABLE2

Изменим наш проект в Proteus-е:

А теперь напишем скетч.

Для удобства – будем хранить номера портов не в обычных переменных типа int, а объединим их структурой:

struct MOTOR    // структура для хранения номеров pin-ов, к которым подключены моторчики
{
  int in1;      // INPUT1
  int in2;      // INPUT2
  int enable;   // ENABLE1
};

однако, если просто объявить такую структуру в коде скетча, например так:

/*
 * тестовый скетч с L293
 */

struct MOTOR    // структура для хранения номеров pin-ов, к которым подключены моторчики
{
  int in1;      // INPUT1
  int in2;      // INPUT2
  int enable;   // ENABLE1
};

// определяем порты, к которым подключены моторчики
MOTOR MOTOR1 = { 13, 12, 11 };
MOTOR MOTOR2 = { 7, 8, 9 };

void set_m_pins(MOTOR *m);

void setup()
{
  set_m_pins(&MOTOR1);
  set_m_pins(&MOTOR2);
  Serial.begin(9600);
}

void loop()
{
  delay(1000);
}

void set_m_pins(MOTOR *m)
{
  if(m)
  {
    pinMode(m->in1, OUTPUT);
    pinMode(m->in2, OUTPUT);
  }
}

То при попытке скомпилировать — получим ошибку:

error: variable or field ‘set_m_pins’ declared void In function ‘void setup()’:
— дело в том, что дополнительные структуры данных должны объявляться в заголовочных (.h) файлах.
Т.е. нужно создать библиотечный файл и подключиться его к скетчу директивой #include

Однако, тут компилятору не нравится именно обращение к новому типу данных по указателю.

Изменим скетч:

/*
 * тестовый скетч с L293
 */

struct MOTOR    // структура для хранения номеров pin-ов, к которым подключены моторчики
{
  int in1;      // INPUT1
  int in2;      // INPUT2
  int enable;   // ENABLE1
};

// определяем порты, к которым подключены моторчики
MOTOR MOTOR1 = { 13, 12, 11 };
MOTOR MOTOR2 = { 7, 8, 9 };

void setup()
{
  Serial.begin(9600);
  pinMode(MOTOR1.in1, OUTPUT); // настраиваем выводы
  pinMode(MOTOR1.in2, OUTPUT); // на ВЫВОД
  pinMode(MOTOR2.in1, OUTPUT);
  pinMode(MOTOR2.in2, OUTPUT);
}

void loop()
{
  forward1();   // вращаем оба моторчика вперёд
  forward2();
  delay(3000);
  back2();      // вращаем второй моторчик назад
  delay(500);
  forward2();   // а теперь опять вращаем второй моторчик вперёд
}

void forward1() // первый вперёд
{
  digitalWrite(MOTOR1.in1, HIGH);
  digitalWrite(MOTOR1.in2, LOW);
  analogWrite(MOTOR1.enable, 254);
}

void forward2() // второй вперёд
{
  digitalWrite(MOTOR2.in1, HIGH);
  digitalWrite(MOTOR2.in2, LOW);
  analogWrite(MOTOR2.enable, 254);
}

void back1() // первый назад
{
  digitalWrite(MOTOR1.in1, LOW);
  digitalWrite(MOTOR1.in2, HIGH);
  analogWrite(MOTOR1.enable, 254);
}

void back2() // второй назад
{
  digitalWrite(MOTOR2.in1, LOW);
  digitalWrite(MOTOR2.in2, HIGH);
  analogWrite(MOTOR2.enable, 254);
}

Три секунды оба моторчика вращаются вперёд, затем пол-секунды второй моторчик вращается назад, а потом снова вперёд.

Перенесём структуру и функции в нашу библиотеку RoboCraft.

/*
 * robocraft.h
 *
 * RoboCraft - library fo RoboCraft.ru project
 * RoboCraft - библиотека для проекта RoboCraft.ru
 * 
 *
 * Written by noonv, August 2009.
*/

#ifndef robocraft_h
#define robocraft_h

#include "WProgram.h"

#define _RCDEBUG_ 1

struct MOTOR    // структура для хранения номеров pin-ов, к которым подключены моторчики
{
  int in1;      // INPUT1
  int in2;      // INPUT2
  int enable;   // ENABLE1
};

class RoboCraft
{
	public:
		RoboCraft();
		RoboCraft(MOTOR *m1, MOTOR *m2);
		void hello();
		void motor_forward(int m,int speed=254);
		void motor_back(int m, int speed=254);
	private:
		void set_m_pins(MOTOR *m);
		void m_forward(MOTOR *m,int speed=254);
		void m_back(MOTOR *m,int speed=254);
		MOTOR MOTOR1;
		MOTOR MOTOR2;
};

#endif // #ifndef robocraft_h

А скетч тогда будет таким:

#include <robocraft.h>
//
// тестовый скетч с L293
// добавили пробные функции для работы с моторчиками через L293
//
//
// by noonv 
//

MOTOR MOTOR1 = { 13, 12, 11 };
MOTOR MOTOR2 = { 7, 8, 9 };

RoboCraft robot(&MOTOR1, &MOTOR2);     // создаём экземпляр нашего класса

void setup()
{
  Serial.begin(9600);
  robot.hello();    // говорим "Hello" :)
}

void loop()
{
  Serial.println("loop");
  robot.motor_forward(0,254); // оба полный вперёд :)
  delay(3000);
  robot.motor_back(2,254);    // крутим второй назад
  delay(1000);
  robot.motor_forward(2,254);  // и снова 2-й вперёд! 
}

Функции вращения принимают два параметра – номер моторчика(1-2) и скорость вращения (0-255). Если номер отличается от 1-2, то вращение задаётся сразу обоим моторчикам.

У меня под рукой оказалась микросхема L293E – поэтому необходимо использовать защитные диоды (1N4007), которых для двух моторчиков нужно аж 8 штук 🙂

Так же у L293E не 16, а целых 20 ножек:

Впрочем, для тестирования можно собрать схему только для одного моторчика 😉

Соответственно нужно внести изменения в скетч:

MOTOR MOTOR1 = { 13, 12, 11 };
MOTOR MOTOR2 = { 7, 8, 9 };

RoboCraft robot(&MOTOR1, &MOTOR2);     // создаём экземпляр нашего класса

void setup()
{
  Serial.begin(9600);
  robot.hello();    // говорим "Hello" :)
}

void loop()
{
  Serial.println("loop");
  robot.motor_forward(0,254); // полный вперёд :)
  delay(3000);
  robot.motor_back(1,254);    // крутим назад
  delay(1000);
}

— крутим наш моторчик 3 секунды вперёд, а затем одну секунду назад.

Крутится 🙂

читать далее
Простой мотор-шилд для Arduino/CraftDuino
Ещё пара слов про L293
L-Motor Shield

Ссылки
ДРАЙВЕР ДВИГАТЕЛЕЙ L293D
http://www.arduino.cc/playground/Code/Struct


49 комментариев на «“Практическое программирование Arduino/CraftDuino — драйвер двигателей L293D”»

  1. Cмысл в том что подключив на прямую двигатель к контролеру ты сожгеш либо весь контроллер либо если повезет только ту ножку куда подключил.
    Другой вопрос что данный драйвер кушает порядка 2х вольт от напряжения питания двигателей, и в низковольтовых конструкциях(5 или 3.3) лучше применять драйвера по современнее например Toshiba TB6612FNG

    • Подключив напрямую да, но тут проще развязать всё оптопарой, зачем драйвер-то?

    • Если проще — тогда и развязывать не надо оптикой — ставьте транзистор любой=)
      Драйвер это слово умное такое.Ни к чему не обязывающее.Это просто то что управляет, в данном случае мощной нагрузкой (т.е. поставите оптрон — его тоже можно будет драйвером назвать=)
      И кстати оптрон, который будет тянуть 1.5А(как ЭЛЬка) оптроном назвать язык не поворачивается, это уже твердотельное релле, с соотвествующей ценой=))
      И, что главное, с одной ЭЛЬкой можно управлять, с реверсом 2я двигателями — подключил и готово. А «оптроном» или транзистором только в одну сторону — без проблем, реверс добавить — повозится придётся.
      Не много, но придётся — сложно сказать что это проще=)

  2. уже разобрался )) а тут ничего не написано про управление серво… можно пару слов…

    зы: просто задумался о покупке Motor Shield 2, но 800рублей… вот ищу варианты замены…

    • 1. этож кварц с конденсаторами (см любую схему дуины)
      2. атут Элькой точно не обойтись=)
      А это именно двигатель?
      Регулировать скорость надо?
      Изменять направление вращения надо?

    • 1. он нужен для синхронизации?? типа 16МГц?
      2. Да элькой не обойтись =(((
      2.1. Двигатель из стеклоподъемника =)10А это ток короткого замыкания(это граница за которую лучше не выходить, а горит он при 28А), рабочий при опускании 0,3-0,6А при подъёме 3-6А. Есть схема через н-мост, но ищу именно микруху.
      2.2. Регулировать скорость надо ШИМом.
      2.3. Изменять направление вращения надо.

      Для чего мне это нужно?
      1. Стекло подъёмник =) (требуеться 2.1. и 2.2.)
      2. Есть интерестная идея под Ардуино(как сделаю запишу видео и статью)(требуеться 2.1. и 2.3.)

      Т.е. можно два разных драйвера первый у которого есть 2.1. и 2.2., а второй соответсвенно 2.1. и 2.3.; а если есть всё в одном то это просто ВЕЛИКОЛЕПНО!!!

    • 1. Да, точнее для тактирования.Правда в протеусе должно работать и без него — так, для красоты=)
      2. Не совсем понял что такое ток короткого замыкания, а тем более — ток при которм горит 0_о… Максимальный ток двигатель потребляет в заторможенном состоянии. И обычно у него вполне конкретное напряжение питания… Например — имеем питание 12в, холостой ход 0,5А, с заторможенным валом 10А, а до бОльших токов его можно разогнать только увеличением питания…

      «Микросхем» на 10А незнаю, темболее мостовых… А может без моста и микросхем?=)
      Транзистор и перекидное релле?
      и ШИМ и реверс, транзистор (полевичок) на такой ток найти легко.

  3. Да, с к.з. ошибся. Это условие выключения питния в моем случаи.
    перекидное реле боюсь не справяться с ШИМом. У реле частота переключений вроде около 10Гц. А вот Н-мост как заменитель микрухи тоже можно расмотреть =)

    • 0_0
      Аллах свами! Зачем релёй-то ШИМить???
      ШИМ даёт транзистор — дальше через де группы контактов реле на двигатель.
      От положения контактов реле зависит направление вращения двигателя.
      От ШИМа на транзисторе — скорость вращения.

    • нет — напрямую на ножку контроллера можно повесить только светодиод (да и тот через токоограничительный резистор).
      т.к. ток через один пин не должен превышать 40 mA.
      Т.о. образом чтобы управлять даже этим маломощным моторчиком нужен «драйвер», которым, например, может выступать ключевой транзистор.

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

    • Подключил? Как низковольтный движок запитал?

  4. Спасибо за такую подробную статью. Собрал и подключил — работает. Начал регулировать скорость и обнаружил что при определенных значениях слышен писк. Довольно громкий на 30, тихий на 120 и пропадает примерно на 150.

    О чем это сигнализирует?

    • Это вы слышите частоту ШИМа.
      Это сигализируеи о том что он есть(ШИМ=)
      Чтобы его не было надо на нагрузке фильтровать, например так:

      Или
      изучаем библиотеку Timer1, там доступ к таймеру организован — можно частоту ШИМа накрутить чтоб не пищщал=)

    • Месье не может в извращения?
      Цепляем MOSFETы к L293!

    • Да я не извращенец. Просто места жалко, точнее нет его совсем:(. А микруха бы влезла.

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

    У меня двигатель на 0,9-1,3В. В посте выше написано:

    напряжение питания двигателей (Vs) от 4,5 до 36В

    Т.е. L293D не получится использовать для моего движка? Если нет, то что посоветуете?

    • L293D не получится использовать.
      Можно другие микросхемы(на вскидку не помню), можно на рассыпухе сделать.
      Тут больше вводных надо=)
      Реверсировать надо ваш двигатель, или только обороты менять?
      Ток потребления с заклиненным валом какой?
      Питане какое будет использоваться?

    • Питание — батарея крона, либо аккумуляторы примерно на такое же напряжение. Ими питаем arduino через LM7805. Уже от ардуины (5В) питаем движки (2шт х 150мА в момент максимальной нагрузки) через какой-то преобразователь 5В->1В.

      Реверс не нужен, только смена оборотов (регулировать тип вибрации).

      Про ток потребления с заклиненным валом ничего сказать не могу, ибо даташита на движки нет (есть только название QX-5A). Померить пока не могу, т.к. преобразователь напряжения еще не собрал, и 1В взять неоткуда.

    • Использовать другие микросхемы — навряд ли, в нашей деревне L293D повезло что нашел =)
      Так что было бы здорово услышать совет как сделать все на простых элементах ( возможно транзистор+резисторы)? А нельзя ли использовать резистивный делитель?

    • Учитывая, что ток(наверняка) будет копеешный — именно резистивный делитель и транзисторы=)
      А то, что реверсировать не надо — так это вообще упрощает дело=)

      Думаю так пойдёт=)
      Только надо померить сопротивление обмоток моторчика и рассчитать значение R1.
      Тут получается делитель где нижний резистор это ваш мотор.
      скажем по результатам замера оказалось Rмотора =23ом, на нём должно быть 1,3В, а питание у нас 5В.
      U1/U2=R1/R2, Uпит=U1+U2
      R2=23ом
      Uпит=5В
      U2=1,3В -> U1=3.7В, R1=3.7*23/1.3=65ом

      вроде так=)

    • Rмотора измерять, подсоединяя мультиметр к проводам + и — мотора?
      Или надо разбирать движок и измерять непосредственно сопротивление обмоток?

      Если второе, то страшно представить как это делать на движке размером 10х4 мм =)

    • Снова наткнулся на данный вопрос.
      По Вашей схеме выше: можно ли вместо резистора использовать ШИМ соответствующей скважности?

      Т.е. мотор на 1В, крона дает 9В. Запитаем мотор сразу от кроны (а не от 5В как на рисунке выше). Значит управляем транзистором так:
      analogWrite(motor, 28);

      Поясню: 28=255/9 (то есть если бы на транзистор подали шим со значением 255, на выходе было бы 9В, но нам надо 1В).

      Как к подобным манипуляциям отнесется обмотка двигателя?

    • Обвязка для L293?

      Если использовать микросхему L293E, то допустимый ток нагрузки на каждый канал уже будет 1А (а пиковый ток – 2А), но придётся использовать внешние защитные диоды, которые у L293D встроены в саму микросхему.

      Т.е. для D — только кондёры(не строго обязательно). Диоды (как встроенные так и внешние) нужны для устранения выбросов самоиндукции от мотора.
      И по TB6612FNG вроде только кондёры нужны.

  6. скажите, вот имеется микросхема L293C, D типа небыло в магазине, у С нет диодов внутренних, их нужно припаять к выводам микрухи как на схеме у D? какие диоды нужны?

    • Вот так:

      Диоды, например 1n4007 — оч. популярные=)

  7. Вопрос — а как можно контроллировать моторчик по создаваемой им нагрузке? Т.е. когда серво доедет «до упора» и нагрузка подскочит, чтобы питание на него автоматически отключалось. Девайс планируется к использованию в уличных условиях, возможны лёд, грязь и всё такое, что может помешать серву двигаться, вот и хотелось бы обезопаситься от этого…

  8. Здравствуйте! подскажите пожалуйста как правильно собрать схему для ARDUINO UNO и L293D, объединив двигатель и подсветку светодиодной ленты с возможностью изменения яркости.

  9. Спасибо за статью.
    Собрал драйвер с робозона — то же самое на L298, помощнее и перед входами направления поставлена логика для уменьшения числа выходов.
    Прошивку использую вашу. Но есть глюк.
    Один канал честно регулируется от нуля до 254, второй же — только логический уровень — ноль или пять вольт.
    Прошивка вот

    // Import the Arduino Servo library
    #include <Servo.h> 
    
    struct MOTOR    // структура для хранения номеров pin-ов, к которым подключены моторчики
    {
      int dir;      // DIRECTION
      int enable;   // ENABLE
    };
    
    // определяем порты, к которым подключены моторчики
    MOTOR MOTOR1 = { 12, 11 };
    MOTOR MOTOR2 = { 8, 10 };
    
    // Create a Servo object for each servo
    Servo servo1;
    Servo servo2;
    // TO ADD SERVOS:
    //   Servo servoN;
    //   etc...
    
    // Common servo setup values
    int minPulse = 600;   // minimum servo position, us (microseconds)
    int maxPulse = 2400;  // maximum servo position, us
    
    // User input for servo and position
    int userInput[3];    // raw input from serial buffer, 3 bytes
    int startbyte;       // start byte, begin reading input
    int servo;           // which servo to pulse?
    int pos;             // servo angle 0-180
    int i;               // iterator
    
    void setup() 
    { 
      // Attach each Servo object to a digital pin
      servo1.attach(2, minPulse, maxPulse);
      servo2.attach(3, minPulse, maxPulse);
      // TO ADD SERVOS:
      //   servoN.attach(YOUR_PIN, minPulse, maxPulse);
      //   etc...
      pinMode(MOTOR1.dir, OUTPUT); // настраиваем выводы на вывод
      pinMode(MOTOR2.dir, OUTPUT);
      
    
      // Open the serial connection, 9600 baud
      Serial.begin(9600);
    } 
    
    void forward1(int pos) // первый вперёд
    {
      digitalWrite(MOTOR1.dir, HIGH);
      analogWrite(MOTOR1.enable, pos);
    }
    
    void forward2(int pos) // второй вперёд
    {
      digitalWrite(MOTOR2.dir, HIGH);
      analogWrite(MOTOR2.enable, pos);
    }
    
    void loop() 
    { 
      // Wait for serial input (min 3 bytes in buffer)
      if (Serial.available() > 2) {
        // Read the first byte
        startbyte = Serial.read();
        // If it's really the startbyte (255) ...
        if (startbyte == 255) {
          // ... then get the next two bytes
          for (i=0;i<2;i++) {
            userInput[i] = Serial.read();
          }
          // First byte = servo to move?
          servo = userInput[0];
          // Second byte = which position?
          pos = userInput[1];
          // Packet error checking and recovery
          if (pos == 255) { servo = 255; }
    
          // Assign new position to appropriate servo or motor
          switch (servo) {
            case 1:
              servo1.write(pos);    // move servo1 to 'pos'
              break;
            case 2:
              servo2.write(pos);
              break;
            case 3:
              forward1(pos);
              break;
            case 4:
              forward2(pos);
              break;
       // TO ADD SERVOS:
       //     case 5:
       //       servo5.write(pos);
       //       break;
       // etc...
          }
        }
      }
    
    
    }

    Где я дурак?

    • единственное предположение, что используется не-PWM порт для управления или же возможность PWM блокируется…
      внимательно читаем статью про библиотеку Servo и замечаем, что она блокиреут PWM на 9 и 10 пинах 😉
      т.о. или просто пробуем убрать Servo из скетча 🙂
      или используем для управления не 10-й пин, а 3, 5 или 6.

    • Ага, спасибо. Хм. Похоже, на атмеге 8 я вообще обломаюсь, судя по этой фразе «На старых версиях плат Arduino на основе микроконтроллера ATmega8 функция analogWrite() работает только на портах 9, 10 и 11.» Но, опять же, серва почему-то на втором порту работает и не гавкает.

  10. Здрасте всем!
    Помогите пожалуйста разобраться.
    Я начинающий и впервые увидел что, кроме void setup и void loop можно назначать какое то свое действо. Так вот. У меня получилось это, но в таком случае я никак не могу поставить условие if… Не пойму в чем дело.

    int led1 = 12;
    int led2 = 11;
    int led3 = 10;
    int led4 = 9;
    int ik = 5;
    int val = 0;
    
    void setup()
    {
      pinMode(led1, OUTPUT);
      pinMode(led2, OUTPUT);
      pinMode(led3, OUTPUT);
      pinMode(led4, OUTPUT);
      pinMode(ik, INPUT);
    }
    
    void run()
    {
      digitalWrite(led1, HIGH);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
    }
    void back()
    {
      digitalWrite(led1, HIGH);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, HIGH);
      digitalWrite(led4, HIGH);
    }
    
    void Stop()
    {
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
    }
    void loop()
    {
      val = digitalRead(ik);
      if(val==LOW)
      {
      run();
      }
      else
      {
      Stop();
      delay(2000);
      back();
      delay(2000);
      Stop();
      delay(1000);
      }
    }
    • То то и оно что компиоируется без проблем. А при закачивании скетча в ардуину, он абсолютно игнорирует if. Получается выполняет все подряд не дожидаясь что на 5 порту появится HIGH. У меня уже мозг кипит:(

    • а он и не должен дожидаться, он проверяет состояние порта на текущий момент и продолжает выполнение. Проверьте схему 🙂

    • Схема была изрыта всеми возможными приборами. Чисто все. А оказалось все гораздо проще! Установил старую версию ARDUINO IDE и все заработало как надо. Причину почему обновленная версия криво компилирует не нашел

Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Arduino Bluetooth CraftDuino DIY Google IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение