Проект модели грузовика распечатанного на 3D принтере

Список оборудования необходимого для проекта:

  • Raspberry Pi 3 model A+
  • Преобразователь логических уровней с 3.3в на 5в
  • Драйвер бесколлекторного двигателя L298N
  • Аккумулятор мощностью 5в на 2700 мАч
  • Сервопривод MG995
  • Бесколлекторный двигатель

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

Данный проект является продолжением цикла статей об удаленном управлении самодвижущимися платформами с использованием микрокомпьютера Raspberry Pi. В прошлой статье мы устанавливали Raspberry Pi на китайскую модель пикапа 1:10 и заменяли модуль радиоуправления на управление по Wi-Fi.

В этой статье мы решили пойти дальше и изменить конструкцию модели нашего автомобиля. За основу был взят готовый проект модели грузовика для печати на 3D принтере. Выбранный проект обладает рядом преимуществ. В модели предусмотрена система независимой подвески, привод распределен по всем 4 колесам, есть возможность дополнительной установки блокировки дифференциала. Размер модели грузовика позволяет разместить все необходимое оборудование.

3D печать и сборка модели грузовика

Блуждая по просторам необъятного, на сайте thingiverse.com, наткнулся на интересный проект 3D модели грузовика от пользователя MrCrankyface. Проект сразу заинтересовал своей сложностью, много частей для 3D печати, множество дополнительных метfллических деталей, которые нужно было покупать отдельно. Но обо всем по порядку.

Печать

Блуждая по просторам необъятного, на сайте thingiverse.com, наткнулся на интересный проект 3D модели грузовика от пользователя MrCrankyface. Проект сразу заинтересовал своей сложностью, много частей для 3D печати, множество дополнительных метfллических деталей, которые нужно было покупать отдельно. Но обо всем по порядку.

Во время 3D печати столкнулись со стандартным набором проблем, это плохая адгезия (когда детали отклеивались и изгибались), расслоение напечатанных деталей, банальное непопадание в размер стекающихся частей (решалось корректировкой 3D модели).

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

Проблему с расслоением деталей решили просто увеличив температуру печатающего сопла, а так же температуру стола. Для нашего ABS пластика подходящие параметры печати составили 245 градусов температура сопла и 100 градусов у стола.

Сборка

Для сборки модели потребовалось купить дополнительные крепежи из металла, для соединения напечатанных 3D деталей. Полный список необходимых комплектующих можно найти на странице автора проекта (см. примечание). Некоторые детали были доступны в местных магазинах (типа болтов, шпилек и гаек M3 и M4), некоторые пришлось заказывать через интернет (типа шаровых для крепления подвески и подшипников, для крутящихся частей).

Сама модель состоит из несущей центральной рамы размером 7см*40см к которой крепится подвеска и силовая часть, центральный дифференциал, мосты, коллекторный электродвигатель и сервопривод, выполняющий роль поворотного двигателя.

На изображении выше представлен поворотный механизм передних колес. Шпилька М3 была загнута и использована в качестве рулевой рейки, идущей от сервопривода к поворотному механизму не переднем мосте.

Амортизаторы были распечатаны на 3D принтере. Данная модель также предусматривает установку фабричных воздушных амортизаторов для радио моделей.

Шины для колес были взяты от китайской радиоуправляемой модели из предыдущего проекта[ссылка]. Диски разрабатывались в 3D редакторе специально под размер данных шин и креплений к мостам модели грузовика. За основу дизайна колесных дисков был взят дизайн колес легендарного российского грузовика Урал.

Разработка и 3D печать платформы для оборудования

Чтобы надежно разместить оборудование на корпусе модели, дополнительно, была разработана 3D модель платформы с креплениями для установки печатных плат с микрокомпьютером Raspberry Pi и драйверами двигателей. Все размеры были сняты с самих плат при помощи линейки, с небольшой погрешностью. Для проведения проводки на платформе были предусмотрены специальные пазы. В задней части корпуса расположен блок аккумуляторов. По бокам платформа имеет крепления для установки корпуса, который будет распечатан в следующих циклах статей.

Для удобства 3D печати модель платформы была разделена на две части. 3D печать всех частей платформы заняла около 7 часов. Печать производилась со 100% заполнением и поддержкой. После печати 3D модель платформы была очищена от лишнего пластика и подогнана под оборудование с помощью макетного ножа и напильника. Вся электроника идеально встала на свои места.

Установка и подключение оборудования

Состав оборудования:

  • Raspberry Pi 3 model A+
  • Преобразователь логических уровней с 3.3в на 5в
  • Драйвер бесколлекторного двигателя L298N
  • Аккумулятор мощностью 5в на 2700 мАч
  • Сервопривод MG995
  • Бесколлекторный двигатель

Всё перечисленное оборудование можно заказать в любом интернет магазине радио компонентов. За исключением Raspberry Pi, его иногда приходится искать отдельно.

Итак приступим, в начале необходимо разместить все электронные платы на специальной платформе расположенной на раме нашего грузовика. Они фиксируются при помощи мелких шурупов M1.

Затем, руководствуясь схемой изображенной ниже, нужно правильно соединить все выходы на наших устройствах. Все электронные компоненты были подключены с использованием соединительных проводов 10-pin (F) — 10-pin (M). Предварительно потребуется скрутить (можно и спаять) две заготовки для разветвления питания от аккумуляторов.

Общая схема подключения электроники
Провода для разветвления питания от аккумуляторов

Аккумулятор 5v для питания двигателей подключается и отключается при помощи pin разъемов. Микрокомпьютер Raspberry Pi запитывается отдельно от внешнего блока питания для мобильных устройств с емкостью 9000 mAh с напряжением на выходе 5v и силой тока 2A.

Для дальнейших манипуляций необходимо проверить правильность подключения схемы. Для этого достаточно подключить аккумуляторы к двигателям и к Raspberry Pi, удаленно подключится к Raspberry по SSH (или подключить монитор для теста) и запустить пару тестовых скриптов для проверки работы сервопривода и коллекторного двигателя из предыдущих статей. Если всё работает исправно, можно двигается дальше и приступать к разработке мобильного приложения для управления нашим грузовиком.

Разработка мобильного приложения с пультом управления

Для управления двигателями модели грузовика было разработано мобильное Android приложение с минималистичным дизайном. В приложение был добавлен новый экран, для управления сервоприводом, он доступен из пункта меню “Servo control”. В настройках появились два новых поля “Motor PWM” и “Servo turn” для указания номеров пинов для широтно-импульсной модуляции (PWM) коллекторного мотора, чтобы управлять плавностью хода и для поворота сервопривода соответственно.

Главный экран приложения
Экран с настройками
Экран управления сервоприводом и коллекторным двигателем.

На экране настроек в приложении необходимо указать адрес и порт для подключения к Raspberry Pi, а так же номера пинов Raspberry Pi отвечающих за управление двигателями. Поля “Go left” и “Go right” нам не понадобятся, т.к. поворот осуществляется при помощи сервопривода.

Вот описание корректных значений полей, если подключаться согласно схеме представленной выше:

Go forward: 8 (Бесколлекторный двигатель движение вперед)

Go back: 7 (Бесколлекторный двигатель движение назад)

Motor PWM: 25 (Широтно-импульсная модуляция)

Servo turn:17 (Поворот сервопривода)

После сохранения настроек приложение будет посылать HTTP запросы на Raspberry Pi для активации соответствующих пинов.

Код мини веб-сервера на Python

Для того чтобы Raspberry Pi понимал наши команды и запускал нужные пины, было разработанно небольшое веб-приложение написанное на Python. Перед подключением через мобильное приложение необходимо запустить Python скрипт с кодом указанным ниже. Этот веб-сервер имееет открытый интерфейс АПИ с командами, вызывая котоыре можно управлять двигателями, подключенными к Raspberry Pi.

from flask import Flask, json, request
from werkzeug.serving import make_server
import RPi.GPIO as GPIO
import threading
import time

app = Flask(__name__)

p_servo = 17  # GPIO num for servo
fPWM = 50  # Hz (not higher with software PWM)
a = 10
b = 2

in1 = 23  # GPIO num for motor go forward
in2 = 24  # GPIO num for motor go backward
p_motor = 18  # GPIO num for PWM control motor
go_forward = 1

min_angle = 30
max_angle = 90
default_forward_angle = 60

throttle_current = 0

is_making_connection = 0

class ServerThread(threading.Thread):

    def __init__(self, app):
        threading.Thread.__init__(self)
        self.srv = make_server('0.0.0.0', 5000, app)
        self.ctx = app.app_context()
        self.ctx.push()

    def run(self):
        print('starting server')
        try:
            self.srv.serve_forever()
        finally:
            self.srv.server_close()

    def shutdown(self):
        print('server stopped now !')
        self.srv.shutdown()
        self.srv.server_close()


@app.route('/')
def hello_world():
    return 'Hello, from Raspberry Pi!'

@app.route('/set-servo-angle')
def set_servo_angle():
    servo_angle = request.args.get('servo_angle')
    if servo_angle != 'None':
        setDirection(servo_angle)
        #return '{"status":"ok"}'
    #else:
        #return '{"status":"err", "err_msg":"empty servo_angle parameter"}'
    return 'ok'


@app.route('/set-throttle')
def set_throttle():
    throttle_val = request.args.get('throttle_val')
    if throttle_val != 'None':
        setThrottle(int(throttle_val))
        # return '{"status":"ok"}'
    # else:
    # return '{"status":"err", "err_msg":"empty throttle_val parameter"}'
    return 'ok'


@app.route('/set-go-forward')
def set_go_forward():
    global go_forward
    go_forward_val = request.args.get('go_forward')
    if throttle_current == 0 and go_forward_val != 'None':
        go_forward = int(go_forward_val)
        return '{"status":"ok"}'
    else:
        return '{"status":"err", "err_msg":"empty go_forward parameter"}'


@app.route('/make-connection')
def make_connection():
    pwm_servo = request.args.get('p_servo')
    pwm_motor = request.args.get('p_motor')
    inpt1 = request.args.get('in1')
    inpt2 = request.args.get('in2')
    if pwm_servo != 'None' and pwm_motor != 'None' and inpt1 != 'None' and inpt2 != 'None':
        setup(int(pwm_servo), int(pwm_motor), int(inpt1), int(inpt2))
        return '{"status":"ok"}'
    else:
        return '{"status":"err", "err_msg":"empty setup GPIO parameters"}'


@app.route('/exit')
def app_exit():
    setDirection(default_forward_angle)
    time.sleep(5)
    GPIO.cleanup()
    print("stopping server")
    stop_server()
    return "Server closed"


def setup(pwm_servo_val, pwm_motor_val, inpt1, inpt2):
    global servo_pwm, motor_pwm, in1, in2, p_servo, p_motor, is_making_connection
    # global servo_pwm, motor_pwm, is_making_connection

    if is_making_connection == 0:
        p_servo = pwm_servo_val
        p_motor = pwm_motor_val
        in1 = inpt1
        in2 = inpt2

        print('Setup: p_servo {} | p_motor {} | in1 {} | in2 {}'.format(p_servo, p_motor, in1, in2))

        GPIO.setmode(GPIO.BCM)
        GPIO.setup(p_servo, GPIO.OUT)
        GPIO.setup(in1, GPIO.OUT)
        GPIO.setup(in2, GPIO.OUT)
        GPIO.setup(p_motor, GPIO.OUT)
        GPIO.output(in1, GPIO.LOW)
        GPIO.output(in2, GPIO.LOW)
        motor_pwm = GPIO.PWM(p_motor, 1000)
        motor_pwm.start(throttle_current)
        servo_pwm = GPIO.PWM(p_servo, fPWM)
        servo_pwm.start(getDutyFromAngle(default_forward_angle))
        is_making_connection = 1


def getDutyFromAngle(angle):
    duty = float(angle) / (180 / (10)) + 2.0
    duty = round(duty, 2)
    print("getDutyFromAngle: duty = ", duty)
    return duty


def setDirection(angle):
    # duty = a / 120 * direction + b
    angle = ((int)(angle))
    print('setDirection: ', angle)

    if angle >= max_angle:
        angle = max_angle
    elif angle <= min_angle:
        angle = min_angle

    if min_angle <= angle <= max_angle:
        duty = getDutyFromAngle(angle)
        servo_pwm.ChangeDutyCycle(duty)
        print("direction =", angle, "-> duty =", duty)
        # time.sleep(2) # allow to settle
    return angle


def setThrottle(throttle_val):
    global throttle_current
    print('setThrottle: throttle_current {} | throttle_val {}'.format(throttle_current, throttle_val))
    if throttle_current == 0 and throttle_val > 0:
        startMotor()

    if 0 <= throttle_val <= 100:
        throttle_current = throttle_val
        if throttle_current == 100:
            GPIO.output(p_motor, GPIO.HIGH)
            print('set MAX throttle')
        else:
            motor_pwm.ChangeDutyCycle(throttle_current)  # change motor PWM to move
            print("setThrottle(): throttle_current = ", throttle_current)
        if throttle_current == 0:
            stopMotor()


def startMotor():
    if go_forward == 1:
        GPIO.output(in1, GPIO.HIGH)
        GPIO.output(in2, GPIO.LOW)
        print('start motor go forward')
    elif go_forward == 0:
        GPIO.output(in1, GPIO.LOW)
        GPIO.output(in2, GPIO.HIGH)
        print('start motor go backward')


def stopMotor():
    GPIO.output(in1, GPIO.LOW)
    GPIO.output(in2, GPIO.LOW)
    print('stop motor')


def start_server():
    global server
    server = ServerThread(app)
    server.start()
    print('server started')


def stop_server():
    global server
    server.shutdown()


def main():
    # setup()
    start_server()


if __name__ == '__main__':
    main()

Запуск и тестирование

Перед стартом модели необходимо подключить питание от внешнего аккумулятора к Raspberry Pi. После загрузки Raspberry Pi и успешного подключения к нему по SSH можно подключать дополнительный аккумулятор в схему наших двигателей. Должны загореться светодиоды на корпусе драйвера коллекторного двигателя.

Стоит напомнить, что на Raspberry Pi должен быть установлен и запущен сервис WebIOPi (подробнее в предыдущей статье).

Если в настройках приложения всё указано правильно, открываем экран «Servo Control», статус подключения должен измениться на «Connected», после этого можно начинать управление двигателями модели. Подробный процесс запуска и тестирования модели можно увидеть на видео ниже.

Выводы

1. Недостаточная мощность аккумулятора для питания двигателей. Текущая мощность в 4.8в недостаточная для питания сервопривода и бесколлекторного двигателя. В результате чего вращательной силы бесколлекторного двигателя едва хватает чтобы сдвинуть модель с места. В следующей статье мы попробуем последовательно подключить ещё 4 аккумулятора GP по 1.2в для достижения мощности в полноценные 9в и установим более мощный двигатель.

2. Необходимо смазать трущиеся детали. Это касается пластиковых шестерней внутри передней и задней оси, дифференциале и коробке передач.

3. Нужно распечатать внешний корпус для защиты электроники от попадания пыли и волос. Форма корпуса будет повторять форм-фактор реального грузовика.

1. Android приложение Car Control:

Car Control v1.1

2. 3D модель из блендера и STL файлы платформы для электроники

3. Проект с исходным кодом приложения на GitHub: CarControl

Комментарии:

Напишите комментарий

Ваше имя:
Введите текст с изображения:

Наверх
Copyright © 2019-2024 «Elegant Develop»