Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

LEGO Wall-E с Arduino

Компоненты и расходные материалы

LEGO Wall-E
Пришлось получить одну вторую руку, потому что они больше не делают их
× 1
Arduino Nano R3
× 1
Двигатель постоянного тока (общий)
× 2
Контроллер двух двигателей L298N
× 1
Двухцветный светодиод
с 3 выводами
× 1
Инфракрасный датчик
× 1
Зуммер
Тот, который может воспроизводить разные тона
× 1
батарея 9 В
× 1
Резистор 330 Ом
× 3
Перемычки (общие)
× 20

Необходимые инструменты и машины

Паяльник (общий)

Приложения и онлайн-сервисы

IDE Arduino

Об этом проекте

Все знают фильм Wall-E (а если нет, идите и посмотрите его сейчас!) И желтого героя, который пытается очистить землю. В этом проекте я использовал Lego-версию нашего маленького друга и научил его избегать препятствий. Это был мой первый проект и отличный опыт обучения основам электроники.

Шаг 1. Код

Как разработчик программного обеспечения по профессии, я подумал о том, что я хочу, чтобы он сделал, и начал с кода.

  // Эта программа предназначена для управления роботом Wall-E Lego .// Wall-E разъезжает. Когда он видит препятствие, он останавливается, чтобы осмотреться, и выбирает другой путь. // Arduino Nano имеет 21 контакт, который можно использовать для digitalRead и digitalWrite // Контакты 3, 5, 6, 9, 10, 11 ШИМ можно использовать для analogWrite // контакты 0 и 1 могут использоваться для TTL // контакты 2 и 3 могут использоваться для внешних прерываний // контакты 10, 11, 12, 13 поддерживают связь SPI // контакт 13 может быть внутренним светодиодом // контакты 14 к 21 также являются аналоговыми выводами от A0 до A7 и могут использоваться для аналогового чтения # define INFRA_RED 9 // может быть любым выводом # define GREEN_LED 7 // может быть любым выводом, но требуется резистор, может быть 220 Ом - или вывод заземления получает 1 кОм # define RED_LED 8 // может быть любым выводом, но требуется резистор, может быть 220 Ом - или вывод заземления получает 1 кОм # define BUZZER 10 // должен быть выводом PWM для установки частоты, требуется резистор, может быть 1 кОм // MR - это правый двигатель, ML - левый двигатель # define MR_1 A1 // может быть любым выводом, поэтому давайте сделаем их соответствующими номерам выводов на экране L289N # define MR_2 A2 // может быть любым выводом, поэтому давайте сделаем их соответствующими п цифрами на экране L289N # define MR_ENABLE 5 // должен быть выводом ШИМ для управления скоростью # define ML_1 A3 // может быть любым контактом, поэтому давайте сделаем их соответствующими номерам контактов на экране L289N # define ML_2 A4 // может быть любым выводом, поэтому давайте сделаем их соответствующими номерам выводов на экране L289N. # define ML_ENABLE 6 // должен быть выводом PWM для управления скоростью // установить его нормальную скорость на максимальное значение const int NORMAL_SPEED =255; void setup () { // сразу после нажатия кнопки сброса подождать немного, чтобы мы могли выключить его, не повредив какие-либо компоненты из-за задержки скачков напряжения (2000); // инициализировать светодиоды и зуммер pinMode (GREEN_LED, OUTPUT); pinMode (RED_LED, OUTPUT); // pinMode (ЗУММЕР, ВЫХОД); // не обязательно // сбросить светодиод на зеленый digitalWrite (RED_LED, LOW); digitalWrite (GREEN_LED, HIGH); // установить контакты двигателя постоянного тока pinMode (MR_ENABLE, OUTPUT); // двигатель правый pinMode (MR_1, OUTPUT); pinMode (MR_2, ВЫХОД); pinMode (ML_ENABLE, ВЫХОД); // мотор слева pinMode (ML_1, OUTPUT); pinMode (ML_2, ВЫХОД); // инициализировать инфракрасный pinMode (INFRA_RED, INPUT); // инициализировать генератор случайных чисел для случайных ходов randomSeed (analogRead (0)); // поздороваемся playHello ();} void loop () {// нормальные операции driveForwards (NORMAL_SPEED); // установить светодиод на зеленый digitalWrite (RED_LED, LOW); digitalWrite (GREEN_LED, HIGH); // проверяем наличие препятствий if (digitalRead (INFRA_RED) ==LOW) {// LOW означает обнаружение препятствия // меняем светодиод на красный digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, HIGH); // останавливаем двигатели stopDriving (); // проигрываем звук playUhOh (); // проверяем левый turnLeft (500); логическое препятствиеLeft =false; если (digitalRead (INFRA_RED) ==LOW) {constraleLeft =true; } // возвращаемся к центру delay (100); TurnRight (500); // подождем немного, мы не хотим показаться торопливым delay (500); // проверяем направо turnRight (500); логическое препятствиеRight =false; если (digitalRead (INFRA_RED) ==LOW) {damageRight =true; } // возвращаемся к центру delay (100); turnLeft (500); // теперь проверим, как отсюда выбраться if (preventleLeft &&preventleRight) {driveBackwards (NORMAL_SPEED / 3); // звуковой сигнал при движении назад на 5 секунд for (int i =0; i <5; i ++) {tone (BUZZER, 1000, 500); задержка (1000); } // чтобы не застрять где-нибудь, перед продолжением путешествия произвольно поверните в нужном направлении randomTurn (800, 1600); } иначе, если (препятствиеLeft) {turnRight (1000); } иначе, если (препятствиеRight) {turnLeft (1000); } else {randomTurn (1000, 1800); }} // делаем случайные вещи для большего взаимодействия int number =random (100); // создает случайное число от 0 до 99 if (number ==0) {randomTurn (200,2000); }} void driveForwards (int speed) {// установить двигатели в одном направлении digitalWrite (MR_1, LOW); digitalWrite (MR_2, ВЫСОКИЙ); digitalWrite (ML_1, ВЫСОКИЙ); digitalWrite (ML_2, LOW); setSpeed ​​(speed);} void driveBackwards (int speed) {// установить двигатели в противоположном направлении digitalWrite (MR_1, HIGH); digitalWrite (MR_2, LOW); digitalWrite (ML_1, LOW); digitalWrite (ML_2, ВЫСОКИЙ); setSpeed ​​(speed);} void turnLeft (int duration) {// повернуть налево, двигаясь вперед правым колесом и назад левым колесом digitalWrite (MR_1, HIGH); digitalWrite (MR_2, LOW); digitalWrite (ML_1, ВЫСОКИЙ); digitalWrite (ML_2, LOW); // замедляемся до поворота setSpeed ​​(NORMAL_SPEED / 2); задержка (продолжительность); stopDriving ();} void turnRight (int duration) {// повернуть направо, двигаясь назад правым колесом и вперед левым колесом digitalWrite (MR_1, LOW); digitalWrite (MR_2, ВЫСОКИЙ); digitalWrite (ML_1, LOW); digitalWrite (ML_2, ВЫСОКИЙ); // замедляемся до поворота setSpeed ​​(NORMAL_SPEED / 2); задержка (продолжительность); stopDriving ();} void stopDriving () {// выключаем все выводы двигателя digitalWrite (MR_1, LOW); digitalWrite (MR_2, LOW); digitalWrite (ML_1, LOW); digitalWrite (ML_2, LOW); // не знаю, что делать с контактами ENABLE, но не помешает их выключить, я думаю, digitalWrite (MR_ENABLE, LOW); digitalWrite (ML_ENABLE, LOW);} void setSpeed ​​(int speed) {// скорость должна быть от 0 до 255 speed =constrain (speed, 0, 255); // устанавливаем скорость включения двигателей analogWrite (MR_ENABLE, speed); analogWrite (ML_ENABLE, скорость);} void randomTurn (int минимум, int максимум) {беззнаковое долгое время =millis (); int duration =random (минимум, максимум); если (время% 2) {turnRight (продолжительность); } else {turnLeft (продолжительность); }} void playHello () {тон (ЗУММЕР, 262, 250); // проигрывает C4 delay (300); тон (ЗУММЕР, 330, 250); // проигрывает E4 delay (300); тон (ЗУММЕР, 392, 250); // проигрывает задержку G4 (300); тон (ЗУММЕР, 523, 500); // проигрывает C5 delay (550);} void playUhOh () {tone (BUZZER, 523, 250); // проигрывает C5 delay (300); тон (ЗУММЕР, 415, 500); // воспроизводит задержку Gis4 (600);}  

Когда вы отсоединяете работающий двигатель, могут произойти скачки напряжения и повредить вашу электронику. Поэтому я заставляю Валла подождать две секунды, прежде чем он что-нибудь сделает. Это означает, что я могу просто нажать кнопку сброса на Arduino и быстро отключить аккумулятор, ничего не повредив.

Он играет небольшую мелодию, когда просыпается, а затем начинает водить машину. Когда он видит препятствие, он останавливается, воспроизводит звук «Угу» и оглядывается, чтобы определить лучший путь. Тип инфракрасного датчика, который я использовал, имеет небольшой винт на задней панели, который позволяет вам определять расстояние, на котором он создает сигнал. Поэтому в коде нет расчетов расстояний. (Я хотел сначала использовать ультразвуковой датчик, но он не подходит для его глаз.)

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

Я пытался заставить его делать случайные повороты, но эта часть еще не завершена. Я пытаюсь использовать встроенный таймер Arduino. Дайте мне знать в комментариях, если у вас есть идеи, как его оптимизировать!

Шаг 2. Подключите его

Первым делом нужно было встроить инфракрасный датчик в глаз, чтобы он не выглядел слишком очевидным. Я разобрал его, приклеил к датчику булавку Lego (чтобы его глаз мог двигаться вверх и вниз), а затем с помощью синей кнопки закрепил детали Lego вокруг датчика:

Самым важным в двигателях было то, что у них был достаточный крутящий момент, потому что установка колес Wall-E требует довольно небольшого усилия для движения. Мне пришлось припаять провода к двигателям и прикрепить их таким образом, чтобы они надежно подключались к Lego. Поэтому я разобрал его колеса, заказал целую сумку, полную булавок Lego Technic, обмотал гипсовой лентой (как вы это называете? Это похоже на мягкую ленту, которая может попасть на вашу кожу) вокруг валов двигателей и воткнул их в два стержня. это стало главной осью для каждого колеса. Это сработало в течение нескольких минут, но затем трение было слишком большим, чтобы клей на ленте держался. К счастью, у булавок Technic есть маленькие бороздки сбоку, поэтому у ленты было место, за которое можно было держаться, что они с радостью сделали после того, как замочили в суперклее.

Я также снял часть его груди, чтобы просунуть светодиод. Затем я соединил все части и Arduino.

Моторный щит просто вписывается в его животик:

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

Согласно соглашению, все красные провода положительные («подают» электричество), а все черные провода - отрицательные («получают» электричество). Желтый провод в правом верхнем углу передает сигнал инфракрасного датчика; оранжевый и зеленый провода предназначены для трехконтактного двухцветного светодиода, пурпурные провода - для указания моторному экрану, в каком направлении нужно повернуть моторы, а синие кабели сообщают моторному экрану, с какой скоростью их поворачивать.>

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

Еще одна проблема, с которой я столкнулся, собирая все вместе, - это отсутствие контактов напряжения и заземления. Я хотел запитать двигатели напрямую через моторный щит, чтобы они могли получить как можно больше мощности, но мне каким-то образом пришлось подать 5 В на Arduino и инфракрасный датчик. Итак, я сделал то, что почти все в сети сказали, что я не должен:я подключил выход 5 В моторного щита к контакту 5 В Arduino в качестве входа. Теперь с экраном, который я использую, я могу быть абсолютно уверен, что он выдает регулируемое напряжение 5 В без каких-либо неприятных всплесков, которые могут повредить мою Arduino. Если вы прикрепите к этому контакту нерегулируемый источник питания, вы, вероятно, что-нибудь поджарите. Сначала я хотел использовать вывод Vin, но у него есть встроенный механизм, который регулирует все вниз, поэтому мои 5 В превратились бы в 3,8 В или около того, что недостаточно для правильной работы Arduino. Вместо этого я использовал бесплатный Vin для питания (!) Инфракрасного датчика с помощью 5 В, потому что у меня не было никаких разветвителей кабеля, и я знал, что оттуда тоже будет выходить 5 В. Да, в этот момент все стало немного похоже на Франкенштейна. Но это сработало!

Шаг 3 - Wall-E в действии

Вот несколько видеороликов, демонстрирующих его в действии:

И вот я проверил, что он будет делать, если застрянет в углу:

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

И так Wall-E жил с удовольствием когда-либо после. конец.

Код

  • Wall_e_control
Wall_e_control Arduino
Это центральный управляющий файл для Wall-E. Это базовое, но все, что ему нужно на данный момент.
 // Эта программа предназначена для управления роботом Wall-E Lego .// Wall-E разъезжает. Когда он видит препятствие, он останавливается, чтобы осмотреться, и выбирает другой путь. // Arduino Nano имеет 21 контакт, который можно использовать для digitalRead и digitalWrite // Контакты 3, 5, 6, 9, 10, 11 ШИМ можно использовать для analogWrite // контакты 0 и 1 могут использоваться для TTL // контакты 2 и 3 могут использоваться для внешних прерываний // контакты 10, 11, 12, 13 поддерживают связь SPI // контакт 13 может быть внутренним светодиодом // контакты 14 к 21 также являются аналоговыми выводами от A0 до A7 и могут использоваться для аналогового чтения # define INFRA_RED 9 // может быть любым выводом # define GREEN_LED 7 // может быть любым выводом, но требуется резистор, может быть 220 Ом - или вывод заземления получает 1 кОм # define RED_LED 8 // может быть любым выводом, но требуется резистор, может быть 220 Ом - или вывод заземления получает 1 кОм # define BUZZER 10 // должен быть выводом PWM для установки частоты, требуется резистор, может быть 1 кОм // MR - это правый двигатель, ML - левый двигатель # define MR_1 A1 // может быть любым выводом, поэтому давайте сделаем их соответствующими номерам выводов на экране L289N # define MR_2 A2 // может быть любым выводом, поэтому давайте сделаем их соответствующими п цифрами на экране L289N # define MR_ENABLE 5 // должен быть выводом ШИМ для управления скоростью # define ML_1 A3 // может быть любым контактом, поэтому давайте сделаем их соответствующими номерам контактов на экране L289N # define ML_2 A4 // может быть любым выводом, поэтому давайте сделаем их соответствующими номерам выводов на экране L289N. # define ML_ENABLE 6 // должен быть выводом PWM для управления скоростью // установить его нормальную скорость на максимальное значение const int NORMAL_SPEED =255; void setup () { // сразу после нажатия кнопки сброса подождать немного, чтобы мы могли выключить его, не повредив какие-либо компоненты из-за задержки скачков напряжения (2000); // инициализировать светодиоды и зуммер pinMode (GREEN_LED, OUTPUT); pinMode (RED_LED, OUTPUT); // pinMode (ЗУММЕР, ВЫХОД); // не обязательно // сбросить светодиод на зеленый digitalWrite (RED_LED, LOW); digitalWrite (GREEN_LED, HIGH); // установить контакты двигателя постоянного тока pinMode (MR_ENABLE, OUTPUT); // двигатель правый pinMode (MR_1, OUTPUT); pinMode (MR_2, ВЫХОД); pinMode (ML_ENABLE, ВЫХОД); // мотор слева pinMode (ML_1, OUTPUT); pinMode (ML_2, ВЫХОД); // инициализировать инфракрасный pinMode (INFRA_RED, INPUT); // инициализировать генератор случайных чисел для случайных ходов randomSeed (analogRead (0)); // поздороваемся playHello ();} void loop () {// нормальные операции driveForwards (NORMAL_SPEED); // установить светодиод на зеленый digitalWrite (RED_LED, LOW); digitalWrite (GREEN_LED, HIGH); // проверяем наличие препятствий if (digitalRead (INFRA_RED) ==LOW) {// LOW означает обнаружение препятствия // меняем светодиод на красный digitalWrite (GREEN_LED, LOW); digitalWrite (RED_LED, HIGH); // останавливаем двигатели stopDriving (); // проигрываем звук playUhOh (); // проверяем левый turnLeft (500); логическое препятствиеLeft =false; если (digitalRead (INFRA_RED) ==LOW) {constraleLeft =true; } // возвращаемся к центру delay (100); TurnRight (500); // подождем немного, мы не хотим показаться торопливым delay (500); // проверяем направо turnRight (500); логическое препятствиеRight =false; если (digitalRead (INFRA_RED) ==LOW) {damageRight =true; } // возвращаемся к центру delay (100); turnLeft (500); // теперь проверим, как отсюда выбраться if (preventleLeft &&preventleRight) {driveBackwards (NORMAL_SPEED / 3); // звуковой сигнал при движении назад на 5 секунд for (int i =0; i <5; i ++) {tone (BUZZER, 1000, 500); задержка (1000); } // чтобы не застрять где-нибудь, перед продолжением путешествия произвольно поверните в нужном направлении randomTurn (800, 1600); } иначе, если (препятствиеLeft) {turnRight (1000); } иначе, если (препятствиеRight) {turnLeft (1000); } else {randomTurn (1000, 1800); }} // делаем случайные вещи для большего взаимодействия int number =random (100); // создает случайное число от 0 до 99 if (number ==0) {randomTurn (200,2000); }} void driveForwards (int speed) {// установить двигатели в одном направлении digitalWrite (MR_1, LOW); digitalWrite (MR_2, ВЫСОКИЙ); digitalWrite (ML_1, ВЫСОКИЙ); digitalWrite (ML_2, LOW); setSpeed ​​(speed);} void driveBackwards (int speed) {// установить двигатели в противоположном направлении digitalWrite (MR_1, HIGH); digitalWrite (MR_2, LOW); digitalWrite (ML_1, LOW); digitalWrite (ML_2, ВЫСОКИЙ); setSpeed ​​(speed);} void turnLeft (int duration) {// повернуть налево, двигаясь вперед правым колесом и назад левым колесом digitalWrite (MR_1, HIGH); digitalWrite (MR_2, LOW); digitalWrite (ML_1, ВЫСОКИЙ); digitalWrite (ML_2, LOW); // замедляемся до поворота setSpeed ​​(NORMAL_SPEED / 2); задержка (продолжительность); stopDriving ();} void turnRight (int duration) {// повернуть направо, двигаясь назад правым колесом и вперед левым колесом digitalWrite (MR_1, LOW); digitalWrite (MR_2, ВЫСОКИЙ); digitalWrite (ML_1, LOW); digitalWrite (ML_2, ВЫСОКИЙ); // замедляемся до поворота setSpeed ​​(NORMAL_SPEED / 2); задержка (продолжительность); stopDriving ();} void stopDriving () {// выключаем все выводы двигателя digitalWrite (MR_1, LOW); digitalWrite (MR_2, LOW); digitalWrite (ML_1, LOW); digitalWrite (ML_2, LOW); // не знаю, что делать с контактами ENABLE, но не помешает их выключить, я думаю, digitalWrite (MR_ENABLE, LOW); digitalWrite (ML_ENABLE, LOW);} void setSpeed ​​(int speed) {// скорость должна быть от 0 до 255 speed =constrain (speed, 0, 255); // устанавливаем скорость включения двигателей analogWrite (MR_ENABLE, speed); analogWrite (ML_ENABLE, скорость);} void randomTurn (int минимум, int максимум) {беззнаковое долгое время =millis (); int duration =random (минимум, максимум); если (время% 2) {turnRight (продолжительность); } else {turnLeft (продолжительность); }} void playHello () {тон (ЗУММЕР, 262, 250); // проигрывает C4 delay (300); тон (ЗУММЕР, 330, 250); // проигрывает E4 delay (300); тон (ЗУММЕР, 392, 250); // проигрывает задержку G4 (300); тон (ЗУММЕР, 523, 500); // проигрывает C5 delay (550);} void playUhOh () {tone (BUZZER, 523, 250); // проигрывает C5 delay (300); тон (ЗУММЕР, 415, 500); // воспроизводит задержку Gis4 (600);} 

Схема

Значение цветов кабеля:
красный =напряжение (положительное)
черный =земля (отрицательный)
желтый =сигнал инфракрасного датчика
оранжевый и зеленый =подключения для входа красного и зеленого светодиода
фиолетовый =управление направлением двигателя
синий =контроль скорости двигателя (к сожалению, у детали Fritzing не было двух контактов, которые были у моего моторного моста для этих соединений, поэтому в данный момент это выглядит как ослабленные провода) wall-e2_3P6X71BCnP.fzz

Производственный процесс

  1. Мониторинг CO2 с помощью датчика K30
  2. Слепоглухое общение с 1Sheeld / Arduino
  3. Управление монетоприемником с помощью Arduino
  4. Автоматический стрелок из лего
  5. Робот с сервомотором избегает препятствий
  6. Arduino с Bluetooth для управления светодиодом!
  7. Емкостной датчик отпечатков пальцев с Arduino или ESP8266
  8. Робот-последователь линии
  9. Игра с дисплеем Nextion
  10. Роботизированная рука, управляемая нунчук (с Arduino)