Торговый автомат «Сделай сам» — проект мехатроники на базе Arduino
<основной класс="главный сайт" id="главный">
В этом проекте мы научимся делать торговый автомат своими руками на базе Arduino. Я покажу вам весь процесс сборки, начиная с резки и сборки плат МДФ, заканчивая соединением всех электронных частей и написанием кода Arduino.
Вы можете посмотреть следующее видео или прочитать письменное руководство ниже.
Обзор
Торговый автомат оснащен четырьмя разгрузочными устройствами, управляемыми четырьмя серводвигателями непрерывного вращения, несущей системой, управляемой шаговыми двигателями, ЖК-дисплеем, четырьмя кнопками для выбора товара и детектором монет.
Возможно, сейчас вы думаете, что контейнер для предметов не так полезен для этого торгового автомата, и да, возможно, вы правы. Но моя идея заключалась в том, чтобы сделать этот проект более интересным или немного более сложным, чтобы вы могли узнать больше нового. Я думаю, что эта идея проекта может быть отличной для студентов, изучающих электронику или мехатронику, которые рассматривают создание такого проекта в качестве своего последнего проекта, а также для всех энтузиастов Arduino.
Сборка торгового автомата
Я начал с обрезки плиты МДФ толщиной 8 мм по размеру.
Ранее я сделал 3D-модель машины, откуда взял все размеры.
Вы можете найти и скачать эту 3D-модель, а также изучить ее в своем браузере на Thangs.
Для резки МДФ я использовал циркулярную пилу. На самом деле это самодельный верстак с циркулярной пилой, фрезером и электролобзиком, сделанный моим партнером Марией, и на ее YouTube-канале Creativity Hero есть видео о нем.
После вырезания всех панелей с помощью циркулярной пилы я продолжил делать отверстия в некоторых панелях с помощью перевернутого лобзика.
На самом деле лобзик можно даже использовать для предыдущего шага, если у вас нет циркулярной пилы. Я также использовал лобзик для вырезания мелких деталей, у которых было несколько надрезов. Однако обратите внимание, что это опасные машины, поэтому вам нужно быть очень осторожным при их использовании.
Когда все детали из МДФ были готовы, я начал их собирать, используя клей для дерева и шурупы. Для крепления панелей я использовал хомуты под углом 90 градусов. Используя аккумуляторную дрель, я сначала сделал направляющие отверстия, затем сделал встречные раковины и вкрутил 3-миллиметровые винты на место. Я использовал один и тот же метод для сборки всех панелей, а для некоторых из них я также использовал F-зажимы.
Рельсовая система
На этом этапе сборки я продолжу делать рельсовую систему. Для этой цели я использую алюминиевые трубки, которые я вырезаю по размеру с помощью ручной пилы по металлу. Диаметр трубы для горизонтального рельса составляет 16 мм, а для вертикального — 20 мм. На цельной доске толщиной 18 мм я сделал прорези для трубок с помощью сверла Форстнера, а затем прикрепил к ним трубки.
Горизонтальная перекладина состоит из двух трубок длиной 27 см, а вертикальная – из трех трубок длиной 45 см.
Далее идут ползунки, и вот как я их сделал. Я использовал деревянную доску размером 21 на 21 см, на которой сделал отверстия диаметром 8 мм.
Затем я вставил в эти отверстия шпильки с резьбой 8 мм и с помощью шайб и гаек закрепил подшипники 22 мм. Что касается горизонтального слайдера, я использовал тот же метод, но с меньшими подшипниками с внешним диаметром 16 мм.
После того, как я вставил ползунок между направляющими трубки, я заметил, что он немного болтается. Для решения этой проблемы мне пришлось уменьшить расстояние между двумя рельсами. Итак, сначала я расширил прорези для труб, затем сделал перпендикулярные прорези в трубах и, наконец, с помощью стержня с резьбой скрепил две трубчатые рейки ближе друг к другу. После этого ползунки больше не болтались и работали нормально.
Однако в этот момент мне пришлось разобрать рельсы, чтобы добавить к ним другие элементы. Сначала я добавил 5-миллиметровый болт с левой стороны направляющих, на который я буду прикреплять шкив для горизонтального зубчатого ремня, а также еще два подшипника, которые будут скользить по левой вертикальной направляющей.
С другой правой стороны рельса мне пришлось прикрепить шаговый двигатель для горизонтального перемещения. Сначала я закрепил двигатель на плите МДФ толщиной 8 мм, затем добавил к ней опорную деревяшку, а также закрепил на ней прорезную часть. Наконец, я прикрепил всю эту сборку к вертикальному слайдеру, используя столярный клей и два винта.
Затем я продолжил добавление контейнера на горизонтальный слайдер. Для этой цели я использовал несколько небольших кусочков дерева, которые я соединил вместе с помощью столярного клея. Как только я закончил с этим, я был готов собрать рельсовую систему. Я залил эпоксидной смолой прорези рельсов и добавил дополнительную деревянную доску по бокам рельсов, чтобы сделать всю систему рельсов более жесткой.
На следующем этапе я вставил сборку между вертикальными направляющими и также закрепил их на месте. Конечный результат:ползунки и система рельсов работают превосходно.
Я продолжил установку горизонтального ремня ГРМ. Я измерил нужную мне длину, обрезал ее по размеру и прикрепил к слайдеру с помощью стяжки-молнии. Что касается вертикального слайдера, я прикрепил шаговый двигатель к верхней части машины с помощью куска МДФ и нескольких болтов. Внизу прикрепил шкив и аналогичным образом установил ремень ГРМ.
Разрядные блоки
Далее я перешел к блоку выгрузки предметов. Я сделал спиральную спираль из металлической проволоки диаметром 3 мм, обернув ее вокруг баллончика с краской диаметром 7 см.
После этого с помощью клеевого пистолета прикрепил его к серводвигателю непрерывного вращения.
Передняя панель
Далее идет панель передней двери, которую я прикрепил к торговому автомату с помощью простых петель, а для ее блокировки я использовал магнитный дверной фиксатор. Затем я использовал 5-миллиметровый акрил, чтобы закрыть большое переднее отверстие, а для меньшего отверстия с правой стороны я использовал очень оловянную алюминиевую пластину. Здесь я сделал 4 отверстия для кнопок, а также отверстия для монет и ЖК-дисплея. Для их изготовления я использовал дрель и ножовку. После того, как я прикрепил детали электроники к алюминиевой пластине, я прикрепил их к панели передней двери с помощью 5-миллиметровых болтов.
Для позиционирования держателя в исходное положение я установил два микропереключателя, а для монет приклеил направляющую, которая будет направлять монету в нижнюю часть автомата.
Детектор монет представляет собой простой инфракрасный датчик приближения, поэтому, когда рядом с ним будет проходить монета, датчик даст нам положительную обратную связь.
Схема цепи
Далее начинается самое интересное — подключение всех электронных компонентов к плате Arduino. Вот полная принципиальная схема этого проекта торгового автомата, сделанного своими руками.
Итак, нам нужен блок питания 12 В, не менее 2 ампер. Нам нужно 12 В для двух шаговых двигателей, а также светодиодные ленты, которые я позже прикреплю к входной двери. Однако для всех других компонентов нам нужно 5 В, поэтому я использовал понижающий преобразователь, чтобы понизить 12 В до 5 В. Серводвигатели непрерывного вращения DS04-NFC питаются от напряжения 5 В и управляются сигналами ШИМ, поступающими с платы Arduino, а шаговые двигатели управляются драйверами A4988. Четыре кнопки и два микропереключателя подключены к заземлению и цифровым контактам Arduino, поэтому, используя внутренние подтягивающие резисторы платы Arduino, мы можем легко определить, когда они нажаты.
Компоненты, необходимые для этого руководства по Arduino, можно получить по ссылкам ниже:
- Понижающий преобразователь постоянного тока LM2596 …………..
- ЖК-дисплей 16×2……………………………………………………..
- Серводвигатель непрерывного действия на 360 градусов…
- Шаговый двигатель NEMA 17 ……………………….
- Драйвер шагового двигателя A4988 ……………….
- ИК-датчик приближения …………………………………..
- Кнопки …………………………………………………….
- Микроконцевой выключатель………………………………….
- Плата Arduino …………………………………………
Я соединил компоненты электроники с помощью соединительных проводов. С таким количеством проводов стало немного грязно, но все работало правильно. В конце я прикрепил две светодиодные полосы на дверной панели, чтобы осветить внутреннюю часть торгового автомата.
Код Arduino
Теперь осталось запрограммировать Arduino, и вот код, который я сделал для этого проекта. Ниже приведено описание кода.
/* DIY Vending Machine - Arduino based Mechatronics Project
by Dejan Nedelkovski, www.HowToMechatronics.com
*/
#include <LiquidCrystal.h> // includes the LiquidCrystal Library
#include <Servo.h>
LiquidCrystal lcd(27, 26, 25, 24, 23, 22); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)
Servo servo1, servo2, servo3, servo4; // DS04-NFC motors
// Stepper motors pins
#define dirPinVertical 0
#define stepPinVertical 1
#define dirPinHorizontal 2
#define stepPinHorizontal 3
#define coinDetector 9
#define button1 13
#define button2 12
#define button3 11
#define button4 10
#define microSwitchV 15
#define microSwitchH 14
int buttonPressed;
void setup() {
lcd.begin(16, 2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display
servo1.attach(4);
servo2.attach(5);
servo3.attach(6);
servo4.attach(7);
pinMode(dirPinVertical, OUTPUT);
pinMode(stepPinVertical, OUTPUT);
pinMode(dirPinHorizontal, OUTPUT);
pinMode(stepPinHorizontal, OUTPUT);
pinMode(coinDetector, INPUT);
// Activating the digital pins pull up resistors
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
pinMode(button3, INPUT_PULLUP);
pinMode(button4, INPUT_PULLUP);
pinMode(microSwitchV, INPUT_PULLUP);
pinMode(microSwitchH, INPUT_PULLUP);
// Vertical starting position
digitalWrite(dirPinVertical, HIGH); // Set the stepper to move in a particular direction
while (true) {
if (digitalRead(microSwitchV) == LOW) { // If the micro switch is pressed, move the platfor a little bit up and exit the while loop
moveUp(70);
break;
}
// Move the carrier up until the micro switch is pressed
digitalWrite(stepPinVertical, HIGH);
delayMicroseconds(300);
digitalWrite(stepPinVertical, LOW);
delayMicroseconds(300);
}
// Horizontal starting position
digitalWrite(dirPinHorizontal, LOW);
while (true) {
if (digitalRead(microSwitchH) == LOW) {
moveLeft(350);
break;
}
digitalWrite(stepPinHorizontal, HIGH);
delayMicroseconds(300);
digitalWrite(stepPinHorizontal, LOW);
delayMicroseconds(300);
}
}
void loop() {
// Print "Insert a coin!" on the LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Insert a coin!");
// Wait until a coin is detected
while (true) {
if (digitalRead(coinDetector) == LOW) { // If a coin is detected, exit the from the while loop
break;
}
}
delay(10);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Select your item");
lcd.setCursor(0, 1);
lcd.print(" 1, 2, 3 or 4?");
// Wait until a button is pressed
while (true) {
if (digitalRead(button1) == LOW) {
buttonPressed = 1;
break;
}
if (digitalRead(button2) == LOW) {
buttonPressed = 2;
break;
}
if (digitalRead(button3) == LOW) {
buttonPressed = 3;
break;
}
if (digitalRead(button4) == LOW) {
buttonPressed = 4;
break;
}
}
// Print "Delivering..."
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Delivering...");
// Depending on the pressed button, move the carrier to that position and discharge the selected item
switch (buttonPressed) {
case 1:
// Move the container to location 1
moveUp(4900); // Move up 4900 steps (Note: the stepper motor is set in Quarter set resolution)
delay(200);
moveLeft(1700); // Move left 1700 steps
delay(300);
// Rotate the helical coil, discharge the selected item
servo1.writeMicroseconds(2000); // rotate
delay(950);
servo1.writeMicroseconds(1500); // stop
delay(500);
// Move the container back to starting position
moveRight(1700);
delay(200);
moveDown(4900);
break;
case 2:
// Move the container to location 2
moveUp(4900);
delay(200);
// Rotate the helix, push the selected item
servo2.writeMicroseconds(2000); // rotate
delay(950);
servo2.writeMicroseconds(1500); // stop
delay(500);
moveDown(4900);
break;
case 3:
// Move the container to location 3
moveUp(2200);
delay(200);
moveLeft(1700);
delay(300);
// Rotate the helix, push the selected item
servo3.writeMicroseconds(2000); // rotate
delay(950);
servo3.writeMicroseconds(1500); // stop
delay(500);
// Move the container back to starting position
moveRight(1700);
delay(200);
moveDown(2200);
break;
case 4:
// Move the container to location 4
moveUp(2200); // Move verticaly 4800 steps
delay(200);
// Rotate the helix, push the selected item
servo4.writeMicroseconds(2000); // rotate
delay(950);
servo4.writeMicroseconds(1500); // stop
delay(500);
moveDown(2200);
break;
}
lcd.clear(); // Clears the display
lcd.setCursor(0, 0);
lcd.print("Item delivered!"); // Prints on the LCD
delay(2000);
}
// == Custom functions ==
void moveUp (int steps) {
digitalWrite(dirPinVertical, LOW);
for (int x = 0; x < steps; x++) {
digitalWrite(stepPinVertical, HIGH);
delayMicroseconds(300);
digitalWrite(stepPinVertical, LOW);
delayMicroseconds(300);
}
}
void moveDown (int steps) {
digitalWrite(dirPinVertical, HIGH);
for (int x = 0; x < steps; x++) {
digitalWrite(stepPinVertical, HIGH);
delayMicroseconds(300);
digitalWrite(stepPinVertical, LOW);
delayMicroseconds(300);
}
}
void moveLeft (int steps) {
digitalWrite(dirPinHorizontal, HIGH);
for (int x = 0; x < steps; x++) {
digitalWrite(stepPinHorizontal, HIGH);
delayMicroseconds(300);
digitalWrite(stepPinHorizontal, LOW);
delayMicroseconds(300);
}
}
void moveRight (int steps) {
digitalWrite(dirPinHorizontal, LOW);
for (int x = 0; x < steps; x++) {
digitalWrite(stepPinHorizontal, HIGH);
delayMicroseconds(300);
digitalWrite(stepPinHorizontal, LOW);
delayMicroseconds(300);
}
}
Code language: Arduino (arduino)
Объяснение исходного кода
Сначала нам нужно включить библиотеки Servo и LiquidCrystal, определить контакты ЖК-дисплея, четыре серводвигателя, контакты шагового двигателя, детектор монет, а также четыре кнопки и два микропереключателя.
В разделе настройки мы устанавливаем режимы вывода для каждого из упомянутых выше выводов. Мы можем отметить, что для кнопок и контактов микропереключателей мы активировали внутренние подтягивающие резисторы. Это означает, что логический уровень на этих выводах все время будет ВЫСОКИМ, и как только мы их нажмем, логический уровень упадет до НИЗКОГО.
Прежде чем мы войдем в основной цикл, мы также устанавливаем носитель в исходное положение, которое определяется двумя микропереключателями. Таким образом, с помощью цикла while мы продолжаем перемещать тележку в исходное положение, и как только будут нажаты два микропереключателя, двигатели остановятся и переместятся в желаемое исходное положение.
// Vertical starting position
digitalWrite(dirPinVertical, HIGH); // Set the stepper to move in a particular direction
while (true) {
if (digitalRead(microSwitchV) == LOW) { // If the micro switch is pressed, move the platfor a little bit up and exit the while loop
moveUp(70);
break;
}
// Move the carrier up until the micro switch is pressed
digitalWrite(stepPinVertical, HIGH);
delayMicroseconds(300);
digitalWrite(stepPinVertical, LOW);
delayMicroseconds(300);
}
// Horizontal starting position
digitalWrite(dirPinHorizontal, LOW);
while (true) {
if (digitalRead(microSwitchH) == LOW) {
moveLeft(350);
break;
}
digitalWrite(stepPinHorizontal, HIGH);
delayMicroseconds(300);
digitalWrite(stepPinHorizontal, LOW);
delayMicroseconds(300);
}
Code language: Arduino (arduino)
В основной программе при старте выводом на ЖКИ сообщение «Вставьте монету». Затем мы застреваем в цикле while. Как только монета вставлена и она проходит рядом с датчиком приближения, логическое состояние на выводе детектора монет упадет до НИЗКОГО, и в этом случае мы выйдем из цикла while, используя оператор break.
// Wait until a coin is detected
while (true) {
if (digitalRead(coinDetector) == LOW) { // If a coin is detected, exit the from the while loop
break;
}
}
Code language: Arduino (arduino)
Затем мы печатаем сообщение «Выберите свой элемент» и застреваем в другом цикле while.
// Wait until a button is pressed
while (true) {
if (digitalRead(button1) == LOW) {
buttonPressed = 1;
break;
}
if (digitalRead(button2) == LOW) {
buttonPressed = 2;
break;
}
if (digitalRead(button3) == LOW) {
buttonPressed = 3;
break;
}
if (digitalRead(button4) == LOW) {
buttonPressed = 4;
break;
}
}
Code language: Arduino (arduino)
Этот цикл while ждет, пока мы нажмем любую из четырех кнопок, и как только мы это сделаем, мы выходим из него и печатаем сообщение «Доставка».
Теперь в зависимости от нажатой кнопки мы выполняем один из случаев в операторе switch. В случае, если мы нажали первую кнопку, перевозчик начнет двигаться вверх с помощью специальной функции «moveUp()».
switch (buttonPressed) {
case 1:
// Move the container to location 1
moveUp(4900); // Move up 4900 steps (Note: the stepper motor is set in Quarter set resolution)
delay(200);
moveLeft(1700); // Move left 1700 steps
delay(300);
// Rotate the helical coil, discharge the selected item
servo1.writeMicroseconds(2000); // rotate
delay(950);
servo1.writeMicroseconds(1500); // stop
delay(500);
// Move the container back to starting position
moveRight(1700);
delay(200);
moveDown(4900);
break;
}
Code language: Arduino (arduino)
Если мы посмотрим на эту функцию, то увидим, что она просто заставляет шаговый двигатель двигаться в определенном направлении и делает количество шагов, которое мы ввели в качестве аргумента.
void moveUp (int steps) {
digitalWrite(dirPinVertical, LOW);
for (int x = 0; x < steps; x++) {
digitalWrite(stepPinVertical, HIGH);
delayMicroseconds(300);
digitalWrite(stepPinVertical, LOW);
delayMicroseconds(300);
}
}
Code language: Arduino (arduino)
Здесь можно отметить, что я настроил драйвер шагового двигателя A4988 на работу в четвертьшаговом разрешении, и при некоторых примерках я пришел к выводу, что мне нужно 4900 шагов, чтобы водила попала в верхнее положение. Аналогичным образом перемещаем перевозчика влево, пока он не достигнет локации номер 1.
Сразу после этого мы вращаем двигатель непрерывного вращения в течение 950 миллисекунд, чтобы спиральная катушка совершила полный цикл.
// Rotate the helical coil, discharge the selected item
servo1.writeMicroseconds(2000); // rotate
delay(950);
servo1.writeMicroseconds(1500); // stop
Code language: Arduino (arduino)
Обратите внимание, что эти значения могут иногда различаться и зависят от самого двигателя. Используя пользовательские функции moveRight() и moveDown(), мы возвращаем перевозчика в исходное положение. Таким же образом мы можем разрядить любые четыре предмета.
В конце мы просто печатаем сообщение «Товар доставлен».
Так что это так просто, и я надеюсь, вам понравилось это видео и вы узнали что-то новое. Не стесняйтесь задавать любые вопросы в разделе комментариев ниже и проверять мою коллекцию проектов Arduino.
Производственный процесс
- Торговый автомат
- Сделайте машинку для письма домашнего задания дома
- Консоль редактирования DIY Photoshop с использованием Arduino Nano RP 2040
- Создание монитора Ambilight с помощью Arduino
- Ультразвуковой левитационный аппарат с использованием ARDUINO
- Вольтметр своими руками с использованием Arduino и смартфона
- Инфракрасный датчик сердцебиения своими руками с использованием Arduino
- Tech-TicTacToe
- DIY вольтметр с Arduino и дисплеем Nokia 5110
- Цифровые часы на Arduino с использованием конечного автомата