Hilfe bei der Anpassung der Vorschubrate meiner CNC-Maschine mit einem Raspberry Pi Pico

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
noahroeschard
User
Beiträge: 1
Registriert: Donnerstag 17. Oktober 2024, 13:09

Hallo,

ich arbeite gerade an einem Projekt, um die Vorschubrate meiner CNC-Maschine zu steuern, da der Controller diese Funktion leider nicht von Haus aus unterstützt. Ich plane daher, eine eigene Lösung zu entwickeln, bei der ich einen Raspberry Pi Pico und ein Potentiometer verwende, um die Vorschubrate extern anzupassen.

Der Controller unterstützt die Anpassung der Vorschubrate über Tastatureingaben, wie zum Beispiel F11 für das Erhöhen und Verringern der Vorschubrate (+/-). Mein Ziel ist es, den Pico zu verwenden, um diese Tastaturbefehle zu simulieren. Der Pico soll Änderungen am Potentiometer erfassen (ich verwende ein 10K Ohm Potentiometer) und bei jeder Änderung von 1% sofort ein „+“ oder „-“ an den Controller senden. Wenn sich das Potentiometer nicht bewegt, soll natürlich auch nichts gesendet werden.

Ich habe dazu bereits Code geschrieben, komme aber leider nicht weiter, da dieser nicht zuverlässig läuft. Die Ausgabe entspricht nicht meinen Vorstellungen, da die Änderungen nicht präzise genug erkannt werden. Der Pico soll exakt auf jede 1%ige Änderung reagieren und sofort das entsprechende "+" oder "-" senden. Wenn keine Bewegung stattfindet, soll nichts gesendet werden.

Hier ist der Code, den ich bisher geschrieben habe. Ich würde mich sehr über Hilfe oder Vorschläge freuen, um die Genauigkeit und Zuverlässigkeit zu verbessern.

Vielen Dank schon mal für die Unterstützung!

Code: Alles auswählen

import time
import analogio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
import board

# Setup potentiometer for feedrate pin and HID keyboard
pot_feedrate = analogio.AnalogIn(board.GP26_A0)  # Using only feedrate potentiometer
kbd = Keyboard(usb_hid.devices)

# Function to map potentiometer values to a percentage
def get_percentage(pin):
    return (pin.value / 65535) * 100

# Parameters for adjustments
change_threshold = 2.4  # Sensitivity with a 2.4% deviation trigger
step_size = 2.4  # Adjustments made in 2.4% increments
debounce_time = 0.3  # Debounce time for avoiding rapid changes
dead_zone = 1.5  # Small dead zone to ignore small changes

feedrate_values = []
moving_average_length = 10

# Moving average calculation
def moving_average(values, new_value, length):
    values.append(new_value)
    if len(values) > length:
        values.pop(0)
    return sum(values) / len(values)

last_feedrate_time = time.monotonic()

while True:
    # Read current value from potentiometer
    current_feedrate = get_percentage(pot_feedrate)

    # Calculate moving average
    avg_feedrate = moving_average(feedrate_values, current_feedrate, moving_average_length)

    # Output feedrate change only when it exceeds the change threshold
    if abs(current_feedrate - avg_feedrate) > change_threshold:
        steps = int((current_feedrate - avg_feedrate) / step_size)
        if abs(current_feedrate - avg_feedrate) > dead_zone:
            if current_feedrate > avg_feedrate:
                print(f"Increasing feedrate by {steps * step_size:.2f}% +")
                for _ in range(steps):
                    kbd.press(Keycode.KEYPAD_PLUS)
                    time.sleep(0.05)
                kbd.release_all()
            elif current_feedrate < avg_feedrate:
                print(f"Decreasing feedrate by {abs(steps) * step_size:.2f}% -")
                for _ in range(abs(steps)):
                    kbd.press(Keycode.KEYPAD_MINUS)
                    time.sleep(0.05)
                kbd.release_all()
            last_feedrate_time = time.monotonic()

    # Debug output showing feedrate and average
    if time.monotonic() - last_feedrate_time > debounce_time:
        print(f"Feedrate: {current_feedrate:.2f}% (Avg: {avg_feedrate:.2f}%)")
        last_feedrate_time = time.monotonic()

    time.sleep(0.1)
sauterle
User
Beiträge: 84
Registriert: Mittwoch 27. Juli 2022, 21:33

Hallo
ich bin mir nicht ganz sicher ob ich dich richtig verstehe. aber ich fasse deine frage mal so auf, dass wenn das poti leicht drehst keine änderungen versendet werden.
Meine Vermutung zu deinem Problem wäre, dass der adc (analog analog digital wandler) deines pi picos zu ungenau ist/schlecht funktioniert. Zumindest bei einem esp32 ist der eingebaute adc zu ungenau/schlecht um eine kleine änderung an einem poti zu erkennen. bei einem Pi pico habe ich das so noch nicht probiert allerdings würde ich das einfach mal überprüfen
LG sauterle
Benutzeravatar
Dennis89
User
Beiträge: 1503
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

wenn du Probleme mit dem Poti hast, dann solltest du ein Skript schreiben, in dem erst mal nur der Poti abgefragt wird, bis du mit dem Verhalten zufrieden bist.
`attent` musst du möglicherweise anpassen und die `reference_value` auch. So könnte Code aussehen, der dir Werte von 0-100 innerhalb einer Umdrehung wieder gibt (ungetestet):

Code: Alles auswählen

from machine import ADC, Pin
from time import sleep

POTI_PIN = 26


def translate_measure_value(value, reference_value):
    # 65535 = max. value ADC.read_u16()
    return reference_value - (reference_value * value // 65535)



def main():
    poti = ADC(Pin(POTI_PIN))
    poti.attent(poti.ATTN_11DB)
    while True:
        print(translate_measure_value(poti.read_u16(), 100))
        sleep(0.1)


if __name__ == "__main__":
    main()
Doku:
https://docs.micropython.org/en/latest/ ... achine-adc

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten