Zdalne sterowanie drukarką 3D za pomocą ESP32

Typ_projektu
microPython
Zdjecie główne
Krótki opis projektu

Celem tego projektu jest stworzenie taniej i kompaktowej alternatywy dla systemów takich jak OctoPrint, które wymagają urządzenia takiego jak np. raspberryPi. W obecnej fazie, ESP32 zostało połączone z płytą główną drukarki oraz został stworzony prosty interfejs HTML, dzięki któremu możemy zdalnie połączyć się z urządzeniem i wysyłać komendy G-code przez pole tekstowe oraz używać kilku przycisków które obsługują najczęściej używane komendy.

Niezbędne elementy

1. Płytka ESP32

2. Przewody

3. Drukarka 3D

Sprzęt

lutownica

Opis projektu

O projekcie:

Celem tego projektu jest stworzenie taniej i kompaktowej alternatywy dla systemów takich jak OctoPrint, które wymagają urządzenia takiego jak np. raspberryPi. W obecnej fazie, ESP32 zostało połączone z płytą główną drukarki oraz został stworzony prosty interfejs HTML, dzięki któremu możemy zdalnie połączyć się z urządzeniem i wysyłać komendy G-code przez pole tekstowe oraz używać kilku przycisków które obsługują najczęściej używane komendy.

Co dalej:

Następne kroki rozwoju projektu składają się z usprawnień graficznych interfejsu, dodanie monitorów temperatur oraz statusu drukarki, możliwość zdalnego przesyłania plików oraz obsługa zdalnego uruchamiania drukarki. Dodatkowo aby ułatwić użytkownikowi integracje systemu z drukarką można stworzyć nakładkę z pinami pogo, pozwalającą na szybkie i niewymagające lutowania połączenie systemu z płytą główną, co pozwoli na nieskomplikowaną wymianę elementów w urządzeniu.
 

Zdjęcia
kod programu

Ustaw odpowiedni# Konfiguracja UART1 (np. TX: GPIO17, RX: GPIO16)

uart = UART(1, baudrate=115200, tx=17, rx=16)

 

# Zmienna do przechowywania danych otrzymanych przez UART

uart_data = ""

 

# Funkcja wysyłania G-code

def send_gcode(gcode_command):

    uart.write(gcode_command + "\n")  # Send the G-code command followed by a newline

    time.sleep(0.5)  # Give time for the printer to process the command

    print("Wysłano: ", gcode_command)

    # Read the response from the printer

    if uart.any():

        response = uart.read()

        print("Response from printer: ", response)

        return response.decode('utf-8')  # Odczytanie odpowiedzi z UART

    return "Brak odpowiedzi od drukarki"

 

 

    # Oczekiwanie na odpowiedź od drukarki (można dostosować czas oczekiwania)

    # Funkcja do łączenia się z Wi-Fi

def connect_wifi():

    ssid = ''  # Zmień na swoją nazwę sieci Wi-Fi

    password = ''  # Zmień na swoje hasło do Wi-Fi

 

    wlan = network.WLAN(network.STA_IF)

    wlan.active(True)

    wlan.connect(ssid, password)

 

    print('Łączenie z siecią Wi-Fi...')

    while not wlan.isconnected():

        time.sleep(1)

   

    print('Połączono z Wi-Fi')

    print('Adres IP:', wlan.ifconfig()[0])

 

# Funkcja do dekodowania URL (ręcznie zamienia %20 na spację i inne znaki)

def url_decode(url):

    url = url.replace('%20', ' ')

    url = url.replace('%3D', '=')

    url = url.replace('%2F', '/')

    url = url.replace('%3A', ':')

    url = url.replace('%0A', '')

   

    return url

 

# Funkcja do odczytu danych z UART i aktualizacji zmiennej

#def read_uart_data():

 #  global uart_data

  # while True:

   #    data = uart.read()

    #   if data:

     #    uart_data = uart_data + data.decode('utf-8')  # Dodajemy nowe dane do bufora

      #   time.sleep(0.1)

 

# Konfiguracja serwera HTTP

def web_server():

    addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

    s = socket.socket()

    s.bind(addr)

    s.listen(1)

 

    print('Serwer nasłuchuje na', addr)

 

    while True:

        cl, addr = s.accept()

       

        cl.settimeout(10.0)

       

        # Strona HTML z przyciskami

        response = """<!DOCTYPE html>

        <html>

        <head>

           <title>Kontrola Drukarki 3D</title>

           <style>

                body { font-family: Arial, sans-serif; text-align: center; }

                button { font-size: 20px; padding: 10px 20px; margin: 10px; }

                textarea { width: 300px; height: 100px; margin-top: 10px; }

                #responseLog { max-height: 200px; overflow-y: scroll; border: 1px solid #ccc; padding: 10px; margin-top: 20px; }

                #uartLog { width: 100%; height: 200px; margin-top: 20px; padding: 10px; border: 1px solid #ccc; overflow-y: scroll; font-family: monospace; }

            </style>

        </head>

        <body>

           <h1>Kontrola drukarki 3D</h1>

   

            <!-- Przesuwanie osi X -->

            <button onclick="sendCommand('G1 X1 F1500')">X+1</button>

            <button onclick="sendCommand('G1 X10 F1500')">X+10</button>

            <button onclick="sendCommand('G1 X-1 F1500')">X-1</button>

            <button onclick="sendCommand('G1 X-10 F1500')">X-10</button>

 

            <!-- Przesuwanie osi Y -->

            <button onclick="sendCommand('G1 Y1 F1500')">Y+1</button>

            <button onclick="sendCommand('G1 Y10 F1500')">Y+10</button>

            <button onclick="sendCommand('G1 Y-1 F1500')">Y-1</button>

            <button onclick="sendCommand('G1 Y-10 F1500')">Y-10</button>

 

            <!-- Przesuwanie osi Z -->

            <button onclick="sendCommand('G1 Z1 F1500')">Z+1</button>

            <button onclick="sendCommand('G1 Z10 F1500')">Z+10</button>

            <button onclick="sendCommand('G1 Z-1 F1500')">Z-1</button>

            <button onclick="sendCommand('G1 Z-10 F1500')">Z-10</button>

 

            <!-- Pole tekstowe do wprowadzania G-code -->

            <textarea id="gcodeInput" placeholder="Wpisz komende G-code..."></textarea><br>

            <button onclick="sendCommandFromText()">Wyslij komende G-code</button>

 

            <!-- Przycisk do nagrzewania hotendu -->

            <button onclick="sendCommand('M104 S200')">Nagrzej hotend</button>

 

            <!-- Przycisk do nagrzewania stolu -->

            <button onclick="sendCommand('M140 S60')">Nagrzej stol</button>

 

            <!-- Log odpowiedzi z drukarki -->

           <h2>Odpowiedz z drukarki:</h2>

            <div id="responseLog"></div>

 

         

 

            <script>

                // Funkcja wysylajaca komende do serwera

                function sendCommand(command) {

                    console.log("Wyslano komende: " + command);

 

                    // Zapewnienie, że komenda jest przesylana poprawnie

                    const urlCommand = 'command=' + encodeURIComponent(command);

                    fetch('/send?' + urlCommand)

                    .then(response => response.text())

                    .then(data => {

                        updateResponseLog(command, data);

                   });

                }

 

                // Funkcja wysylajaca komende z pola tekstowego

                function sendCommandFromText() {

                    const gcodeCommand = document.getElementById('gcodeInput').value;

                    sendCommand(gcodeCommand);

                   document.getElementById('gcodeInput').value = ''; // Wyczysć pole tekstowe po wyslaniu

                }

 

                // Funkcja aktualizujaca log z odpowiedzia

               function updateResponseLog(command, response) {

                    const responseLog = document.getElementById('responseLog');

                    // Pokaż tylko ostatnia wyslana komende i odpowiedz

                    responseLog.innerHTML = `<strong>Komenda:</strong> ${command}<br><strong>Odpowiedz:</strong> ${response}`;

                }

 

                // Funkcja aktualizująca log z UART

               function updateUartLog(data) {

                    const uartLog = document.getElementById('uartLog');

                    uartLog.innerHTML = data; // Zaktualizuj dane UART

                }

 

             

            </script>

        </body>

        </html>

        """

 

        # Obsługuje żądanie /send i /get_uart_data

        try:

            query = cl.recv(1024)

            if 'GET / HTTP/1.1' in str(query):

                cl.send('HTTP/1.1 200 OK\r\n')

                cl.send('Content-Type: text/html\r\n\r\n')

                cl.send(response)

            elif 'GET /send?command=' in str(query):

                start = str(query).find('command=') + 8  # Przesunięcie o 8, aby zaczynało się od 'command='

                end = str(query).find(' HTTP')

                command = str(query)[start:end]

                if command:

                    # Dekodowanie URL

                    decoded_command = url_decode(command)

                    print("Dekodowana komenda:", decoded_command)

                    response_from_printer = send_gcode(decoded_command)

                    cl.send('HTTP/1.1 200 OK\r\n')

                    cl.send('Content-Type: text/html\r\n\r\n')

                   cl.send(response_from_printer)

        except Exception as e:

            print("Błąd podczas obsługi zapytania:", e)

        finally:

            cl.close()

 

# Uruchomienie Wi-Fi i serwera

connect_wifi()

send_gcode('G91')

send_gcode('G28')

send_gcode('M140 S20')

send_gcode('M104 S20')

# Uruchomienie funkcji odczytu danych z UART w osobnym wątku (oddzielny wątek można stworzyć w bardziej zaawansowanej wersji)

#import _thread

#_thread.start_new_thread(read_uart_data, ())

 

# Uruchomienie serwera

web_server() język programowania (ostatnia ikona powyżej)

Tagi
ESP32 Druk3D WiFi Ender3 G-code